@khanacademy/graphql-flow 0.2.3 → 0.3.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.
Files changed (40) hide show
  1. package/.flowconfig +1 -0
  2. package/.github/workflows/changeset-release.yml +3 -17
  3. package/.github/workflows/pr-checks.yml +15 -10
  4. package/CHANGELOG.md +19 -0
  5. package/Readme.md +36 -1
  6. package/dist/cli/config.js +102 -15
  7. package/dist/cli/config.js.flow +131 -29
  8. package/dist/cli/config.js.map +1 -1
  9. package/dist/cli/run.js +45 -11
  10. package/dist/cli/run.js.flow +45 -7
  11. package/dist/cli/run.js.map +1 -1
  12. package/dist/cli/utils.js +21 -0
  13. package/dist/cli/utils.js.flow +14 -0
  14. package/dist/cli/utils.js.map +1 -0
  15. package/dist/enums.js +15 -2
  16. package/dist/enums.js.flow +38 -9
  17. package/dist/enums.js.map +1 -1
  18. package/dist/generateTypeFiles.js +30 -7
  19. package/dist/generateTypeFiles.js.flow +68 -38
  20. package/dist/generateTypeFiles.js.map +1 -1
  21. package/dist/index.js +18 -12
  22. package/dist/index.js.flow +27 -11
  23. package/dist/index.js.map +1 -1
  24. package/dist/types.js.flow +3 -0
  25. package/flow-typed/npm/@babel/types_vx.x.x.js +17 -3
  26. package/package.json +1 -1
  27. package/src/__test__/generateTypeFileContents.test.js +52 -0
  28. package/src/cli/__test__/config.test.js +94 -0
  29. package/src/cli/__test__/utils.test.js +19 -0
  30. package/src/cli/config.js +131 -29
  31. package/src/cli/run.js +45 -7
  32. package/src/cli/utils.js +14 -0
  33. package/src/enums.js +38 -9
  34. package/src/generateTypeFiles.js +68 -38
  35. package/src/index.js +27 -11
  36. package/src/types.js +3 -0
  37. package/.github/actions/filter-files/action.yml +0 -37
  38. package/.github/actions/full-or-limited/action.yml +0 -27
  39. package/.github/actions/json-args/action.yml +0 -32
  40. package/.github/actions/setup/action.yml +0 -28
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/generateTypeFiles.js"],"names":["indexPrelude","regenerateCommand","generateTypeFileContents","fileName","schema","document","options","generatedDir","indexContents","files","addToIndex","filePath","typeName","newLine","path","basename","indexOf","lines","split","map","line","includes","join","generated","forEach","name","code","isFragment","extraTypes","targetFileName","typeFileName","replace","targetPath","fileContents","splitTypes","Object","keys","generateTypeFiles","dirname","generatedDirectory","indexFile","fs","existsSync","mkdirSync","recursive","writeFileSync","readFileSync","key","processPragmas","rawSource","ignorePragma","autogen","loosePragma","autogenStrict","pragma","noPragmas","strictNullability","readOnlyArray","scalars","exportAllObjectTypes"],"mappings":"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","sourcesContent":["// @flow\n// Import this in your jest setup, to mock out graphql-tag!\nimport type {DocumentNode} from 'graphql';\nimport type {Options, Schema, Scalars} from './types';\nimport fs from 'fs';\nimport path from 'path';\nimport {documentToFlowTypes} from '.';\n\nexport type ExternalOptions = {\n pragma?: string,\n loosePragma?: string,\n ignorePragma?: string,\n scalars?: Scalars,\n strictNullability?: boolean,\n /**\n * The command that users should run to regenerate the types files.\n */\n regenerateCommand?: string,\n readOnlyArray?: boolean,\n splitTypes?: boolean,\n generatedDirectory?: string,\n exportAllObjectTypes?: boolean,\n typeFileName?: string,\n};\n\nexport const indexPrelude = (regenerateCommand?: string): string => `// @flow\n//\n// AUTOGENERATED\n// NOTE: New response types are added to this file automatically.\n// Outdated response types can be removed manually as they are deprecated.\n//${regenerateCommand ? ' To regenerate, run ' + regenerateCommand : ''}\n//\n\n`;\n\nexport const generateTypeFileContents = (\n fileName: string,\n schema: Schema,\n document: DocumentNode,\n options: Options,\n generatedDir: string,\n indexContents: string,\n): {indexContents: string, files: {[key: string]: string}} => {\n const files = {};\n\n /// Write export for __generated__/index.js if it doesn't exist\n const addToIndex = (filePath, typeName) => {\n const newLine = `export type {${typeName}} from './${path.basename(\n filePath,\n )}';`;\n if (indexContents.indexOf('./' + path.basename(filePath)) === -1) {\n indexContents += newLine + '\\n';\n } else {\n const lines = indexContents.split('\\n').map((line) => {\n if (line.includes('./' + path.basename(filePath))) {\n return newLine;\n }\n return line;\n });\n indexContents = lines.join('\\n');\n }\n };\n\n const generated = documentToFlowTypes(document, schema, options);\n generated.forEach(({name, typeName, code, isFragment, extraTypes}) => {\n // We write all generated files to a `__generated__` subdir to keep\n // things tidy.\n const targetFileName = options.typeFileName\n ? options.typeFileName.replace('[operationName]', name)\n : `${name}.js`;\n const targetPath = path.join(generatedDir, targetFileName);\n\n let fileContents =\n '// @' +\n `flow\\n// AUTOGENERATED -- DO NOT EDIT\\n` +\n `// Generated for operation '${name}' in file '../${path.basename(\n fileName,\n )}'\\n` +\n (options.regenerateCommand\n ? `// To regenerate, run '${options.regenerateCommand}'.\\n`\n : '') +\n code;\n if (options.splitTypes && !isFragment) {\n fileContents +=\n `\\nexport type ${name} = ${typeName}['response'];\\n` +\n `export type ${name}Variables = ${typeName}['variables'];\\n`;\n }\n Object.keys(extraTypes).forEach((name) => {\n fileContents += `\\n\\nexport type ${name} = ${extraTypes[name]};`;\n });\n\n addToIndex(targetPath, typeName);\n files[targetPath] =\n fileContents\n // Remove whitespace from the ends of lines; babel's generate sometimes\n // leaves them hanging around.\n .replace(/\\s+$/gm, '') + '\\n';\n });\n\n return {files, indexContents};\n};\n\nexport const generateTypeFiles = (\n fileName: string,\n schema: Schema,\n document: DocumentNode,\n options: Options,\n) => {\n const generatedDir = path.join(\n path.dirname(fileName),\n options.generatedDirectory ?? '__generated__',\n );\n const indexFile = path.join(generatedDir, 'index.js');\n\n if (!fs.existsSync(generatedDir)) {\n fs.mkdirSync(generatedDir, {recursive: true});\n }\n if (!fs.existsSync(indexFile)) {\n fs.writeFileSync(indexFile, indexPrelude(options.regenerateCommand));\n }\n\n const {indexContents, files} = generateTypeFileContents(\n fileName,\n schema,\n document,\n options,\n generatedDir,\n fs.readFileSync(indexFile, 'utf8'),\n );\n\n fs.writeFileSync(indexFile, indexContents);\n Object.keys(files).forEach((key) => {\n fs.writeFileSync(key, files[key]);\n });\n\n fs.writeFileSync(indexFile, indexContents);\n};\n\nexport const processPragmas = (\n options: ExternalOptions,\n rawSource: string,\n): null | Options => {\n if (options.ignorePragma && rawSource.includes(options.ignorePragma)) {\n return null;\n }\n\n const autogen = options.loosePragma\n ? rawSource.includes(options.loosePragma)\n : false;\n const autogenStrict = options.pragma\n ? rawSource.includes(options.pragma)\n : false;\n const noPragmas = !options.loosePragma && !options.pragma;\n\n if (autogen || autogenStrict || noPragmas) {\n return {\n regenerateCommand: options.regenerateCommand,\n strictNullability: noPragmas\n ? options.strictNullability\n : autogenStrict || !autogen,\n readOnlyArray: options.readOnlyArray,\n scalars: options.scalars,\n splitTypes: options.splitTypes,\n generatedDirectory: options.generatedDirectory,\n exportAllObjectTypes: options.exportAllObjectTypes,\n typeFileName: options.typeFileName,\n };\n } else {\n return null;\n }\n};\n"],"file":"generateTypeFiles.js"}
1
+ {"version":3,"sources":["../src/generateTypeFiles.js"],"names":["indexPrelude","regenerateCommand","generateTypeFileContents","fileName","schema","document","options","generatedDir","indexContents","files","addToIndex","filePath","typeName","newLine","path","basename","indexOf","lines","split","map","line","includes","join","generated","forEach","name","code","isFragment","extraTypes","experimentalEnums","targetFileName","typeFileName","replace","targetPath","fileContents","splitTypes","Object","keys","enumNames","length","getGeneratedDir","generatedDirectory","isAbsolute","relative","process","cwd","dirname","generateTypeFiles","indexFile","fs","existsSync","mkdirSync","recursive","writeFileSync","readFileSync","key","processPragmas","rawSource","ignorePragma","autogen","loosePragma","autogenStrict","pragma","noPragmas","strictNullability","readOnlyArray","scalars","exportAllObjectTypes"],"mappings":"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","sourcesContent":["// @flow\n// Import this in your jest setup, to mock out graphql-tag!\nimport type {DocumentNode} from 'graphql';\nimport type {Options, Schema, Scalars} from './types';\nimport fs from 'fs';\nimport path from 'path';\nimport {documentToFlowTypes} from '.';\n\nexport type ExternalOptions = {\n pragma?: string,\n loosePragma?: string,\n ignorePragma?: string,\n scalars?: Scalars,\n strictNullability?: boolean,\n /**\n * The command that users should run to regenerate the types files.\n */\n regenerateCommand?: string,\n readOnlyArray?: boolean,\n splitTypes?: boolean,\n generatedDirectory?: string,\n exportAllObjectTypes?: boolean,\n typeFileName?: string,\n experimentalEnums?: boolean,\n};\n\nexport const indexPrelude = (regenerateCommand?: string): string => `// @flow\n//\n// AUTOGENERATED\n// NOTE: New response types are added to this file automatically.\n// Outdated response types can be removed manually as they are deprecated.\n//${regenerateCommand ? ' To regenerate, run ' + regenerateCommand : ''}\n//\n\n`;\n\nexport const generateTypeFileContents = (\n fileName: string,\n schema: Schema,\n document: DocumentNode,\n options: Options,\n generatedDir: string,\n indexContents: string,\n): {indexContents: string, files: {[key: string]: string}} => {\n const files = {};\n\n /// Write export for __generated__/index.js if it doesn't exist\n const addToIndex = (filePath, typeName) => {\n const newLine = `export type {${typeName}} from './${path.basename(\n filePath,\n )}';`;\n if (indexContents.indexOf('./' + path.basename(filePath)) === -1) {\n indexContents += newLine + '\\n';\n } else {\n const lines = indexContents.split('\\n').map((line) => {\n if (line.includes('./' + path.basename(filePath))) {\n return newLine;\n }\n return line;\n });\n indexContents = lines.join('\\n');\n }\n };\n\n const generated = documentToFlowTypes(document, schema, options);\n generated.forEach(\n ({name, typeName, code, isFragment, extraTypes, experimentalEnums}) => {\n // We write all generated files to a `__generated__` subdir to keep\n // things tidy.\n const targetFileName = options.typeFileName\n ? options.typeFileName.replace('[operationName]', name)\n : `${name}.js`;\n const targetPath = path.join(generatedDir, targetFileName);\n\n let fileContents =\n '// @' +\n `flow\\n// AUTOGENERATED -- DO NOT EDIT\\n` +\n `// Generated for operation '${name}' in file '../${path.basename(\n fileName,\n )}'\\n` +\n (options.regenerateCommand\n ? `// To regenerate, run '${options.regenerateCommand}'.\\n`\n : '') +\n code;\n if (options.splitTypes && !isFragment) {\n fileContents +=\n `\\nexport type ${name} = ${typeName}['response'];\\n` +\n `export type ${name}Variables = ${typeName}['variables'];\\n`;\n }\n Object.keys(extraTypes).forEach(\n (name) =>\n (fileContents += `\\n\\nexport type ${name} = ${extraTypes[name]};`),\n );\n const enumNames = Object.keys(experimentalEnums);\n if (options.experimentalEnums && enumNames.length) {\n // TODO(somewhatabstract, FEI-4172): Update to fixed eslint-plugin-flowtype\n // and remove this disable.\n fileContents += `\\n\\n/* eslint-disable no-undef */`;\n enumNames.forEach(\n (name) =>\n (fileContents += `\\nexport ${experimentalEnums[name]};\\n`),\n );\n fileContents += `/* eslint-enable no-undef */`;\n }\n\n addToIndex(targetPath, typeName);\n files[targetPath] =\n fileContents\n // Remove whitespace from the ends of lines; babel's generate sometimes\n // leaves them hanging around.\n .replace(/\\s+$/gm, '') + '\\n';\n },\n );\n\n return {files, indexContents};\n};\n\nconst getGeneratedDir = (fileName: string, options: Options) => {\n const generatedDirectory = options.generatedDirectory ?? '__generated__';\n if (path.isAbsolute(generatedDirectory)) {\n // fileName is absolute here, so we make it relative to cwd\n // for more reasonable filenames. We convert leading ..'s\n // to `__` so this doesn't escape the output directory.\n return path.join(\n generatedDirectory,\n path\n .relative(process.cwd(), path.dirname(fileName))\n .replace(/\\.\\.\\//g, '__/'),\n );\n } else {\n return path.join(path.dirname(fileName), generatedDirectory);\n }\n};\n\nexport const generateTypeFiles = (\n fileName: string,\n schema: Schema,\n document: DocumentNode,\n options: Options,\n) => {\n const generatedDir = getGeneratedDir(fileName, options);\n const indexFile = path.join(generatedDir, 'index.js');\n\n if (!fs.existsSync(generatedDir)) {\n fs.mkdirSync(generatedDir, {recursive: true});\n }\n if (!fs.existsSync(indexFile)) {\n fs.writeFileSync(indexFile, indexPrelude(options.regenerateCommand));\n }\n\n const {indexContents, files} = generateTypeFileContents(\n fileName,\n schema,\n document,\n options,\n generatedDir,\n fs.readFileSync(indexFile, 'utf8'),\n );\n\n fs.writeFileSync(indexFile, indexContents);\n Object.keys(files).forEach((key) => {\n fs.writeFileSync(key, files[key]);\n });\n\n fs.writeFileSync(indexFile, indexContents);\n};\n\nexport const processPragmas = (\n options: ExternalOptions,\n rawSource: string,\n): null | Options => {\n if (options.ignorePragma && rawSource.includes(options.ignorePragma)) {\n return null;\n }\n\n const autogen = options.loosePragma\n ? rawSource.includes(options.loosePragma)\n : false;\n const autogenStrict = options.pragma\n ? rawSource.includes(options.pragma)\n : false;\n const noPragmas = !options.loosePragma && !options.pragma;\n\n if (autogen || autogenStrict || noPragmas) {\n return {\n regenerateCommand: options.regenerateCommand,\n strictNullability: noPragmas\n ? options.strictNullability\n : autogenStrict || !autogen,\n readOnlyArray: options.readOnlyArray,\n scalars: options.scalars,\n splitTypes: options.splitTypes,\n generatedDirectory: options.generatedDirectory,\n exportAllObjectTypes: options.exportAllObjectTypes,\n typeFileName: options.typeFileName,\n experimentalEnums: options.experimentalEnums,\n };\n } else {\n return null;\n }\n};\n"],"file":"generateTypeFiles.js"}
package/dist/index.js CHANGED
@@ -52,6 +52,7 @@ const optionsToConfig = (schema, definitions, options, errors = []) => {
52
52
  errors,
53
53
  allObjectTypes: null,
54
54
  path: [],
55
+ experimentalEnumsMap: options !== null && options !== void 0 && options.experimentalEnums ? {} : undefined,
55
56
  ...internalOptions
56
57
  };
