Skip to content

Commit

Permalink
config, readme and working example, and faker typings in config
Browse files Browse the repository at this point in the history
  • Loading branch information
aexol committed Jan 9, 2024
1 parent b4efd1d commit 8568a51
Show file tree
Hide file tree
Showing 21 changed files with 187 additions and 26 deletions.
38 changes: 37 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,47 @@ Just run the CLI on your schema.
demeter schema.graphql
```

Mock server should be running on port 4000

## Configuration
Demeter will automatically create config file on the first start `.graphql.demeter.js`.

![](./readme.png)

As you can see if you provide type it will autocomplete faker values

```js
/** @type {import('graphql-demeter-core').FakerConfig} */
const config = {
objects: {
Card:{
description:{
type:"values",
values:["Very powerful card", "Most fire resistant character", "Good melee fighter"]
},
name:{
type:"values",
values:["Zeus", "Athena", "Hera", "Ares", "Kronos"]
},
image:{
type:"faker",
key:"internet.avatar"
}
}
},
scalars: {},
};
module.exports = config
```

## Development & Examples

1. Clone this repository
2. Install dependencies
3. Run npm run run-example

You should have your server running on port 4000 with sample schema. Feel free to modify schema locally to just test it with your schema.
You should have your server running on port 4000 with sample schema. Feel free to modify schema locally to just test it with your schema.

## Roadmap
[ ] - reload on config change
[ ] - add ai possibilities with OpenAI Key
21 changes: 21 additions & 0 deletions examples/olympus/.graphql.demeter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/** @type {import('graphql-demeter-core').FakerConfig} */
const config = {
objects: {
Card:{
description:{
type:"values",
values:["Very powerful card", "Most fire resistant character", "Good melee fighter"]
},
name:{
type:"values",
values:["Zeus", "Athena", "Hera", "Ares", "Kronos"]
},
image:{
type:"faker",
key:"internet.avatar"
}
}
},
scalars: {},
};
module.exports = config
8 changes: 8 additions & 0 deletions examples/olympus/example.query.gql
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
query Draw{
drawCard{
name
description
Attack
Defense
}
}
2 changes: 1 addition & 1 deletion examples/olympus/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"private": true,
"main": "index.js",
"scripts": {
"start": "demeter zeus.graphql"
"start": "node ../../node_modules/.bin/demeter zeus.graphql"
},
"author": "Aexol <[email protected]> (http://aexol.com)",
"license": "ISC",
Expand Down
21 changes: 21 additions & 0 deletions examples/olympus/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"incremental": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".graphql.demeter.js"],
"exclude": ["node_modules"]
}

7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@
"url": "https://github.com/graphql-editor/graphql-demeter.git"
},
"scripts": {
"build": "tspc",
"clean-packages":"rimraf packages/**/lib && rimraf packages/**/tsconfig.tsbuildinfo",
"build": "npm run clean-packages && npm run build --ws --if-present",
"lint": "tspc && eslint \"./packages/**/src/**/*.{ts,js}\" --quiet --fix",
"cli": "node ./packages/graphql-demeter/lib/index.js",
"run-example":"npm run build && npm run start -w olympus",
"example": "npm run start -w olympus",
"run-example": "npm run build && npm run example",
"test": "jest"
},
"devDependencies": {
Expand All @@ -32,6 +34,7 @@
"husky": "^8.0.3",
"jest": "^29.7.0",
"prettier": "^3.1.1",
"rimraf": "^5.0.5",
"ts-jest": "^29.1.1",
"ts-node": "^10.9.2",
"ts-patch": "^3.1.1",
Expand Down
3 changes: 2 additions & 1 deletion packages/graphql-demeter-core/.eslintrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
"extends": ["../../.eslintrc"]
"extends": ["../../.eslintrc"],
"ignorePatterns":["lib"]
}
4 changes: 2 additions & 2 deletions packages/graphql-demeter-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"main": "./lib/index.js",
"author": "GraphQL Editor, Artur Czemiel",
"scripts": {
"build": "tspc --build tsconfig.build.json",
"start": "tspc --build tsconfig.build.json --watch"
"build": "tspc",
"start": "tspc --watch"
},
"repository": {
"type": "git",
Expand Down
52 changes: 48 additions & 4 deletions packages/graphql-demeter-core/src/MockServer/models.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,51 @@
export type FakerConfiguratedField = {
type: string;
values?: Array<string | number>;
};
import type { faker } from '@faker-js/faker';

type FakerType = typeof faker;
type FakerFunctionKey =
| 'address'
| 'commerce'
| 'company'
| 'database'
| 'date'
| 'finance'
| 'hacker'
| 'helpers'
| 'internet'
| 'lorem'
| 'name'
| 'phone'
| 'random'
| 'system';

type Join<Key, Previous, TKey extends number | string = string> = Key extends TKey
? Previous extends TKey
? `${Key}${'.'}${Previous}`
: never
: never;

type Previous = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...0[]];

export type Paths<TEntity, TDepth extends number = 3, TKey extends number | string = string> = [TDepth] extends [never]
? never
: TEntity extends object
? {
[Key in keyof TEntity]-?: Key extends TKey
? `${Key}` | Join<Key, Paths<TEntity[Key], Previous[TDepth]>>
: never;
}[keyof TEntity]
: '';

type AllowedFakerStrings = Exclude<Paths<Pick<FakerType, FakerFunctionKey>>, FakerFunctionKey>;

export type FakerConfiguratedField =
| {
type: 'values';
values: Array<string | number>;
}
| {
type: 'faker';
key: AllowedFakerStrings;
};

export type FakerConfig = {
objects: Record<string, Record<string, FakerConfiguratedField>> | undefined;
Expand Down
5 changes: 3 additions & 2 deletions packages/graphql-demeter-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export const createFakeResolvers = (schemaString: string, fakerConfig?: FakerCon
a.name,
() => {
const resolverValues = fakerConfig?.objects?.[n.name]?.[a.name];
if (resolverValues?.values && resolverValues.values.length) {
if (resolverValues?.type === 'values' && resolverValues.values && resolverValues.values.length) {
return mockValue(a.type.fieldType, () => {
if (!resolverValues.values?.length) throw new Error('Invalid values length 0');
const chosenValue = Math.floor(Math.random() * resolverValues.values.length);
Expand All @@ -59,7 +59,8 @@ export const createFakeResolvers = (schemaString: string, fakerConfig?: FakerCon
}
if ([ScalarTypes.ID, ScalarTypes.String].includes(tName as ScalarTypes)) {
return mockValue(a.type.fieldType, () => {
const valueFromFaker = fakeValue(a.name);
const valueFromFaker =
resolverValues?.type === 'faker' ? fakeValue(resolverValues.key) : fakeValue(a.name);
if (typeof valueFromFaker !== 'string') {
return fakeScalar(tName)();
}
Expand Down
4 changes: 0 additions & 4 deletions packages/graphql-demeter-core/tsconfig.build.json

This file was deleted.

2 changes: 1 addition & 1 deletion packages/graphql-demeter-core/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"strict": true,
"outDir": "./lib",
"lib": ["ESNext", "DOM", "DOM.Iterable"],
"rootDir": "./",
"rootDir": "./src",
"baseUrl": "./src",
"composite": true,
"paths": {
Expand Down
3 changes: 2 additions & 1 deletion packages/graphql-demeter/.eslintrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
"extends": ["../../.eslintrc"]
"extends": ["../../.eslintrc"],
"ignorePatterns":["lib"]
}
4 changes: 2 additions & 2 deletions packages/graphql-demeter/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
"version": "1.0.0",
"private": false,
"scripts": {
"start": "tspc --build tsconfig.build.json --watch",
"build": "tspc --build tsconfig.build.json"
"start": "tspc --watch",
"build": "tspc"
},
"author": "GraphQL Editor, Artur Czemiel",
"license": "MIT",
Expand Down
25 changes: 24 additions & 1 deletion packages/graphql-demeter/src/CLIClass.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { runMockServer } from '@/server.js';
import { FakerConfig } from 'graphql-demeter-core';
import { join } from 'node:path';
import * as fs from 'fs';
/**
* basic yargs interface
*/
interface Yargs {
[x: string]: unknown;
url: string | undefined;
config: string | undefined;
_: (string | number)[];
$0: string;
}
Expand All @@ -18,6 +21,22 @@ type CliArgs = Yargs;
* Main class for controlling CLI
*/
export class CLI {
static getConfig = async (configPath: string): Promise<FakerConfig> => {
const fullConfigPath = join(process.cwd(), configPath);
const configExists = fs.existsSync(fullConfigPath);
if (!configExists) {
fs.writeFileSync(
fullConfigPath,
`const config = {
objects: {},
scalars: {},
};
module.exports = config`,
);
}

return import(fullConfigPath).then((d) => d.default);
};
/**
* Execute yargs provided args
*/
Expand All @@ -31,6 +50,10 @@ export class CLI {
throw new Error('First argument should be path to the schema file');
}
const schemaFileContent = fs.readFileSync(schemaFile, 'utf-8');
runMockServer(schemaFileContent);
const configPath = args.config || CONFIG;
const configFile = await CLI.getConfig(configPath);
runMockServer(schemaFileContent, configFile);
};
}

const CONFIG = '.graphql.demeter.js';
6 changes: 6 additions & 0 deletions packages/graphql-demeter/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env node

import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';
import { CLI } from '@/CLIClass.js';
Expand All @@ -17,5 +18,10 @@ demeter [path] [output_path] [options]
describe: 'Get schema in-memory from url',
type: 'string',
})
.option('config', {
alias: 'c',
describe: 'GraphQL Demeter config path',
type: 'string',
})
.demandCommand(1).argv;
CLI.execute(args);
3 changes: 0 additions & 3 deletions packages/graphql-demeter/tsconfig.build.json

This file was deleted.

2 changes: 1 addition & 1 deletion packages/graphql-demeter/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"strict": true,
"outDir": "./lib",
"lib": ["ESNext", "DOM", "DOM.Iterable"],
"rootDir": "./",
"rootDir": "./src",
"baseUrl": "./src",
"typeRoots": ["../../node_modules/@types"],
"paths": {
Expand Down
Binary file added readme.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
},
{
"path": "./packages/graphql-demeter"
},
{
"path": "./examples/olympus"
}
]
}

0 comments on commit 8568a51

Please sign in to comment.