@khanacademy/graphql-flow 3.0.1 → 3.1.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 (39) hide show
  1. package/.eslintrc.js +15 -4
  2. package/.github/workflows/changeset-release.yml +3 -5
  3. package/.github/workflows/pr-checks.yml +17 -17
  4. package/.prettierrc +2 -2
  5. package/.vscode/settings.json +6 -0
  6. package/CHANGELOG.md +6 -0
  7. package/dist/cli/config.js +6 -15
  8. package/dist/cli/run.js +27 -36
  9. package/dist/enums.js +9 -9
  10. package/dist/generateResponseType.js +36 -40
  11. package/dist/generateTypeFiles.js +10 -10
  12. package/dist/generateVariablesType.js +12 -13
  13. package/dist/index.js +4 -6
  14. package/dist/parser/parse.js +43 -52
  15. package/dist/parser/resolve.js +16 -16
  16. package/dist/parser/utils.js +19 -9
  17. package/dist/schemaFromIntrospectionData.js +5 -5
  18. package/dist/utils.js +8 -8
  19. package/package.json +12 -13
  20. package/src/__test__/generateTypeFileContents.test.ts +26 -25
  21. package/src/__test__/graphql-flow.test.ts +32 -33
  22. package/src/__test__/processPragmas.test.ts +14 -13
  23. package/src/cli/__test__/config.test.ts +51 -56
  24. package/src/cli/config.ts +23 -20
  25. package/src/cli/run.ts +41 -45
  26. package/src/enums.ts +17 -17
  27. package/src/generateResponseType.ts +120 -91
  28. package/src/generateTypeFiles.ts +24 -22
  29. package/src/generateVariablesType.ts +20 -20
  30. package/src/index.ts +28 -29
  31. package/src/parser/__test__/parse.test.ts +114 -23
  32. package/src/parser/__test__/utils.test.ts +80 -0
  33. package/src/parser/parse.ts +119 -105
  34. package/src/parser/resolve.ts +61 -34
  35. package/src/parser/utils.ts +23 -10
  36. package/src/schemaFromIntrospectionData.ts +10 -8
  37. package/src/types.ts +57 -53
  38. package/src/utils.ts +30 -16
  39. package/tools/find-files-with-gql.ts +7 -11
package/.eslintrc.js CHANGED
@@ -1,9 +1,20 @@
1
1
  module.exports = {
2
- extends: ['@khanacademy'],
3
2
  root: true,
4
- parser: '@babel/eslint-parser',
5
- plugins: ['flowtype-errors'],
3
+ plugins: ["prettier", "jest"],
4
+ extends: ["eslint:recommended", "prettier"],
5
+ parser: "@typescript-eslint/parser",
6
+ parserOptions: {
7
+ sourceType: "module",
8
+ ecmaVersion: 2020,
9
+ },
6
10
  rules: {
7
- 'prettier/prettier': ['error', {singleQuote: true}],
11
+ "prettier/prettier": "error",
12
+ "no-unused-vars": "off",
13
+ "no-case-declarations": "off",
14
+ },
15
+ env: {
16
+ es6: true,
17
+ node: true,
18
+ jest: true,
8
19
  },
9
20
  };
@@ -31,12 +31,10 @@ jobs:
31
31
  name: Release
32
32
  runs-on: ubuntu-latest
33
33
  steps:
34
- - uses: actions/checkout@v2
34
+ - uses: actions/checkout@v4
35
+ - uses: Khan/actions@shared-node-cache-v2
35
36
  with:
36
- fetch-depth: 0
37
- - uses: Khan/actions@shared-node-cache-v0.0.2
38
- with:
39
- node-version: 16.x
37
+ node-version: 20.x
40
38
 
41
39
  - name: Create Release Pull Request or Publish to npm
42
40
  id: changesets
@@ -14,45 +14,45 @@ jobs:
14
14
  strategy:
15
15
  matrix:
16
16
  os: [ubuntu-latest]
17
- node-version: [16.x]
17
+ node-version: [20.x]
18
18
  steps:
19
- - uses: actions/checkout@v2
20
- - uses: Khan/actions@shared-node-cache-v0
19
+ - uses: actions/checkout@v4
20
+ - uses: Khan/actions@shared-node-cache-v2
21
21
  with:
22
22
  node-version: ${{ matrix.node-version }}
23
23
 
24
24
  - name: Get All Changed Files
25
- uses: Khan/actions@get-changed-files-v1
25
+ uses: Khan/actions@get-changed-files-v2
26
26
  id: changed
27
27
 
