@khanacademy/graphql-flow 3.0.1 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/.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 +12 -0
  7. package/dist/cli/config.js +6 -15
  8. package/dist/cli/run.js +26 -49
  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 +48 -56
  15. package/dist/parser/resolve.js +20 -16
  16. package/dist/parser/utils.js +29 -16
  17. package/dist/schemaFromIntrospectionData.js +5 -5
  18. package/dist/utils.js +8 -8
  19. package/package.json +12 -13
  20. package/schema.json +18 -2
  21. package/src/__test__/generateTypeFileContents.test.ts +26 -25
  22. package/src/__test__/graphql-flow.test.ts +32 -33
  23. package/src/__test__/processPragmas.test.ts +14 -13
  24. package/src/cli/__test__/config.test.ts +51 -56
  25. package/src/cli/config.ts +23 -20
  26. package/src/cli/run.ts +38 -52
  27. package/src/enums.ts +17 -17
  28. package/src/generateResponseType.ts +120 -91
  29. package/src/generateTypeFiles.ts +24 -22
  30. package/src/generateVariablesType.ts +20 -20
  31. package/src/index.ts +28 -29
  32. package/src/parser/__test__/parse.test.ts +114 -23
  33. package/src/parser/__test__/utils.test.ts +80 -0
  34. package/src/parser/parse.ts +126 -109
  35. package/src/parser/resolve.ts +64 -34
  36. package/src/parser/utils.ts +25 -15
  37. package/src/schemaFromIntrospectionData.ts +10 -8
  38. package/src/types.ts +57 -53
  39. package/src/utils.ts +30 -16
  40. package/tools/find-files-with-gql.ts +7 -11
@@ -1,40 +1,44 @@
1
1
  /* eslint-disable no-console */
2
- import generate from '@babel/generator'; // eslint-disable-line flowtype-errors/uncovered
3
- import * as babelTypes from '@babel/types';
4
- import {TSType} from '@babel/types';
2
+ import generate from "@babel/generator";
3
+ import * as babelTypes from "@babel/types";
4
+ import {TSType} from "@babel/types";
5
5
  import type {
6
6
  FieldNode,
7
7
  IntrospectionOutputTypeRef,
8
8
  OperationDefinitionNode,
9
9
  FragmentDefinitionNode,
10
10
  SelectionNode,
11
- } from 'graphql';
12
- import type {Context, Schema, Selections} from './types';
11
+ } from "graphql";
12
+ import type {Context, Schema, Selections} from "./types";
13
13
  import {
14
14
  liftLeadingPropertyComments,
15
15
  maybeAddDescriptionComment,
16
16
  transferLeadingComments,
17
17
  nullableType,
18
18
  objectTypeFromProperties,
19
- } from './utils';
20
- import {enumTypeToFlow, scalarTypeToFlow} from './enums';
19
+ } from "./utils";
20
+ import {enumTypeToFlow, scalarTypeToFlow} from "./enums";
21
21
  import type {
22
22
  IntrospectionField,
23
23
  IntrospectionInterfaceType,
24
24
  IntrospectionObjectType,
25
25
  IntrospectionUnionType,
26
- } from 'graphql/utilities/introspectionQuery';
26
+ } from "graphql";
27
27
 
