@khanacademy/graphql-flow 1.2.0 → 3.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 (78) 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 +8 -7
  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 +9 -23
  10. package/dist/generateVariablesType.js +15 -31
  11. package/dist/index.js +8 -15
  12. package/dist/parser/parse.js +6 -7
  13. package/dist/parser/resolve.js +1 -2
  14. package/dist/parser/utils.js +1 -2
  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 +9 -8
  19. package/{dist/__test__/generateTypeFileContents.test.js → src/__test__/generateTypeFileContents.test.ts} +38 -41
  20. package/{dist/__test__/graphql-flow.test.js → src/__test__/graphql-flow.test.ts} +232 -235
  21. package/src/__test__/{processPragmas.test.js → processPragmas.test.ts} +0 -1
  22. package/{dist/cli/__test__/config.test.js → src/cli/__test__/config.test.ts} +5 -6
  23. package/src/cli/{config.js → config.ts} +10 -15
  24. package/src/cli/{run.js → run.ts} +5 -4
  25. package/src/{enums.js → enums.ts} +20 -22
  26. package/src/{generateResponseType.js → generateResponseType.ts} +167 -182
  27. package/src/{generateTypeFiles.js → generateTypeFiles.ts} +20 -30
  28. package/src/{generateVariablesType.js → generateVariablesType.ts} +34 -44
  29. package/{dist/index.js.flow → src/index.ts} +32 -24
  30. package/{dist/parser/__test__/parse.test.js → src/parser/__test__/parse.test.ts} +12 -11
  31. package/src/parser/{parse.js → parse.ts} +65 -47
  32. package/{dist/parser/resolve.js.flow → src/parser/resolve.ts} +15 -11
  33. package/{dist/parser/utils.js.flow → src/parser/utils.ts} +0 -1
  34. package/{dist/schemaFromIntrospectionData.js.flow → src/schemaFromIntrospectionData.ts} +1 -4
  35. package/src/types.ts +97 -0
  36. package/src/utils.ts +73 -0
  37. package/tools/{find-files-with-gql.js → find-files-with-gql.ts} +2 -3
  38. package/tsconfig.json +110 -0
  39. package/types/flow-to-ts.d.ts +1 -0
  40. package/dist/__test__/example-schema.graphql +0 -67
  41. package/dist/__test__/processPragmas.test.js +0 -76
  42. package/dist/cli/config.js.flow +0 -84
  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/enums.js.flow +0 -98
  47. package/dist/enums.js.map +0 -1
  48. package/dist/generateResponseType.js.flow +0 -583
  49. package/dist/generateResponseType.js.map +0 -1
  50. package/dist/generateTypeFiles.js.flow +0 -191
  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.flow +0 -417
  56. package/dist/parser/parse.js.map +0 -1
  57. package/dist/parser/resolve.js.map +0 -1
  58. package/dist/parser/utils.js.map +0 -1
  59. package/dist/schemaFromIntrospectionData.js.map +0 -1
  60. package/dist/types.js.flow +0 -88
  61. package/dist/types.js.map +0 -1
  62. package/dist/utils.js.flow +0 -50
  63. package/dist/utils.js.map +0 -1
  64. package/flow-typed/npm/@babel/types_vx.x.x.js +0 -5331
  65. package/flow-typed/npm/jest_v23.x.x.js +0 -1155
  66. package/flow-typed/overrides.js +0 -435
  67. package/src/__test__/generateTypeFileContents.test.js +0 -157
  68. package/src/__test__/graphql-flow.test.js +0 -639
  69. package/src/cli/__test__/config.test.js +0 -120
  70. package/src/cli/schema.json +0 -97
  71. package/src/index.js +0 -160
  72. package/src/parser/__test__/parse.test.js +0 -249
  73. package/src/parser/resolve.js +0 -119
  74. package/src/parser/utils.js +0 -25
  75. package/src/schemaFromIntrospectionData.js +0 -68
  76. package/src/types.js +0 -88
  77. package/src/utils.js +0 -50
  78. /package/{dist/cli/schema.json → schema.json} +0 -0