28
- - id: js-files
29
- name: Find .js changed files
30
- uses: Khan/actions@filter-files-v0
28
+ - id: ts-files
29
+ name: Find .ts changed files
30
+ uses: Khan/actions@filter-files-v1
31
31
  with:
32
32
  changed-files: ${{ steps.changed.outputs.files }}
33
- extensions: '.js'
33
+ extensions: '.ts'
34
34
 
35
- - name: Run Flow
36
- if: steps.js-files.outputs.filtered != '[]'
37
- run: yarn flow
35
+ - name: Run TypeScript
36
+ if: steps.ts-files.outputs.filtered != '[]'
37
+ run: yarn tsc
38
38
 
39
39
  - id: eslint-reset
40
- uses: Khan/actions@filter-files-v0
40
+ uses: Khan/actions@filter-files-v1
41
41
  name: Files that would trigger a full eslint run
42
42
  with:
43
43
  changed-files: ${{ steps.changed.outputs.files }}
44
44
  files: '.eslintrc.js,package.json,.eslintignore'
45
45
 
46
- - name: Eslint
46
+ - name: ESlint
47
47
  uses: Khan/actions@full-or-limited-v0
48
48
  with:
49
49
  full-trigger: ${{ steps.eslint-reset.outputs.filtered }}
50
- full: yarn eslint
51
- limited-trigger: ${{ steps.js-files.outputs.filtered }}
50
+ full: yarn eslint src/**/*.ts
51
+ limited-trigger: ${{ steps.ts-files.outputs.filtered }}
52
52
  limited: yarn eslint {}
53
53
 
54
54
  - id: jest-reset
55
- uses: Khan/actions@filter-files-v0
55
+ uses: Khan/actions@filter-files-v1
56
56
  name: Files that would trigger a full jest run
57
57
  with:
58
58
  changed-files: ${{ steps.changed.outputs.files }}
@@ -63,5 +63,5 @@ jobs:
63
63
  with:
64
64
  full-trigger: ${{ steps.jest-reset.outputs.filtered }}
65
65
  full: yarn jest
66
- limited-trigger: ${{ steps.js-files.outputs.filtered }}
66
+ limited-trigger: ${{ steps.ts-files.outputs.filtered }}
67
67
  limited: yarn jest --findRelatedTests {}
package/.prettierrc CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
- "parser": "flow",
2
+ "parser": "typescript",
3
3
  "tabWidth": 4,
4
4
  "trailingComma": "all",
5
5
  "bracketSpacing": false,
6
- "singleQuote": true
6
+ "singleQuote": false
7
7
  }
@@ -0,0 +1,6 @@
1
+ {
2
+ "editor.defaultFormatter": "dbaeumer.vscode-eslint",
3
+ "editor.formatOnPaste": true,
4
+ "editor.formatOnSave": true,
5
+ "eslint.format.enable": true
6
+ }
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @khanacademy/graphql-flow
2
2
 
3
+ ## 3.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - d872096: Add alias resolution.
8
+
3
9
  ## 3.0.1
4
10
 
5
11
  ### Patch Changes
@@ -17,27 +17,20 @@ var _jsonschema = require("jsonschema");
17
17
 
18
18
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19
19
 
20
- // eslint-disable-line flowtype-errors/uncovered
21
- // eslint-disable-line flowtype-errors/uncovered
22
20
  const validateOrThrow = (value, jsonSchema) => {
23
- /* eslint-disable flowtype-errors/uncovered */
24
21
  const result = (0, _jsonschema.validate)(value, jsonSchema);
25
22
 
26
23
  if (!result.valid) {
27
- throw new Error(result.errors.map(error => error.toString()).join('\n'));
24
+ throw new Error(result.errors.map(error => error.toString()).join("\n"));
28
25
  }
29
- /* eslint-enable flowtype-errors/uncovered */
30
-
31
26
  };
32
27
 
33
28
  exports.validateOrThrow = validateOrThrow;
34
29
 
35
30
  const loadConfigFile = configFile => {
36
- const data = require(configFile); // eslint-disable-line flowtype-errors/uncovered
37
-
38
-
39
- validateOrThrow(data, _schema.default); // eslint-disable-line flowtype-errors/uncovered
31
+ const data = require(configFile);
40
32
 
33
+ validateOrThrow(data, _schema.default);
41
34
  return data;
42
35
  };
