@khanacademy/graphql-flow 1.1.2 → 2.0.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 (76) hide show
  1. package/.babelrc +1 -1
  2. package/.eslintrc.js +0 -1
  3. package/.github/workflows/changeset-release.yml +1 -1
  4. package/CHANGELOG.md +16 -0
  5. package/dist/cli/config.js +2 -4
  6. package/dist/cli/run.js +1 -2
  7. package/dist/enums.js +8 -9
  8. package/dist/generateResponseType.js +33 -41
  9. package/dist/generateTypeFiles.js +13 -35
  10. package/dist/generateVariablesType.js +15 -31
  11. package/dist/index.js +11 -17
  12. package/dist/parser/parse.js +10 -8
  13. package/dist/parser/resolve.js +11 -8
  14. package/dist/parser/utils.js +36 -0
  15. package/dist/schemaFromIntrospectionData.js +1 -2
  16. package/dist/types.js +1 -2
  17. package/dist/utils.js +43 -3
  18. package/package.json +8 -7
  19. package/{src/cli/schema.json → schema.json} +3 -0
  20. package/{dist/__test__/generateTypeFileContents.test.js → src/__test__/generateTypeFileContents.test.ts} +38 -41
  21. package/{dist/__test__/graphql-flow.test.js → src/__test__/graphql-flow.test.ts} +232 -235
  22. package/src/__test__/{processPragmas.test.js → processPragmas.test.ts} +0 -1
  23. package/{dist/cli/__test__/config.test.js → src/cli/__test__/config.test.ts} +5 -6
  24. package/{dist/cli/config.js.flow → src/cli/config.ts} +6 -11
  25. package/src/cli/{run.js → run.ts} +5 -4
  26. package/src/{enums.js → enums.ts} +20 -22
  27. package/{dist/generateResponseType.js.flow → src/generateResponseType.ts} +167 -182
  28. package/src/{generateTypeFiles.js → generateTypeFiles.ts} +24 -40
  29. package/src/{generateVariablesType.js → generateVariablesType.ts} +34 -44
  30. package/{dist/index.js.flow → src/index.ts} +33 -24
  31. package/{dist/parser/__test__/parse.test.js → src/parser/__test__/parse.test.ts} +12 -11
  32. package/{dist/parser/parse.js.flow → src/parser/parse.ts} +69 -48
  33. package/{dist/parser/resolve.js.flow → src/parser/resolve.ts} +25 -19
  34. package/src/parser/utils.ts +24 -0
  35. package/{dist/schemaFromIntrospectionData.js.flow → src/schemaFromIntrospectionData.ts} +1 -4
  36. package/src/types.ts +97 -0
  37. package/src/utils.ts +73 -0
  38. package/tools/{find-files-with-gql.js → find-files-with-gql.ts} +2 -3
  39. package/tsconfig.json +110 -0
  40. package/types/flow-to-ts.d.ts +1 -0
  41. package/dist/__test__/example-schema.graphql +0 -67
  42. package/dist/__test__/processPragmas.test.js +0 -76
  43. package/dist/cli/config.js.map +0 -1
  44. package/dist/cli/run.js.flow +0 -236
  45. package/dist/cli/run.js.map +0 -1
  46. package/dist/cli/schema.json +0 -94
  47. package/dist/enums.js.flow +0 -98
  48. package/dist/enums.js.map +0 -1
  49. package/dist/generateResponseType.js.map +0 -1
  50. package/dist/generateTypeFiles.js.flow +0 -197
  51. package/dist/generateTypeFiles.js.map +0 -1
  52. package/dist/generateVariablesType.js.flow +0 -156
  53. package/dist/generateVariablesType.js.map +0 -1
  54. package/dist/index.js.map +0 -1
  55. package/dist/parser/parse.js.map +0 -1
  56. package/dist/parser/resolve.js.map +0 -1
  57. package/dist/schemaFromIntrospectionData.js.map +0 -1
  58. package/dist/types.js.flow +0 -87
  59. package/dist/types.js.map +0 -1
  60. package/dist/utils.js.flow +0 -50
  61. package/dist/utils.js.map +0 -1
  62. package/flow-typed/npm/@babel/types_vx.x.x.js +0 -5331
  63. package/flow-typed/npm/jest_v23.x.x.js +0 -1155
  64. package/flow-typed/overrides.js +0 -435
  65. package/src/__test__/generateTypeFileContents.test.js +0 -157
  66. package/src/__test__/graphql-flow.test.js +0 -639
  67. package/src/cli/__test__/config.test.js +0 -120
  68. package/src/cli/config.js +0 -84
  69. package/src/generateResponseType.js +0 -583
  70. package/src/index.js +0 -159
  71. package/src/parser/__test__/parse.test.js +0 -249
  72. package/src/parser/parse.js +0 -414
  73. package/src/parser/resolve.js +0 -117
  74. package/src/schemaFromIntrospectionData.js +0 -68
  75. package/src/types.js +0 -87
  76. package/src/utils.js +0 -50
