@khanacademy/graphql-flow 0.0.1 → 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.
Files changed (54) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/Readme.md +67 -67
  3. package/dist/cli/config.js +73 -0
  4. package/dist/cli/config.js.flow +104 -0
  5. package/dist/cli/config.js.map +1 -0
  6. package/dist/cli/run.js +157 -0
  7. package/dist/cli/run.js.flow +164 -0
  8. package/dist/cli/run.js.map +1 -0
  9. package/dist/enums.js +2 -1
  10. package/dist/enums.js.map +1 -0
  11. package/dist/generateResponseType.js +170 -60
  12. package/dist/generateResponseType.js.flow +248 -82
  13. package/dist/generateResponseType.js.map +1 -0
  14. package/dist/generateTypeFiles.js +141 -0
  15. package/dist/generateTypeFiles.js.flow +167 -0
  16. package/dist/generateTypeFiles.js.map +1 -0
  17. package/dist/generateVariablesType.js +8 -1
  18. package/dist/generateVariablesType.js.flow +6 -0
  19. package/dist/generateVariablesType.js.map +1 -0
  20. package/dist/index.js +45 -4
  21. package/dist/index.js.flow +54 -4
  22. package/dist/index.js.map +1 -0
  23. package/dist/jest-mock-graphql-tag.js +42 -123
  24. package/dist/jest-mock-graphql-tag.js.flow +50 -145
  25. package/dist/jest-mock-graphql-tag.js.map +1 -0
  26. package/dist/parser/parse.js +349 -0
  27. package/dist/parser/parse.js.flow +403 -0
  28. package/dist/parser/parse.js.map +1 -0
  29. package/dist/parser/resolve.js +111 -0
  30. package/dist/parser/resolve.js.flow +117 -0
  31. package/dist/parser/resolve.js.map +1 -0
  32. package/dist/schemaFromIntrospectionData.js +2 -1
  33. package/dist/schemaFromIntrospectionData.js.map +1 -0
  34. package/dist/types.js +2 -1
  35. package/dist/types.js.flow +7 -0
  36. package/dist/types.js.map +1 -0
  37. package/dist/utils.js +2 -1
  38. package/dist/utils.js.map +1 -0
  39. package/package.json +13 -9
  40. package/src/__test__/example-schema.graphql +3 -1
  41. package/src/__test__/generateTypeFileContents.test.js +61 -0
  42. package/src/__test__/graphql-flow.test.js +329 -54
  43. package/src/__test__/{jest-mock-graphql-tag.test.js → processPragmas.test.js} +13 -1
  44. package/src/cli/config.js +104 -0
  45. package/src/cli/run.js +164 -0
  46. package/src/generateResponseType.js +248 -82
  47. package/src/generateTypeFiles.js +167 -0
  48. package/src/generateVariablesType.js +6 -0
  49. package/src/index.js +54 -4
  50. package/src/jest-mock-graphql-tag.js +50 -145
  51. package/src/parser/__test__/parse.test.js +247 -0
  52. package/src/parser/parse.js +403 -0
  53. package/src/parser/resolve.js +117 -0
  54. package/src/types.js +7 -0