57
58
  return config;
@@ -78,17 +79,15 @@ const documentToFlowTypes = (document, schema, options) => {
78
79
  path: [name],
79
80
  allObjectTypes: options !== null && options !== void 0 && options.exportAllObjectTypes ? types : null
80
81
  })};`;
81
- const extraTypes = {};
82
- Object.keys(types).forEach(k => {
83
- // eslint-disable-next-line flowtype-errors/uncovered
84
- extraTypes[k] = (0, _generator.default)(types[k]).code;
85
- });
82
+ const extraTypes = codegenExtraTypes(types);
83
+ const experimentalEnums = codegenExtraTypes(config.experimentalEnumsMap || {});
86
84
  return {
87
85
  name,
88
86
  typeName: name,
89
87
  code,
90
88
  isFragment: true,
91
- extraTypes
89
+ extraTypes,
90
+ experimentalEnums
92
91
  };
93
92
  }
94
93
 
@@ -106,16 +105,14 @@ const documentToFlowTypes = (document, schema, options) => {
106
105
  // We'll see what's required to get webapp on board.
107
106
 
108
107
  const code = `export type ${typeName} = {|\n variables: ${variables},\n response: ${response}\n|};`;
109
- const extraTypes = {};
110
- Object.keys(types).forEach(k => {
111
- // eslint-disable-next-line flowtype-errors/uncovered
112
- extraTypes[k] = (0, _generator.default)(types[k]).code;
113
- });
108
+ const extraTypes = codegenExtraTypes(types);
109
+ const experimentalEnums = codegenExtraTypes(config.experimentalEnumsMap || {});
114
110
  return {
115
111
  name,
116
112
  typeName,
117
113
  code,
118
- extraTypes
114
+ extraTypes,
115
+ experimentalEnums
119
116
  };
120
117
  }
121
118
  }).filter(Boolean);
@@ -128,4 +125,13 @@ const documentToFlowTypes = (document, schema, options) => {
128
125
  };
129
126
 
130
127
  exports.documentToFlowTypes = documentToFlowTypes;
128
+
129
+ function codegenExtraTypes(types) {
130
+ const extraTypes = {};
131
+ Object.keys(types).forEach(k => {
132
+ // eslint-disable-next-line flowtype-errors/uncovered
133
+ extraTypes[k] = (0, _generator.default)(types[k]).code;
134
+ });
135
+ return extraTypes;
136
+ }
131
137
  //# sourceMappingURL=index.js.map
@@ -15,6 +15,7 @@ import {
15
15
  generateResponseType,
16
16
  } from './generateResponseType';
17
17
  import {generateVariablesType} from './generateVariablesType';
18
+ import type {BabelNode} from '@babel/types';
18
19
  export {spyOnGraphqlTagToCollectQueries} from './jest-mock-graphql-tag';
19
20
 
20
21
  import type {Config, Options, Schema} from './types';
@@ -42,6 +43,7 @@ const optionsToConfig = (
42
43
  errors,
43
44
  allObjectTypes: null,
44
45
  path: [],
46
+ experimentalEnumsMap: options?.experimentalEnums ? {} : undefined,
45
47
  ...internalOptions,
46
48
  };
47
49
 
@@ -66,6 +68,7 @@ export const documentToFlowTypes = (
66
68
  code: string,
67
69
  isFragment?: boolean,
68
70
  extraTypes: {[key: string]: string},
71
+ experimentalEnums: {[key: string]: string},
69
72
  }> => {
70
73
  const errors: Array<string> = [];
71
74
  const config = optionsToConfig(
@@ -90,17 +93,19 @@ export const documentToFlowTypes = (
90
93
  : null,
91
94
  },
92
95
  )};`;
