@khanacademy/graphql-flow 0.1.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.babelrc +1 -1
- package/CHANGELOG.md +23 -0
- package/Readme.md +15 -0
- package/dist/cli/config.js +4 -4
- package/dist/cli/config.js.flow +3 -0
- package/dist/cli/config.js.map +1 -1
- package/dist/cli/run.js +18 -14
- package/dist/cli/run.js.flow +18 -14
- package/dist/cli/run.js.map +1 -1
- package/dist/generateResponseType.js +152 -53
- package/dist/generateResponseType.js.flow +223 -65
- package/dist/generateResponseType.js.map +1 -1
- package/dist/generateTypeFiles.js +80 -39
- package/dist/generateTypeFiles.js.flow +75 -35
- package/dist/generateTypeFiles.js.map +1 -1
- package/dist/index.js +48 -6
- package/dist/index.js.flow +54 -4
- package/dist/index.js.map +1 -1
- package/dist/parser/parse.js +27 -17
- package/dist/parser/parse.js.map +1 -1
- package/dist/types.js.flow +6 -0
- package/package.json +1 -1
- package/src/__test__/example-schema.graphql +1 -1
- package/src/__test__/generateTypeFileContents.test.js +61 -0
- package/src/__test__/graphql-flow.test.js +243 -32
- package/src/cli/config.js +3 -0
- package/src/cli/run.js +18 -14
- package/src/generateResponseType.js +223 -65
- package/src/generateTypeFiles.js +75 -35
- package/src/index.js +54 -4
- package/src/types.js +6 -0
package/.babelrc
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# @khanacademy/graphql-flow
|
|
2
2
|
|
|
3
|
+
## 0.2.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 31dd235: Compile for node 12 instead of 16
|
|
8
|
+
|
|
9
|
+
## 0.2.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- e8a8025: Add shebang to the exported binary, so that it runs
|
|
14
|
+
|
|
15
|
+
## 0.2.0
|
|
16
|
+
|
|
17
|
+
### Minor Changes
|
|
18
|
+
|
|
19
|
+
- d9a8229: Generate types for fragments!
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- 7497164: Fix a bug in index file generation that resulted in duplicate entries
|
|
24
|
+
- 26abf9b: Add options for specifying the name of the generated directory, and for exporting the response and variables types.
|
|
25
|
+
|
|
3
26
|
## 0.1.0
|
|
4
27
|
|
|
5
28
|
### Minor Changes
|
package/Readme.md
CHANGED
|
@@ -42,6 +42,15 @@ type Options = {
|
|
|
42
42
|
readOnlyArray: boolean = true,
|
|
43
43
|
scalars: {[key: string]: 'string' | 'boolean' | 'number'}
|
|
44
44
|
|
|
45
|
+
// Specify the name of the generated types directory
|
|
46
|
+
generatedDirectory: string = '__generated__',
|
|
47
|
+
|
|
48
|
+
// The default generated type contains both the types of the response
|
|
49
|
+
// and the variables, combined as [operatioName]Type. Setting
|
|
50
|
+
// `splitTypes = true` adds the additional exports [operationName]
|
|
51
|
+
// (for the response) and [operationName]Variables (for the variables).
|
|
52
|
+
splitTypes?: boolean,
|
|
53
|
+
|
|
45
54
|
// Specify an opt-in pragma that must be present in a graphql string source
|
|
46
55
|
// in order for it to be picked up and processed
|
|
47
56
|
// e.g. set this to `"# @autogen\n"` to only generate types for queries that
|
|
@@ -55,6 +64,12 @@ type Options = {
|
|
|
55
64
|
|
|
56
65
|
// Any graphql operations containing ignorePragma will be skipped
|
|
57
66
|
ignorePragma?: string,
|
|
67
|
+
|
|
68
|
+
// Set to true to mirror gqlgen's behavior of exporting all
|
|
69
|
+
// nested object types within the response type.
|
|
70
|
+
// Names are generated by concatenating the attribute names
|
|
71
|
+
// of the path to the object type, separated by underscores.
|
|
72
|
+
exportAllObjectTypes?: boolean,
|
|
58
73
|
}
|
|
59
74
|
```
|
|
60
75
|
|
package/dist/cli/config.js
CHANGED
|
@@ -16,7 +16,7 @@ var _path = _interopRequireDefault(require("path"));
|
|
|
16
16
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
17
17
|
|
|
18
18
|
const loadConfigFile = configFile => {
|
|
19
|
-
var _data$excludes;
|
|
19
|
+
var _data$options, _data$excludes$map, _data$excludes;
|
|
20
20
|
|
|
21
21
|
// eslint-disable-next-line flowtype-errors/uncovered
|
|
22
22
|
const data = JSON.parse(_fs.default.readFileSync(configFile, 'utf8'));
|
|
@@ -28,7 +28,7 @@ const loadConfigFile = configFile => {
|
|
|
28
28
|
});
|
|
29
29
|
|
|
30
30
|
if (data.options) {
|
|
31
|
-
const externalOptionsKeys = ['pragma', 'loosePragma', 'ignorePragma', 'scalars', 'strictNullability', 'regenerateCommand', 'readOnlyArray'];
|
|
31
|
+
const externalOptionsKeys = ['pragma', 'loosePragma', 'ignorePragma', 'scalars', 'strictNullability', 'regenerateCommand', 'readOnlyArray', 'splitTypes', 'generatedDirectory', 'exportAllObjectTypes'];
|
|
32
32
|
Object.keys(data.options).forEach(k => {
|
|
33
33
|
if (!externalOptionsKeys.includes(k)) {
|
|
34
34
|
throw new Error(`Invalid option in config file ${configFile}: ${k}. Allowed options: ${externalOptionsKeys.join(', ')}`);
|
|
@@ -37,8 +37,8 @@ const loadConfigFile = configFile => {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
return {
|
|
40
|
-
options: data.options
|
|
41
|
-
excludes: ((_data$excludes = data.excludes) === null || _data$excludes === void 0 ? void 0 : _data$excludes.map(string => new RegExp(string)))
|
|
40
|
+
options: (_data$options = data.options) !== null && _data$options !== void 0 ? _data$options : {},
|
|
41
|
+
excludes: (_data$excludes$map = (_data$excludes = data.excludes) === null || _data$excludes === void 0 ? void 0 : _data$excludes.map(string => new RegExp(string))) !== null && _data$excludes$map !== void 0 ? _data$excludes$map : [],
|
|
42
42
|
schemaFilePath: _path.default.join(_path.default.dirname(configFile), data.schemaFilePath)
|
|
43
43
|
};
|
|
44
44
|
};
|
package/dist/cli/config.js.flow
CHANGED
|
@@ -53,6 +53,9 @@ export const loadConfigFile = (configFile: string): CliConfig => {
|
|
|
53
53
|
'strictNullability',
|
|
54
54
|
'regenerateCommand',
|
|
55
55
|
'readOnlyArray',
|
|
56
|
+
'splitTypes',
|
|
57
|
+
'generatedDirectory',
|
|
58
|
+
'exportAllObjectTypes',
|
|
56
59
|
];
|
|
57
60
|
Object.keys(data.options).forEach((k) => {
|
|
58
61
|
if (!externalOptionsKeys.includes(k)) {
|
package/dist/cli/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/config.js"],"names":["loadConfigFile","configFile","data","JSON","parse","fs","readFileSync","toplevelKeys","Object","keys","forEach","k","includes","Error","join","options","externalOptionsKeys","excludes","map","string","RegExp","schemaFilePath","path","dirname","getSchemas","raw","endsWith","schemaForValidation","queryResponse","descriptions","schemaForTypeGeneration","introspectionData"],"mappings":";;;;;;;AAKA;;AAEA;;AACA;;AAOA;;;;AAkBO,MAAMA,cAAc,GAAIC,UAAD,IAAmC;AAAA;;AAC7D;AACA,QAAMC,IAAgB,GAAGC,IAAI,CAACC,KAAL,CAAWC,YAAGC,YAAH,CAAgBL,UAAhB,EAA4B,MAA5B,CAAX,CAAzB;AACA,QAAMM,YAAY,GAAG,CAAC,UAAD,EAAa,gBAAb,EAA+B,SAA/B,CAArB;AACAC,EAAAA,MAAM,CAACC,IAAP,CAAYP,IAAZ,EAAkBQ,OAAlB,CAA2BC,CAAD,IAAO;AAC7B,QAAI,CAACJ,YAAY,CAACK,QAAb,CAAsBD,CAAtB,CAAL,EAA+B;AAC3B,YAAM,IAAIE,KAAJ,CACD,oCAAmCZ,UAAW,KAAIU,CAAE,yBAAwBJ,YAAY,CAACO,IAAb,CACzE,IADyE,CAE3E,EAHA,CAAN;AAKH;AACJ,GARD;;AASA,MAAIZ,IAAI,CAACa,OAAT,EAAkB;AACd,UAAMC,mBAAmB,GAAG,CACxB,QADwB,EAExB,aAFwB,EAGxB,cAHwB,EAIxB,SAJwB,EAKxB,mBALwB,EAMxB,mBANwB,EAOxB,eAPwB,CAA5B;
|
|
1
|
+
{"version":3,"sources":["../../src/cli/config.js"],"names":["loadConfigFile","configFile","data","JSON","parse","fs","readFileSync","toplevelKeys","Object","keys","forEach","k","includes","Error","join","options","externalOptionsKeys","excludes","map","string","RegExp","schemaFilePath","path","dirname","getSchemas","raw","endsWith","schemaForValidation","queryResponse","descriptions","schemaForTypeGeneration","introspectionData"],"mappings":";;;;;;;AAKA;;AAEA;;AACA;;AAOA;;;;AAkBO,MAAMA,cAAc,GAAIC,UAAD,IAAmC;AAAA;;AAC7D;AACA,QAAMC,IAAgB,GAAGC,IAAI,CAACC,KAAL,CAAWC,YAAGC,YAAH,CAAgBL,UAAhB,EAA4B,MAA5B,CAAX,CAAzB;AACA,QAAMM,YAAY,GAAG,CAAC,UAAD,EAAa,gBAAb,EAA+B,SAA/B,CAArB;AACAC,EAAAA,MAAM,CAACC,IAAP,CAAYP,IAAZ,EAAkBQ,OAAlB,CAA2BC,CAAD,IAAO;AAC7B,QAAI,CAACJ,YAAY,CAACK,QAAb,CAAsBD,CAAtB,CAAL,EAA+B;AAC3B,YAAM,IAAIE,KAAJ,CACD,oCAAmCZ,UAAW,KAAIU,CAAE,yBAAwBJ,YAAY,CAACO,IAAb,CACzE,IADyE,CAE3E,EAHA,CAAN;AAKH;AACJ,GARD;;AASA,MAAIZ,IAAI,CAACa,OAAT,EAAkB;AACd,UAAMC,mBAAmB,GAAG,CACxB,QADwB,EAExB,aAFwB,EAGxB,cAHwB,EAIxB,SAJwB,EAKxB,mBALwB,EAMxB,mBANwB,EAOxB,eAPwB,EAQxB,YARwB,EASxB,oBATwB,EAUxB,sBAVwB,CAA5B;AAYAR,IAAAA,MAAM,CAACC,IAAP,CAAYP,IAAI,CAACa,OAAjB,EAA0BL,OAA1B,CAAmCC,CAAD,IAAO;AACrC,UAAI,CAACK,mBAAmB,CAACJ,QAApB,CAA6BD,CAA7B,CAAL,EAAsC;AAClC,cAAM,IAAIE,KAAJ,CACD,iCAAgCZ,UAAW,KAAIU,CAAE,sBAAqBK,mBAAmB,CAACF,IAApB,CACnE,IADmE,CAErE,EAHA,CAAN;AAKH;AACJ,KARD;AASH;;AACD,SAAO;AACHC,IAAAA,OAAO,mBAAEb,IAAI,CAACa,OAAP,yDAAkB,EADtB;AAEHE,IAAAA,QAAQ,0CAAEf,IAAI,CAACe,QAAP,mDAAE,eAAeC,GAAf,CAAoBC,MAAD,IAAY,IAAIC,MAAJ,CAAWD,MAAX,CAA/B,CAAF,mEAAwD,EAF7D;AAGHE,IAAAA,cAAc,EAAEC,cAAKR,IAAL,CACZQ,cAAKC,OAAL,CAAatB,UAAb,CADY,EAEZC,IAAI,CAACmB,cAFO;AAHb,GAAP;AAQH,CA5CM;AA8CP;AACA;AACA;;;;;AACO,MAAMG,UAAU,GAAIH,cAAD,IAAqD;AAC3E,QAAMI,GAAG,GAAGpB,YAAGC,YAAH,CAAgBe,cAAhB,EAAgC,MAAhC,CAAZ;;AACA,MAAIA,cAAc,CAACK,QAAf,CAAwB,UAAxB,CAAJ,EAAyC;AACrC,UAAMC,mBAAmB,GAAG,0BAAYF,GAAZ,CAA5B;AACA,UAAMG,aAAa,GAAG,0BAClBD,mBADkB,EAElB,oCAAsB;AAACE,MAAAA,YAAY,EAAE;AAAf,KAAtB,CAFkB,CAAtB;AAIA,UAAMC,uBAAuB,GAAG,+DAC5B;AACEF,IAAAA,aAAa,CAAC1B,IAFY,CAAhC;AAIA,WAAO,CAACyB,mBAAD,EAAsBG,uBAAtB,CAAP;AACH,GAXD,MAWO;AACH;AACA,UAAMC,iBAAqC,GAAG5B,IAAI,CAACC,KAAL,CAAWqB,GAAX,CAA9C;AACA,UAAME,mBAAmB,GAAG,gCAAkBI,iBAAlB,CAA5B;AACA,UAAMD,uBAAuB,GACzB,8DAA4BC,iBAA5B,CADJ;AAEA,WAAO,CAACJ,mBAAD,EAAsBG,uBAAtB,CAAP;AACH;AACJ,CArBM","sourcesContent":["// @flow\nimport type {ExternalOptions} from '../generateTypeFiles';\nimport type {Schema} from '../types';\nimport type {GraphQLSchema} from 'graphql/type/schema';\n\nimport {schemaFromIntrospectionData} from '../schemaFromIntrospectionData';\n\nimport fs from 'fs';\nimport {\n buildClientSchema,\n buildSchema,\n getIntrospectionQuery,\n graphqlSync,\n type IntrospectionQuery,\n} from 'graphql';\nimport path from 'path';\n\nexport type CliConfig = {\n excludes: Array<RegExp>,\n schemaFilePath: string,\n options: ExternalOptions,\n};\n\n/**\n * This is the json-compatible form of the config\n * object.\n */\ntype JSONConfig = {\n excludes?: Array<string>,\n schemaFilePath: string,\n options?: ExternalOptions,\n};\n\nexport const loadConfigFile = (configFile: string): CliConfig => {\n // eslint-disable-next-line flowtype-errors/uncovered\n const data: JSONConfig = JSON.parse(fs.readFileSync(configFile, 'utf8'));\n const toplevelKeys = ['excludes', 'schemaFilePath', 'options'];\n Object.keys(data).forEach((k) => {\n if (!toplevelKeys.includes(k)) {\n throw new Error(\n `Invalid attribute in config file ${configFile}: ${k}. Allowed attributes: ${toplevelKeys.join(\n ', ',\n )}`,\n );\n }\n });\n if (data.options) {\n const externalOptionsKeys = [\n 'pragma',\n 'loosePragma',\n 'ignorePragma',\n 'scalars',\n 'strictNullability',\n 'regenerateCommand',\n 'readOnlyArray',\n 'splitTypes',\n 'generatedDirectory',\n 'exportAllObjectTypes',\n ];\n Object.keys(data.options).forEach((k) => {\n if (!externalOptionsKeys.includes(k)) {\n throw new Error(\n `Invalid option in config file ${configFile}: ${k}. Allowed options: ${externalOptionsKeys.join(\n ', ',\n )}`,\n );\n }\n });\n }\n return {\n options: data.options ?? {},\n excludes: data.excludes?.map((string) => new RegExp(string)) ?? [],\n schemaFilePath: path.join(\n path.dirname(configFile),\n data.schemaFilePath,\n ),\n };\n};\n\n/**\n * Loads a .json 'introspection query response', or a .graphql schema definition.\n */\nexport const getSchemas = (schemaFilePath: string): [GraphQLSchema, Schema] => {\n const raw = fs.readFileSync(schemaFilePath, 'utf8');\n if (schemaFilePath.endsWith('.graphql')) {\n const schemaForValidation = buildSchema(raw);\n const queryResponse = graphqlSync(\n schemaForValidation,\n getIntrospectionQuery({descriptions: true}),\n );\n const schemaForTypeGeneration = schemaFromIntrospectionData(\n // eslint-disable-next-line flowtype-errors/uncovered\n ((queryResponse.data: any): IntrospectionQuery),\n );\n return [schemaForValidation, schemaForTypeGeneration];\n } else {\n // eslint-disable-next-line flowtype-errors/uncovered\n const introspectionData: IntrospectionQuery = JSON.parse(raw);\n const schemaForValidation = buildClientSchema(introspectionData);\n const schemaForTypeGeneration =\n schemaFromIntrospectionData(introspectionData);\n return [schemaForValidation, schemaForTypeGeneration];\n }\n};\n"],"file":"config.js"}
|
package/dist/cli/run.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/* eslint-disable no-console */
|
|
1
4
|
"use strict";
|
|
2
5
|
|
|
3
6
|
var _generateTypeFiles = require("../generateTypeFiles");
|
|
@@ -22,7 +25,6 @@ var _path = _interopRequireDefault(require("path"));
|
|
|
22
25
|
|
|
23
26
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
24
27
|
|
|
25
|
-
/* eslint-disable no-console */
|
|
26
28
|
// eslint-disable-line flowtype-errors/uncovered
|
|
27
29
|
|
|
28
30
|
/**
|
|
@@ -113,28 +115,30 @@ Object.keys(resolved).forEach(k => {
|
|
|
113
115
|
const rawSource = raw.literals[0];
|
|
114
116
|
const processedOptions = (0, _generateTypeFiles.processPragmas)(config.options, rawSource);
|
|
115
117
|
|
|
116
|
-
if (!
|
|
118
|
+
if (!processedOptions) {
|
|
117
119
|
return;
|
|
118
120
|
} // eslint-disable-next-line flowtype-errors/uncovered
|
|
119
121
|
|
|
120
122
|
|
|
121
123
|
const withTypeNames = (0, _apolloUtilities.addTypenameToDocument)(document);
|
|
122
124
|
const printed = (0, _printer.print)(withTypeNames);
|
|
123
|
-
/* eslint-disable flowtype-errors/uncovered */
|
|
124
125
|
|
|
125
|
-
|
|
126
|
-
|
|
126
|
+
if (hasNonFragments) {
|
|
127
|
+
/* eslint-disable flowtype-errors/uncovered */
|
|
128
|
+
const errors = (0, _validation.validate)(schemaForValidation, withTypeNames);
|
|
129
|
+
/* eslint-disable flowtype-errors/uncovered */
|
|
130
|
+
|
|
131
|
+
if (errors.length) {
|
|
132
|
+
errors.forEach(error => {
|
|
133
|
+
console.error(`Schema validation found errors for ${raw.loc.path}!`);
|
|
134
|
+
console.error(printed);
|
|
135
|
+
console.error(error);
|
|
136
|
+
validationFailures++;
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
/* eslint-enable flowtype-errors/uncovered */
|
|
127
140
|
|
|
128
|
-
if (errors.length) {
|
|
129
|
-
errors.forEach(error => {
|
|
130
|
-
console.error(`Schema validation found errors for ${raw.loc.path}!`);
|
|
131
|
-
console.error(printed);
|
|
132
|
-
console.error(error);
|
|
133
|
-
validationFailures++;
|
|
134
|
-
});
|
|
135
141
|
}
|
|
136
|
-
/* eslint-enable flowtype-errors/uncovered */
|
|
137
|
-
|
|
138
142
|
|
|
139
143
|
try {
|
|
140
144
|
(0, _generateTypeFiles.generateTypeFiles)(raw.loc.path, schemaForTypeGeneration, withTypeNames, processedOptions); // eslint-disable-next-line flowtype-errors/uncovered
|
package/dist/cli/run.js.flow
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
1
2
|
// @flow
|
|
2
3
|
/* eslint-disable no-console */
|
|
3
4
|
import {generateTypeFiles, processPragmas} from '../generateTypeFiles';
|
|
@@ -113,27 +114,30 @@ Object.keys(resolved).forEach((k) => {
|
|
|
113
114
|
);
|
|
114
115
|
const rawSource: string = raw.literals[0];
|
|
115
116
|
const processedOptions = processPragmas(config.options, rawSource);
|
|
116
|
-
if (!
|
|
117
|
+
if (!processedOptions) {
|
|
117
118
|
return;
|
|
118
119
|
}
|
|
119
120
|
|
|
120
121
|
// eslint-disable-next-line flowtype-errors/uncovered
|
|
121
122
|
const withTypeNames: DocumentNode = addTypenameToDocument(document);
|
|
122
123
|
const printed = print(withTypeNames);
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
errors
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
124
|
+
|
|
125
|
+
if (hasNonFragments) {
|
|
126
|
+
/* eslint-disable flowtype-errors/uncovered */
|
|
127
|
+
const errors = validate(schemaForValidation, withTypeNames);
|
|
128
|
+
/* eslint-disable flowtype-errors/uncovered */
|
|
129
|
+
if (errors.length) {
|
|
130
|
+
errors.forEach((error) => {
|
|
131
|
+
console.error(
|
|
132
|
+
`Schema validation found errors for ${raw.loc.path}!`,
|
|
133
|
+
);
|
|
134
|
+
console.error(printed);
|
|
135
|
+
console.error(error);
|
|
136
|
+
validationFailures++;
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
/* eslint-enable flowtype-errors/uncovered */
|
|
135
140
|
}
|
|
136
|
-
/* eslint-enable flowtype-errors/uncovered */
|
|
137
141
|
|
|
138
142
|
try {
|
|
139
143
|
generateTypeFiles(
|
package/dist/cli/run.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/run.js"],"names":["findGraphqlTagReferences","root","response","encoding","cwd","trim","split","map","relative","path","join","_","__","configFile","cliFiles","process","argv","console","log","exit","config","schemaForValidation","schemaForTypeGeneration","schemaFilePath","inputFiles","length","files","f","filesHadErrors","Object","keys","forEach","key","file","errors","error","message","resolved","loc","validationFailures","k","document","raw","excludes","some","rx","test","hasNonFragments","definitions","kind","rawSource","literals","processedOptions","options","withTypeNames","printed","err"],"mappings":";;AAEA;;AACA;;AACA;;AACA;;AAEA;;AAEA;;AACA;;AAEA;;AACA;;AACA;;;;
|
|
1
|
+
{"version":3,"sources":["../../src/cli/run.js"],"names":["findGraphqlTagReferences","root","response","encoding","cwd","trim","split","map","relative","path","join","_","__","configFile","cliFiles","process","argv","console","log","exit","config","schemaForValidation","schemaForTypeGeneration","schemaFilePath","inputFiles","length","files","f","filesHadErrors","Object","keys","forEach","key","file","errors","error","message","resolved","loc","validationFailures","k","document","raw","excludes","some","rx","test","hasNonFragments","definitions","kind","rawSource","literals","processedOptions","options","withTypeNames","printed","err"],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n// @flow\n/* eslint-disable no-console */\nimport {generateTypeFiles, processPragmas} from '../generateTypeFiles';\nimport {processFiles} from '../parser/parse';\nimport {resolveDocuments} from '../parser/resolve';\nimport {getSchemas, loadConfigFile} from './config';\n\nimport {addTypenameToDocument} from 'apollo-utilities'; // eslint-disable-line flowtype-errors/uncovered\n\nimport {execSync} from 'child_process';\nimport {readFileSync} from 'fs';\nimport {type DocumentNode} from 'graphql';\nimport {print} from 'graphql/language/printer';\nimport {validate} from 'graphql/validation';\nimport path from 'path';\n\n/**\n * This CLI tool executes the following steps:\n * 1) process options\n * 2) crawl files to find all operations and fragments, with\n * tagged template literals and expressions.\n * 3) resolve the found operations, passing the literals and\n * fragments into the `graphql-tag` function to produce\n * the DocumentNodes.\n * 4) generate types for all resolved Queries & Mutations\n */\n\n/** Step (1) */\n\nconst findGraphqlTagReferences = (root: string): Array<string> => {\n const response = execSync(\n \"git grep -I --word-regexp --name-only --fixed-strings 'graphql-tag' -- '*.js' '*.jsx'\",\n {\n encoding: 'utf8',\n cwd: root,\n },\n );\n return response\n .trim()\n .split('\\n')\n .map((relative) => path.join(root, relative));\n};\n\nconst [_, __, configFile, ...cliFiles] = process.argv;\n\nif (\n configFile === '-h' ||\n configFile === '--help' ||\n configFile === 'help' ||\n !configFile\n) {\n console.log(`graphql-flow\n\nUsage: graphql-flow [configFile.json] [filesToCrawl...]`);\n process.exit(1); // eslint-disable-line flowtype-errors/uncovered\n}\n\nconst config = loadConfigFile(configFile);\n\nconst [schemaForValidation, schemaForTypeGeneration] = getSchemas(\n config.schemaFilePath,\n);\n\nconst inputFiles = cliFiles.length\n ? cliFiles\n : findGraphqlTagReferences(process.cwd());\n\n/** Step (2) */\n\nconst files = processFiles(inputFiles, (f) => readFileSync(f, 'utf8'));\n\nlet filesHadErrors = false;\nObject.keys(files).forEach((key) => {\n const file = files[key];\n if (file.errors.length) {\n filesHadErrors = true;\n console.error(`Errors in ${file.path}`);\n file.errors.forEach((error) => {\n console.error(` - ${error.message}`);\n });\n }\n});\n\nif (filesHadErrors) {\n console.error('Aborting');\n process.exit(1); // eslint-disable-line flowtype-errors/uncovered\n}\n\n/** Step (3) */\n\nconst {resolved, errors} = resolveDocuments(files);\nif (errors.length) {\n errors.forEach((error) => {\n console.error(`Resolution error ${error.message} in ${error.loc.path}`);\n });\n console.error('Aborting');\n process.exit(1); // eslint-disable-line flowtype-errors/uncovered\n}\n\nconsole.log(Object.keys(resolved).length, 'resolved queries');\n\n/** Step (4) */\n\nlet validationFailures: number = 0;\n\nObject.keys(resolved).forEach((k) => {\n const {document, raw} = resolved[k];\n if (config.excludes.some((rx) => rx.test(raw.loc.path))) {\n return; // skip\n }\n const hasNonFragments = document.definitions.some(\n ({kind}) => kind !== 'FragmentDefinition',\n );\n const rawSource: string = raw.literals[0];\n const processedOptions = processPragmas(config.options, rawSource);\n if (!processedOptions) {\n return;\n }\n\n // eslint-disable-next-line flowtype-errors/uncovered\n const withTypeNames: DocumentNode = addTypenameToDocument(document);\n const printed = print(withTypeNames);\n\n if (hasNonFragments) {\n /* eslint-disable flowtype-errors/uncovered */\n const errors = validate(schemaForValidation, withTypeNames);\n /* eslint-disable flowtype-errors/uncovered */\n if (errors.length) {\n errors.forEach((error) => {\n console.error(\n `Schema validation found errors for ${raw.loc.path}!`,\n );\n console.error(printed);\n console.error(error);\n validationFailures++;\n });\n }\n /* eslint-enable flowtype-errors/uncovered */\n }\n\n try {\n generateTypeFiles(\n raw.loc.path,\n schemaForTypeGeneration,\n withTypeNames,\n processedOptions,\n );\n // eslint-disable-next-line flowtype-errors/uncovered\n } catch (err) {\n console.error(`Error while generating operation from ${raw.loc.path}`);\n console.error(printed);\n // eslint-disable-next-line flowtype-errors/uncovered\n console.error(err);\n validationFailures++;\n }\n});\n\nif (validationFailures) {\n console.error(\n `Encountered ${validationFailures} validation failures while printing types.`,\n );\n // eslint-disable-next-line flowtype-errors/uncovered\n process.exit(1);\n}\n"],"file":"run.js"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.unionOrInterfaceToFlow = exports.typeToFlow = exports.objectPropertiesToFlow = exports.generateResponseType = void 0;
|
|
6
|
+
exports.unionOrInterfaceToFlow = exports.typeToFlow = exports.objectPropertiesToFlow = exports.generateResponseType = exports.generateFragmentType = void 0;
|
|
7
7
|
|
|
8
8
|
var _generator = _interopRequireDefault(require("@babel/generator"));
|
|
9
9
|
|
|
@@ -29,6 +29,55 @@ const generateResponseType = (schema, query, config) => {
|
|
|
29
29
|
|
|
30
30
|
exports.generateResponseType = generateResponseType;
|
|
31
31
|
|
|
32
|
+
const sortedObjectTypeAnnotation = (config, properties) => {
|
|
33
|
+
const obj = babelTypes.objectTypeAnnotation(properties.sort((a, b) => {
|
|
34
|
+
if (a.type === 'ObjectTypeProperty' && b.type === 'ObjectTypeProperty') {
|
|
35
|
+
const aName = a.key.type === 'Identifier' ? a.key.name : '';
|
|
36
|
+
const bName = b.key.type === 'Identifier' ? b.key.name : '';
|
|
37
|
+
return aName < bName ? -1 : 1;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return 0;
|
|
41
|
+
}), undefined
|
|
42
|
+
/* indexers */
|
|
43
|
+
, undefined
|
|
44
|
+
/* callProperties */
|
|
45
|
+
, undefined
|
|
46
|
+
/* internalSlots */
|
|
47
|
+
, true
|
|
48
|
+
/* exact */
|
|
49
|
+
);
|
|
50
|
+
const name = config.path.join('_');
|
|
51
|
+
const isTopLevelType = config.path.length <= 1;
|
|
52
|
+
|
|
53
|
+
if (config.allObjectTypes != null && !isTopLevelType) {
|
|
54
|
+
config.allObjectTypes[name] = obj;
|
|
55
|
+
return babelTypes.genericTypeAnnotation(babelTypes.identifier(name));
|
|
56
|
+
} else {
|
|
57
|
+
return obj;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const generateFragmentType = (schema, fragment, config) => {
|
|
62
|
+
const onType = fragment.typeCondition.name.value;
|
|
63
|
+
let ast;
|
|
64
|
+
|
|
65
|
+
if (schema.typesByName[onType]) {
|
|
66
|
+
ast = sortedObjectTypeAnnotation(config, objectPropertiesToFlow(config, schema.typesByName[onType], onType, fragment.selectionSet.selections));
|
|
67
|
+
} else if (schema.interfacesByName[onType]) {
|
|
68
|
+
ast = unionOrInterfaceToFlow(config, config.schema.interfacesByName[onType], fragment.selectionSet.selections);
|
|
69
|
+
} else if (schema.unionsByName[onType]) {
|
|
70
|
+
ast = unionOrInterfaceToFlow(config, config.schema.unionsByName[onType], fragment.selectionSet.selections);
|
|
71
|
+
} else {
|
|
72
|
+
throw new Error(`Unknown ${onType}`);
|
|
73
|
+
} // eslint-disable-next-line flowtype-errors/uncovered
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
return (0, _generator.default)(ast).code;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
exports.generateFragmentType = generateFragmentType;
|
|
80
|
+
|
|
32
81
|
const _typeToFlow = (config, type, selection) => {
|
|
33
82
|
if (type.kind === 'SCALAR') {
|
|
34
83
|
return (0, _enums.scalarTypeToFlow)(config, type.name);
|
|
@@ -103,30 +152,32 @@ const typeToFlow = (config, type, selection) => {
|
|
|
103
152
|
|
|
104
153
|
exports.typeToFlow = typeToFlow;
|
|
105
154
|
|
|
106
|
-
const
|
|
155
|
+
const ensureOnlyOneTypenameProperty = properties => {
|
|
107
156
|
let seenTypeName = false;
|
|
108
|
-
return
|
|
157
|
+
return properties.filter(type => {
|
|
109
158
|
// The apollo-utilities "addTypeName" utility will add it
|
|
110
159
|
// even if it's already specified :( so we have to filter out
|
|
111
160
|
// the extra one here.
|
|
112
161
|
if (type.type === 'ObjectTypeProperty' && type.key.name === '__typename') {
|
|
162
|
+
const name = type.value.type === 'StringLiteralTypeAnnotation' ? type.value.value : 'INVALID';
|
|
163
|
+
|
|
113
164
|
if (seenTypeName) {
|
|
165
|
+
if (name !== seenTypeName) {
|
|
166
|
+
throw new Error(`Got two different type names ${name}, ${seenTypeName}`);
|
|
167
|
+
}
|
|
168
|
+
|
|
114
169
|
return false;
|
|
115
170
|
}
|
|
116
171
|
|
|
117
|
-
seenTypeName =
|
|
172
|
+
seenTypeName = name;
|
|
118
173
|
}
|
|
119
174
|
|
|
120
175
|
return true;
|
|
121
|
-
})
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
,
|
|
126
|
-
/* internalSlots */
|
|
127
|
-
, true
|
|
128
|
-
/* exact */
|
|
129
|
-
);
|
|
176
|
+
});
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
const querySelectionToObjectType = (config, selections, type, typeName) => {
|
|
180
|
+
return sortedObjectTypeAnnotation(config, ensureOnlyOneTypenameProperty(objectPropertiesToFlow(config, type, typeName, selections)));
|
|
130
181
|
};
|
|
131
182
|
|
|
132
183
|
const objectPropertiesToFlow = (config, type, typeName, selections) => {
|
|
@@ -134,9 +185,14 @@ const objectPropertiesToFlow = (config, type, typeName, selections) => {
|
|
|
134
185
|
switch (selection.kind) {
|
|
135
186
|
case 'InlineFragment':
|
|
136
187
|
{
|
|
137
|
-
var _selection$typeCondit;
|
|
188
|
+
var _selection$typeCondit, _selection$typeCondit2;
|
|
189
|
+
|
|
190
|
+
const newTypeName = (_selection$typeCondit = (_selection$typeCondit2 = selection.typeCondition) === null || _selection$typeCondit2 === void 0 ? void 0 : _selection$typeCondit2.name.value) !== null && _selection$typeCondit !== void 0 ? _selection$typeCondit : typeName;
|
|
191
|
+
|
|
192
|
+
if (newTypeName !== typeName) {
|
|
193
|
+
return [];
|
|
194
|
+
}
|
|
138
195
|
|
|
139
|
-
const newTypeName = ((_selection$typeCondit = selection.typeCondition) === null || _selection$typeCondit === void 0 ? void 0 : _selection$typeCondit.name.value) ?? typeName;
|
|
140
196
|
return objectPropertiesToFlow(config, config.schema.typesByName[newTypeName], newTypeName, selection.selectionSet.selections);
|
|
141
197
|
}
|
|
142
198
|
|
|
@@ -162,7 +218,9 @@ const objectPropertiesToFlow = (config, type, typeName, selections) => {
|
|
|
162
218
|
}
|
|
163
219
|
|
|
164
220
|
const typeField = type.fieldsByName[name];
|
|
165
|
-
return [(0, _utils.maybeAddDescriptionComment)(typeField.description, (0, _utils.liftLeadingPropertyComments)(babelTypes.objectTypeProperty(babelTypes.identifier(alias), typeToFlow(config,
|
|
221
|
+
return [(0, _utils.maybeAddDescriptionComment)(typeField.description, (0, _utils.liftLeadingPropertyComments)(babelTypes.objectTypeProperty(babelTypes.identifier(alias), typeToFlow({ ...config,
|
|
222
|
+
path: config.path.concat([alias])
|
|
223
|
+
}, typeField.type, selection))))];
|
|
166
224
|
|
|
167
225
|
default:
|
|
168
226
|
config.errors.push( // eslint-disable-next-line flowtype-errors/uncovered
|
|
@@ -175,46 +233,80 @@ const objectPropertiesToFlow = (config, type, typeName, selections) => {
|
|
|
175
233
|
exports.objectPropertiesToFlow = objectPropertiesToFlow;
|
|
176
234
|
|
|
177
235
|
const unionOrInterfaceToFlow = (config, type, selections) => {
|
|
178
|
-
const selectedAttributes = type.possibleTypes.map(possible => {
|
|
179
|
-
let seenTypeName = false;
|
|
180
|
-
return selections.map(selection => unionOrInterfaceSelection(config, type, possible, selection)).flat().filter(type => {
|
|
181
|
-
// The apollo-utilities "addTypeName" utility will add it
|
|
182
|
-
// even if it's already specified :( so we have to filter out
|
|
183
|
-
// the extra one here.
|
|
184
|
-
if (type.type === 'ObjectTypeProperty' && type.key.name === '__typename') {
|
|
185
|
-
if (seenTypeName) {
|
|
186
|
-
return false;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
seenTypeName = true;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
return true;
|
|
193
|
-
});
|
|
194
|
-
});
|
|
195
236
|
const allFields = selections.every(selection => selection.kind === 'Field');
|
|
237
|
+
const selectedAttributes = type.possibleTypes.slice().sort((a, b) => {
|
|
238
|
+
return a.name < b.name ? -1 : 1;
|
|
239
|
+
}).map(possible => {
|
|
240
|
+
const configWithUpdatedPath = { ...config,
|
|
241
|
+
path: allFields ? config.path : config.path.concat([possible.name])
|
|
242
|
+
};
|
|
243
|
+
return {
|
|
244
|
+
typeName: possible.name,
|
|
245
|
+
attributes: ensureOnlyOneTypenameProperty(selections.map(selection => unionOrInterfaceSelection(configWithUpdatedPath, type, possible, selection)).flat())
|
|
246
|
+
};
|
|
247
|
+
}); // If they're all fields, the only selection that could be different is __typename
|
|
248
|
+
|
|
249
|
+
if (allFields) {
|
|
250
|
+
const sharedAttributes = selectedAttributes[0].attributes.slice();
|
|
251
|
+
const typeNameIndex = selectedAttributes[0].attributes.findIndex(x => x.type === 'ObjectTypeProperty' && x.key.type === 'Identifier' && x.key.name === '__typename');
|
|
252
|
+
|
|
253
|
+
if (typeNameIndex !== -1) {
|
|
254
|
+
sharedAttributes[typeNameIndex] = babelTypes.objectTypeProperty(babelTypes.identifier('__typename'), babelTypes.unionTypeAnnotation(selectedAttributes.map(attrs => // eslint-disable-next-line flowtype-errors/uncovered
|
|
255
|
+
attrs.attributes[typeNameIndex].value)));
|
|
256
|
+
}
|
|
196
257
|
|
|
197
|
-
|
|
198
|
-
return babelTypes.objectTypeAnnotation(selectedAttributes[0], undefined
|
|
199
|
-
/* indexers */
|
|
200
|
-
, undefined
|
|
201
|
-
/* callProperties */
|
|
202
|
-
, undefined
|
|
203
|
-
/* internalSlots */
|
|
204
|
-
, true
|
|
205
|
-
/* exact */
|
|
206
|
-
);
|
|
258
|
+
return sortedObjectTypeAnnotation(config, sharedAttributes);
|
|
207
259
|
}
|
|
208
260
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
261
|
+
if (selectedAttributes.length === 1) {
|
|
262
|
+
return sortedObjectTypeAnnotation(config, selectedAttributes[0].attributes);
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* When generating the objects for the sub-options of a union, the path needs
|
|
266
|
+
* to include the name of the object type.
|
|
267
|
+
* ```
|
|
268
|
+
* query getFriend {
|
|
269
|
+
* friend {
|
|
270
|
+
* ... on Human { id }
|
|
271
|
+
* ... on Droid { arms }
|
|
272
|
+
* }
|
|
273
|
+
* }
|
|
274
|
+
* ```
|
|
275
|
+
* produces
|
|
276
|
+
* ```
|
|
277
|
+
* type getFriend = {friend: getFriend_friend_Human | getFriend_friend_Droid }
|
|
278
|
+
* type getFriend_friend_Human = {id: string}
|
|
279
|
+
* type getFriend_friend_Droid = {arms: number}
|
|
280
|
+
* ```
|
|
281
|
+
* Note that this is different from when an attribute has a plain object type.
|
|
282
|
+
* ```
|
|
283
|
+
* query getHuman {
|
|
284
|
+
* me: human(id: "me") { id }
|
|
285
|
+
* }
|
|
286
|
+
* ```
|
|
287
|
+
* produces
|
|
288
|
+
* ```
|
|
289
|
+
* type getHuman = {me: getHuman_me}
|
|
290
|
+
* type getHuman_me = {id: string}
|
|
291
|
+
* ```
|
|
292
|
+
* instead of e.g. `getHuman_me_Human`.
|
|
293
|
+
*/
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
const result = babelTypes.unionTypeAnnotation(selectedAttributes.map(({
|
|
297
|
+
typeName,
|
|
298
|
+
attributes
|
|
299
|
+
}) => sortedObjectTypeAnnotation({ ...config,
|
|
300
|
+
path: config.path.concat([typeName])
|
|
301
|
+
}, attributes)));
|
|
302
|
+
const name = config.path.join('_');
|
|
303
|
+
|
|
304
|
+
if (config.allObjectTypes && config.path.length > 1) {
|
|
305
|
+
config.allObjectTypes[name] = result;
|
|
306
|
+
return babelTypes.genericTypeAnnotation(babelTypes.identifier(name));
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
return result;
|
|
218
310
|
};
|
|
219
311
|
|
|
220
312
|
exports.unionOrInterfaceToFlow = unionOrInterfaceToFlow;
|
|
@@ -236,11 +328,18 @@ const unionOrInterfaceSelection = (config, type, possible, selection) => {
|
|
|
236
328
|
}
|
|
237
329
|
|
|
238
330
|
const typeField = type.fieldsByName[name];
|
|
239
|
-
return [(0, _utils.liftLeadingPropertyComments)(babelTypes.objectTypeProperty(babelTypes.identifier(alias), typeToFlow(config,
|
|
331
|
+
return [(0, _utils.liftLeadingPropertyComments)(babelTypes.objectTypeProperty(babelTypes.identifier(alias), typeToFlow({ ...config,
|
|
332
|
+
path: config.path.concat([name])
|
|
333
|
+
}, typeField.type, selection)))];
|
|
240
334
|
}
|
|
241
335
|
|
|
242
336
|
if (selection.kind === 'FragmentSpread') {
|
|
243
337
|
const fragment = config.fragments[selection.name.value];
|
|
338
|
+
|
|
339
|
+
if (!fragment) {
|
|
340
|
+
throw new Error(`Unknown fragment ${selection.name.value}`);
|
|
341
|
+
}
|
|
342
|
+
|
|
244
343
|
const typeName = fragment.typeCondition.name.value;
|
|
245
344
|
|
|
246
345
|
if (config.schema.interfacesByName[typeName] && config.schema.interfacesByName[typeName].possibleTypesByName[possible.name] || typeName === possible.name) {
|