@khanacademy/graphql-flow 0.1.0 → 0.2.0
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/CHANGELOG.md +11 -0
- package/Readme.md +15 -0
- package/dist/cli/config.js +1 -1
- package/dist/cli/config.js.flow +3 -0
- package/dist/cli/config.js.map +1 -1
- package/dist/cli/run.js +15 -13
- package/dist/cli/run.js.flow +17 -14
- package/dist/cli/run.js.map +1 -1
- package/dist/generateResponseType.js +150 -51
- package/dist/generateResponseType.js.flow +223 -65
- package/dist/generateResponseType.js.map +1 -1
- package/dist/generateTypeFiles.js +78 -39
- package/dist/generateTypeFiles.js.flow +75 -35
- package/dist/generateTypeFiles.js.map +1 -1
- package/dist/index.js +43 -3
- package/dist/index.js.flow +54 -4
- package/dist/index.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 +17 -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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# @khanacademy/graphql-flow
|
|
2
2
|
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- d9a8229: Generate types for fragments!
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 7497164: Fix a bug in index file generation that resulted in duplicate entries
|
|
12
|
+
- 26abf9b: Add options for specifying the name of the generated directory, and for exporting the response and variables types.
|
|
13
|
+
|
|
3
14
|
## 0.1.0
|
|
4
15
|
|
|
5
16
|
### 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
|
@@ -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(', ')}`);
|
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,EAAEb,IAAI,CAACa,OAAL,IAAgB,EADtB;AAEHE,IAAAA,QAAQ,EAAE,mBAAAf,IAAI,CAACe,QAAL,kEAAeC,GAAf,CAAoBC,MAAD,IAAY,IAAIC,MAAJ,CAAWD,MAAX,CAA/B,MAAsD,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
|
@@ -113,28 +113,30 @@ Object.keys(resolved).forEach(k => {
|
|
|
113
113
|
const rawSource = raw.literals[0];
|
|
114
114
|
const processedOptions = (0, _generateTypeFiles.processPragmas)(config.options, rawSource);
|
|
115
115
|
|
|
116
|
-
if (!
|
|
116
|
+
if (!processedOptions) {
|
|
117
117
|
return;
|
|
118
118
|
} // eslint-disable-next-line flowtype-errors/uncovered
|
|
119
119
|
|
|
120
120
|
|
|
121
121
|
const withTypeNames = (0, _apolloUtilities.addTypenameToDocument)(document);
|
|
122
122
|
const printed = (0, _printer.print)(withTypeNames);
|
|
123
|
-
/* eslint-disable flowtype-errors/uncovered */
|
|
124
123
|
|
|
125
|
-
|
|
126
|
-
|
|
124
|
+
if (hasNonFragments) {
|
|
125
|
+
/* eslint-disable flowtype-errors/uncovered */
|
|
126
|
+
const errors = (0, _validation.validate)(schemaForValidation, withTypeNames);
|
|
127
|
+
/* eslint-disable flowtype-errors/uncovered */
|
|
128
|
+
|
|
129
|
+
if (errors.length) {
|
|
130
|
+
errors.forEach(error => {
|
|
131
|
+
console.error(`Schema validation found errors for ${raw.loc.path}!`);
|
|
132
|
+
console.error(printed);
|
|
133
|
+
console.error(error);
|
|
134
|
+
validationFailures++;
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
/* eslint-enable flowtype-errors/uncovered */
|
|
127
138
|
|
|
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
139
|
}
|
|
136
|
-
/* eslint-enable flowtype-errors/uncovered */
|
|
137
|
-
|
|
138
140
|
|
|
139
141
|
try {
|
|
140
142
|
(0, _generateTypeFiles.generateTypeFiles)(raw.loc.path, schemaForTypeGeneration, withTypeNames, processedOptions); // eslint-disable-next-line flowtype-errors/uncovered
|
package/dist/cli/run.js.flow
CHANGED
|
@@ -113,27 +113,30 @@ Object.keys(resolved).forEach((k) => {
|
|
|
113
113
|
);
|
|
114
114
|
const rawSource: string = raw.literals[0];
|
|
115
115
|
const processedOptions = processPragmas(config.options, rawSource);
|
|
116
|
-
if (!
|
|
116
|
+
if (!processedOptions) {
|
|
117
117
|
return;
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
// eslint-disable-next-line flowtype-errors/uncovered
|
|
121
121
|
const withTypeNames: DocumentNode = addTypenameToDocument(document);
|
|
122
122
|
const printed = print(withTypeNames);
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
errors
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
123
|
+
|
|
124
|
+
if (hasNonFragments) {
|
|
125
|
+
/* eslint-disable flowtype-errors/uncovered */
|
|
126
|
+
const errors = validate(schemaForValidation, withTypeNames);
|
|
127
|
+
/* eslint-disable flowtype-errors/uncovered */
|
|
128
|
+
if (errors.length) {
|
|
129
|
+
errors.forEach((error) => {
|
|
130
|
+
console.error(
|
|
131
|
+
`Schema validation found errors for ${raw.loc.path}!`,
|
|
132
|
+
);
|
|
133
|
+
console.error(printed);
|
|
134
|
+
console.error(error);
|
|
135
|
+
validationFailures++;
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
/* eslint-enable flowtype-errors/uncovered */
|
|
135
139
|
}
|
|
136
|
-
/* eslint-enable flowtype-errors/uncovered */
|
|
137
140
|
|
|
138
141
|
try {
|
|
139
142
|
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":"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
|
|
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":["// @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) => {
|
|
@@ -137,6 +188,11 @@ const objectPropertiesToFlow = (config, type, typeName, selections) => {
|
|
|
137
188
|
var _selection$typeCondit;
|
|
138
189
|
|
|
139
190
|
const newTypeName = ((_selection$typeCondit = selection.typeCondition) === null || _selection$typeCondit === void 0 ? void 0 : _selection$typeCondit.name.value) ?? typeName;
|
|
191
|
+
|
|
192
|
+
if (newTypeName !== typeName) {
|
|
193
|
+
return [];
|
|
194
|
+
}
|
|
195
|
+
|
|
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) {
|