@@ -0,0 +1,167 @@
1
+ // @flow
2
+ // Import this in your jest setup, to mock out graphql-tag!
3
+ import type {DocumentNode} from 'graphql';
4
+ import type {Options, Schema, Scalars} from './types';
5
+ import fs from 'fs';
6
+ import path from 'path';
7
+ import {documentToFlowTypes} from '.';
8
+
9
+ export type ExternalOptions = {
10
+ pragma?: string,
11
+ loosePragma?: string,
12
+ ignorePragma?: string,
13
+ scalars?: Scalars,
14
+ strictNullability?: boolean,
15
+ /**
16
+ * The command that users should run to regenerate the types files.
17
+ */
18
+ regenerateCommand?: string,
19
+ readOnlyArray?: boolean,
20
+ splitTypes?: boolean,
21
+ generatedDirectory?: string,
22
+ exportAllObjectTypes?: boolean,
23
+ };
24
+
25
+ export const indexPrelude = (regenerateCommand?: string): string => `// @flow
26
+ //
27
+ // AUTOGENERATED
28
+ // NOTE: New response types are added to this file automatically.
29
+ // Outdated response types can be removed manually as they are deprecated.
30
+ //${regenerateCommand ? ' To regenerate, run ' + regenerateCommand : ''}
31
+ //
32
+
33
+ `;
34
+
35
+ export const generateTypeFileContents = (
36
+ fileName: string,
37
+ schema: Schema,
38
+ document: DocumentNode,
39
+ options: Options,
40
+ generatedDir: string,
41
+ indexContents: string,
42
+ ): {indexContents: string, files: {[key: string]: string}} => {
43
+ const files = {};
44
+
45
+ /// Write export for __generated__/index.js if it doesn't exist
46
+ const addToIndex = (filePath, typeName) => {
47
+ const newLine = `export type {${typeName}} from './${path.basename(
48
+ filePath,
49
+ )}';`;
50
+ if (indexContents.indexOf('./' + path.basename(filePath)) === -1) {
51
+ indexContents += newLine + '\n';
52
+ } else {
53
+ const lines = indexContents.split('\n').map((line) => {
54
+ if (line.includes('./' + path.basename(filePath))) {
55
+ return newLine;
56
+ }
57
+ return line;
58
+ });
59
+ indexContents = lines.join('\n');
60
+ }
61
+ };
62
+
63
+ const generated = documentToFlowTypes(document, schema, options);
64
+ generated.forEach(({name, typeName, code, isFragment, extraTypes}) => {
65
+ // We write all generated files to a `__generated__` subdir to keep
66
+ // things tidy.
67
+ const targetFileName = `${name}.js`;
68
+ const targetPath = path.join(generatedDir, targetFileName);
69
+
70
+ let fileContents =
71
+ '// @' +
72
+ `flow\n// AUTOGENERATED -- DO NOT EDIT\n` +
73
+ `// Generated for operation '${name}' in file '../${path.basename(
74
+ fileName,
75
+ )}'\n` +
76
+ (options.regenerateCommand
77
+ ? `// To regenerate, run '${options.regenerateCommand}'.\n`
78
+ : '') +
79
+ code;
80
+ if (options.splitTypes && !isFragment) {
81
+ fileContents +=
82
+ `\nexport type ${name} = ${typeName}['response'];\n` +
83
+ `export type ${name}Variables = ${typeName}['variables'];\n`;
84
+ }
85
+ Object.keys(extraTypes).forEach((name) => {
86
+ fileContents += `\n\nexport type ${name} = ${extraTypes[name]};`;
87
+ });
88
+
89
+ addToIndex(targetPath, typeName);
90
+ files[targetPath] =
91
+ fileContents
92
+ // Remove whitespace from the ends of lines; babel's generate sometimes
93
+ // leaves them hanging around.
94
+ .replace(/\s+$/gm, '') + '\n';
95
+ });
96
+
97
+ return {files, indexContents};
98
+ };
99
+
100
+ export const generateTypeFiles = (
101
+ fileName: string,
102
+ schema: Schema,
103
+ document: DocumentNode,
104
+ options: Options,
105
+ ) => {
106
+ const generatedDir = path.join(
107
+ path.dirname(fileName),
108
+ options.generatedDirectory ?? '__generated__',
109
+ );
110
+ const indexFile = path.join(generatedDir, 'index.js');
111
+
112
+ if (!fs.existsSync(generatedDir)) {
113
+ fs.mkdirSync(generatedDir, {recursive: true});
114
+ }
115
+ if (!fs.existsSync(indexFile)) {
116
+ fs.writeFileSync(indexFile, indexPrelude(options.regenerateCommand));
117
+ }
118
+
119
+ const {indexContents, files} = generateTypeFileContents(
120
+ fileName,
121
+ schema,
122
+ document,
123
+ options,
124
+ generatedDir,
125
+ fs.readFileSync(indexFile, 'utf8'),
126
+ );
127
+
128
+ fs.writeFileSync(indexFile, indexContents);
129
+ Object.keys(files).forEach((key) => {
130
+ fs.writeFileSync(key, files[key]);
131
+ });
132
+
133
+ fs.writeFileSync(indexFile, indexContents);
134
+ };
135
+
136
+ export const processPragmas = (
137
+ options: ExternalOptions,
138
+ rawSource: string,
139
+ ): null | Options => {
140
+ if (options.ignorePragma && rawSource.includes(options.ignorePragma)) {
141
+ return null;
142
+ }
143
+
144
+ const autogen = options.loosePragma
145
+ ? rawSource.includes(options.loosePragma)
146
+ : false;
147
+ const autogenStrict = options.pragma
148
+ ? rawSource.includes(options.pragma)
149
+ : false;
150
+ const noPragmas = !options.loosePragma && !options.pragma;
151
+
152
+ if (autogen || autogenStrict || noPragmas) {
153
+ return {
154
+ regenerateCommand: options.regenerateCommand,
155
+ strictNullability: noPragmas
156
+ ? options.strictNullability
157
+ : autogenStrict || !autogen,
158
+ readOnlyArray: options.readOnlyArray,
159
+ scalars: options.scalars,
160
+ splitTypes: options.splitTypes,
161
+ generatedDirectory: options.generatedDirectory,
162
+ exportAllObjectTypes: options.exportAllObjectTypes,
163
+ };
164
+ } else {
165
+ return null;
166
+ }
167
+ };
@@ -0,0 +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","targetPath","fileContents","splitTypes","Object","keys","replace","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};\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 = `${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 };\n } else {\n return null;\n }\n};\n"],"file":"generateTypeFiles.js"}
@@ -104,6 +104,12 @@ const _variableToFlow = (config, type) => {
104
104
  return (0, _enums.enumTypeToFlow)(config, type.name.value);
105
105
  }
106
106
 
107
+ const customScalarType = config.scalars[type.name.value];
108
+
109
+ if (customScalarType) {
110
+ return babelTypes.genericTypeAnnotation(babelTypes.identifier(customScalarType));
111
+ }
112
+
107
113
  return inputObjectToFlow(config, type.name.value);
108
114
  }
109
115
 
@@ -129,4 +135,5 @@ const generateVariablesType = (schema, item, config) => {
129
135
  return (0, _generator.default)(variableObject).code; // eslint-disable-line flowtype-errors/uncovered
130
136
  };
131
137
 
132
- exports.generateVariablesType = generateVariablesType;
138
+ exports.generateVariablesType = generateVariablesType;
139
+ //# sourceMappingURL=generateVariablesType.js.map
@@ -117,6 +117,12 @@ const _variableToFlow = (config: Config, type: TypeNode) => {
117
117
  if (config.schema.enumsByName[type.name.value]) {
118
118
  return enumTypeToFlow(config, type.name.value);
119
119
  }
120
+ const customScalarType = config.scalars[type.name.value];
121
+ if (customScalarType) {
122
+ return babelTypes.genericTypeAnnotation(
123
+ babelTypes.identifier(customScalarType),
124
+ );
125
+ }
120
126
  return inputObjectToFlow(config, type.name.value);
121
127
  }
122
128
  if (type.kind === 'ListType') {
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/generateVariablesType.js"],"names":["inputObjectToFlow","config","name","inputObject","schema","inputObjectsByName","errors","push","babelTypes","stringLiteralTypeAnnotation","description","objectTypeAnnotation","inputFields","map","vbl","maybeOptionalObjectTypeProperty","inputRefToFlow","type","undefined","prop","objectTypeProperty","identifier","optional","inputRef","kind","_inputRefToFlow","ofType","result","nullableTypeAnnotation","genericTypeAnnotation","typeParameterInstantiation","JSON","stringify","variableToFlow","_variableToFlow","builtinScalars","value","enumsByName","customScalarType","scalars","generateVariablesType","item","variableObject","variableDefinitions","variable","code"],"mappings":"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","sourcesContent":["// @flow\nimport generate from '@babel/generator'; // eslint-disable-line flowtype-errors/uncovered\nimport type {\n BabelNodeFlowType,\n BabelNodeObjectTypeProperty,\n} from '@babel/types';\nimport * as babelTypes from '@babel/types';\nimport type {OperationDefinitionNode, TypeNode} from 'graphql/language/ast';\nimport type {IntrospectionInputTypeRef} from 'graphql/utilities/introspectionQuery';\nimport {builtinScalars, enumTypeToFlow, scalarTypeToFlow} from './enums';\nimport type {Config, Schema} from './types';\nimport {\n liftLeadingPropertyComments,\n maybeAddDescriptionComment,\n transferLeadingComments,\n} from './utils';\n\nexport const inputObjectToFlow = (\n config: Config,\n name: string,\n): BabelNodeFlowType => {\n const inputObject = config.schema.inputObjectsByName[name];\n if (!inputObject) {\n config.errors.push(`Unknown input object ${name}`);\n return babelTypes.stringLiteralTypeAnnotation(\n `Unknown input object ${name}`,\n );\n }\n\n return maybeAddDescriptionComment(\n inputObject.description,\n babelTypes.objectTypeAnnotation(\n inputObject.inputFields.map((vbl) =>\n maybeAddDescriptionComment(\n vbl.description,\n maybeOptionalObjectTypeProperty(\n vbl.name,\n inputRefToFlow(config, vbl.type),\n ),\n ),\n ),\n undefined /* indexers */,\n undefined /* callProperties */,\n undefined /* internalSlots */,\n true /* exact */,\n ),\n );\n};\n\nexport const maybeOptionalObjectTypeProperty = (\n name: string,\n type: babelTypes.BabelNodeFlowType,\n): BabelNodeObjectTypeProperty => {\n const prop = liftLeadingPropertyComments(\n babelTypes.objectTypeProperty(babelTypes.identifier(name), type),\n );\n if (type.type === 'NullableTypeAnnotation') {\n prop.optional = true;\n }\n return prop;\n};\n\nexport const inputRefToFlow = (\n config: Config,\n inputRef: IntrospectionInputTypeRef,\n): BabelNodeFlowType => {\n if (inputRef.kind === 'NON_NULL') {\n return _inputRefToFlow(config, inputRef.ofType);\n }\n const result = _inputRefToFlow(config, inputRef);\n return transferLeadingComments(\n result,\n babelTypes.nullableTypeAnnotation(result),\n );\n};\n\nconst _inputRefToFlow = (\n config: Config,\n inputRef: IntrospectionInputTypeRef,\n) => {\n if (inputRef.kind === 'SCALAR') {\n return scalarTypeToFlow(config, inputRef.name);\n }\n if (inputRef.kind === 'ENUM') {\n return enumTypeToFlow(config, inputRef.name);\n }\n if (inputRef.kind === 'INPUT_OBJECT') {\n return inputObjectToFlow(config, inputRef.name);\n }\n if (inputRef.kind === 'LIST') {\n return babelTypes.genericTypeAnnotation(\n babelTypes.identifier('$ReadOnlyArray'),\n babelTypes.typeParameterInstantiation([\n inputRefToFlow(config, inputRef.ofType),\n ]),\n );\n }\n return babelTypes.stringLiteralTypeAnnotation(JSON.stringify(inputRef));\n};\n\nconst variableToFlow = (config: Config, type: TypeNode) => {\n if (type.kind === 'NonNullType') {\n return _variableToFlow(config, type.type);\n }\n const result = _variableToFlow(config, type);\n return transferLeadingComments(\n result,\n babelTypes.nullableTypeAnnotation(result),\n );\n};\n\nconst _variableToFlow = (config: Config, type: TypeNode) => {\n if (type.kind === 'NamedType') {\n if (builtinScalars[type.name.value]) {\n return scalarTypeToFlow(config, type.name.value);\n }\n if (config.schema.enumsByName[type.name.value]) {\n return enumTypeToFlow(config, type.name.value);\n }\n const customScalarType = config.scalars[type.name.value];\n if (customScalarType) {\n return babelTypes.genericTypeAnnotation(\n babelTypes.identifier(customScalarType),\n );\n }\n return inputObjectToFlow(config, type.name.value);\n }\n if (type.kind === 'ListType') {\n return babelTypes.genericTypeAnnotation(\n babelTypes.identifier('$ReadOnlyArray'),\n babelTypes.typeParameterInstantiation([\n variableToFlow(config, type.type),\n ]),\n );\n }\n return babelTypes.stringLiteralTypeAnnotation(\n 'UNKNOWN' + JSON.stringify(type),\n );\n};\n\nexport const generateVariablesType = (\n schema: Schema,\n item: OperationDefinitionNode,\n config: Config,\n): string => {\n const variableObject = babelTypes.objectTypeAnnotation(\n (item.variableDefinitions || []).map((vbl) => {\n return maybeOptionalObjectTypeProperty(\n vbl.variable.name.value,\n variableToFlow(config, vbl.type),\n );\n }),\n undefined /* indexers */,\n undefined /* callProperties */,\n undefined /* internalSlots */,\n true /* exact */,\n );\n return generate(variableObject).code; // eslint-disable-line flowtype-errors/uncovered\n};\n"],"file":"generateVariablesType.js"}
package/dist/index.js CHANGED
@@ -11,12 +11,16 @@ Object.defineProperty(exports, "spyOnGraphqlTagToCollectQueries", {
11
11
  }
12
12
  });
13
13
 
14
+ var _generator = _interopRequireDefault(require("@babel/generator"));
15
+
14
16
  var _generateResponseType = require("./generateResponseType");
15
17
 
16
18
  var _generateVariablesType = require("./generateVariablesType");
17
19
 
18
20
  var _jestMockGraphqlTag = require("./jest-mock-graphql-tag");
19
21
 
22
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23
+
20
24
  /* eslint-disable no-console */
21
25
 
22
26
  /* flow-uncovered-file */
@@ -27,6 +31,7 @@ var _jestMockGraphqlTag = require("./jest-mock-graphql-tag");
27
31
  * It relies on `introspection-query.json` existing in this directory,
28
32
  * which is produced by running `./tools/graphql-flow/sendIntrospection.js`.
29
33
  */
34
+ // eslint-disable-line flowtype-errors/uncovered
30
35
  const optionsToConfig = (schema, definitions, options, errors = []) => {
31
36
  const internalOptions = {
32
37
  strictNullability: (options === null || options === void 0 ? void 0 : options.strictNullability) ?? true,
@@ -43,6 +48,8 @@ const optionsToConfig = (schema, definitions, options, errors = []) => {
43
48
  fragments,
44
49
  schema,
45
50
  errors,
51
+ allObjectTypes: null,
52
+ path: [],
46
53
  ...internalOptions
47
54
  };
48
55
  return config;
@@ -62,18 +69,51 @@ const documentToFlowTypes = (document, schema, options) => {
62
69
  const errors = [];
63
70
  const config = optionsToConfig(schema, document.definitions, options, errors);
64
71
  const result = document.definitions.map(item => {
72
+ if (item.kind === 'FragmentDefinition') {
73
+ const name = item.name.value;
74
+ const types = {};
75
+ const code = `export type ${name} = ${(0, _generateResponseType.generateFragmentType)(schema, item, { ...config,
76
+ path: [name],
77
+ allObjectTypes: options !== null && options !== void 0 && options.exportAllObjectTypes ? types : null
78
+ })};`;
79
+ const extraTypes = {};
80
+ Object.keys(types).forEach(k => {
81
+ // eslint-disable-next-line flowtype-errors/uncovered
82
+ extraTypes[k] = (0, _generator.default)(types[k]).code;
83
+ });
84
+ return {
85
+ name,
86
+ typeName: name,
87
+ code,
88
+ isFragment: true,
89
+ extraTypes
90
+ };
91
+ }
92
+
65
93
  if (item.kind === 'OperationDefinition' && (item.operation === 'query' || item.operation === 'mutation') && item.name) {
94
+ const types = {};
66
95
  const name = item.name.value;
67
- const response = (0, _generateResponseType.generateResponseType)(schema, item, config);
68
- const variables = (0, _generateVariablesType.generateVariablesType)(schema, item, config);
96
+ const response = (0, _generateResponseType.generateResponseType)(schema, item, { ...config,
97
+ path: [name],
98
+ allObjectTypes: options !== null && options !== void 0 && options.exportAllObjectTypes ? types : null
99
+ });
100
+ const variables = (0, _generateVariablesType.generateVariablesType)(schema, item, { ...config,
101
+ path: [name]
102
+ });
69
103
  const typeName = `${name}Type`; // TODO(jared): Maybe make this template configurable?
70
104
  // We'll see what's required to get webapp on board.
71
105
 
72
106
  const code = `export type ${typeName} = {|\n variables: ${variables},\n response: ${response}\n|};`;
107
+ const extraTypes = {};
108
+ Object.keys(types).forEach(k => {
109
+ // eslint-disable-next-line flowtype-errors/uncovered
110
+ extraTypes[k] = (0, _generator.default)(types[k]).code;
111
+ });
73
112
  return {
74
113
  name,
75
114
  typeName,
76
- code
115
+ code,
116
+ extraTypes
77
117
  };
78
118
  }
79
119
  }).filter(Boolean);
@@ -85,4 +125,5 @@ const documentToFlowTypes = (document, schema, options) => {
85
125
  return result;
86
126
  };
87
127
 
88
- exports.documentToFlowTypes = documentToFlowTypes;
128
+ exports.documentToFlowTypes = documentToFlowTypes;
129
+ //# sourceMappingURL=index.js.map
@@ -9,7 +9,11 @@
9
9
  */
10
10
  import type {DefinitionNode, DocumentNode} from 'graphql';
11
11
 
12
- import {generateResponseType} from './generateResponseType';
12
+ import generate from '@babel/generator'; // eslint-disable-line flowtype-errors/uncovered
13
+ import {
14
+ generateFragmentType,
15
+ generateResponseType,
16
+ } from './generateResponseType';
13
17
  import {generateVariablesType} from './generateVariablesType';
14
18
  export {spyOnGraphqlTagToCollectQueries} from './jest-mock-graphql-tag';
15
19
 
@@ -36,6 +40,8 @@ const optionsToConfig = (
36
40
  fragments,
37
41
  schema,
38
42
  errors,
43
+ allObjectTypes: null,
44
+ path: [],
39
45
  ...internalOptions,
40
46
  };
41
47
 
@@ -58,6 +64,8 @@ export const documentToFlowTypes = (
58
64
  name: string,
59
65
  typeName: string,
60
66
  code: string,
67
+ isFragment?: boolean,
68
+ extraTypes: {[key: string]: string},
61
69
  }> => {
62
70
  const errors: Array<string> = [];
63
71
  const config = optionsToConfig(
@@ -68,21 +76,63 @@ export const documentToFlowTypes = (
68
76
  );
69
77
  const result = document.definitions
70
78
  .map((item) => {
79
+ if (item.kind === 'FragmentDefinition') {
80
+ const name = item.name.value;
81
+ const types = {};
82
+ const code = `export type ${name} = ${generateFragmentType(
83
+ schema,
84
+ item,
85
+ {
86
+ ...config,
87
+ path: [name],
88
+ allObjectTypes: options?.exportAllObjectTypes
89
+ ? types
90
+ : null,
91
+ },
92
+ )};`;
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
+ });
98
+ return {
99
+ name,
100
+ typeName: name,
101
+ code,
102
+ isFragment: true,
103
+ extraTypes,
104
+ };
105
+ }
71
106
  if (
72
107
  item.kind === 'OperationDefinition' &&
73
108
  (item.operation === 'query' || item.operation === 'mutation') &&
74
109
  item.name
75
110
  ) {
111
+ const types = {};
76
112
  const name = item.name.value;
77
- const response = generateResponseType(schema, item, config);
78
- const variables = generateVariablesType(schema, item, config);
113
+ const response = generateResponseType(schema, item, {
114
+ ...config,
115
+ path: [name],
116
+ allObjectTypes: options?.exportAllObjectTypes
117
+ ? types
118
+ : null,
119
+ });
120
+ const variables = generateVariablesType(schema, item, {
121
+ ...config,
122
+ path: [name],
123
+ });
79
124
 
80
125
  const typeName = `${name}Type`;
81
126
  // TODO(jared): Maybe make this template configurable?
82
127
  // We'll see what's required to get webapp on board.
83
128
  const code = `export type ${typeName} = {|\n variables: ${variables},\n response: ${response}\n|};`;
84
129
 
85
- return {name, typeName, code};
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};
86
136
  }
87
137
  })
88
138
  .filter(Boolean);
@@ -0,0 +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"}
@@ -10,134 +10,69 @@ var _apolloUtilities = require("apollo-utilities");
10
10
 
11
11
  var _schemaFromIntrospectionData = require("./schemaFromIntrospectionData");
12
12
 
13
+ var _generateTypeFiles = require("./generateTypeFiles");
14
+
13
15
  // Import this in your jest setup, to mock out graphql-tag!
14
16
  // eslint-disable-line flowtype-errors/uncovered
15
- const indexPrelude = `// @flow
16
- //
17
- // AUTOGENERATED
18
- // NOTE: New response types are added to this file automatically.
19
- // Outdated response types can be removed manually as they are deprecated.
20
- //
21
-
22
- `;
23
-
24
- const generateTypeFiles = (schema, document, options) => {
25
- const {
26
- documentToFlowTypes
27
- } = require('.');
28
-
29
- const path = require('path');
30
-
31
- const fs = require('fs');
32
-
33
- const format = require('prettier-eslint'); // eslint-disable-line flowtype-errors/uncovered
34
-
35
-
36
- const indexFile = generatedDir => path.join(generatedDir, 'index.js');
37
-
38
- const maybeCreateGeneratedDir = generatedDir => {
39
- if (!fs.existsSync(generatedDir)) {
40
- fs.mkdirSync(generatedDir, {
41
- recursive: true
42
- }); // Now write an index.js for each __generated__ dir.
43
-
44
- fs.writeFileSync(indexFile(generatedDir), indexPrelude);
45
- }
46
- }; /// Write export for __generated__/index.js if it doesn't exist
47
-
48
-
49
- const writeToIndex = (filePath, typeName) => {
50
- const index = indexFile(path.dirname(filePath));
51
- const indexContents = fs.readFileSync(index, 'utf8');
52
- const newLine = `export type {${typeName}} from './${path.basename(filePath)}';`;
53
-
54
- if (indexContents.indexOf(path.basename(filePath)) === -1) {
55
- fs.appendFileSync(index, newLine + '\n');
56
- } else {
57
- const lines = indexContents.split('\n').map(line => {
58
- if (line.includes(path.basename(filePath))) {
59
- return newLine;
60
- }
61
-
62
- return line;
63
- });
64
- fs.writeFileSync(index, lines.join('\n'));
65
- }
66
- }; // Get the name of the file that `gql` was called from
67
-
68
-
69
- const errorLines = new Error().stack.split('\n');
70
- const fileName = errorLines[3].split('(').slice(-1)[0].split(':')[0];
71
- const generated = documentToFlowTypes(document, schema, options);
72
- generated.forEach(({
73
- name,
74
- typeName,
75
- code
76
- }) => {
77
- // We write all generated files to a `__generated__` subdir to keep
78
- // things tidy.
79
- const targetFileName = `${typeName}.js`;
80
- const generatedDir = path.join(path.dirname(fileName), '__generated__');
81
- const targetPath = path.join(generatedDir, targetFileName);
82
- maybeCreateGeneratedDir(generatedDir); // NOTE: Uncomment this to write the query definitions to disk if
83
- // you need to add new features to the flow type generation
84
- // fs.writeFileSync(
85
- // targetFileName + '.query',
86
- // JSON.stringify(definitions, null, 2),
87
- // );
88
-
89
- const fileContents = format({
90
- text: '// @' + `flow\n// AUTOGENERATED -- DO NOT EDIT\n` + `// Generated for operation '${name}' in file '../${path.basename(fileName)}'\n` + `// To regenerate, run 'yarn test queries'.\n` + code
91
- });
92
- fs.writeFileSync(targetPath, fileContents);
93
- writeToIndex(targetPath, typeName);
94
- });
95
- };
96
17
 
