Skip to content

Commit

Permalink
feat(core): add support for loading GraphQL schema from js export file
Browse files Browse the repository at this point in the history
  • Loading branch information
dotansimha committed Dec 29, 2016
1 parent 82b565e commit 1587ef7
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 16 deletions.
23 changes: 12 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,18 @@ CLI usage is as follow:

Allowed flags:

| Flag Name | Type | Description |
|-----------------|----------|----------------------------------------------------------------------------------------|
| -f,--file | String | Introspection JSON file, must provide file or URL flag |
| -u,--url | String | GraphQL server endpoint to fetch the introspection from, must provide URL or file flag |
| -h,--header | String | Header to add to the introspection HTTP request when using --url |
| -t,--template | String | Template name, for example: "typescript" |
| -o,--out | String | Path for output file/directory. When using single-file generator specify filename, and when using multiple-files generator specify a directory |
| -nm,--no-model | void | If specified, server side schema won't be generated through the template (enums won't omit) |
| -nd,--no-documents | void | If specified, client side documents won't be generated through the template |
| -d,--dev | void | Turns ON development mode - prints output to console instead of files |
| documents... | [String] | Space separated paths of `.graphql` files or code files (glob path is supported) that contains GraphQL documents inside strings, or with `gql` tag (JavaScript), this field is optional - if no documents specified, only server side schema types will be generated |
| Flag Name | Type | Description |
|--------------------|----------|----------------------------------------------------------------------------------------|
| -f,--file | String | Introspection JSON file, must provide file or URL flag |
| -u,--url | String | GraphQL server endpoint to fetch the introspection from, must provide URL or file flag |
| -e,--export | String | Path to a JavaScript (es5/6) file that exports (as default export) your `GraphQLSchema` object |
| -h,--header | String | Header to add to the introspection HTTP request when using --url |
| -t,--template | String | Template name, for example: "typescript" |
| -o,--out | String | Path for output file/directory. When using single-file generator specify filename, and when using multiple-files generator specify a directory |
| -m,--no-schema | void | If specified, server side schema won't be generated through the template (enums won't omit) |
| -c,--no-documents | void | If specified, client side documents won't be generated through the template |
| -d,--dev | void | Turns ON development mode - prints output to console instead of files |
| documents... | [String] | Space separated paths of `.graphql` files or code files (glob path is supported) that contains GraphQL documents inside strings, or with `gql` tag (JavaScript), this field is optional - if no documents specified, only server side schema types will be generated |

**Usage examples:***

Expand Down
15 changes: 15 additions & 0 deletions dev-test/githunt/schema-export.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const GraphQL = require('graphql');

module.exports = new GraphQL.GraphQLSchema({
query: new GraphQL.GraphQLObjectType({
name: 'RootQueryType',
fields: {
hello: {
type: GraphQL.GraphQLString,
resolve() {
return 'world';
}
}
}
})
});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"debug": "cd dist && node --inspect --debug-brk gql-gen.js",
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s",
"create-git-tag": "git tag $(cat package.json | $(npm bin)/json version)",
"dev": "cd dist && nodemon --ext ts,js,d.ts,template,graphql,json,handlebars gql-gen.js --dev --file ../dev-test/githunt/schema.json --template ts --out ../dev-test/githunt/typings.d.ts",
"dev": "cd dist && nodemon --ext ts,js,d.ts,template,graphql,json,handlebars gql-gen.js --dev --export ../dev-test/githunt/schema-export.js --template ts --out ../dev-test/githunt/typings.d.ts",
"prepare": "npm run build && npm run test && npm run create-git-tag && git push && git push --tags",
"test": "jest"
},
Expand Down
16 changes: 12 additions & 4 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {introspectionFromUrl} from './introspection-from-url';
import {introspectionFromFile} from './introspection-from-file';
import {documentsFromGlobs} from './documents-glob';
import {getTemplateGenerator} from './template-loader';
import {introspectionFromExport} from './introspection-from-export';

function collect(val, memo) {
memo.push(val);
Expand All @@ -17,10 +18,11 @@ export const initCLI = (args): commander.IExportedCommand => {
.option('-d, --dev', 'Turn on development mode - prints results to console')
.option('-f, --file <filePath>', 'Parse local GraphQL introspection JSON file')
.option('-u, --url <graphql-endpoint>', 'Parse remote GraphQL endpoint as introspection file')
.option('-u, --export <export-file>', 'Path to a JavaScript (es5/6) file that exports (as default export) your `GraphQLSchema` object')
.option('-h, --header [header]', 'Header to add to the introspection HTTP request when using --url', collect, [])
.option('-t, --template <template-name>', 'Language/platform name templates')
.option('-nm, --no-schema', 'Generates only client side documents, without server side schema types')
.option('-nd, --no-documents', 'Generates only server side schema types, without client side documents')
.option('-m, --no-schema', 'Generates only client side documents, without server side schema types')
.option('-c, --no-documents', 'Generates only server side schema types, without client side documents')
.option('-o, --out <path>', 'Output file(s) path', String, './')
.arguments('<options> [documents...]')
.parse(args);
Expand All @@ -42,11 +44,12 @@ export const cliError = (err: string) => {
export const validateCliOptions = (options) => {
const file = options['file'];
const url = options['url'];
const fsExport = options['export'];
const template = options['template'];
const out = options['out'];

if (!file && !url) {
cliError('Please specify one of --file or --url flags!');
if (!file && !url && !fsExport) {
cliError('Please specify one of --file, --url or --export flags!');
}

if (!template) {
Expand All @@ -57,6 +60,7 @@ export const validateCliOptions = (options) => {
export const transformOptions = (options): Promise<TransformedOptions> => {
const file: string = options['file'];
const url: string = options['url'];
const fsExport: string = options['export'];
const documents: string[] = options['args'] || [];
const template: string = options['template'];
const out: string = options['out'];
Expand All @@ -77,6 +81,10 @@ export const transformOptions = (options): Promise<TransformedOptions> => {
else if (url) {
introspectionPromise = introspectionFromUrl(url, headers);
}
else if (fsExport) {
introspectionPromise = introspectionFromExport(fsExport);
}


const documentsPromise = documentsFromGlobs(documents);
const generatorTemplatePromise = getTemplateGenerator(template);
Expand Down
27 changes: 27 additions & 0 deletions src/introspection-from-export.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import * as fs from 'fs';
import {IntrospectionQuery} from 'graphql/utilities/introspectionQuery';
import {GraphQLSchema} from 'graphql/type/schema';
import { graphql, introspectionQuery } from 'graphql';

export const introspectionFromExport = (file: string) => {
return new Promise<IntrospectionQuery>((resolve, reject) => {
if (fs.existsSync(file)) {
try {
const schema = require(file);

if (schema && schema instanceof GraphQLSchema) {
resolve(graphql(schema, introspectionQuery).then(res => res.data));
}
else {
reject(new Error(`Invalid export from export file ${file}, make sure to default export your GraphQLSchema object!`));
}
}
catch (e) {
reject(e);
}
}
else {
reject(`Unable to locate introspection export file: ${file}`);
}
});
};

0 comments on commit 1587ef7

Please sign in to comment.