@khanacademy/graphql-flow 3.1.3 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # @khanacademy/graphql-flow
2
2
 
3
+ ## 3.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 96c201e: Add a noComments config option to exclude all comments in the output
8
+ - 7c01b6a: Add a --schema-file graphql argument, and allow exporting a function from the config.js file
9
+ - 96c201e: Add a `noComments` config option to exclude all comments
10
+
3
11
  ## 3.1.3
4
12
 
5
13
  ### Patch Changes
@@ -3,12 +3,15 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.validateOrThrow = exports.loadConfigFile = exports.getSchemas = exports.findApplicableConfig = void 0;
7
- var _schemaFromIntrospectionData = require("../schemaFromIntrospectionData");
6
+ exports.validateOrThrow = exports.parseCliOptions = exports.makeAbsPath = exports.loadConfigFile = exports.getSchemas = exports.getInputFiles = exports.findApplicableConfig = void 0;
8
7
  var _schema = _interopRequireDefault(require("../../schema.json"));
8
+ var _schemaFromIntrospectionData = require("../schemaFromIntrospectionData");
9
9
  var _fs = _interopRequireDefault(require("fs"));
10
10
  var _graphql = require("graphql");
11
11
  var _jsonschema = require("jsonschema");
12
+ var _minimist = _interopRequireDefault(require("minimist"));
13
+ var _child_process = require("child_process");
14
+ var _path = _interopRequireDefault(require("path"));
12
15
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
16
  const validateOrThrow = (value, jsonSchema) => {
14
17
  const result = (0, _jsonschema.validate)(value, jsonSchema);
@@ -17,16 +20,47 @@ const validateOrThrow = (value, jsonSchema) => {
17
20
  }
18
21
  };
19
22
  exports.validateOrThrow = validateOrThrow;