@@ -1,119 +0,0 @@
1
- // @flow
2
- import gql from 'graphql-tag';
3
- import {getPathWithExtension} from './utils';
4
- import type {DocumentNode} from 'graphql/language/ast';
5
- import type {FileResult, Files, Import, Template, Document} from './parse';
6
-
7
- export type Resolved = {
8
- [key: string]: {
9
- document: DocumentNode,
10
- raw: Template,
11
- },
12
- };
13
-
14
- export const resolveDocuments = (
15
- files: Files,
16
- ): {resolved: Resolved, errors: FileResult['errors']} => {
17
- const resolved: Resolved = {};
18
- const errors: FileResult['errors'] = [];
19
- Object.keys(files).forEach((path) => {
20
- const file = files[path];
21
- file.operations.forEach((op) => {
22
- resolveGqlTemplate(op.source, files, errors, resolved, {});
23
- });
24
- Object.keys(file.locals).forEach((k) => {
25
- const local = file.locals[k];
26
- if (local.type === 'document') {
27
- resolveGqlTemplate(local.source, files, errors, resolved, {});
28
- }
29
- });
30
- });
31
- return {resolved, errors};
32
- };
33
-
34
- const resolveImport = (
35
- expr: Import,
36
- files: Files,
37
- errors: FileResult['errors'],
38
- seen: {[key: string]: true},
39
- ): ?Document => {
40
- const absPath: string = getPathWithExtension(expr.path);
41
- if (seen[absPath]) {
42
- errors.push({
43
- loc: expr.loc,
44
- message: `Circular import ${Object.keys(seen).join(
45
- ' -> ',
46
- )} -> ${absPath}`,
47
- });
48
- return null;
49
- }
50
- seen[absPath] = true;
51
- const res = files[absPath];
52
- if (!res) {
53
- errors.push({loc: expr.loc, message: `No file ${absPath}`});
54
- return null;
55
- }
56
- if (!res.exports[expr.name]) {
57
- errors.push({
58
- loc: expr.loc,
59
- message: `${absPath} has no valid gql export ${expr.name}`,
60
- });
61
- return null;
62
- }
63
- const value = res.exports[expr.name];
64
- if (value.type === 'import') {
65
- return resolveImport(value, files, errors, seen);
66
- }
67
- return value;
68
- };
69
-
70
- const resolveGqlTemplate = (
71
- template: Template,
72
- files: Files,
73
- errors: FileResult['errors'],
74
- resolved: Resolved,
75
- seen: {[key: string]: Template},
76
- ): ?DocumentNode => {
77
- const key = template.loc.path + ':' + template.loc.line;
78
- if (seen[key]) {
79
- errors.push({
80
- loc: template.loc,
81
- message: `Recursive template dependency! ${Object.keys(seen)
82
- .map(
83
- (k) =>
84
- k +
85
- ' ~ ' +
86
- seen[k].expressions.length +
87
- ',' +
88
- seen[k].literals.length,
89
- )
90
- .join(' -> ')} -> ${key}`,
91
- });
92
- return null;
93
- }
94
- seen[key] = template;
95
- if (resolved[key]) {
96
- return resolved[key].document;
97
- }
98
- const expressions = template.expressions.map((expr) => {
99
- if (expr.type === 'import') {
100
- const document = resolveImport(expr, files, errors, {});
101
- return document
102
- ? resolveGqlTemplate(document.source, files, errors, resolved, {
103
- ...seen,
104
- })
105
- : null;
106
- }
107
- return resolveGqlTemplate(expr.source, files, errors, resolved, {
108
- ...seen,
109
- });
110
- });
111
- if (expressions.includes(null)) {
112
- return null;
113
- }
114
- resolved[key] = {
115
- document: gql(template.literals, ...expressions),
116
- raw: template,
117
- };
118
- return resolved[key].document;
119
- };
@@ -1,25 +0,0 @@
1
- // @flow
2
- import fs from 'fs';
3
-
4
- export const getPathWithExtension = (pathWithoutExtension: string): string => {
5
- if (
6
- /\.(less|css|png|gif|jpg|jpeg|js|jsx|ts|tsx|mjs)$/.test(
7
- pathWithoutExtension,
8
- )
9
- ) {
10
- return pathWithoutExtension;
11
- }
12
- if (fs.existsSync(pathWithoutExtension + '.js')) {
13
- return pathWithoutExtension + '.js';
14
- }
15
- if (fs.existsSync(pathWithoutExtension + '.jsx')) {
16
- return pathWithoutExtension + '.jsx';
17
- }
18
- if (fs.existsSync(pathWithoutExtension + '.tsx')) {
19
- return pathWithoutExtension + '.tsx';
20
- }
21
- if (fs.existsSync(pathWithoutExtension + '.ts')) {
22
- return pathWithoutExtension + '.ts';
23
- }
24
- throw new Error("Can't find file at " + pathWithoutExtension);
25
- };
@@ -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,88 +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
- omitFileExtensions?: boolean,
36
- |};
37
-
38
- export type CrawlConfig = {
39
- root: string,
40
- pragma?: string,
41
- loosePragma?: string,
42
- ignorePragma?: string,
43
- dumpOperations?: string,
44
- };
45
-
46
- export type Config = {
47
- crawl: CrawlConfig,
48
- generate: GenerateConfig | Array<GenerateConfig>,
49
- };
50
-
51
- export type Schema = {
52
- interfacesByName: {
53
- [key: string]: IntrospectionInterfaceType & {
54
- fieldsByName: {[key: string]: IntrospectionField},
55
- possibleTypesByName: {[key: string]: boolean},
56
- },
57
- },
58
- inputObjectsByName: {
59
- [key: string]: IntrospectionInputObjectType,
60
- },
61
- typesByName: {
62
- [key: string]: IntrospectionObjectType & {
63
- fieldsByName: {[key: string]: IntrospectionField},
64
- },
65
- },
66
- unionsByName: {
67
- [key: string]: IntrospectionUnionType,
68
- },
69
- enumsByName: {
70
- [key: string]: IntrospectionEnumType,
71
- },
72
- };
73
-
74
- export type Context = {
75
- path: Array<string>,
76
- strictNullability: boolean,
77
- readOnlyArray: boolean,
78
- fragments: {[key: string]: FragmentDefinitionNode},
79
-
80
- schema: Schema,
81
- scalars: Scalars,
82
- errors: Array<string>,
83
- allObjectTypes: null | {[key: string]: BabelNode},
84
- typeScript: boolean,
85
-
86
- experimentalEnumsMap?: {[key: string]: BabelNode}, // index signature that is populated with declarations
87
- };
88
- export type Scalars = {[key: string]: 'string' | 'number' | 'boolean'};
package/src/utils.js DELETED
@@ -1,50 +0,0 @@
1
- // @flow
2
-
3
- import * as babelTypes from '@babel/types';
4
- import {BabelNodeObjectTypeProperty} from '@babel/types';
5
-
6
- export const liftLeadingPropertyComments = (
7
- property: BabelNodeObjectTypeProperty,
8
- ): BabelNodeObjectTypeProperty => {
9
- return transferLeadingComments(property.value, property);
10
- };
11
-
12
- export const maybeAddDescriptionComment = <T: babelTypes.BabelNode>(
13
- description: ?string,
14
- node: T,
15
- ): T => {
16
- if (description) {
17
- addCommentAsLineComments(description, node);
18
- }
19
- return node;
20
- };
21
-
22
- export function addCommentAsLineComments(
23
- description: string,
24
- res: babelTypes.BabelNode,
25
- ) {
26
- if (res.leadingComments?.length) {
27
- res.leadingComments[0].value += '\n\n---\n\n' + description;
28
- } else {
29
- babelTypes.addComment(
30
- res,
31
- 'leading',
32
- '* ' + description,
33
- false, // this specifies that it's a block comment, not a line comment
34
- );
35
- }
36
- }
37
-
38
- export const transferLeadingComments = <T: babelTypes.BabelNode>(
39
- source: babelTypes.BabelNode,
40
- dest: T,
41
- ): T => {
42
- if (source.leadingComments?.length) {
43
- dest.leadingComments = [
44
- ...(dest.leadingComments || []),
45
- ...source.leadingComments,
46
- ];
47
- source.leadingComments = [];
48
- }
49
- return dest;
50
- };
File without changes