43
36
  /**
@@ -48,9 +41,9 @@ const loadConfigFile = configFile => {
48
41
  exports.loadConfigFile = loadConfigFile;
49
42
 
50
43
  const getSchemas = schemaFilePath => {
51
- const raw = _fs.default.readFileSync(schemaFilePath, 'utf8');
44
+ const raw = _fs.default.readFileSync(schemaFilePath, "utf8");
52
45
 
53
- if (schemaFilePath.endsWith('.graphql')) {
46
+ if (schemaFilePath.endsWith(".graphql")) {
54
47
  const schemaForValidation = (0, _graphql.buildSchema)(raw);
55
48
  const queryResponse = (0, _graphql.graphqlSync)({
56
49
  schema: schemaForValidation,
@@ -58,11 +51,9 @@ const getSchemas = schemaFilePath => {
58
51
  descriptions: true
59
52
  })
60
53
  });
61
- const schemaForTypeGeneration = (0, _schemaFromIntrospectionData.schemaFromIntrospectionData)( // eslint-disable-next-line flowtype-errors/uncovered
62
- queryResponse.data);
54
+ const schemaForTypeGeneration = (0, _schemaFromIntrospectionData.schemaFromIntrospectionData)(queryResponse.data);
63
55
  return [schemaForValidation, schemaForTypeGeneration];
64
56
  } else {
65
- // eslint-disable-next-line flowtype-errors/uncovered
66
57
  const introspectionData = JSON.parse(raw);
67
58
  const schemaForValidation = (0, _graphql.buildClientSchema)(introspectionData);
68
59
  const schemaForTypeGeneration = (0, _schemaFromIntrospectionData.schemaFromIntrospectionData)(introspectionData);
package/dist/cli/run.js CHANGED
@@ -27,8 +27,6 @@ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "functio
27
27
 
28
28
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
29
29
 
30
- // eslint-disable-line flowtype-errors/uncovered
31
-
32
30
  /**
33
31
  * This CLI tool executes the following steps:
34
32
  * 1) parse & validate config file
@@ -46,19 +44,19 @@ const findGraphqlTagReferences = root => {
46
44
  // generate types for them. This is useful for when we have a new file
47
45
  // that we want to generate types for, but we haven't committed it yet.
48
46
  const response = (0, _child_process.execSync)("git grep -I --word-regexp --name-only --fixed-strings --untracked 'graphql-tag' -- '*.js' '*.jsx' '*.ts' '*.tsx'", {
49
- encoding: 'utf8',
47
+ encoding: "utf8",
50
48
  cwd: root
51
49
  });
52
- return response.trim().split('\n').map(relative => _path.default.join(root, relative));
50
+ return response.trim().split("\n").map(relative => _path.default.join(root, relative));
53
51
  };
54
52
 
55
53
  const [_, __, configFilePath, ...cliFiles] = process.argv;
56
54
 
57
- if (configFilePath === '-h' || configFilePath === '--help' || configFilePath === 'help' || !configFilePath) {
55
+ if (configFilePath === "-h" || configFilePath === "--help" || configFilePath === "help" || !configFilePath) {
58
56
  console.log(`graphql-flow
59
57
 
60
58
  Usage: graphql-flow [configFile.json] [filesToCrawl...]`);
61
- process.exit(1); // eslint-disable-line flowtype-errors/uncovered
59
+ process.exit(1);
62
60
  }
63
61
 
64
62
  const makeAbsPath = (maybeRelativePath, basePath) => {
@@ -70,29 +68,29 @@ const config = (0, _config.loadConfigFile)(absConfigPath);
70
68
  const inputFiles = cliFiles.length ? cliFiles : findGraphqlTagReferences(makeAbsPath(config.crawl.root, _path.default.dirname(absConfigPath)));
71
69
  /** Step (2) */
72
70
 