28
- export const generateResponseType = (schema: Schema, query: OperationDefinitionNode, ctx: Context): string => {
28
+ export const generateResponseType = (
29
+ schema: Schema,
30
+ query: OperationDefinitionNode,
31
+ ctx: Context,
32
+ ): string => {
29
33
  const ast = querySelectionToObjectType(
30
34
  ctx,
31
35
  query.selectionSet.selections,
32
- query.operation === 'mutation'
36
+ query.operation === "mutation"
33
37
  ? schema.typesByName.Mutation
34
38
  : schema.typesByName.Query,
35
- query.operation === 'mutation' ? 'mutation' : 'query',
39
+ query.operation === "mutation" ? "mutation" : "query",
36
40
  );
37
- // eslint-disable-next-line flowtype-errors/uncovered
41
+
38
42
  return generate(ast).code;
39
43
  };
40
44
 
@@ -45,17 +49,17 @@ const sortedObjectTypeAnnotation = (
45
49
  const obj = objectTypeFromProperties(
46
50
  properties.sort((a, b) => {
47
51
  if (
48
- a.type === 'TSPropertySignature' &&
49
- b.type === 'TSPropertySignature'
52
+ a.type === "TSPropertySignature" &&
53
+ b.type === "TSPropertySignature"
50
54
  ) {
51
- const aName = a.key.type === 'Identifier' ? a.key.name : '';
52
- const bName = b.key.type === 'Identifier' ? b.key.name : '';
55
+ const aName = a.key.type === "Identifier" ? a.key.name : "";
56
+ const bName = b.key.type === "Identifier" ? b.key.name : "";
53
57
  return aName < bName ? -1 : 1;
54
58
  }
55
59
  return 0;
56
60
  }),
57
61
  );
58
- const name = ctx.path.join('_');
62
+ const name = ctx.path.join("_");
59
63
  const isTopLevelType = ctx.path.length <= 1;
60
64
  if (ctx.allObjectTypes != null && !isTopLevelType) {
61
65
  ctx.allObjectTypes[name] = obj;
@@ -65,7 +69,11 @@ const sortedObjectTypeAnnotation = (
65
69
  }
66
70
  };
67
71
 
68
- export const generateFragmentType = (schema: Schema, fragment: FragmentDefinitionNode, ctx: Context): string => {
72
+ export const generateFragmentType = (
73
+ schema: Schema,
74
+ fragment: FragmentDefinitionNode,
75
+ ctx: Context,
76
+ ): string => {
69
77
  const onType = fragment.typeCondition.name.value;
70
78
  let ast;
71
79
 
@@ -95,28 +103,31 @@ export const generateFragmentType = (schema: Schema, fragment: FragmentDefinitio
95
103
  throw new Error(`Unknown ${onType}`);
96
104
  }
97
105
 
98
- // eslint-disable-next-line flowtype-errors/uncovered
99
106
  return generate(ast).code;
100
107
  };
101
108
 
102
- const _typeToFlow = (ctx: Context, type: any, selection: FieldNode): babelTypes.TSType => {
103
- if (type.kind === 'SCALAR') {
109
+ const _typeToFlow = (
110
+ ctx: Context,
111
+ type: any,
112
+ selection: FieldNode,
113
+ ): babelTypes.TSType => {
114
+ if (type.kind === "SCALAR") {
104
115
  return scalarTypeToFlow(ctx, type.name);
105
116
  }
106
- if (type.kind === 'LIST') {
117
+ if (type.kind === "LIST") {
107
118
  return babelTypes.tsTypeReference(
108
119
  ctx.readOnlyArray
109
- ? babelTypes.identifier('ReadonlyArray')
110
- : babelTypes.identifier('Array'),
120
+ ? babelTypes.identifier("ReadonlyArray")
121
+ : babelTypes.identifier("Array"),
111
122
  babelTypes.tsTypeParameterInstantiation([
112
123
  typeToFlow(ctx, type.ofType, selection),
113
124
  ]),
114
125
  );
115
126
  }
116
- if (type.kind === 'UNION') {
127
+ if (type.kind === "UNION") {
117
128
  const union = ctx.schema.unionsByName[type.name];
118
129
  if (!selection.selectionSet) {
119
- console.log('no selection set', selection);
130
+ console.log("no selection set", selection);
120
131
  return babelTypes.tsAnyKeyword();
121
132
  }
122
133
  return unionOrInterfaceToFlow(
@@ -126,9 +137,9 @@ const _typeToFlow = (ctx: Context, type: any, selection: FieldNode): babelTypes.
126
137
  );
127
138
  }
128
139
 
129
- if (type.kind === 'INTERFACE') {
140
+ if (type.kind === "INTERFACE") {
130
141
  if (!selection.selectionSet) {
131
- console.log('no selection set', selection);
142
+ console.log("no selection set", selection);
132
143
  return babelTypes.tsAnyKeyword();
133
144
  }
134
145
  return unionOrInterfaceToFlow(
@@ -137,22 +148,22 @@ const _typeToFlow = (ctx: Context, type: any, selection: FieldNode): babelTypes.
137
148
  selection.selectionSet.selections,
138
149
  );
139
150
  }
140
- if (type.kind === 'ENUM') {
151
+ if (type.kind === "ENUM") {
141
152
  return enumTypeToFlow(ctx, type.name);
142
153
  }
143
- if (type.kind !== 'OBJECT') {
144
- console.log('not object', type);
154
+ if (type.kind !== "OBJECT") {
155
+ console.log("not object", type);
145
156
  return babelTypes.tsAnyKeyword();
146
157
  }
147
158
 
148
159
  const tname = type.name;
149
160
  if (!ctx.schema.typesByName[tname]) {
150
- console.log('unknown referenced type', tname);
161
+ console.log("unknown referenced type", tname);
151
162
  return babelTypes.tsAnyKeyword();
152
163
  }
153
164
  const childType = ctx.schema.typesByName[tname];
154
165
  if (!selection.selectionSet) {
155
- console.log('no selection set', selection);
166
+ console.log("no selection set", selection);
156
167
  return babelTypes.tsAnyKeyword();
157
168
  }
158
169
  return maybeAddDescriptionComment(
@@ -166,9 +177,13 @@ const _typeToFlow = (ctx: Context, type: any, selection: FieldNode): babelTypes.
166
177
  );
167
178
  };
168
179
 
169
- export const typeToFlow = (ctx: Context, type: IntrospectionOutputTypeRef, selection: FieldNode): babelTypes.TSType => {
180
+ export const typeToFlow = (
181
+ ctx: Context,
182
+ type: IntrospectionOutputTypeRef,
183
+ selection: FieldNode,
184
+ ): babelTypes.TSType => {
170
185
  // throw new Error('npoe');
171
- if (type.kind === 'NON_NULL') {
186
+ if (type.kind === "NON_NULL") {
172
187
  return _typeToFlow(ctx, type.ofType, selection);
173
188
  }
174
189
  // If we don'babelTypes care about strict nullability checking, then pretend everything is non-null
@@ -180,22 +195,25 @@ export const typeToFlow = (ctx: Context, type: IntrospectionOutputTypeRef, selec
180
195
  return transferLeadingComments(inner, result);
181
196
  };
182
197
 
183
- const ensureOnlyOneTypenameProperty = (properties: Array<babelTypes.TSPropertySignature>) => {
198
+ const ensureOnlyOneTypenameProperty = (
199
+ properties: Array<babelTypes.TSPropertySignature>,
200
+ ) => {
184
201
  let seenTypeName: false | string = false;
185
202
  return properties.filter((type) => {
186
203
  // The apollo-utilities "addTypeName" utility will add it
187
204
  // even if it's already specified :( so we have to filter out
188
205
  // the extra one here.
189
206
  if (
190
- type.type === 'TSPropertySignature' &&
207
+ type.type === "TSPropertySignature" &&
191
208
  type.key.type === "Identifier" &&
192
- type.key.name === '__typename'
209
+ type.key.name === "__typename"
193
210
  ) {
194
211
  const name =
195
- type.typeAnnotation?.typeAnnotation.type === 'TSLiteralType' &&
196
- type.typeAnnotation.typeAnnotation.literal.type === 'StringLiteral'
212
+ type.typeAnnotation?.typeAnnotation.type === "TSLiteralType" &&
213
+ type.typeAnnotation.typeAnnotation.literal.type ===
214
+ "StringLiteral"
197
215
  ? type.typeAnnotation.typeAnnotation.literal.value
198
- : 'INVALID';
216
+ : "INVALID";
199
217
  if (seenTypeName) {
200
218
  if (name !== seenTypeName) {
201
219
  throw new Error(
@@ -210,7 +228,12 @@ const ensureOnlyOneTypenameProperty = (properties: Array<babelTypes.TSPropertySi
210
228
  });
211
229
  };
212
230
 
213
- const querySelectionToObjectType = (ctx: Context, selections: any, type: any, typeName: string): babelTypes.TSType => {
231
+ const querySelectionToObjectType = (
232
+ ctx: Context,
233
+ selections: any,
234
+ type: any,
235
+ typeName: string,
236
+ ): babelTypes.TSType => {
214
237
  return sortedObjectTypeAnnotation(
215
238
  ctx,
216
239
  ensureOnlyOneTypenameProperty(
@@ -223,15 +246,15 @@ export const objectPropertiesToFlow = (
223
246
  ctx: Context,
224
247
  type: IntrospectionObjectType & {
225
248
  fieldsByName: {
226
- [name: string]: IntrospectionField
227
- }
249
+ [name: string]: IntrospectionField;
250
+ };
228
251
  },
229
252
  typeName: string,
230
253
  selections: Selections,
231
254
  ): Array<babelTypes.TSPropertySignature> => {
232
255
  return selections.flatMap((selection) => {
233
256
  switch (selection.kind) {
234
- case 'InlineFragment': {
257
+ case "InlineFragment": {
235
258
  const newTypeName =
236
259
  selection.typeCondition?.name.value ?? typeName;
237
260
  if (newTypeName !== typeName) {
@@ -244,7 +267,7 @@ export const objectPropertiesToFlow = (
244
267
  selection.selectionSet.selections,
245
268
  );
246
269
  }
247
- case 'FragmentSpread':
270
+ case "FragmentSpread":
248
271
  if (!ctx.fragments[selection.name.value]) {
249
272
  ctx.errors.push(
250
273
  `No fragment named '${selection.name.value}'. Did you forget to include it in the template literal?`,
@@ -255,7 +278,7 @@ export const objectPropertiesToFlow = (
255
278
  babelTypes.tsTypeAnnotation(
256
279
  babelTypes.tsTypeReference(
257
280
  babelTypes.identifier(`UNKNOWN_FRAGMENT`),
258
- )
281
+ ),
259
282
  ),
260
283
  ),
261
284
  ];
@@ -265,16 +288,15 @@ export const objectPropertiesToFlow = (
265
288
  ctx,
266
289
  type,
267
290
  typeName,
268
- ctx.fragments[selection.name.value].selectionSet
269
- .selections,
291
+ ctx.fragments[selection.name.value].selectionSet.selections,
270
292
  );
271
293
 
272
- case 'Field':
294
+ case "Field":
273
295
  const name = selection.name.value;
274
296
  const alias: string = selection.alias
275
297
  ? selection.alias.value
276
298
  : name;
277
- if (name === '__typename') {
299
+ if (name === "__typename") {
278
300
  return [
279
301
  babelTypes.tsPropertySignature(
280
302
  babelTypes.identifier(alias),
@@ -298,9 +320,9 @@ export const objectPropertiesToFlow = (
298
320
  babelTypes.identifier(
299
321
  `UNKNOWN_FIELD["${name}"]`,
300
322
  ),
301
- )
323
+ ),
302
324
  ),
303
- )
325
+ ),
304
326
  ];
305
327
  }
306
328
  const typeField = type.fieldsByName[name];
@@ -320,7 +342,7 @@ export const objectPropertiesToFlow = (
320
342
  typeField.type,
321
343
  selection,
322
344
  ),
323
- )
345
+ ),
324
346
  ),
325
347
  ),
326
348
  ),
@@ -328,7 +350,6 @@ export const objectPropertiesToFlow = (
328
350
 
329
351
  default:
330
352
  ctx.errors.push(
331
- // @ts-expect-error: `selection` is `never` here
332
353
  `Unsupported selection kind '${selection.kind}'`,
333
354
  );
334
355
  return [];
@@ -338,19 +359,21 @@ export const objectPropertiesToFlow = (
338
359
 
339
360
  export const unionOrInterfaceToFlow = (
340
361
  ctx: Context,
341
- type: IntrospectionUnionType | IntrospectionInterfaceType & {
342
- fieldsByName: {
343
- [key: string]: IntrospectionField
344
- }
345
- },
362
+ type:
363
+ | IntrospectionUnionType
364
+ | (IntrospectionInterfaceType & {
365
+ fieldsByName: {
366
+ [key: string]: IntrospectionField;
367
+ };
368
+ }),
346
369
  selections: Selections,
347
370
  ): TSType => {
348
371
  const allFields = selections.every(
349
- (selection) => selection.kind === 'Field',
372
+ (selection) => selection.kind === "Field",
350
373
  );
351
374
  const selectedAttributes: Array<{
352
- attributes: Array<babelTypes.TSPropertySignature>
353
- typeName: string
375
+ attributes: Array<babelTypes.TSPropertySignature>;
376
+ typeName: string;
354
377
  }> = type.possibleTypes
355
378
  .slice()
356
379
  .sort((a, b) => {
@@ -382,23 +405,25 @@ export const unionOrInterfaceToFlow = (
382
405
  const sharedAttributes = selectedAttributes[0].attributes.slice();
383
406
  const typeNameIndex = selectedAttributes[0].attributes.findIndex(
384
407
  (x) =>
385
- x.type === 'TSPropertySignature' &&
386
- x.key.type === 'Identifier' &&
387
- x.key.name === '__typename',
408
+ x.type === "TSPropertySignature" &&
409
+ x.key.type === "Identifier" &&
410
+ x.key.name === "__typename",
388
411
  );
389
412
  if (typeNameIndex !== -1) {
390
413
  sharedAttributes[typeNameIndex] = babelTypes.tsPropertySignature(
391
- babelTypes.identifier('__typename'),
414
+ babelTypes.identifier("__typename"),
392
415
  babelTypes.tsTypeAnnotation(
393
416
  babelTypes.tsUnionType(
394
417
  selectedAttributes.map(
395
418
  (attrs) =>
396
- (attrs.attributes[
397
- typeNameIndex
398
- ] as babelTypes.TSPropertySignature).typeAnnotation!.typeAnnotation,
419
+ (
420
+ attrs.attributes[
421
+ typeNameIndex
422
+ ] as babelTypes.TSPropertySignature
423
+ ).typeAnnotation!.typeAnnotation,
399
424
  ),
400
425
  ),
401
- )
426
+ ),
402
427
  );
403
428
  }
404
429
  return sortedObjectTypeAnnotation(ctx, sharedAttributes);
@@ -447,17 +472,20 @@ export const unionOrInterfaceToFlow = (
447
472
  ),
448
473
  ),
449
474
  );
450
- const name = ctx.path.join('_');
475
+ const name = ctx.path.join("_");
451
476
  if (ctx.allObjectTypes && ctx.path.length > 1) {
452
477
  ctx.allObjectTypes[name] = result;
453
- return babelTypes.tsTypeReference(
454
- babelTypes.identifier(name),
455
- );
478
+ return babelTypes.tsTypeReference(babelTypes.identifier(name));
456
479
  }
457
480
  return result;
458
481
  };
459
- const unionOrInterfaceSelection = (config: Context, type: any, possible: any, selection: SelectionNode): Array<babelTypes.TSPropertySignature> => {
460
- if (selection.kind === 'Field' && selection.name.value === '__typename') {
482
+ const unionOrInterfaceSelection = (
483
+ config: Context,
484
+ type: any,
485
+ possible: any,
486
+ selection: SelectionNode,
487
+ ): Array<babelTypes.TSPropertySignature> => {
488
+ if (selection.kind === "Field" && selection.name.value === "__typename") {
461
489
  const alias = selection.alias
462
490
  ? selection.alias.value
463
491
  : selection.name.value;
@@ -472,17 +500,17 @@ const unionOrInterfaceSelection = (config: Context, type: any, possible: any, se
472
500
  ),
473
501
  ];
474
502
  }
475
- if (selection.kind === 'Field' && type.kind !== 'UNION') {
503
+ if (selection.kind === "Field" && type.kind !== "UNION") {
476
504
  // this is an interface
477
505
  const name = selection.name.value;
478
506
  const alias = selection.alias ? selection.alias.value : name;
479
507
  if (!type.fieldsByName[name]) {
480
508
  config.errors.push(
481
- 'Unknown field: ' +
509
+ "Unknown field: " +
482
510
  name +
483
- ' on type ' +
511
+ " on type " +
484
512
  type.name +
485
- ' for possible ' +
513
+ " for possible " +
486
514
  possible.name,
487
515
  );
488
516
  return [
@@ -512,7 +540,7 @@ const unionOrInterfaceSelection = (config: Context, type: any, possible: any, se
512
540
  ),
513
541
  ];
514
542
  }
515
- if (selection.kind === 'FragmentSpread') {
543
+ if (selection.kind === "FragmentSpread") {
516
544
  const fragment = config.fragments[selection.name.value];
517
545
  if (!fragment) {
518
546
  throw new Error(`Unknown fragment ${selection.name.value}`);
@@ -525,23 +553,24 @@ const unionOrInterfaceSelection = (config: Context, type: any, possible: any, se
525
553
  ]) ||
526
554
  typeName === possible.name
527
555
  ) {
528
- return fragment.selectionSet.selections.flatMap((selection: SelectionNode) =>
529
- unionOrInterfaceSelection(
530
- config,
531
- config.schema.typesByName[possible.name],
532
- possible,
533
- selection,
534
- ),
556
+ return fragment.selectionSet.selections.flatMap(
557
+ (selection: SelectionNode) =>
558
+ unionOrInterfaceSelection(
559
+ config,
560
+ config.schema.typesByName[possible.name],
561
+ possible,
562
+ selection,
563
+ ),
535
564
  );
536
565
  } else {
537
566
  return [];
538
567
  }
539
568
  }
540
- if (selection.kind !== 'InlineFragment') {
569
+ if (selection.kind !== "InlineFragment") {
541
570
  config.errors.push(
542
571
  `union selectors must be inline fragment: found ${selection.kind}`,
543
572
  );
544
- if (type.kind === 'UNION') {
573
+ if (type.kind === "UNION") {
545
574
  config.errors
546
575
  .push(`You're trying to select a field from the union ${type.name},
547
576
  but the only field you're allowed to select is "__typename".
@@ -1,13 +1,15 @@
1
- import type {DocumentNode} from 'graphql';
2
- import type {GenerateConfig, CrawlConfig, Schema} from './types';
3
- import fs from 'fs';
4
- import path from 'path';
5
- import {documentToFlowTypes} from '.';
6
-
7
- export const indexPrelude = (regenerateCommand?: string): string => `// AUTOGENERATED
1
+ import type {DocumentNode} from "graphql";
2
+ import type {GenerateConfig, CrawlConfig, Schema} from "./types";
3
+ import fs from "fs";
4
+ import path from "path";
5
+ import {documentToFlowTypes} from ".";
6
+
7
+ export const indexPrelude = (
8
+ regenerateCommand?: string,
9
+ ): string => `// AUTOGENERATED
8
10
  // NOTE: New response types are added to this file automatically.
9
11
  // Outdated response types can be removed manually as they are deprecated.
10
- //${regenerateCommand ? ' To regenerate, run ' + regenerateCommand : ''}
12
+ //${regenerateCommand ? " To regenerate, run " + regenerateCommand : ""}
11
13
  //
12
14
 
13
15
  `;
@@ -20,10 +22,10 @@ export const generateTypeFileContents = (
20
22
  generatedDir: string,
21
23
  indexContents: string,
22
24
  ): {
23
- indexContents: string
25
+ indexContents: string;
24
26
  files: {
25
- [key: string]: string
26
- }
27
+ [key: string]: string;
28
+ };
27
29
  } => {
28
30
  const files: Record<string, any> = {};
29
31
 
@@ -31,7 +33,7 @@ export const generateTypeFileContents = (
31
33
  const addToIndex = (filePath: string, typeName: unknown) => {
32
34
  if (options.typeScript || options.omitFileExtensions) {
33
35
  // Typescript doesn't like file extensions
34
- filePath = filePath.replace(/\.ts$/, '');
36
+ filePath = filePath.replace(/\.ts$/, "");
35
37
  }
36
38
  const newLine = `export type {${typeName}} from './${path.basename(
37
39
  filePath,
@@ -39,7 +41,7 @@ export const generateTypeFileContents = (
39
41
  // We match the entire new line to avoid issues that can arise from
40
42
  // prefix matches.
41
43
  if (indexContents.indexOf(newLine) === -1) {
42
- indexContents += newLine + '\n';
44
+ indexContents += newLine + "\n";
43
45
  }
44
46
  };
45
47
 
@@ -49,7 +51,7 @@ export const generateTypeFileContents = (
49
51
  // We write all generated files to a `__generated__` subdir to keep
50
52
  // things tidy.
51
53
  const targetFileName = options.typeFileName
52
- ? options.typeFileName.replace('[operationName]', name)
54
+ ? options.typeFileName.replace("[operationName]", name)
53
55
  : `${name}.ts`;
54
56
  const targetPath = path.join(generatedDir, targetFileName);
55
57
 
@@ -60,7 +62,7 @@ export const generateTypeFileContents = (
60
62
  )}'\n` +
61
63
  (options.regenerateCommand
62
64
  ? `// To regenerate, run '${options.regenerateCommand}'.\n`
63
- : '') +
65
+ : "") +
64
66
  code;
65
67
  if (options.splitTypes && !isFragment) {
66
68
  fileContents +=
@@ -88,7 +90,7 @@ export const generateTypeFileContents = (
88
90
  fileContents
89
91
  // Remove whitespace from the ends of lines; babel's generate sometimes
90
92
  // leaves them hanging around.
91
- .replace(/\s+$/gm, '') + '\n';
93
+ .replace(/\s+$/gm, "") + "\n";
92
94
  },
93
95
  );
94
96
 
@@ -96,7 +98,7 @@ export const generateTypeFileContents = (
96
98
  };
97
99
 
98
100
  const getGeneratedDir = (fileName: string, options: GenerateConfig) => {
99
- const generatedDirectory = options.generatedDirectory ?? '__generated__';
101
+ const generatedDirectory = options.generatedDirectory ?? "__generated__";
100
102
  if (path.isAbsolute(generatedDirectory)) {
101
103
  // fileName is absolute here, so we make it relative to cwd
102
104
  // for more reasonable filenames. We convert leading ..'s
@@ -105,7 +107,7 @@ const getGeneratedDir = (fileName: string, options: GenerateConfig) => {
105
107
  generatedDirectory,
106
108
  path
107
109
  .relative(process.cwd(), path.dirname(fileName))
108
- .replace(/\.\.\//g, '__/'),
110
+ .replace(/\.\.\//g, "__/"),
109
111
  );
110
112
  } else {
111
113
  return path.join(path.dirname(fileName), generatedDirectory);
@@ -119,7 +121,7 @@ export const generateTypeFiles = (
119
121
  options: GenerateConfig,
120
122
  ) => {
121
123
  const generatedDir = getGeneratedDir(fileName, options);
122
- const indexFile = path.join(generatedDir, 'index.ts');
124
+ const indexFile = path.join(generatedDir, "index.ts");
123
125
 
124
126
  if (!fs.existsSync(generatedDir)) {
125
127
  fs.mkdirSync(generatedDir, {recursive: true});
@@ -134,7 +136,7 @@ export const generateTypeFiles = (
134
136
  document,
135
137
  options,
136
138
  generatedDir,
137
- fs.readFileSync(indexFile, 'utf8'),
139
+ fs.readFileSync(indexFile, "utf8"),
138
140
  );
139
141
 
140
142
  fs.writeFileSync(indexFile, indexContents);
@@ -150,8 +152,8 @@ export const processPragmas = (
150
152
  crawlConfig: CrawlConfig,
151
153
  rawSource: string,
152
154
  ): {
153
- generate: boolean
154
- strict?: boolean
155
+ generate: boolean;
156
+ strict?: boolean;
155
157
  } => {
156
158
  if (
157
159
  crawlConfig.ignorePragma &&