93
- const extraTypes: {[key: string]: string} = {};
94
- Object.keys(types).forEach((k) => {
95
- // eslint-disable-next-line flowtype-errors/uncovered
96
- extraTypes[k] = generate(types[k]).code;
97
- });
96
+
97
+ const extraTypes = codegenExtraTypes(types);
98
+ const experimentalEnums = codegenExtraTypes(
99
+ config.experimentalEnumsMap || {},
100
+ );
101
+
98
102
  return {
99
103
  name,
100
104
  typeName: name,
101
105
  code,
102
106
  isFragment: true,
103
107
  extraTypes,
108
+ experimentalEnums,
104
109
  };
105
110
  }
106
111
  if (
@@ -127,12 +132,12 @@ export const documentToFlowTypes = (
127
132
  // We'll see what's required to get webapp on board.
128
133
  const code = `export type ${typeName} = {|\n variables: ${variables},\n response: ${response}\n|};`;
129
134
 
130
- const extraTypes: {[key: string]: string} = {};
131
- Object.keys(types).forEach((k) => {
132
- // eslint-disable-next-line flowtype-errors/uncovered
133
- extraTypes[k] = generate(types[k]).code;
134
- });
135
- return {name, typeName, code, extraTypes};
135
+ const extraTypes = codegenExtraTypes(types);
136
+ const experimentalEnums = codegenExtraTypes(
137
+ config.experimentalEnumsMap || {},
138
+ );
139
+
140
+ return {name, typeName, code, extraTypes, experimentalEnums};
136
141
  }
137
142
  })