73
- const files = (0, _parse.processFiles)(inputFiles, f => {
71
+ const files = (0, _parse.processFiles)(inputFiles, config, f => {
74
72
  if ((0, _fs.existsSync)(f)) {
75
- return (0, _fs.readFileSync)(f, 'utf8');
73
+ return (0, _fs.readFileSync)(f, "utf8");
76
74
  }
77
75
 
78
- if ((0, _fs.existsSync)(f + '.js')) {
76
+ if ((0, _fs.existsSync)(f + ".js")) {
79
77
  return {
80
- text: (0, _fs.readFileSync)(f + '.js', 'utf8'),
81
- resolvedPath: f + '.js'
78
+ text: (0, _fs.readFileSync)(f + ".js", "utf8"),
79
+ resolvedPath: f + ".js"
82
80
  };
83
81
  }
84
82
 
85
- if ((0, _fs.existsSync)(f + '.ts')) {
83
+ if ((0, _fs.existsSync)(f + ".ts")) {
86
84
  return {
87
- text: (0, _fs.readFileSync)(f + '.ts', 'utf8'),
88
- resolvedPath: f + '.ts'
85
+ text: (0, _fs.readFileSync)(f + ".ts", "utf8"),
86
+ resolvedPath: f + ".ts"
89
87
  };
90
88
  }
91
89
 
92
- if ((0, _fs.existsSync)(f + '.tsx')) {
90
+ if ((0, _fs.existsSync)(f + ".tsx")) {
93
91
  return {
94
- text: (0, _fs.readFileSync)(f + '.tsx', 'utf8'),
95
- resolvedPath: f + '.tsx'
92
+ text: (0, _fs.readFileSync)(f + ".tsx", "utf8"),
93
+ resolvedPath: f + ".tsx"
96
94
  };
97
95
  }
98
96
 
@@ -112,8 +110,8 @@ Object.keys(files).forEach(key => {
112
110
  });
113
111
 
114
112
  if (filesHadErrors) {
115
- console.error('Aborting');
116
- process.exit(1); // eslint-disable-line flowtype-errors/uncovered
113
+ console.error("Aborting");
114
+ process.exit(1);
117
115
  }
118
116
  /** Step (3) */
119
117
 
@@ -121,17 +119,17 @@ if (filesHadErrors) {
121
119
  const {
122
120
  resolved,
123
121
  errors
124
- } = (0, _resolve.resolveDocuments)(files);
122
+ } = (0, _resolve.resolveDocuments)(files, config);
125
123
 
126
124
  if (errors.length) {
127
125
  errors.forEach(error => {
128
126
  console.error(`Resolution error ${error.message} in ${error.loc.path}`);
129
127
  });
130
- console.error('Aborting');
131
- process.exit(1); // eslint-disable-line flowtype-errors/uncovered
128
+ console.error("Aborting");
129
+ process.exit(1);
132
130
  }
133
131
 
134
- console.log(Object.keys(resolved).length, 'resolved queries');
132
+ console.log(Object.keys(resolved).length, "resolved queries");
135
133
  /** Step (4) */
136
134
 
137
135
  const schemaCache = {};
@@ -153,15 +151,14 @@ Object.keys(resolved).forEach(filePathAndLine => {
153
151
  } = resolved[filePathAndLine];
154
152
  const hasNonFragments = document.definitions.some(({
155
153
  kind
156
- }) => kind !== 'FragmentDefinition');
154
+ }) => kind !== "FragmentDefinition");
157
155
  const rawSource = raw.literals[0];
158
156
  const generateConfig = (0, _config.findApplicableConfig)( // strip off the trailing line number, e.g. `:23`
159
- filePathAndLine.split(':')[0], config.generate);
157
+ filePathAndLine.split(":")[0], config.generate);
160
158
 
161
159
  if (!generateConfig) {
162
160
  return; // no generate config matches, bail
163
- } // eslint-disable-next-line flowtype-errors/uncovered
164
-
161
+ }
165
162
 
166
163
  const withTypeNames = (0, _apolloUtilities.addTypenameToDocument)(document);
167
164
  const printed = (0, _printer.print)(withTypeNames);
@@ -183,9 +180,7 @@ Object.keys(resolved).forEach(filePathAndLine => {
183
180
  const [schemaForValidation, schemaForTypeGeneration] = getCachedSchemas(generateConfig.schemaFilePath);
184
181
 
185
182
  if (hasNonFragments) {
186
- /* eslint-disable flowtype-errors/uncovered */
187
183
  const errors = (0, _validation.validate)(schemaForValidation, withTypeNames);
188
- /* eslint-disable flowtype-errors/uncovered */
189
184
 
190
185
  if (errors.length) {
191
186
  errors.forEach(error => {
@@ -195,24 +190,20 @@ Object.keys(resolved).forEach(filePathAndLine => {
195
190
  validationFailures++;
196
191
  });
197
192
  }
198
- /* eslint-enable flowtype-errors/uncovered */
199
-
200
193
  }
201
194
 
202
195
  try {
203
- (0, _generateTypeFiles.generateTypeFiles)(raw.loc.path, schemaForTypeGeneration, withTypeNames, generateConfig); // eslint-disable-next-line flowtype-errors/uncovered
196
+ (0, _generateTypeFiles.generateTypeFiles)(raw.loc.path, schemaForTypeGeneration, withTypeNames, generateConfig);
204
197
  } catch (err) {
205
198
  console.error(`Error while generating operation from ${raw.loc.path}`);
206
- console.error(printed); // eslint-disable-next-line flowtype-errors/uncovered
207
-
199
+ console.error(printed);
208
200
  console.error(err);
209
201
  validationFailures++;
210
202
  }
211
203
  });
212
204
 
213
205
  if (validationFailures) {
214
- console.error(`Encountered ${validationFailures} validation failures while printing types.`); // eslint-disable-next-line flowtype-errors/uncovered
215
-
206
+ console.error(`Encountered ${validationFailures} validation failures while printing types.`);
216
207
  process.exit(1);
217
208
  }
218
209
 
package/dist/enums.js CHANGED
@@ -31,10 +31,10 @@ exports.experimentalEnumTypeToFlow = experimentalEnumTypeToFlow;
31
31
 
32
32
  const enumTypeToFlow = (ctx, name) => {
33
33
  const enumConfig = ctx.schema.enumsByName[name];
34
- let combinedDescription = enumConfig.enumValues.map(n => `- ${n.name}` + (n.description ? '\n\n ' + n.description.replace(/\n/g, '\n ') : '')).join('\n');
34
+ let combinedDescription = enumConfig.enumValues.map(n => `- ${n.name}` + (n.description ? "\n\n " + n.description.replace(/\n/g, "\n ") : "")).join("\n");
35
35
 
36
36
  if (enumConfig.description) {
37
- combinedDescription = enumConfig.description + '\n\n' + combinedDescription;
37
+ combinedDescription = enumConfig.description + "\n\n" + combinedDescription;
38
38
  }
39
39
 
40
40
  return ctx.experimentalEnumsMap ? experimentalEnumTypeToFlow(ctx, enumConfig, combinedDescription) : (0, _utils.maybeAddDescriptionComment)(combinedDescription, babelTypes.tsUnionType(enumConfig.enumValues.map(n => babelTypes.tsLiteralType(babelTypes.stringLiteral(n.name)))));
@@ -42,13 +42,13 @@ const enumTypeToFlow = (ctx, name) => {
42
42
 
43
43
  exports.enumTypeToFlow = enumTypeToFlow;
44
44
  const builtinScalars = {
45
- Boolean: 'boolean',
46
- String: 'string',
47
- DateTime: 'string',
48
- Date: 'string',
49
- ID: 'string',
50
- Int: 'number',
51
- Float: 'number'
45
+ Boolean: "boolean",
46
+ String: "string",
47
+ DateTime: "string",
48
+ Date: "string",
49
+ ID: "string",
50
+ Int: "number",
51
+ Float: "number"
52
52
  };
53
53
  exports.builtinScalars = builtinScalars;
54
54
 
@@ -20,10 +20,8 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
20
20
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
21
21
 
22
22
  /* eslint-disable no-console */
23
- // eslint-disable-line flowtype-errors/uncovered
24
23
  const generateResponseType = (schema, query, ctx) => {
25
- const ast = querySelectionToObjectType(ctx, query.selectionSet.selections, query.operation === 'mutation' ? schema.typesByName.Mutation : schema.typesByName.Query, query.operation === 'mutation' ? 'mutation' : 'query'); // eslint-disable-next-line flowtype-errors/uncovered
26
-
24
+ const ast = querySelectionToObjectType(ctx, query.selectionSet.selections, query.operation === "mutation" ? schema.typesByName.Mutation : schema.typesByName.Query, query.operation === "mutation" ? "mutation" : "query");
27
25
  return (0, _generator.default)(ast).code;
28
26
  };
29
27
 
@@ -31,15 +29,15 @@ exports.generateResponseType = generateResponseType;
31
29
 
32
30
  const sortedObjectTypeAnnotation = (ctx, properties) => {
33
31
  const obj = (0, _utils.objectTypeFromProperties)(properties.sort((a, b) => {
34
- if (a.type === 'TSPropertySignature' && b.type === 'TSPropertySignature') {
35
- const aName = a.key.type === 'Identifier' ? a.key.name : '';
36
- const bName = b.key.type === 'Identifier' ? b.key.name : '';
32
+ if (a.type === "TSPropertySignature" && b.type === "TSPropertySignature") {
33
+ const aName = a.key.type === "Identifier" ? a.key.name : "";
34
+ const bName = b.key.type === "Identifier" ? b.key.name : "";
37
35
  return aName < bName ? -1 : 1;
38
36
  }
39
37
 
40
38
  return 0;
41
39
  }));
42
- const name = ctx.path.join('_');
40
+ const name = ctx.path.join("_");
43
41
  const isTopLevelType = ctx.path.length <= 1;
44
42
 
45
43
  if (ctx.allObjectTypes != null && !isTopLevelType) {
@@ -62,8 +60,7 @@ const generateFragmentType = (schema, fragment, ctx) => {
62
60
  ast = unionOrInterfaceToFlow(ctx, ctx.schema.unionsByName[onType], fragment.selectionSet.selections);
63
61
  } else {
64
62
  throw new Error(`Unknown ${onType}`);
65
- } // eslint-disable-next-line flowtype-errors/uncovered
66
-
63
+ }
67
64
 
68
65
  return (0, _generator.default)(ast).code;
69
66
  };
@@ -71,54 +68,54 @@ const generateFragmentType = (schema, fragment, ctx) => {
71
68
  exports.generateFragmentType = generateFragmentType;
72
69
 
73
70
  const _typeToFlow = (ctx, type, selection) => {
74
- if (type.kind === 'SCALAR') {
71
+ if (type.kind === "SCALAR") {
75
72
  return (0, _enums.scalarTypeToFlow)(ctx, type.name);
76
73
  }
77
74
 
78
- if (type.kind === 'LIST') {
79
- return babelTypes.tsTypeReference(ctx.readOnlyArray ? babelTypes.identifier('ReadonlyArray') : babelTypes.identifier('Array'), babelTypes.tsTypeParameterInstantiation([typeToFlow(ctx, type.ofType, selection)]));
75
+ if (type.kind === "LIST") {
76
+ return babelTypes.tsTypeReference(ctx.readOnlyArray ? babelTypes.identifier("ReadonlyArray") : babelTypes.identifier("Array"), babelTypes.tsTypeParameterInstantiation([typeToFlow(ctx, type.ofType, selection)]));
80
77
  }
81
78
 
82
- if (type.kind === 'UNION') {
79
+ if (type.kind === "UNION") {
83
80
  const union = ctx.schema.unionsByName[type.name];
84
81
 
85
82
  if (!selection.selectionSet) {
86
- console.log('no selection set', selection);
83
+ console.log("no selection set", selection);
87
84
  return babelTypes.tsAnyKeyword();
88
85
  }
89
86
 
90
87
  return unionOrInterfaceToFlow(ctx, union, selection.selectionSet.selections);
91
88
  }
92
89
 
93
- if (type.kind === 'INTERFACE') {
90
+ if (type.kind === "INTERFACE") {
94
91
  if (!selection.selectionSet) {
95
- console.log('no selection set', selection);
92
+ console.log("no selection set", selection);
96
93
  return babelTypes.tsAnyKeyword();
97
94
  }
98
95
 
99
96
  return unionOrInterfaceToFlow(ctx, ctx.schema.interfacesByName[type.name], selection.selectionSet.selections);
100
97
  }
101
98
 
102
- if (type.kind === 'ENUM') {
99
+ if (type.kind === "ENUM") {
103
100
  return (0, _enums.enumTypeToFlow)(ctx, type.name);
104
101
  }
105
102
 
106
- if (type.kind !== 'OBJECT') {
107
- console.log('not object', type);
103
+ if (type.kind !== "OBJECT") {
104
+ console.log("not object", type);
108
105
  return babelTypes.tsAnyKeyword();
109
106
  }
110
107
 
111
108
  const tname = type.name;
112
109
 
113
110
  if (!ctx.schema.typesByName[tname]) {
114
- console.log('unknown referenced type', tname);
111
+ console.log("unknown referenced type", tname);
115
112
  return babelTypes.tsAnyKeyword();
116
113
  }
117
114
 
118
115
  const childType = ctx.schema.typesByName[tname];
119
116
 
120
117
  if (!selection.selectionSet) {
121
- console.log('no selection set', selection);
118
+ console.log("no selection set", selection);
122
119
  return babelTypes.tsAnyKeyword();
123
120
  }
124
121
 
@@ -127,7 +124,7 @@ const _typeToFlow = (ctx, type, selection) => {
127
124
 
128
125
  const typeToFlow = (ctx, type, selection) => {
129
126
  // throw new Error('npoe');
130
- if (type.kind === 'NON_NULL') {
127
+ if (type.kind === "NON_NULL") {
131
128
  return _typeToFlow(ctx, type.ofType, selection);
132
129
  } // If we don'babelTypes care about strict nullability checking, then pretend everything is non-null
133
130
 
@@ -150,10 +147,10 @@ const ensureOnlyOneTypenameProperty = properties => {
150
147
  // The apollo-utilities "addTypeName" utility will add it
151
148
  // even if it's already specified :( so we have to filter out
152
149
  // the extra one here.
153
- if (type.type === 'TSPropertySignature' && type.key.type === "Identifier" && type.key.name === '__typename') {
150
+ if (type.type === "TSPropertySignature" && type.key.type === "Identifier" && type.key.name === "__typename") {
154
151
  var _type$typeAnnotation;
155
152
 
156
- const name = ((_type$typeAnnotation = type.typeAnnotation) === null || _type$typeAnnotation === void 0 ? void 0 : _type$typeAnnotation.typeAnnotation.type) === 'TSLiteralType' && type.typeAnnotation.typeAnnotation.literal.type === 'StringLiteral' ? type.typeAnnotation.typeAnnotation.literal.value : 'INVALID';
153
+ const name = ((_type$typeAnnotation = type.typeAnnotation) === null || _type$typeAnnotation === void 0 ? void 0 : _type$typeAnnotation.typeAnnotation.type) === "TSLiteralType" && type.typeAnnotation.typeAnnotation.literal.type === "StringLiteral" ? type.typeAnnotation.typeAnnotation.literal.value : "INVALID";
157
154
 
158
155
  if (seenTypeName) {
159
156
  if (name !== seenTypeName) {
@@ -177,7 +174,7 @@ const querySelectionToObjectType = (ctx, selections, type, typeName) => {
177
174
  const objectPropertiesToFlow = (ctx, type, typeName, selections) => {
178
175
  return selections.flatMap(selection => {
179
176
  switch (selection.kind) {
180
- case 'InlineFragment':
177
+ case "InlineFragment":
181
178
  {
182
179
  var _selection$typeCondit, _selection$typeCondit2;
183
180
 
@@ -190,7 +187,7 @@ const objectPropertiesToFlow = (ctx, type, typeName, selections) => {
190
187
  return objectPropertiesToFlow(ctx, ctx.schema.typesByName[newTypeName], newTypeName, selection.selectionSet.selections);
191
188
  }
192
189
 
193
- case 'FragmentSpread':
190
+ case "FragmentSpread":
194
191
  if (!ctx.fragments[selection.name.value]) {
195
192
  ctx.errors.push(`No fragment named '${selection.name.value}'. Did you forget to include it in the template literal?`);
196
193
  return [babelTypes.tsPropertySignature(babelTypes.identifier(selection.name.value), babelTypes.tsTypeAnnotation(babelTypes.tsTypeReference(babelTypes.identifier(`UNKNOWN_FRAGMENT`))))];
@@ -198,11 +195,11 @@ const objectPropertiesToFlow = (ctx, type, typeName, selections) => {
198
195
 
199
196
  return objectPropertiesToFlow(ctx, type, typeName, ctx.fragments[selection.name.value].selectionSet.selections);
200
197
 
201
- case 'Field':
198
+ case "Field":
202
199
  const name = selection.name.value;
203
200
  const alias = selection.alias ? selection.alias.value : name;
204
201
 
205
- if (name === '__typename') {
202
+ if (name === "__typename") {
206
203
  return [babelTypes.tsPropertySignature(babelTypes.identifier(alias), babelTypes.tsTypeAnnotation(babelTypes.tsLiteralType(babelTypes.stringLiteral(typeName))))];
207
204
  }
208
205
 
@@ -217,8 +214,7 @@ const objectPropertiesToFlow = (ctx, type, typeName, selections) => {
217
214
  }, typeField.type, selection)))))];
218
215
 
219
216
  default:
220
- ctx.errors.push( // @ts-expect-error: `selection` is `never` here
221
- `Unsupported selection kind '${selection.kind}'`);
217
+ ctx.errors.push(`Unsupported selection kind '${selection.kind}'`);
222
218
  return [];
223
219
  }
224
220
  });
@@ -227,7 +223,7 @@ const objectPropertiesToFlow = (ctx, type, typeName, selections) => {
227
223
  exports.objectPropertiesToFlow = objectPropertiesToFlow;
228
224
 
229
225
  const unionOrInterfaceToFlow = (ctx, type, selections) => {
230
- const allFields = selections.every(selection => selection.kind === 'Field');
226
+ const allFields = selections.every(selection => selection.kind === "Field");
231
227
  const selectedAttributes = type.possibleTypes.slice().sort((a, b) => {
232
228
  return a.name < b.name ? -1 : 1;
233
229
  }).map(possible => {
@@ -242,10 +238,10 @@ const unionOrInterfaceToFlow = (ctx, type, selections) => {
242
238
 
243
239
  if (allFields) {
244
240
  const sharedAttributes = selectedAttributes[0].attributes.slice();
245
- const typeNameIndex = selectedAttributes[0].attributes.findIndex(x => x.type === 'TSPropertySignature' && x.key.type === 'Identifier' && x.key.name === '__typename');
241
+ const typeNameIndex = selectedAttributes[0].attributes.findIndex(x => x.type === "TSPropertySignature" && x.key.type === "Identifier" && x.key.name === "__typename");
246
242
 
247
243
  if (typeNameIndex !== -1) {
248
- sharedAttributes[typeNameIndex] = babelTypes.tsPropertySignature(babelTypes.identifier('__typename'), babelTypes.tsTypeAnnotation(babelTypes.tsUnionType(selectedAttributes.map(attrs => attrs.attributes[typeNameIndex].typeAnnotation.typeAnnotation))));
244
+ sharedAttributes[typeNameIndex] = babelTypes.tsPropertySignature(babelTypes.identifier("__typename"), babelTypes.tsTypeAnnotation(babelTypes.tsUnionType(selectedAttributes.map(attrs => attrs.attributes[typeNameIndex].typeAnnotation.typeAnnotation))));
249
245
  }
250
246
 
251
247
  return sortedObjectTypeAnnotation(ctx, sharedAttributes);
@@ -292,7 +288,7 @@ const unionOrInterfaceToFlow = (ctx, type, selections) => {
292
288
  }) => sortedObjectTypeAnnotation({ ...ctx,
293
289
  path: ctx.path.concat([typeName])
294
290
  }, attributes)));
295
- const name = ctx.path.join('_');
291
+ const name = ctx.path.join("_");
296
292
 
297
293
  if (ctx.allObjectTypes && ctx.path.length > 1) {
298
294
  ctx.allObjectTypes[name] = result;
@@ -305,18 +301,18 @@ const unionOrInterfaceToFlow = (ctx, type, selections) => {
305
301
  exports.unionOrInterfaceToFlow = unionOrInterfaceToFlow;
306
302
 
307
303
  const unionOrInterfaceSelection = (config, type, possible, selection) => {
308
- if (selection.kind === 'Field' && selection.name.value === '__typename') {
304
+ if (selection.kind === "Field" && selection.name.value === "__typename") {
309
305
  const alias = selection.alias ? selection.alias.value : selection.name.value;
310
306
  return [babelTypes.tsPropertySignature(babelTypes.identifier(alias), babelTypes.tsTypeAnnotation(babelTypes.tsLiteralType(babelTypes.stringLiteral(possible.name))))];
311
307
  }
312
308
 
313
- if (selection.kind === 'Field' && type.kind !== 'UNION') {
309
+ if (selection.kind === "Field" && type.kind !== "UNION") {
314
310
  // this is an interface
315
311
  const name = selection.name.value;
316
312
  const alias = selection.alias ? selection.alias.value : name;
317
313
 
318
314
  if (!type.fieldsByName[name]) {
319
- config.errors.push('Unknown field: ' + name + ' on type ' + type.name + ' for possible ' + possible.name);
315
+ config.errors.push("Unknown field: " + name + " on type " + type.name + " for possible " + possible.name);
320
316
  return [babelTypes.tsPropertySignature(babelTypes.identifier(alias), babelTypes.tsTypeAnnotation(babelTypes.tsTypeReference(babelTypes.identifier(`UNKNOWN_FIELD`))))];
321
317
  }
322
318
 
@@ -326,7 +322,7 @@ const unionOrInterfaceSelection = (config, type, possible, selection) => {
326
322
  }, typeField.type, selection))))];
327
323
  }
328
324
 
329
- if (selection.kind === 'FragmentSpread') {
325
+ if (selection.kind === "FragmentSpread") {
330
326
  const fragment = config.fragments[selection.name.value];
331
327
 
332
328
  if (!fragment) {
@@ -342,10 +338,10 @@ const unionOrInterfaceSelection = (config, type, possible, selection) => {
342
338
  }
343
339
  }
344
340
 
345
- if (selection.kind !== 'InlineFragment') {
341
+ if (selection.kind !== "InlineFragment") {
346
342
  config.errors.push(`union selectors must be inline fragment: found ${selection.kind}`);
347
343
 
348
- if (type.kind === 'UNION') {
344
+ if (type.kind === "UNION") {
349
345
  config.errors.push(`You're trying to select a field from the union ${type.name},
350
346
  but the only field you're allowed to select is "__typename".
351
347
  Try using an inline fragment "... on SomeType {}".`);