@@ -1,414 +0,0 @@
1
- // @flow
2
- import type {
3
- BabelNodeImportDeclaration,
4
- BabelNodeVariableDeclarator,
5
- BabelNodeTaggedTemplateExpression,
6
- BabelNodeFile,
7
- } from '@babel/types';
8
-
9
- import {parse} from '@babel/parser'; // eslint-disable-line flowtype-errors/uncovered
10
- import traverse from '@babel/traverse'; // eslint-disable-line flowtype-errors/uncovered
11
-
12
- import path from 'path';
13
-
14
- /**
15
- * This file is responsible for finding all gql`-annotated
16
- * template strings in a set of provided files, and for resolving
17
- * all fragment references to their eventual sources.
18
- *
19
- * Things that are supported:
20
- * - importing fragments from other files
21
- * - re-exporting fragments that were imported
22
- * - using locally-defined fragments, even if they're
23
- * not at the top level (scope is honored correctly)
24
- * - importing the gql tag as some other name
25
- * (e.g. 'import blah from "graphql-tag"')
26
- * - renaming fragments at the top level
27
- *
28
- * Things that are *not* supported:
29
- * - doing anything other than 'const x = gql`my template`'
30
- * e.g. const x = someCond ? one fragment literal : another fragment literal
31
- * or const x = someFragmentPreprocessor(fragment literal)
32
- * - importing the graphql tag fn from anywhere other than "graphql-tag"
33
- * - anything else fancy with the graphql tag fn, e.g. 'const blah = gql; blah`xyz`'
34
- * - including a fragment in an operation by anything other than a bare identifier,
35
- * e.g. 'const myQuery = gql`query xyz {...} ${cond ? someFrag : otherFrag}`.
36
- * - getting fragments from e.g. function arguments, or renaming non-toplevel fragments
37
- *
38
- * Things that could be supported, but are not yet:
39
- * - tracking whether a given graphql operation has already been wrapped
40
- * in `gqlOp<Type>()` or not (to inform an auto-wrapper of the future)
41
- */
42
-
43
- export type Template = {|
44
- literals: Array<string>,
45
- expressions: Array<Document | Import>,
46
- loc: Loc,
47
- |};
48
- export type Loc = {start: number, end: number, path: string, line: number};
49
-
50
- export type Document = {|
51
- type: 'document',
52
- source: Template,
53
- |};
54
- export type Import = {|
55
- type: 'import',
56
- name: string,
57
- path: string,
58
- loc: Loc,
59
- |};
60
-
61
- export type Operation = {|
62
- source: Template,
63
- // TODO: Determine if an operation is already wrapped
64
- // in `gqlOp` so we can automatically wrap if needed.
65
- // needsWrapping: boolean,
66
- |};
67
-
68
- export type FileResult = {|
69
- path: string,
70
- operations: Array<Operation>,
71
- exports: {[key: string]: Document | Import},
72
- locals: {[key: string]: Document | Import},
73
- errors: Array<{loc: Loc, message: string}>,
74
- |};
75
-
76
- export type Files = {[path: string]: FileResult};
77
-
78
- /**
79
- * Finds all referenced imports that might possibly be relevant
80
- * graphql fragments.
81
- *
82
- * Importantly, any values that are re-exported are treated as
83
- * potentially relevant, and of course any values referenced
84
- * from a graphql template are treated as relevant.
85
- */
86
- const listExternalReferences = (file: FileResult): Array<string> => {
87
- const paths = {};
88
- const add = (v: Document | Import, followImports: boolean) => {
89
- if (v.type === 'import') {
90
- if (followImports) {
91
- paths[v.path] = true;
92
- }
93
- } else {
94
- v.source.expressions.forEach((expr) => add(expr, true));
95
- }
96
- };
97
- Object.keys(file.exports).forEach((k) =>
98
- add(
99
- file.exports[k],
100
- // If we're re-exporting something, we need to follow that import.
101
- true,
102
- ),
103
- );
104
- Object.keys(file.locals).forEach((k) =>
105
- add(
106
- file.locals[k],
107
- // If we've imported something but haven't used it or exported it,
108
- // we don't need to follow the import.
109
- false,
110
- ),
111
- );
112
- file.operations.forEach((op) =>
113
- op.source.expressions.forEach((expr) =>
114
- add(
115
- expr,
116
- // Imports that are used in graphql expressions definitely need to be followed.
117
- true,
118
- ),
119
- ),
120
- );
121
- return Object.keys(paths);
122
- };
123
-
124
- export const processFile = (
125
- filePath: string,
126
- contents: string | {text: string, resolvedPath: string},
127
- ): FileResult => {
128
- const dir = path.dirname(filePath);
129
- const result: FileResult = {
130
- path: filePath,
131
- operations: [],
132
- exports: {},
133
- locals: {},
134
- errors: [],
135
- };
136
- const resolved =
137
- typeof contents === 'string' ? filePath : contents.resolvedPath;
138
- const text = typeof contents === 'string' ? contents : contents.text;
139
- const plugins = resolved.match(/\.tsx?$/)
140
- ? ['typescript', filePath.endsWith('x') ? 'jsx' : null].filter(Boolean)
141
- : [['flow', {enums: true}], 'jsx'];
142
- /* eslint-disable flowtype-errors/uncovered */
143
- const ast: BabelNodeFile = parse(text, {
144
- sourceType: 'module',
145
- allowImportExportEverywhere: true,
146
- plugins: plugins,
147
- });
148
- /* eslint-enable flowtype-errors/uncovered */
149
- const gqlTagNames = [];
150
- const seenTemplates: {[key: number]: Document | false} = {};
151
-
152
- ast.program.body.forEach((toplevel) => {
153
- if (toplevel.type === 'ImportDeclaration') {
154
- const newLocals = getLocals(dir, toplevel, filePath);
155
- if (newLocals) {
156
- Object.keys(newLocals).forEach((k) => {
157
- const local = newLocals[k];
158
- if (local.path.startsWith('/')) {
159
- result.locals[k] = local;
160
- }
161
- if (
162
- local.path === 'graphql-tag' &&
163
- local.name === 'default'
164
- ) {
165
- gqlTagNames.push(k);
166
- }
167
- });
168
- }
169
- }
170
- if (toplevel.type === 'ExportNamedDeclaration') {
171
- if (toplevel.source) {
172
- const source = toplevel.source;
173
- const importPath = source.value.startsWith('.')
174
- ? path.resolve(path.join(dir, source.value))
175
- : source.value;
176
- toplevel.specifiers?.forEach((spec) => {
177
- if (
178
- spec.type === 'ExportSpecifier' &&
179
- spec.exported.type === 'Identifier'
180
- ) {
181
- result.exports[spec.exported.name] = {
182
- type: 'import',
183
- name: spec.local.name,
184
- path: importPath,
185
- loc: {
186
- start: spec.start ?? -1,
187
- end: spec.end ?? -1,
188
- line: spec.loc?.start.line ?? -1,
189
- path: filePath,
190
- },
191
- };
192
- }
193
- });
194
- } else {
195
- toplevel.specifiers?.forEach((spec) => {
196
- if (spec.type === 'ExportSpecifier') {
197
- const local = result.locals[spec.local.name];
198
- if (local && spec.exported.type === 'Identifier') {
199
- result.exports[spec.exported.name] = local;
200
- }
201
- }
202
- });
203
- }
204
- }
205
-
206
- const processDeclarator = (
207
- decl: BabelNodeVariableDeclarator,
208
- isExported: boolean,
209
- ) => {
210
- if (decl.id.type !== 'Identifier' || !decl.init) {
211
- return;
212
- }
213
- const {init} = decl;
214
- const id = decl.id.name;
215
- if (
216
- init.type === 'TaggedTemplateExpression' &&
217
- init.tag.type === 'Identifier'
218
- ) {
219
- if (gqlTagNames.includes(init.tag.name)) {
220
- const tpl = processTemplate(init, result);
221
- if (tpl) {
222
- const document = (result.locals[id] = {
223
- type: 'document',
224
- source: tpl,
225
- });
226
- seenTemplates[init.start ?? -1] = document;
227
- if (isExported) {
228
- result.exports[id] = document;
229
- }
230
- } else {
231
- seenTemplates[init.start ?? -1] = false;
232
- }
233
- }
234
- }
235
- if (init.type === 'Identifier' && result.locals[init.name]) {
236
- result.locals[id] = result.locals[init.name];
237
- if (isExported) {
238
- result.exports[id] = result.locals[init.name];
239
- }
240
- }
241
- };
242
-
243
- if (toplevel.type === 'VariableDeclaration') {
244
- toplevel.declarations.forEach((decl) => {
245
- processDeclarator(decl, false);
246
- });
247
- }
248
-
249
- if (
250
- toplevel.type === 'ExportNamedDeclaration' &&
251
- toplevel.declaration?.type === 'VariableDeclaration'
252
- ) {
253
- toplevel.declaration.declarations.forEach((decl) => {
254
- processDeclarator(decl, true);
255
- });
256
- }
257
- });
258
-
259
- const visitTpl = (
260
- node: BabelNodeTaggedTemplateExpression,
261
- getBinding: (name: string) => Document | null,
262
- ) => {
263
- if (seenTemplates[node.start ?? -1] != null) {
264
- return;
265
- }
266
- if (
267
- node.tag.type !== 'Identifier' ||
268
- !gqlTagNames.includes(node.tag.name)
269
- ) {
270
- return;
271
- }
272
- const tpl = processTemplate(node, result, getBinding);
273
- if (tpl) {
274
- seenTemplates[node.start ?? -1] = {type: 'document', source: tpl};
275
- result.operations.push({
276
- source: tpl,
277
- });
278
- } else {
279
- seenTemplates[node.start ?? -1] = false;
280
- }
281
- };
282
-
283
- /* eslint-disable flowtype-errors/uncovered */
284
- traverse(ast, {
285
- TaggedTemplateExpression(path) {
286
- visitTpl(path.node, (name) => {
287
- const binding = path.scope.getBinding(name);
288
- const start = binding.path.node.init
289
- ? binding.path.node.init.start
290
- : null;
291
- if (start && seenTemplates[start]) {
292
- return seenTemplates[start];
293
- }
294
- return null;
295
- });
296
- },
297
- });
298
- /* eslint-enable flowtype-errors/uncovered */
299
-
300
- return result;
301
- };
302
-
303
- const processTemplate = (
304
- tpl: BabelNodeTaggedTemplateExpression,
305
- result: FileResult,
306
- getTemplate?: (name: string) => Document | null,
307
- // getBinding?: (name: string) => Binding,
308
- // seenTemplates,
309
- ): ?Template => {
310
- // 'cooked' is the string as runtime javascript will see it.
311
- const literals = tpl.quasi.quasis.map((q) => q.value.cooked || '');
312
- const expressions = tpl.quasi.expressions.map(
313
- (expr): null | Document | Import => {
314
- const loc: Loc = {
315
- start: expr.start ?? -1,
316
- end: expr.end ?? -1,
317
- line: expr.loc?.start.line ?? -1,
318
- path: result.path,
319
- };
320
- if (expr.type !== 'Identifier') {
321
- result.errors.push({
322
- loc,
323
- message: `Template literal interpolation must be an identifier`,
324
- });
325
- return null;
326
- }
327
- if (!result.locals[expr.name]) {
328
- if (getTemplate) {
329
- const found = getTemplate(expr.name);
330
- return found;
331
- }
332
- result.errors.push({
333
- loc,
334
- message: `Unable to resolve ${expr.name}`,
335
- });
336
- return null;
337
- }
338
- return result.locals[expr.name];
339
- },
340
- );
341
- if (expressions.includes(null)) {
342
- // bail, stop processing.
343
- return;
344
- }
345
- return {
346
- literals,
347
- expressions: expressions.filter(Boolean),
348
- loc: {
349
- line: tpl.loc?.start.line ?? -1,
350
- start: tpl.start ?? -1,
351
- end: tpl.end ?? -1,
352
- path: result.path,
353
- },
354
- };
355
- };
356
-
357
- const getLocals = (
358
- dir,
359
- toplevel: BabelNodeImportDeclaration,
360
- myPath: string,
361
- ): ?{[key: string]: Import} => {
362
- if (toplevel.importKind === 'type') {
363
- return null;
364
- }
365
- const importPath = toplevel.source.value.startsWith('.')
366
- ? path.resolve(path.join(dir, toplevel.source.value))
367
- : toplevel.source.value;
368
- const locals = {};
369
- toplevel.specifiers.forEach((spec) => {
370
- if (spec.type === 'ImportDefaultSpecifier') {
371
- locals[spec.local.name] = {
372
- type: 'import',
373
- name: 'default',
374
- path: importPath,
375
- loc: {start: spec.start, end: spec.end, path: myPath},
376
- };
377
- } else if (spec.type === 'ImportSpecifier') {
378
- locals[spec.local.name] = {
379
- type: 'import',
380
- name:
381
- spec.imported.type === 'Identifier'
382
- ? spec.imported.name
383
- : spec.imported.value,
384
- path: importPath,
385
- loc: {start: spec.start, end: spec.end, path: myPath},
386
- };
387
- }
388
- });
389
- return locals;
390
- };
391
-
392
- export const processFiles = (
393
- filePaths: Array<string>,
394
- getFileSource: (
395
- path: string,
396
- ) => string | {text: string, resolvedPath: string},
397
- ): Files => {
398
- const files: Files = {};
399
- const toProcess = filePaths.slice();
400
- while (toProcess.length) {
401
- const next = toProcess.shift();
402
- if (files[next]) {
403
- continue;
404
- }
405
- const result = processFile(next, getFileSource(next));
406
- files[next] = result;
407
- listExternalReferences(result).forEach((path) => {
408
- if (!files[path] && !toProcess.includes(path)) {
409
- toProcess.push(path);
410
- }
411
- });
412
- }
413
- return files;
414
- };
@@ -1,117 +0,0 @@
1
- // @flow
2
- import gql from 'graphql-tag';
3
- import type {DocumentNode} from 'graphql/language/ast';
4
- import type {FileResult, Files, Import, Template, Document} from './parse';
5
-
6
- export type Resolved = {
7
- [key: string]: {
8
- document: DocumentNode,
9
- raw: Template,
10
- },
11
- };
12
-
13
- export const resolveDocuments = (
14
- files: Files,
15
- ): {resolved: Resolved, errors: FileResult['errors']} => {
16
- const resolved: Resolved = {};
17
- const errors: FileResult['errors'] = [];
18
- Object.keys(files).forEach((path) => {
19
- const file = files[path];
20
- file.operations.forEach((op) => {
21
- resolveGqlTemplate(op.source, files, errors, resolved, {});
22
- });
23
- Object.keys(file.locals).forEach((k) => {
24
- const local = file.locals[k];
25
- if (local.type === 'document') {
26
- resolveGqlTemplate(local.source, files, errors, resolved, {});
27
- }
28
- });
29
- });
30
- return {resolved, errors};
31
- };
32
-
33
- const resolveImport = (
34
- expr: Import,
35
- files: Files,
36
- errors: FileResult['errors'],
37
- seen: {[key: string]: true},
38
- ): ?Document => {
39
- if (seen[expr.path]) {
40
- errors.push({
41
- loc: expr.loc,
42
- message: `Circular import ${Object.keys(seen).join(' -> ')} -> ${
43
- expr.path
44
- }`,
45
- });
46
- return null;
47
- }
48
- seen[expr.path] = true;
49
- const res = files[expr.path];
50
- if (!res) {
51
- errors.push({loc: expr.loc, message: `No file ${expr.path}`});
52
- return null;
53
- }
54
- if (!res.exports[expr.name]) {
55
- errors.push({
56
- loc: expr.loc,
57
- message: `${expr.path} has no valid gql export ${expr.name}`,
58
- });
59
- return null;
60
- }
61
- const value = res.exports[expr.name];
62
- if (value.type === 'import') {
63
- return resolveImport(value, files, errors, seen);
64
- }
65
- return value;
66
- };
67
-
68
- const resolveGqlTemplate = (
69
- template: Template,
70
- files: Files,
71
- errors: FileResult['errors'],
72
- resolved: Resolved,
73
- seen: {[key: string]: Template},
74
- ): ?DocumentNode => {
75
- const key = template.loc.path + ':' + template.loc.line;
76
- if (seen[key]) {
77
- errors.push({
78
- loc: template.loc,
79
- message: `Recursive template dependency! ${Object.keys(seen)
80
- .map(
81
- (k) =>
82
- k +
83
- ' ~ ' +
84
- seen[k].expressions.length +
85
- ',' +
86
- seen[k].literals.length,
87
- )
88
- .join(' -> ')} -> ${key}`,
89
- });
90
- return null;
91
- }
92
- seen[key] = template;
93
- if (resolved[key]) {
94
- return resolved[key].document;
95
- }
96
- const expressions = template.expressions.map((expr) => {
97
- if (expr.type === 'import') {
98
- const document = resolveImport(expr, files, errors, {});
99
- return document
100
- ? resolveGqlTemplate(document.source, files, errors, resolved, {
101
- ...seen,
102
- })
103
- : null;
104
- }
105
- return resolveGqlTemplate(expr.source, files, errors, resolved, {
106
- ...seen,
107
- });
108
- });
109
- if (expressions.includes(null)) {
110
- return null;
111
- }
112
- resolved[key] = {
113
- document: gql(template.literals, ...expressions),
114
- raw: template,
115
- };
116
- return resolved[key].document;
117
- };
@@ -1,68 +0,0 @@
1
- // @flow
2
- /**
3
- * Takes the introspectionQuery response and parses it into the "Schema"
4
- * type that we use to look up types, interfaces, etc.
5
- */
6
- import type {IntrospectionQuery} from 'graphql';
7
- import type {Schema} from './types';
8
-
9
- export const schemaFromIntrospectionData = (
10
- schema: IntrospectionQuery,
11
- ): Schema => {
12
- const result: Schema = {
13
- interfacesByName: {},
14
- typesByName: {},
15
- inputObjectsByName: {},
16
- unionsByName: {},
17
- enumsByName: {},
18
- };
19
-
20
- schema.__schema.types.forEach((type) => {
21
- if (type.kind === 'ENUM') {
22
- result.enumsByName[type.name] = type;
23
- return;
24
- }
25
- if (type.kind === 'UNION') {
26
- result.unionsByName[type.name] = type;
27
- return;
28
- }
29
- if (type.kind === 'INTERFACE') {
30
- result.interfacesByName[type.name] = {
31
- ...type,
32
- possibleTypesByName: {},
33
- fieldsByName: {},
34
- };
35
- type.possibleTypes.forEach(
36
- (p) =>
37
- (result.interfacesByName[type.name].possibleTypesByName[
38
- p.name
39
- ] = true),
40
- );
41
- type.fields.forEach((field) => {
42
- result.interfacesByName[type.name].fieldsByName[field.name] =
43
- field;
44
- });
45
- return;
46
- }
47
- if (type.kind === 'INPUT_OBJECT') {
48
- result.inputObjectsByName[type.name] = type;
49
- return;
50
- }
51
- if (type.kind === 'SCALAR') {
52
- return;
53
- }
54
- result.typesByName[type.name] = {
55
- ...type,
56
- fieldsByName: {},
57
- };
58
- if (!type.fields) {
59
- return;
60
- }
61
-
62
- type.fields.forEach((field) => {
63
- result.typesByName[type.name].fieldsByName[field.name] = field;
64
- });
65
- });
66
-
67
- return result;
68
- };
package/src/types.js DELETED
@@ -1,87 +0,0 @@
1
- // @flow
2
-
3
- import type {BabelNode} from '@babel/types';
4
- import type {
5
- FragmentDefinitionNode,
6
- IntrospectionEnumType,
7
- IntrospectionField,
8
- IntrospectionInputObjectType,
9
- IntrospectionInterfaceType,
10
- IntrospectionObjectType,
11
- IntrospectionUnionType,
12
- SelectionNode,
13
- } from 'graphql';
14
-
15
- export type Selections = $ReadOnlyArray<SelectionNode>;
16
-
17
- export type GenerateConfig = {|
18
- schemaFilePath: string,
19
- match?: Array<RegExp | string>,
20
- exclude?: Array<RegExp | string>,
21
-
22
- typeScript?: boolean,
23
- scalars?: Scalars,
24
- strictNullability?: boolean,
25
- /**
26
- * The command that users should run to regenerate the types files.
27
- */
28
- regenerateCommand?: string,
29
- readOnlyArray?: boolean,
30
- splitTypes?: boolean,
31
- generatedDirectory?: string,
32
- exportAllObjectTypes?: boolean,
33
- typeFileName?: string,
34
- experimentalEnums?: boolean,
35
- |};
36
-
37
- export type CrawlConfig = {
38
- root: string,
39
- pragma?: string,
40
- loosePragma?: string,
41
- ignorePragma?: string,
42
- dumpOperations?: string,
43
- };
44
-
45
- export type Config = {
46
- crawl: CrawlConfig,
47
- generate: GenerateConfig | Array<GenerateConfig>,
48
- };
49
-
50
- export type Schema = {
51
- interfacesByName: {
52
- [key: string]: IntrospectionInterfaceType & {
53
- fieldsByName: {[key: string]: IntrospectionField},
54
- possibleTypesByName: {[key: string]: boolean},
55
- },
56
- },
57
- inputObjectsByName: {
58
- [key: string]: IntrospectionInputObjectType,
59
- },
60
- typesByName: {
61
- [key: string]: IntrospectionObjectType & {
62
- fieldsByName: {[key: string]: IntrospectionField},
63
- },
64
- },
65
- unionsByName: {
66
- [key: string]: IntrospectionUnionType,
67
- },
68
- enumsByName: {
69
- [key: string]: IntrospectionEnumType,
70
- },
71
- };
72
-
73
- export type Context = {
74
- path: Array<string>,
75
- strictNullability: boolean,
76
- readOnlyArray: boolean,
77
- fragments: {[key: string]: FragmentDefinitionNode},
78
-
79
- schema: Schema,
80
- scalars: Scalars,
81
- errors: Array<string>,
82
- allObjectTypes: null | {[key: string]: BabelNode},
83
- typeScript: boolean,
84
-
85
- experimentalEnumsMap?: {[key: string]: BabelNode}, // index signature that is populated with declarations
86
- };
87
- export type Scalars = {[key: string]: 'string' | 'number' | 'boolean'};