138
143
  .filter(Boolean);
@@ -141,3 +146,14 @@ export const documentToFlowTypes = (
141
146
  }
142
147
  return result;
143
148
  };
149
+
150
+ function codegenExtraTypes(types: {[key: string]: BabelNode}): {
151
+ [key: string]: string,
152
+ } {
153
+ const extraTypes: {[key: string]: string} = {};
154
+ Object.keys(types).forEach((k: string) => {
155
+ // eslint-disable-next-line flowtype-errors/uncovered
156
+ extraTypes[k] = generate(types[k]).code;
157
+ });
158
+ return extraTypes;
159
+ }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.js"],"names":["optionsToConfig","schema","definitions","options","errors","internalOptions","strictNullability","readOnlyArray","scalars","fragments","forEach","def","kind","name","value","config","allObjectTypes","path","FlowGenerationError","Error","constructor","join","messages","documentToFlowTypes","document","result","map","item","types","code","exportAllObjectTypes","extraTypes","Object","keys","k","typeName","isFragment","operation","response","variables","filter","Boolean","length"],"mappings":"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","sourcesContent":["/* eslint-disable no-console */\n/* flow-uncovered-file */\n// @flow\n/**\n * This tool generates flowtype definitions from graphql queries.\n *\n * It relies on `introspection-query.json` existing in this directory,\n * which is produced by running `./tools/graphql-flow/sendIntrospection.js`.\n */\nimport type {DefinitionNode, DocumentNode} from 'graphql';\n\nimport generate from '@babel/generator'; // eslint-disable-line flowtype-errors/uncovered\nimport {\n generateFragmentType,\n generateResponseType,\n} from './generateResponseType';\nimport {generateVariablesType} from './generateVariablesType';\nexport {spyOnGraphqlTagToCollectQueries} from './jest-mock-graphql-tag';\n\nimport type {Config, Options, Schema} from './types';\n\nconst optionsToConfig = (\n schema: Schema,\n definitions: $ReadOnlyArray<DefinitionNode>,\n options?: Options,\n errors: Array<string> = [],\n): Config => {\n const internalOptions = {\n strictNullability: options?.strictNullability ?? true,\n readOnlyArray: options?.readOnlyArray ?? true,\n scalars: options?.scalars ?? {},\n };\n const fragments = {};\n definitions.forEach((def) => {\n if (def.kind === 'FragmentDefinition') {\n fragments[def.name.value] = def;\n }\n });\n const config = {\n fragments,\n schema,\n errors,\n allObjectTypes: null,\n path: [],\n ...internalOptions,\n };\n\n return config;\n};\n\nexport class FlowGenerationError extends Error {\n messages: Array<string>;\n constructor(errors: Array<string>) {\n super(`Graphql-flow type generation failed! ${errors.join('; ')}`);\n this.messages = errors;\n }\n}\n\nexport const documentToFlowTypes = (\n document: DocumentNode,\n schema: Schema,\n options?: Options,\n): $ReadOnlyArray<{\n name: string,\n typeName: string,\n code: string,\n isFragment?: boolean,\n extraTypes: {[key: string]: string},\n}> => {\n const errors: Array<string> = [];\n const config = optionsToConfig(\n schema,\n document.definitions,\n options,\n errors,\n );\n const result = document.definitions\n .map((item) => {\n if (item.kind === 'FragmentDefinition') {\n const name = item.name.value;\n const types = {};\n const code = `export type ${name} = ${generateFragmentType(\n schema,\n item,\n {\n ...config,\n path: [name],\n allObjectTypes: options?.exportAllObjectTypes\n ? types\n : null,\n },\n )};`;\n const extraTypes: {[key: string]: string} = {};\n Object.keys(types).forEach((k) => {\n // eslint-disable-next-line flowtype-errors/uncovered\n extraTypes[k] = generate(types[k]).code;\n });\n return {\n name,\n typeName: name,\n code,\n isFragment: true,\n extraTypes,\n };\n }\n if (\n item.kind === 'OperationDefinition' &&\n (item.operation === 'query' || item.operation === 'mutation') &&\n item.name\n ) {\n const types = {};\n const name = item.name.value;\n const response = generateResponseType(schema, item, {\n ...config,\n path: [name],\n allObjectTypes: options?.exportAllObjectTypes\n ? types\n : null,\n });\n const variables = generateVariablesType(schema, item, {\n ...config,\n path: [name],\n });\n\n const typeName = `${name}Type`;\n // TODO(jared): Maybe make this template configurable?\n // We'll see what's required to get webapp on board.\n const code = `export type ${typeName} = {|\\n variables: ${variables},\\n response: ${response}\\n|};`;\n\n const extraTypes: {[key: string]: string} = {};\n Object.keys(types).forEach((k) => {\n // eslint-disable-next-line flowtype-errors/uncovered\n extraTypes[k] = generate(types[k]).code;\n });\n return {name, typeName, code, extraTypes};\n }\n })\n .filter(Boolean);\n if (errors.length) {\n throw new FlowGenerationError(errors);\n }\n return result;\n};\n"],"file":"index.js"}
1
+ {"version":3,"sources":["../src/index.js"],"names":["optionsToConfig","schema","definitions","options","errors","internalOptions","strictNullability","readOnlyArray","scalars","fragments","forEach","def","kind","name","value","config","allObjectTypes","path","experimentalEnumsMap","experimentalEnums","undefined","FlowGenerationError","Error","constructor","join","messages","documentToFlowTypes","document","result","map","item","types","code","exportAllObjectTypes","extraTypes","codegenExtraTypes","typeName","isFragment","operation","response","variables","filter","Boolean","length","Object","keys","k"],"mappings":"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","sourcesContent":["/* eslint-disable no-console */\n/* flow-uncovered-file */\n// @flow\n/**\n * This tool generates flowtype definitions from graphql queries.\n *\n * It relies on `introspection-query.json` existing in this directory,\n * which is produced by running `./tools/graphql-flow/sendIntrospection.js`.\n */\nimport type {DefinitionNode, DocumentNode} from 'graphql';\n\nimport generate from '@babel/generator'; // eslint-disable-line flowtype-errors/uncovered\nimport {\n generateFragmentType,\n generateResponseType,\n} from './generateResponseType';\nimport {generateVariablesType} from './generateVariablesType';\nimport type {BabelNode} from '@babel/types';\nexport {spyOnGraphqlTagToCollectQueries} from './jest-mock-graphql-tag';\n\nimport type {Config, Options, Schema} from './types';\n\nconst optionsToConfig = (\n schema: Schema,\n definitions: $ReadOnlyArray<DefinitionNode>,\n options?: Options,\n errors: Array<string> = [],\n): Config => {\n const internalOptions = {\n strictNullability: options?.strictNullability ?? true,\n readOnlyArray: options?.readOnlyArray ?? true,\n scalars: options?.scalars ?? {},\n };\n const fragments = {};\n definitions.forEach((def) => {\n if (def.kind === 'FragmentDefinition') {\n fragments[def.name.value] = def;\n }\n });\n const config = {\n fragments,\n schema,\n errors,\n allObjectTypes: null,\n path: [],\n experimentalEnumsMap: options?.experimentalEnums ? {} : undefined,\n ...internalOptions,\n };\n\n return config;\n};\n\nexport class FlowGenerationError extends Error {\n messages: Array<string>;\n constructor(errors: Array<string>) {\n super(`Graphql-flow type generation failed! ${errors.join('; ')}`);\n this.messages = errors;\n }\n}\n\nexport const documentToFlowTypes = (\n document: DocumentNode,\n schema: Schema,\n options?: Options,\n): $ReadOnlyArray<{\n name: string,\n typeName: string,\n code: string,\n isFragment?: boolean,\n extraTypes: {[key: string]: string},\n experimentalEnums: {[key: string]: string},\n}> => {\n const errors: Array<string> = [];\n const config = optionsToConfig(\n schema,\n document.definitions,\n options,\n errors,\n );\n const result = document.definitions\n .map((item) => {\n if (item.kind === 'FragmentDefinition') {\n const name = item.name.value;\n const types = {};\n const code = `export type ${name} = ${generateFragmentType(\n schema,\n item,\n {\n ...config,\n path: [name],\n allObjectTypes: options?.exportAllObjectTypes\n ? types\n : null,\n },\n )};`;\n\n const extraTypes = codegenExtraTypes(types);\n const experimentalEnums = codegenExtraTypes(\n config.experimentalEnumsMap || {},\n );\n\n return {\n name,\n typeName: name,\n code,\n isFragment: true,\n extraTypes,\n experimentalEnums,\n };\n }\n if (\n item.kind === 'OperationDefinition' &&\n (item.operation === 'query' || item.operation === 'mutation') &&\n item.name\n ) {\n const types = {};\n const name = item.name.value;\n const response = generateResponseType(schema, item, {\n ...config,\n path: [name],\n allObjectTypes: options?.exportAllObjectTypes\n ? types\n : null,\n });\n const variables = generateVariablesType(schema, item, {\n ...config,\n path: [name],\n });\n\n const typeName = `${name}Type`;\n // TODO(jared): Maybe make this template configurable?\n // We'll see what's required to get webapp on board.\n const code = `export type ${typeName} = {|\\n variables: ${variables},\\n response: ${response}\\n|};`;\n\n const extraTypes = codegenExtraTypes(types);\n const experimentalEnums = codegenExtraTypes(\n config.experimentalEnumsMap || {},\n );\n\n return {name, typeName, code, extraTypes, experimentalEnums};\n }\n })\n .filter(Boolean);\n if (errors.length) {\n throw new FlowGenerationError(errors);\n }\n return result;\n};\n\nfunction codegenExtraTypes(types: {[key: string]: BabelNode}): {\n [key: string]: string,\n} {\n const extraTypes: {[key: string]: string} = {};\n Object.keys(types).forEach((k: string) => {\n // eslint-disable-next-line flowtype-errors/uncovered\n extraTypes[k] = generate(types[k]).code;\n });\n return extraTypes;\n}\n"],"file":"index.js"}
@@ -23,6 +23,7 @@ export type Options = {|
23
23
  generatedDirectory?: string,
24
24
  exportAllObjectTypes?: boolean,
25
25
  typeFileName?: string,
26
+ experimentalEnums?: boolean, // default false
26
27
  |};