20
- const loadConfigFile = configFile => {
21
- const data = require(configFile);
23
+ const makeAbsPath = (maybeRelativePath, basePath) => {
24
+ return _path.default.isAbsolute(maybeRelativePath) ? maybeRelativePath : _path.default.join(basePath, maybeRelativePath);
25
+ };
26
+ exports.makeAbsPath = makeAbsPath;
27
+ const loadConfigFile = options => {
28
+ let data = require(options.configFilePath);
29
+ if (typeof data === "function") {
30
+ data = data(options);
31
+ } else {
32
+ if (options.schemaFile) {
33
+ if (Array.isArray(data.generate)) {
34
+ data.generate.forEach(item => {
35
+ item.schemaFilePath = options.schemaFile;
36
+ });
37
+ } else {
38
+ data.generate.schemaFilePath = options.schemaFile;
39
+ }
40
+ }
41
+ }
22
42
  validateOrThrow(data, _schema.default);
23
43
  return data;
24
44
  };
45
+ exports.loadConfigFile = loadConfigFile;
46
+ const findGraphqlTagReferences = root => {
47
+ // NOTE(john): We want to include untracked files here so that we can
48
+ // generate types for them. This is useful for when we have a new file
49
+ // that we want to generate types for, but we haven't committed it yet.
50
+ const response = (0, _child_process.execSync)("git grep -I --word-regexp --name-only --fixed-strings --untracked 'graphql-tag' -- '*.js' '*.jsx' '*.ts' '*.tsx'", {
51
+ encoding: "utf8",
52
+ cwd: root
53
+ });
54
+ return response.trim().split("\n").map(relative => _path.default.join(root, relative));
55
+ };
56
+ const getInputFiles = (options, config) => {
57
+ return options.cliFiles.length ? options.cliFiles : findGraphqlTagReferences(makeAbsPath(config.crawl.root, _path.default.dirname(options.configFilePath)));
58
+ };
25
59
 
26
60
  /**
27
61
  * Loads a .json 'introspection query response', or a .graphql schema definition.
28
62
  */
29
- exports.loadConfigFile = loadConfigFile;
63
+ exports.getInputFiles = getInputFiles;
30
64
  const getSchemas = schemaFilePath => {
31
65
  const raw = _fs.default.readFileSync(schemaFilePath, "utf8");
32
66
  if (schemaFilePath.endsWith(".graphql")) {
@@ -46,13 +80,30 @@ const getSchemas = schemaFilePath => {
46
80
  return [schemaForValidation, schemaForTypeGeneration];
47
81
  }
48
82
  };
83
+ exports.getSchemas = getSchemas;
84
+ const parseCliOptions = (argv, relativeBase) => {
85
+ const args = (0, _minimist.default)(argv);
86
+ let [configFilePath, ...cliFiles] = args._;
87
+ if (args.h || args.help || !configFilePath) {
88
+ return false;
89
+ }
90
+ configFilePath = makeAbsPath(configFilePath, relativeBase);
91
+ const options = {
92
+ configFilePath,
93
+ cliFiles
94
+ };
95
+ if (args["schema-file"]) {
96
+ options.schemaFile = args["schema-file"];
97
+ }
98
+ return options;
99
+ };
49
100
 
50
101
  /**
51
102
  * Find the first item of the `config.generate` array where both:
52
103
  * - no item of `exclude` matches
53
104
  * - at least one item of `match` matches
54
105
  */
55
- exports.getSchemas = getSchemas;
106
+ exports.parseCliOptions = parseCliOptions;
56
107
  const findApplicableConfig = (path, configs) => {
57
108
  if (!Array.isArray(configs)) {
58
109
  configs = [configs];
package/dist/cli/run.js CHANGED
@@ -8,7 +8,6 @@ var _resolve = require("../parser/resolve");
8
8
  var _utils = require("../parser/utils");
9
9
  var _config = require("./config");
10
10
  var _apolloUtilities = require("apollo-utilities");
11
- var _child_process = require("child_process");
12
11
  var _fs = require("fs");
13
12
  var _printer = require("graphql/language/printer");
14
13
  var _validation = require("graphql/validation");
@@ -26,29 +25,17 @@ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e;
26
25
  * 4) generate types for all resolved Queries & Mutations
27
26
  */
28
27
  /** Step (1) */
29
- const findGraphqlTagReferences = root => {
30
- // NOTE(john): We want to include untracked files here so that we can
31
- // generate types for them. This is useful for when we have a new file
32
- // that we want to generate types for, but we haven't committed it yet.
33
- const response = (0, _child_process.execSync)("git grep -I --word-regexp --name-only --fixed-strings --untracked 'graphql-tag' -- '*.js' '*.jsx' '*.ts' '*.tsx'", {
34
- encoding: "utf8",
35
- cwd: root
36
- });
37
- return response.trim().split("\n").map(relative => _path.default.join(root, relative));
38
- };
39
- const [_, __, configFilePath, ...cliFiles] = process.argv;
40
- if (configFilePath === "-h" || configFilePath === "--help" || configFilePath === "help" || !configFilePath) {
28
+ const options = (0, _config.parseCliOptions)(process.argv.slice(2), process.cwd());
29
+ if (options === false) {
41
30
  console.log(`graphql-flow
42
31
 
43
- Usage: graphql-flow [configFile.json] [filesToCrawl...]`);
32
+ Usage: graphql-flow [configFile.json] [filesToCrawl...]
33
+ Options:
34
+ --schema-file: provide a schema file to override the one defined in config`);
44
35
  process.exit(1);
45
36
  }
46
- const makeAbsPath = (maybeRelativePath, basePath) => {
47
- return _path.default.isAbsolute(maybeRelativePath) ? maybeRelativePath : _path.default.join(basePath, maybeRelativePath);
48
- };
49
- const absConfigPath = makeAbsPath(configFilePath, process.cwd());
50
- const config = (0, _config.loadConfigFile)(absConfigPath);
51
- const inputFiles = cliFiles.length ? cliFiles : findGraphqlTagReferences(makeAbsPath(config.crawl.root, _path.default.dirname(absConfigPath)));
37
+ const config = (0, _config.loadConfigFile)(options);
38
+ const inputFiles = (0, _config.getInputFiles)(options, config);
52
39
 
53
40
  /** Step (2) */
54
41
 
@@ -101,7 +88,7 @@ console.log(Object.keys(resolved).length, "resolved queries");
101
88
  const schemaCache = {};
102
89
  const getCachedSchemas = schemaFilePath => {
103
90
  if (!schemaCache[schemaFilePath]) {
104
- schemaCache[schemaFilePath] = (0, _config.getSchemas)(makeAbsPath(schemaFilePath, _path.default.dirname(absConfigPath)));
91
+ schemaCache[schemaFilePath] = (0, _config.getSchemas)((0, _config.makeAbsPath)(schemaFilePath, _path.default.dirname(options.configFilePath)));
105
92
  }
106
93
  return schemaCache[schemaFilePath];
107
94
  };
package/dist/enums.js CHANGED
@@ -19,7 +19,7 @@ const experimentalEnumTypeToFlow = (ctx, enumConfig, description) => {
19
19
  if (ctx.experimentalEnumsMap) {
20
20
  ctx.experimentalEnumsMap[enumConfig.name] = enumDeclaration;
21
21
  }
22
- return (0, _utils.maybeAddDescriptionComment)(description, babelTypes.tsTypeReference(enumDeclaration.id));
22
+ return (0, _utils.maybeAddDescriptionComment)(ctx.noComments ? null : description, babelTypes.tsTypeReference(enumDeclaration.id));
23
23
  };
24
24
  exports.experimentalEnumTypeToFlow = experimentalEnumTypeToFlow;
25
25
  const enumTypeToFlow = (ctx, name) => {
@@ -28,7 +28,7 @@ const enumTypeToFlow = (ctx, name) => {
28
28
  if (enumConfig.description) {
29
29
  combinedDescription = enumConfig.description + "\n\n" + combinedDescription;
30
30
  }
31
- return ctx.experimentalEnumsMap ? experimentalEnumTypeToFlow(ctx, enumConfig, combinedDescription) : (0, _utils.maybeAddDescriptionComment)(combinedDescription, babelTypes.tsUnionType(enumConfig.enumValues.map(n => babelTypes.tsLiteralType(babelTypes.stringLiteral(n.name)))));
31
+ return ctx.experimentalEnumsMap ? experimentalEnumTypeToFlow(ctx, enumConfig, combinedDescription) : (0, _utils.maybeAddDescriptionComment)(ctx.noComments ? null : combinedDescription, babelTypes.tsUnionType(enumConfig.enumValues.map(n => babelTypes.tsLiteralType(babelTypes.stringLiteral(n.name)))));
32
32
  };
33
33
  exports.enumTypeToFlow = enumTypeToFlow;
34
34
  const builtinScalars = exports.builtinScalars = {
@@ -15,7 +15,9 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
15
15
 
16
16
  const generateResponseType = (schema, query, ctx) => {
17
17
  const ast = querySelectionToObjectType(ctx, query.selectionSet.selections, query.operation === "mutation" ? schema.typesByName.Mutation : schema.typesByName.Query, query.operation === "mutation" ? "mutation" : "query");
18
- return (0, _generator.default)(ast).code;
18
+ return (0, _generator.default)(ast, {
19
+ comments: ctx.noComments ? false : true
20
+ }).code;
19
21
  };
20
22
  exports.generateResponseType = generateResponseType;
21
23
  const sortedObjectTypeAnnotation = (ctx, properties) => {
@@ -48,7 +50,9 @@ const generateFragmentType = (schema, fragment, ctx) => {
48
50
  } else {
49
51
  throw new Error(`Unknown ${onType}`);
50
52
  }
51
- return (0, _generator.default)(ast).code;
53
+ return (0, _generator.default)(ast, {
54
+ comments: ctx.noComments ? false : true
55
+ }).code;
52
56
  };
53
57
  exports.generateFragmentType = generateFragmentType;
54
58
  const _typeToFlow = (ctx, type, selection) => {
@@ -82,6 +82,8 @@ const generateVariablesType = (schema, item, ctx) => {
82
82
  const variableObject = (0, _utils.objectTypeFromProperties)((item.variableDefinitions || []).map(vbl => {
83
83
  return maybeOptionalObjectTypeProperty(vbl.variable.name.value, variableToFlow(ctx, vbl.type));
84
84
  }));
85
- return (0, _generator.default)(variableObject).code;
85
+ return (0, _generator.default)(variableObject, {
86
+ comments: ctx.noComments ? false : true
87
+ }).code;
86
88
  };
87
89
  exports.generateVariablesType = generateVariablesType;
package/dist/index.js CHANGED
@@ -25,7 +25,8 @@ const optionsToConfig = (schema, definitions, options, errors = []) => {
25
25
  readOnlyArray: (_options$readOnlyArra = options === null || options === void 0 ? void 0 : options.readOnlyArray) !== null && _options$readOnlyArra !== void 0 ? _options$readOnlyArra : true,
26
26
  scalars: (_options$scalars = options === null || options === void 0 ? void 0 : options.scalars) !== null && _options$scalars !== void 0 ? _options$scalars : {},
27
27
  typeScript: (_options$typeScript = options === null || options === void 0 ? void 0 : options.typeScript) !== null && _options$typeScript !== void 0 ? _options$typeScript : false,
28
- omitFileExtensions: (_options$omitFileExte = options === null || options === void 0 ? void 0 : options.omitFileExtensions) !== null && _options$omitFileExte !== void 0 ? _options$omitFileExte : false
28
+ omitFileExtensions: (_options$omitFileExte = options === null || options === void 0 ? void 0 : options.omitFileExtensions) !== null && _options$omitFileExte !== void 0 ? _options$omitFileExte : false,
29
+ noComments: options === null || options === void 0 ? void 0 : options.noComments
29
30
  };
30
31
  const fragments = {};
31
32
  definitions.forEach(def => {
@@ -66,8 +67,8 @@ const documentToFlowTypes = (document, schema, options) => {
66
67
  path: [name],
67
68
  allObjectTypes: options !== null && options !== void 0 && options.exportAllObjectTypes ? types : null
68
69
  })};`;
69
- const extraTypes = codegenExtraTypes(types);
70
- const experimentalEnums = codegenExtraTypes(config.experimentalEnumsMap || {});
70
+ const extraTypes = codegenExtraTypes(types, config);
71
+ const experimentalEnums = codegenExtraTypes(config.experimentalEnumsMap || {}, config);
71
72
  return {
72
73
  name,
73
74
  typeName: name,
@@ -93,8 +94,8 @@ const documentToFlowTypes = (document, schema, options) => {
93
94
  // TODO(jared): Maybe make this template configurable?
94
95
  // We'll see what's required to get webapp on board.
95
96
  const code = `export type ${typeName} = {\n variables: ${variables},\n response: ${response}\n};`;
96
- const extraTypes = codegenExtraTypes(types);
97
- const experimentalEnums = codegenExtraTypes(config.experimentalEnumsMap || {});
97
+ const extraTypes = codegenExtraTypes(types, config);
98
+ const experimentalEnums = codegenExtraTypes(config.experimentalEnumsMap || {}, config);
98
99
  return {
99
100
  name,
100
101
  typeName,
@@ -110,10 +111,12 @@ const documentToFlowTypes = (document, schema, options) => {
110
111
  return result;
111
112
  };
112
113
  exports.documentToFlowTypes = documentToFlowTypes;
113
- function codegenExtraTypes(types) {
114
+ function codegenExtraTypes(types, ctx) {
114
115
  const extraTypes = {};
115
116
  Object.keys(types).forEach(k => {
116
- extraTypes[k] = (0, _generator.default)(types[k]).code;
117
+ extraTypes[k] = (0, _generator.default)(types[k], {
118
+ comments: ctx.noComments ? false : true
119
+ }).code;
117
120
  });
118
121
  return extraTypes;
119
122
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@khanacademy/graphql-flow",
3
- "version": "3.1.3",
3
+ "version": "3.2.0",
4
4
  "bin": {
5
5
  "graphql-flow": "./dist/cli/run.js"
6
6
  },
@@ -48,6 +48,7 @@
48
48
  "@khanacademy/wonder-stuff-core": "^1.5.1",
49
49
  "apollo-utilities": "^1.3.4",
50
50
  "graphql": "^16.9.0",
51
- "jsonschema": "^1.4.1"
51
+ "jsonschema": "^1.4.1",
52
+ "minimist": "^1.2.8"
52
53
  }
53
54
  }
package/schema.json CHANGED
@@ -40,6 +40,9 @@
40
40
  "regenerateCommand": {
41
41
  "type": "string"
42
42
  },
43
+ "noComments": {
44
+ "type": "boolean"
45
+ },
43
46
  "readOnlyArray": {
44
47
  "type": "boolean"
45
48
  },
@@ -589,5 +589,36 @@ describe("graphql-flow generation", () => {
589
589
  };
590
590
  `);
591
591
  });
592
+
593
+ it("should strip comments", () => {
594
+ const result = rawQueryToFlowTypes(
595
+ `mutation addCharacter($character: CharacterInput!) {
596
+ addCharacter(character: $character) {
597
+ id
598
+ }
599
+ }`,
600
+ {readOnlyArray: false, noComments: true},
601
+ );
602
+
603
+ expect(result).toMatchInlineSnapshot(`
604
+ // addCharacterType.js
605
+ export type addCharacterType = {
606
+ variables: {
607
+ character: {
608
+ name: string;
609
+ friends?: ReadonlyArray<string> | null | undefined;
610
+ appearsIn?: ReadonlyArray<"NEW_HOPE" | "EMPIRE" | "JEDI"> | null | undefined;
611
+ candies: number;
612
+ friendly?: boolean | null | undefined;
613
+ };
614
+ },
615
+ response: {
616
+ addCharacter: {
617
+ id: string;
618
+ } | null | undefined;
619
+ }
620
+ };
621
+ `);
622
+ });
592
623
  });
593
624
  });
@@ -1,9 +1,48 @@
1
1
  import {describe, it, expect} from "@jest/globals";
2
2
 
3
3
  import type {Config} from "../../types";
4
- import {findApplicableConfig, validateOrThrow} from "../config";
4
+ import {
5
+ findApplicableConfig,
6
+ parseCliOptions,
7
+ validateOrThrow,
8
+ } from "../config";
5
9
  import configSchema from "../../../schema.json";
6
10
 
11
+ describe("parseCliOptions", () => {
12
+ it("should handle basic invocation", () => {
13
+ expect(parseCliOptions(["config.json"], "./")).toEqual({
14
+ configFilePath: "config.json",
15
+ cliFiles: [],
16
+ });
17
+ });
18
+
19
+ it("should handle cli files", () => {
20
+ expect(
21
+ parseCliOptions(["config.json", "one.js", "two.ts"], "./"),
22
+ ).toEqual({
23
+ configFilePath: "config.json",
24
+ cliFiles: ["one.js", "two.ts"],
25
+ });
26
+ });
27
+
28
+ it("should handle -h", () => {
29
+ expect(
30
+ parseCliOptions(["config.json", "-h", "one.js", "two.ts"], "./"),
31
+ ).toEqual(false);
32
+ expect(parseCliOptions([], "./")).toEqual(false);
33
+ });
34
+
35
+ it("should pick up schema-file", () => {
36
+ expect(
37
+ parseCliOptions(["config.json", "--schema-file=some.schema"], "./"),
38
+ ).toEqual({
39
+ configFilePath: "config.json",
40
+ cliFiles: [],
41
+ schemaFile: "some.schema",
42
+ });
43
+ });
44
+ });
45
+
7
46
  describe("findApplicableConfig", () => {
8
47
  it("should work with one that matches", () => {
9
48
  const config = {
package/src/cli/config.ts CHANGED
@@ -1,8 +1,8 @@
1
- import type {Schema} from "../types";
2
1
  import type {GraphQLSchema} from "graphql/type/schema";
2
+ import type {CliOptions, Schema} from "../types";
3
3
 
4
- import {schemaFromIntrospectionData} from "../schemaFromIntrospectionData";
5
4
  import configSchema from "../../schema.json";
5
+ import {schemaFromIntrospectionData} from "../schemaFromIntrospectionData";
6
6
 
7
7
  import fs from "fs";
8
8
  import {
@@ -12,8 +12,11 @@ import {
12
12
  graphqlSync,
13
13
  IntrospectionQuery,
14
14
  } from "graphql";
15
- import type {Config, GenerateConfig} from "../types";
16
15
  import {validate} from "jsonschema";
16
+ import processArgs from "minimist";
17
+ import type {Config, GenerateConfig} from "../types";
18
+ import {execSync} from "child_process";
19
+ import path from "path";
17
20
 
18
21
  export const validateOrThrow = (value: unknown, jsonSchema: unknown) => {
19
22
  const result = validate(value, jsonSchema);
@@ -24,12 +27,61 @@ export const validateOrThrow = (value: unknown, jsonSchema: unknown) => {
24
27
  }
25
28
  };
26
29
 
27
- export const loadConfigFile = (configFile: string): Config => {
28
- const data: Config = require(configFile);
30
+ export const makeAbsPath = (maybeRelativePath: string, basePath: string) => {
31
+ return path.isAbsolute(maybeRelativePath)
32
+ ? maybeRelativePath
33
+ : path.join(basePath, maybeRelativePath);
34
+ };
35
+
36
+ export const loadConfigFile = (options: CliOptions): Config => {
37
+ let data:
38
+ | Config
39
+ | ((c: CliOptions) => Config) = require(options.configFilePath);
40
+ if (typeof data === "function") {
41
+ data = data(options);
42
+ } else {
43
+ if (options.schemaFile) {
44
+ if (Array.isArray(data.generate)) {
45
+ data.generate.forEach((item) => {
46
+ item.schemaFilePath = options.schemaFile!;
47
+ });
48
+ } else {
49
+ data.generate.schemaFilePath = options.schemaFile;
50
+ }
51
+ }
52
+ }
29
53
  validateOrThrow(data, configSchema);
30
54
  return data;
31
55
  };
32
56
 
57
+ const findGraphqlTagReferences = (root: string): Array<string> => {
58
+ // NOTE(john): We want to include untracked files here so that we can
59
+ // generate types for them. This is useful for when we have a new file
60
+ // that we want to generate types for, but we haven't committed it yet.
61
+ const response = execSync(
62
+ "git grep -I --word-regexp --name-only --fixed-strings --untracked 'graphql-tag' -- '*.js' '*.jsx' '*.ts' '*.tsx'",
63
+ {
64
+ encoding: "utf8",
65
+ cwd: root,
66
+ },
67
+ );
68
+ return response
69
+ .trim()
70
+ .split("\n")
71
+ .map((relative) => path.join(root, relative));
72
+ };
73
+
74
+ export const getInputFiles = (options: CliOptions, config: Config) => {
75
+ return options.cliFiles.length
76
+ ? options.cliFiles
77
+ : findGraphqlTagReferences(
78
+ makeAbsPath(
79
+ config.crawl.root,
80
+ path.dirname(options.configFilePath),
81
+ ),
82
+ );
83
+ };
84
+
33
85
  /**
34
86
  * Loads a .json 'introspection query response', or a .graphql schema definition.
35
87
  */
@@ -54,6 +106,28 @@ export const getSchemas = (schemaFilePath: string): [GraphQLSchema, Schema] => {
54
106
  }
55
107
  };
56
108
 
109
+ export const parseCliOptions = (
110
+ argv: string[],
111
+ relativeBase: string,
112
+ ): CliOptions | false => {
113
+ const args = processArgs(argv);
114
+ let [configFilePath, ...cliFiles] = args._;
115
+
116
+ if (args.h || args.help || !configFilePath) {
117
+ return false;
118
+ }
119
+
120
+ configFilePath = makeAbsPath(configFilePath, relativeBase);
121
+
122
+ const options: CliOptions = {configFilePath, cliFiles};
123
+
124
+ if (args["schema-file"]) {
125
+ options.schemaFile = args["schema-file"];
126
+ }
127
+
128
+ return options;
129
+ };
130
+
57
131
  /**
58
132
  * Find the first item of the `config.generate` array where both:
59
133
  * - no item of `exclude` matches
package/src/cli/run.ts CHANGED
@@ -7,7 +7,14 @@ import {generateTypeFiles, processPragmas} from "../generateTypeFiles";
7
7
  import {processFiles} from "../parser/parse";
8
8
  import {resolveDocuments} from "../parser/resolve";
9
9
  import {getPathWithExtension} from "../parser/utils";
10
- import {findApplicableConfig, getSchemas, loadConfigFile} from "./config";
10
+ import {
11
+ findApplicableConfig,
12
+ getInputFiles,
13
+ getSchemas,
14
+ loadConfigFile,
15
+ makeAbsPath,
16
+ parseCliOptions,
17
+ } from "./config";
11
18
 
12
19
  import {addTypenameToDocument} from "apollo-utilities";
13
20
 
@@ -32,52 +39,19 @@ import {dirname} from "path";
32
39
 
33
40
  /** Step (1) */
34
41
 
35
- const findGraphqlTagReferences = (root: string): Array<string> => {
36
- // NOTE(john): We want to include untracked files here so that we can
37
- // generate types for them. This is useful for when we have a new file
38
- // that we want to generate types for, but we haven't committed it yet.
39
- const response = execSync(
40
- "git grep -I --word-regexp --name-only --fixed-strings --untracked 'graphql-tag' -- '*.js' '*.jsx' '*.ts' '*.tsx'",
41
- {
42
- encoding: "utf8",
43
- cwd: root,
44
- },
45
- );
46
- return response
47
- .trim()
48
- .split("\n")
49
- .map((relative) => path.join(root, relative));
50
- };
42
+ const options = parseCliOptions(process.argv.slice(2), process.cwd());
51
43
 
52
- const [_, __, configFilePath, ...cliFiles] = process.argv;
53
-
54
- if (
55
- configFilePath === "-h" ||
56
- configFilePath === "--help" ||
57
- configFilePath === "help" ||
58
- !configFilePath
59
- ) {
44
+ if (options === false) {
60
45
  console.log(`graphql-flow
61
46
 
62
- Usage: graphql-flow [configFile.json] [filesToCrawl...]`);
47
+ Usage: graphql-flow [configFile.json] [filesToCrawl...]
48
+ Options:
49
+ --schema-file: provide a schema file to override the one defined in config`);
63
50
  process.exit(1);
64
51
  }
65
52
 
66
- const makeAbsPath = (maybeRelativePath: string, basePath: string) => {
67
- return path.isAbsolute(maybeRelativePath)
68
- ? maybeRelativePath
69
- : path.join(basePath, maybeRelativePath);
70
- };
71
-
72
- const absConfigPath = makeAbsPath(configFilePath, process.cwd());
73
-
74
- const config = loadConfigFile(absConfigPath);
75
-
76
- const inputFiles = cliFiles.length
77
- ? cliFiles
78
- : findGraphqlTagReferences(
79
- makeAbsPath(config.crawl.root, path.dirname(absConfigPath)),
80
- );
53
+ const config = loadConfigFile(options);
54
+ const inputFiles = getInputFiles(options, config);
81
55
 
82
56
  /** Step (2) */
83
57
 
@@ -130,7 +104,7 @@ const schemaCache: {
130
104
  const getCachedSchemas = (schemaFilePath: string) => {
131
105
  if (!schemaCache[schemaFilePath]) {
132
106
  schemaCache[schemaFilePath] = getSchemas(
133
- makeAbsPath(schemaFilePath, path.dirname(absConfigPath)),
107
+ makeAbsPath(schemaFilePath, path.dirname(options.configFilePath)),
134
108
  );
135
109
  }
136
110
 
package/src/enums.ts CHANGED
@@ -28,7 +28,7 @@ export const experimentalEnumTypeToFlow = (
28
28
  }
29
29
 
30
30
  return maybeAddDescriptionComment(
31
- description,
31
+ ctx.noComments ? null : description,
32
32
  babelTypes.tsTypeReference(enumDeclaration.id),
33
33
  );
34
34
  };
@@ -52,7 +52,7 @@ export const enumTypeToFlow = (ctx: Context, name: string): TSType => {
52
52
  return ctx.experimentalEnumsMap
53
53
  ? experimentalEnumTypeToFlow(ctx, enumConfig, combinedDescription)
54
54
  : maybeAddDescriptionComment(
55
- combinedDescription,
55
+ ctx.noComments ? null : combinedDescription,
56
56
  babelTypes.tsUnionType(
57
57
  enumConfig.enumValues.map((n) =>
58
58
  babelTypes.tsLiteralType(
@@ -39,7 +39,7 @@ export const generateResponseType = (
39
39
  query.operation === "mutation" ? "mutation" : "query",
40
40
  );
41
41
 
42
- return generate(ast as any).code;
42
+ return generate(ast as any, {comments: ctx.noComments ? false : true}).code;
43
43
  };
44
44
 
45
45
  const sortedObjectTypeAnnotation = (
@@ -103,7 +103,7 @@ export const generateFragmentType = (
103
103
  throw new Error(`Unknown ${onType}`);
104
104
  }
105
105
 
106
- return generate(ast as any).code;
106
+ return generate(ast as any, {comments: ctx.noComments ? false : true}).code;
107
107
  };
108
108
 
109
109
  const _typeToFlow = (
@@ -144,5 +144,7 @@ export const generateVariablesType = (
144
144
  );
145
145
  }),
146
146
  );
147
- return generate(variableObject as any).code;
147
+ return generate(variableObject as any, {
148
+ comments: ctx.noComments ? false : true,
149
+ }).code;
148
150
  };
package/src/index.ts CHANGED
@@ -31,6 +31,7 @@ const optionsToConfig = (
31
31
  scalars: options?.scalars ?? {},
32
32
  typeScript: options?.typeScript ?? false,
33
33
  omitFileExtensions: options?.omitFileExtensions ?? false,
34
+ noComments: options?.noComments,
34
35
  } as const;
35
36
  const fragments: Record<string, any> = {};
36
37
  definitions.forEach((def) => {
@@ -101,9 +102,10 @@ export const documentToFlowTypes = (
101
102
  },
102
103
  )};`;
103
104
 
104
- const extraTypes = codegenExtraTypes(types);
105
+ const extraTypes = codegenExtraTypes(types, config);
105
106
  const experimentalEnums = codegenExtraTypes(
106
107
  config.experimentalEnumsMap || {},
108
+ config,
107
109
  );
108
110
 
109
111
  return {
@@ -139,9 +141,10 @@ export const documentToFlowTypes = (
139
141
  // We'll see what's required to get webapp on board.
140
142
  const code = `export type ${typeName} = {\n variables: ${variables},\n response: ${response}\n};`;
141
143
 
142
- const extraTypes = codegenExtraTypes(types);
144
+ const extraTypes = codegenExtraTypes(types, config);
143
145
  const experimentalEnums = codegenExtraTypes(
144
146
  config.experimentalEnumsMap || {},
147
+ config,
145
148
  );
146
149
 
147
150
  return {name, typeName, code, extraTypes, experimentalEnums};
@@ -154,14 +157,19 @@ export const documentToFlowTypes = (
154
157
  return result;
155
158
  };
156
159
 
157
- function codegenExtraTypes(types: {[key: string]: Node}): {
160
+ function codegenExtraTypes(
161
+ types: {[key: string]: Node},
162
+ ctx: Context,
163
+ ): {
158
164
  [key: string]: string;
159
165
  } {
160
166
  const extraTypes: {
161
167
  [key: string]: string;
162
168
  } = {};
163
169
  Object.keys(types).forEach((k: string) => {
164
- extraTypes[k] = generate(types[k] as any).code;
170
+ extraTypes[k] = generate(types[k] as any, {
171
+ comments: ctx.noComments ? false : true,
172
+ }).code;
165
173
  });
166
174
  return extraTypes;
167
175
  }
package/src/types.ts CHANGED
@@ -10,6 +10,12 @@ import type {
10
10
  SelectionNode,
11
11
  } from "graphql";
12
12
 
13
+ export type CliOptions = {
14
+ schemaFile?: string;
15
+ configFilePath: string;
16
+ cliFiles: string[];
17
+ };
18
+
13
19
  export type Selections = ReadonlyArray<SelectionNode>;
14
20
 
15
21
  export type GenerateConfig = {
@@ -18,6 +24,7 @@ export type GenerateConfig = {
18
24
  exclude?: ReadonlyArray<RegExp | string>;
19
25
  typeScript?: boolean;
20
26
  scalars?: Scalars;
27
+ noComments?: boolean;
21
28
  strictNullability?: boolean;
22
29
  /**
23
30
  * The command that users should run to regenerate the types files.
@@ -81,6 +88,7 @@ export type Schema = {
81
88
  export type Context = {
82
89
  path: Array<string>;
83
90
  strictNullability: boolean;
91
+ noComments: boolean;
84
92
  readOnlyArray: boolean;
85
93
  fragments: {
86
94
  [key: string]: FragmentDefinitionNode;