97
- // This function is expected to be called like so:
98
- //
99
- // jest.mock('graphql-tag', () => {
100
- // const introspectionData = jest.requireActual(
101
- // './our-introspection-query.json',
102
- // );
103
- // const {spyOnGraphqlTagToCollectQueries} = jest.requireActual(
104
- // 'graphql-flow/jest-mock-graphql-tag.js');
105
- //
106
- // return spyOnGraphqlTagToCollectQueries(
107
- // jest.requireActual('graphql-tag'),
108
- // introspectionData,
109
- // );
110
- // });
111
- //
112
- // If both pragma and loosePragma are empty, then all graphql
113
- // documents will be processed. Otherwise, only documents
114
- // with one of the pragmas will be processed.
18
+ /**
19
+ * This function is expected to be called like so:
20
+ *
21
+ * jest.mock('graphql-tag', () => {
22
+ * const introspectionData = jest.requireActual(
23
+ * './server-introspection-response.json',
24
+ * );
25
+ * const {spyOnGraphqlTagToCollectQueries} = jest.requireActual(
26
+ * 'graphql-flow/jest-mock-graphql-tag.js');
27
+ *
28
+ * return spyOnGraphqlTagToCollectQueries(
29
+ * jest.requireActual('graphql-tag'),
30
+ * introspectionData,
31
+ * );
32
+ * });
33
+ *
34
+ * If both pragma and loosePragma are empty, then all graphql
35
+ * documents will be processed. Otherwise, only documents
36
+ * with one of the pragmas will be processed.
37
+ * Any operations containing `ignorePragma` (if provided)
38
+ * will be skipped, regardless of whether they contain
39
+ * another specified pragma.
40
+ */
115
41
  const spyOnGraphqlTagToCollectQueries = (realGraphqlTag, introspectionData, options = {}) => {
116
42
  const collection = [];
117
43
  const clientSchema = (0, _graphql.buildClientSchema)(introspectionData);
118
44
  const schema = (0, _schemaFromIntrospectionData.schemaFromIntrospectionData)(introspectionData);
119
45
 
120
46
  const wrapper = function gql() {
47
+ // Get the name of the file that `gql` was called from
48
+ const errorLines = new Error().stack.split('\n');
49
+ const fileName = errorLines[2].split('(').slice(-1)[0].split(':')[0];
121
50
  const document = realGraphqlTag.apply(this, arguments); // eslint-disable-line flowtype-errors/uncovered
122
51
 
123
52
  const hasNonFragments = document.definitions.some(({
124
53
  kind
125
54
  }) => kind !== 'FragmentDefinition');
126
55
 
56
+ if (fileName.includes('course-editor') || fileName.endsWith('_test.js') || fileName.endsWith('.fixture.js')) {
57
+ return document;
58
+ }
59
+
127
60
  if (hasNonFragments) {
128
61
  // eslint-disable-next-line flowtype-errors/uncovered
129
62
  const withTypeNames = (0, _apolloUtilities.addTypenameToDocument)(document);
130
- collection.push({
131
- raw: (0, _printer.print)(withTypeNames),
132
- errors: (0, _validation.validate)(clientSchema, document)
133
- });
134
63
  const rawSource = arguments[0].raw[0]; // eslint-disable-line flowtype-errors/uncovered
135
64
 
136
- const processedOptions = processPragmas(options, rawSource);
65
+ const processedOptions = (0, _generateTypeFiles.processPragmas)(options, rawSource);
137
66
 
138
67
  if (processedOptions) {
139
- generateTypeFiles(schema, withTypeNames, processedOptions);
68
+ (0, _generateTypeFiles.generateTypeFiles)(fileName, schema, withTypeNames, processedOptions);
140
69
  }
70
+
71
+ collection.push({
72
+ raw: (0, _printer.print)(withTypeNames),
73
+ errors: (0, _validation.validate)(clientSchema, document),
74
+ processed: !!processedOptions
75
+ });
141
76
  }
142
77
 
143
78
  return document;
@@ -147,23 +82,7 @@ const spyOnGraphqlTagToCollectQueries = (realGraphqlTag, introspectionData, opti
147
82
  return wrapper;
148
83
  };
149
84
 
150
- const processPragmas = (options, rawSource) => {
151
- const autogen = options.loosePragma ? rawSource.includes(options.loosePragma) : false;
152
- const autogenStrict = options.pragma ? rawSource.includes(options.pragma) : false;
153
- const noPragmas = !options.loosePragma && !options.pragma;
154
-
155
- if (autogen || autogenStrict || noPragmas) {
156
- return {
157
- strictNullability: noPragmas ? options.strictNullability : autogenStrict || !autogen,
158
- readOnlyArray: options.readOnlyArray,
159
- scalars: options.scalars
160
- };
161
- } else {
162
- return null;
163
- }
164
- };
165
-
166
85
  module.exports = {
167
- processPragmas,
168
86
  spyOnGraphqlTagToCollectQueries
169
- };
87
+ };
88
+ //# sourceMappingURL=jest-mock-graphql-tag.js.map