27
28
 
28
29
  export type Schema = {
@@ -58,5 +59,7 @@ export type Config = {
58
59
  scalars: Scalars,
59
60
  errors: Array<string>,
60
61
  allObjectTypes: null | {[key: string]: BabelNode},
62
+
63
+ experimentalEnumsMap?: {[key: string]: BabelNode}, // index signature that is populated with declarations
61
64
  };
62
65
  export type Scalars = {[key: string]: 'string' | 'number' | 'boolean'};
@@ -406,6 +406,23 @@ declare module '@babel/types' {
406
406
  params: Array<BabelNodeFlowType>,
407
407
  ): BabelNodeTypeParameterInstantiation;
408
408
 
409
+ declare function enumDeclaration(
410
+ id: BabelNodeIdentifier,
411
+ body:
412
+ | BabelNodeEnumBooleanBody
413
+ | BabelNodeEnumNumberBody
414
+ | BabelNodeEnumStringBody
415
+ | BabelNodeEnumSymbolBody,
416
+ ): BabelNodeEnumDeclaration;
417
+ declare function enumStringBody(
418
+ members: Array<
419
+ BabelNodeEnumStringMember | BabelNodeEnumDefaultedMember,
420
+ >,
421
+ ): BabelNodeEnumStringBody;
422
+ declare function enumDefaultedMember(
423
+ id: BabelNodeIdentifier,
424
+ ): BabelNodeEnumDefaultedMember;
425
+
409
426
  /*
410
427
  NOTE(jared): There's something weird in the following couple hundred lines
411
428
  that makes flow ignore this whole file 🙃.
@@ -662,9 +679,6 @@ declare module '@babel/types' {
662
679
  id: BabelNodeIdentifier,
663
680
  init: BabelNodeStringLiteral,
664
681
  ): BabelNodeEnumStringMember;
665
- declare function enumDefaultedMember(
666
- id: BabelNodeIdentifier,
667
- ): BabelNodeEnumDefaultedMember;
668
682
  declare function jsxAttribute(
669
683
  name: BabelNodeJSXIdentifier | BabelNodeJSXNamespacedName,
670
684
  value?:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@khanacademy/graphql-flow",
3
- "version": "0.2.3",
3
+ "version": "0.3.0",
4
4
  "bin": {
5
5
  "graphql-flow": "./dist/cli/run.js"
6
6
  },
@@ -100,4 +100,56 @@ describe('generateTypeFileContents', () => {
100
100
  "
101
101
  `);
102
102
  });
103
+
104
+ describe('experimentalEnums', () => {
105
+ it('should generate the expected values', () => {
106
+ const {files} = generateTypeFileContents(
107
+ 'hello.js',
108
+ exampleSchema,
109
+ gql`
110
+ query Hello {
111
+ human(id: "Han") {
112
+ appearsIn
113
+ }
114
+ }
115
+ `,
116
+ {
117
+ experimentalEnums: true,
118
+ },
119
+ '__generated__',
120
+ indexPrelude('yarn queries'),
121
+ );
122
+ expect(
123
+ Object.keys(files)
124
+ .map((k) => `// ${k}\n${files[k]}`)
125
+ .join('\n\n'),
126
+ ).toMatchInlineSnapshot(`
127
+ "// __generated__/Hello.js
128
+ // @flow
129
+ // AUTOGENERATED -- DO NOT EDIT
130
+ // Generated for operation 'Hello' in file '../hello.js'
131
+ export type HelloType = {|
132
+ variables: {||},
133
+ response: {|
134
+ /** A human character*/
135
+ human: ?{|
136
+ appearsIn: ?$ReadOnlyArray<
137
+ /** - NEW_HOPE
138
+ - EMPIRE
139
+ - JEDI*/
140
+ ?Episode>
141
+ |}
142
+ |}
143
+ |};
144
+ /* eslint-disable no-undef */
145
+ export enum Episode {
146
+ NEW_HOPE,
147
+ EMPIRE,
148
+ JEDI,
149
+ };
150
+ /* eslint-enable no-undef */
151
+ "
152
+ `);
153
+ });
154
+ });
103
155
  });
@@ -0,0 +1,94 @@
1
+ import {loadDirConfigFiles} from '../config';
2
+
3
+ import fs from 'fs';
4
+ jest.mock('fs');
5
+
6
+ const filesResponse = `javascript/discussion-package/components/graphql-flow.config.json
7
+ javascript/discussion-package/graphql-flow.config.json
8
+ `;
9
+ const rootConfigPath = './dev/graphql-flow/config.json';
10
+ const mockRootConfig = {
11
+ path: rootConfigPath,
12
+ config: {
13
+ options: {
14
+ splitTypes: true,
15
+ readOnlyArray: false,
16
+ },
17
+ excludes: ['this one', 'that one'],
18
+ schemaFilePath: 'this/is/a/path.graphql',
19
+ dumpOperations: '',
20
+ },
21
+ };
22
+ const firstFileFixture = {
23
+ extends: 'javascript/discussion-package/graphql-flow.config.json',
24
+ options: {
25
+ splitTypes: false,
26
+ },
27
+ excludes: ['that one'],
28
+ };
29
+ const secondFileFixture = {
30
+ extends: rootConfigPath,
31
+ options: {
32
+ readOnlyArray: true,
33
+ },
34
+ excludes: ['another one'],
35
+ };
36
+
37
+ describe('loading subconfigs', () => {
38
+ it('should properly extend', () => {
39
+ // eslint-disable-next-line flowtype-errors/uncovered
40
+ fs.readFileSync
41
+ .mockReturnValueOnce(JSON.stringify(firstFileFixture))
42
+ .mockReturnValueOnce(JSON.stringify(secondFileFixture));
43
+
44
+ const dirConfigMap = loadDirConfigFiles(filesResponse, mockRootConfig);
45
+
46
+ const paths = Object.keys(dirConfigMap);
47
+ const subConfig = dirConfigMap[paths[0]];
48
+ const deeperConfig = dirConfigMap[paths[1]];
49
+
50
+ expect(paths).toHaveLength(2);
51
+
52
+ expect(subConfig.options.splitTypes).toBe(true);
53
+ expect(subConfig.options.readOnlyArray).toBe(true);
54
+ expect(subConfig.excludes.length).toBe(3);
55
+
56
+ expect(deeperConfig.options.splitTypes).toBe(false);
57
+ expect(subConfig.options.readOnlyArray).toBe(true);
58
+ expect(subConfig.excludes.length).toBe(3);
59
+ });
60
+ it('should properly overwrite', () => {
61
+ // eslint-disable-next-line flowtype-errors/uncovered
62
+ fs.readFileSync
63
+ .mockReturnValueOnce(
64
+ JSON.stringify({
65
+ options: {},
66
+ excludes: ['some other one'],
67
+ }),
68
+ )
69
+ .mockReturnValueOnce(
70
+ JSON.stringify({
71
+ options: {
72
+ splitTypes: false,
73
+ },
74
+ excludes: ['a completely different one one'],
75
+ }),
76
+ );
77
+
78
+ const dirConfigMap = loadDirConfigFiles(filesResponse, mockRootConfig);
79
+
80
+ const paths = Object.keys(dirConfigMap);
81
+ const subConfig = dirConfigMap[paths[0]];
82
+ const deeperConfig = dirConfigMap[paths[1]];
83
+
84
+ expect(paths).toHaveLength(2);
85
+
86
+ expect(subConfig.options.splitTypes).toBe(undefined);
87
+ expect(subConfig.options.readOnlyArray).toBe(undefined);
88
+ expect(subConfig.excludes.length).toBe(1);
89
+
90
+ expect(deeperConfig.options.splitTypes).toBe(false);
91
+ expect(subConfig.options.readOnlyArray).toBe(undefined);
92
+ expect(subConfig.excludes.length).toBe(1);
93
+ });
94
+ });
@@ -0,0 +1,19 @@
1
+ // @flow
2
+ import {longestMatchingPath} from '../utils.js';
3
+
4
+ describe('longestMatchingPath', () => {
5
+ const filePath = 'here/is/a/file/path.exe';
6
+ const subConfigPaths = [
7
+ 'not/a/match',
8
+ 'here/is',
9
+ 'here/is/a/file/path',
10
+ 'here/is/a/file/path/that/is/the/longest',
11
+ 'here/is/a/file/path/longer',
12
+ 'here/is/a/file', // here's the one we want
13
+ 'here/is/a',
14
+ ];
15
+ it('returns expected', () => {
16
+ const match = longestMatchingPath(filePath, subConfigPaths);
17
+ expect(match).toBe('here/is/a/file');
18
+ });
19
+ });