@khanacademy/graphql-flow 0.2.5 → 0.3.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/.flowconfig +1 -0
- package/.github/workflows/changeset-release.yml +1 -1
- package/.github/workflows/pr-checks.yml +15 -10
- package/CHANGELOG.md +7 -0
- package/Readme.md +25 -0
- package/dist/cli/config.js +100 -14
- package/dist/cli/config.js.flow +119 -24
- package/dist/cli/config.js.map +1 -1
- package/dist/cli/run.js +21 -3
- package/dist/cli/run.js.flow +25 -3
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/utils.js +21 -0
- package/dist/cli/utils.js.flow +14 -0
- package/dist/cli/utils.js.map +1 -0
- package/dist/enums.js +15 -2
- package/dist/enums.js.flow +38 -9
- package/dist/enums.js.map +1 -1
- package/dist/generateTypeFiles.js +15 -5
- package/dist/generateTypeFiles.js.flow +50 -34
- package/dist/generateTypeFiles.js.map +1 -1
- package/dist/index.js +18 -12
- package/dist/index.js.flow +27 -11
- package/dist/index.js.map +1 -1
- package/dist/types.js.flow +3 -0
- package/flow-typed/npm/@babel/types_vx.x.x.js +17 -3
- package/package.json +1 -1
- package/src/__test__/generateTypeFileContents.test.js +52 -0
- package/src/cli/__test__/config.test.js +94 -0
- package/src/cli/__test__/utils.test.js +19 -0
- package/src/cli/config.js +119 -24
- package/src/cli/run.js +25 -3
- package/src/cli/utils.js +14 -0
- package/src/enums.js +38 -9
- package/src/generateTypeFiles.js +50 -34
- package/src/index.js +27 -11
- package/src/types.js +3 -0
- package/.github/actions/filter-files/action.yml +0 -37
- package/.github/actions/full-or-limited/action.yml +0 -27
- package/.github/actions/json-args/action.yml +0 -32
- package/.github/actions/setup/action.yml +0 -28
package/.flowconfig
CHANGED
|
@@ -17,16 +17,21 @@ jobs:
|
|
|
17
17
|
node-version: [16.x]
|
|
18
18
|
steps:
|
|
19
19
|
- uses: actions/checkout@v2
|
|
20
|
-
- uses:
|
|
21
|
-
id: setup
|
|
20
|
+
- uses: Khan/actions@shared-node-cache-v0
|
|
22
21
|
with:
|
|
23
22
|
node-version: ${{ matrix.node-version }}
|
|
24
23
|
|
|
24
|
+
- name: Get All Changed Files
|
|
25
|
+
uses: jaredly/get-changed-files@absolute
|
|
26
|
+
id: changed
|
|
27
|
+
with:
|
|
28
|
+
format: 'json'
|
|
29
|
+
|
|
25
30
|
- id: js-files
|
|
26
31
|
name: Find .js changed files
|
|
27
|
-
uses:
|
|
32
|
+
uses: Khan/actions@filter-files-v0
|
|
28
33
|
with:
|
|
29
|
-
changed-files: ${{ steps.
|
|
34
|
+
changed-files: ${{ steps.changed.outputs.added_modified }}
|
|
30
35
|
extensions: '.js'
|
|
31
36
|
|
|
32
37
|
- name: Run Flow
|
|
@@ -34,14 +39,14 @@ jobs:
|
|
|
34
39
|
run: yarn flow
|
|
35
40
|
|
|
36
41
|
- id: eslint-reset
|
|
37
|
-
uses:
|
|
42
|
+
uses: Khan/actions@filter-files-v0
|
|
38
43
|
name: Files that would trigger a full eslint run
|
|
39
44
|
with:
|
|
40
|
-
changed-files: ${{ steps.
|
|
45
|
+
changed-files: ${{ steps.changed.outputs.added_modified }}
|
|
41
46
|
files: '.eslintrc.js,package.json,.eslintignore'
|
|
42
47
|
|
|
43
48
|
- name: Eslint
|
|
44
|
-
uses:
|
|
49
|
+
uses: Khan/actions@full-or-limited-v0
|
|
45
50
|
with:
|
|
46
51
|
full-trigger: ${{ steps.eslint-reset.outputs.filtered }}
|
|
47
52
|
full: yarn eslint
|
|
@@ -49,14 +54,14 @@ jobs:
|
|
|
49
54
|
limited: yarn eslint {}
|
|
50
55
|
|
|
51
56
|
- id: jest-reset
|
|
52
|
-
uses:
|
|
57
|
+
uses: Khan/actions@filter-files-v0
|
|
53
58
|
name: Files that would trigger a full jest run
|
|
54
59
|
with:
|
|
55
|
-
changed-files: ${{ steps.
|
|
60
|
+
changed-files: ${{ steps.changed.outputs.added_modified }}
|
|
56
61
|
files: 'package.json,package-lock.json'
|
|
57
62
|
|
|
58
63
|
- name: Jest
|
|
59
|
-
uses:
|
|
64
|
+
uses: Khan/actions@full-or-limited-v0
|
|
60
65
|
with:
|
|
61
66
|
full-trigger: ${{ steps.jest-reset.outputs.filtered }}
|
|
62
67
|
full: yarn jest
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# @khanacademy/graphql-flow
|
|
2
2
|
|
|
3
|
+
## 0.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 093fa5f: Enable `experimentalEnums` in a config or subconfig file in to enable the export of flow enum types, which replace the default string union literals. The type currently comes with eslint decorators to skirt a bug in eslint and flow.
|
|
8
|
+
- 5078624: Users can add files with the name ending in `graphql-flow.config.js` with a subset of the config fields (`options`, `excludes`) in order to have more granular control of the behavior. Another field, `extends`, takes the path of another config file to use as a base and extends/overrides fields. If no `extends` is provided, the file completely overwrites any other config files (as far as `options` and `excludes`).
|
|
9
|
+
|
|
3
10
|
## 0.2.5
|
|
4
11
|
|
|
5
12
|
### Patch Changes
|
package/Readme.md
CHANGED
|
@@ -23,6 +23,26 @@ Write a config file, with the following options:
|
|
|
23
23
|
}
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
+
Optionally add subconfig files to subdirectories for granular control of behavior, with the following options:
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
// Note that this file must be named, or end with, "graphql-flow.config.json"
|
|
31
|
+
// I.e., "my-service.graphql.config.json" would also work.
|
|
32
|
+
// These files will affect the directory in which they are located and all subdirectories, unless overridden by a deeper subconfig.
|
|
33
|
+
|
|
34
|
+
// Optionally add the path of another config file. Can be the root config (provided when running the script) or any other subconfig to merge options.
|
|
35
|
+
// If a chain of extends are provided, will resolve in order. Be sure not to extend in a circle-- currently, this will just cause a stack overflow error.
|
|
36
|
+
// Cannot currently override `schemaFilePath`.
|
|
37
|
+
"extends": "./another/config/from/root.config.json",
|
|
38
|
+
// Can extend or override `excludes` and `options`.
|
|
39
|
+
"excludes": ["\\bsome-thing", "_test.jsx?$"],
|
|
40
|
+
"options": {
|
|
41
|
+
...
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
26
46
|
Then run from the CLI, like so:
|
|
27
47
|
|
|
28
48
|
```bash
|
|
@@ -84,6 +104,11 @@ type Options = {
|
|
|
84
104
|
// A template for the name of generated files
|
|
85
105
|
// default: [operationName].js
|
|
86
106
|
typeFileName?: string,
|
|
107
|
+
|
|
108
|
+
// Generate flow enums to replace literal unions in generated types. Exports
|
|
109
|
+
// each set of enums from each file regardless of other options. Designated
|
|
110
|
+
// "experimental" because of bug in eslint that requires config comments.
|
|
111
|
+
experimentalEnums?: boolean,
|
|
87
112
|
}
|
|
88
113
|
```
|
|
89
114
|
|
package/dist/cli/config.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.loadConfigFile = exports.getSchemas = void 0;
|
|
6
|
+
exports.loadSubConfigFile = exports.loadDirConfigFiles = exports.loadConfigFile = exports.getSchemas = void 0;
|
|
7
7
|
|
|
8
8
|
var _schemaFromIntrospectionData = require("../schemaFromIntrospectionData");
|
|
9
9
|
|
|
@@ -16,7 +16,7 @@ var _path = _interopRequireDefault(require("path"));
|
|
|
16
16
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
17
17
|
|
|
18
18
|
const loadConfigFile = configFile => {
|
|
19
|
-
var _data$options, _data$excludes$map, _data$excludes;
|
|
19
|
+
var _data$options, _data$options2, _data$excludes$map, _data$excludes;
|
|
20
20
|
|
|
21
21
|
// eslint-disable-next-line flowtype-errors/uncovered
|
|
22
22
|
const data = JSON.parse(_fs.default.readFileSync(configFile, 'utf8'));
|
|
@@ -26,30 +26,105 @@ const loadConfigFile = configFile => {
|
|
|
26
26
|
throw new Error(`Invalid attribute in config file ${configFile}: ${k}. Allowed attributes: ${toplevelKeys.join(', ')}`);
|
|
27
27
|
}
|
|
28
28
|
});
|
|
29
|
-
|
|
30
|
-
if (data.options) {
|
|
31
|
-
const externalOptionsKeys = ['pragma', 'loosePragma', 'ignorePragma', 'scalars', 'strictNullability', 'regenerateCommand', 'readOnlyArray', 'splitTypes', 'generatedDirectory', 'exportAllObjectTypes', 'typeFileName'];
|
|
32
|
-
Object.keys(data.options).forEach(k => {
|
|
33
|
-
if (!externalOptionsKeys.includes(k)) {
|
|
34
|
-
throw new Error(`Invalid option in config file ${configFile}: ${k}. Allowed options: ${externalOptionsKeys.join(', ')}`);
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
|
|
29
|
+
validateOptions(configFile, (_data$options = data.options) !== null && _data$options !== void 0 ? _data$options : {});
|
|
39
30
|
return {
|
|
40
|
-
options: (_data$
|
|
31
|
+
options: (_data$options2 = data.options) !== null && _data$options2 !== void 0 ? _data$options2 : {},
|
|
41
32
|
excludes: (_data$excludes$map = (_data$excludes = data.excludes) === null || _data$excludes === void 0 ? void 0 : _data$excludes.map(string => new RegExp(string))) !== null && _data$excludes$map !== void 0 ? _data$excludes$map : [],
|
|
42
33
|
schemaFilePath: _path.default.isAbsolute(data.schemaFilePath) ? data.schemaFilePath : _path.default.join(_path.default.dirname(configFile), data.schemaFilePath),
|
|
43
34
|
dumpOperations: data.dumpOperations
|
|
44
35
|
};
|
|
45
36
|
};
|
|
46
37
|
/**
|
|
47
|
-
*
|
|
38
|
+
* Subdirectory config to extend or overwrite higher-level config.
|
|
39
|
+
* @param {string} extends - Path from root; optional field for a config file in a subdirectory. If left blank, config file will overwrite root for directory.
|
|
48
40
|
*/
|
|
49
41
|
|
|
50
42
|
|
|
51
43
|
exports.loadConfigFile = loadConfigFile;
|
|
52
44
|
|
|
45
|
+
const loadSubConfigFile = configFile => {
|
|
46
|
+
var _data$options3, _data$excludes$map2, _data$excludes2, _data$options4, _data$extends;
|
|
47
|
+
|
|
48
|
+
const jsonData = _fs.default.readFileSync(configFile, 'utf8'); // eslint-disable-next-line flowtype-errors/uncovered
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
const data = JSON.parse(jsonData);
|
|
52
|
+
const toplevelKeys = ['excludes', 'options', 'extends'];
|
|
53
|
+
Object.keys(data).forEach(k => {
|
|
54
|
+
if (!toplevelKeys.includes(k)) {
|
|
55
|
+
throw new Error(`Invalid attribute in non-root config file ${configFile}: ${k}. Allowed attributes: ${toplevelKeys.join(', ')}`);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
validateOptions(configFile, (_data$options3 = data.options) !== null && _data$options3 !== void 0 ? _data$options3 : {});
|
|
59
|
+
return {
|
|
60
|
+
excludes: (_data$excludes$map2 = (_data$excludes2 = data.excludes) === null || _data$excludes2 === void 0 ? void 0 : _data$excludes2.map(string => new RegExp(string))) !== null && _data$excludes$map2 !== void 0 ? _data$excludes$map2 : [],
|
|
61
|
+
options: (_data$options4 = data.options) !== null && _data$options4 !== void 0 ? _data$options4 : {},
|
|
62
|
+
extends: (_data$extends = data.extends) !== null && _data$extends !== void 0 ? _data$extends : ''
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
exports.loadSubConfigFile = loadSubConfigFile;
|
|
67
|
+
|
|
68
|
+
const loadDirConfigFiles = (filesResponse, rootConfig) => {
|
|
69
|
+
const dirConfigMap = {}; // TODO: circular extends will cause infinite loop... consider instrumenting code to monitor for loops in the future?
|
|
70
|
+
|
|
71
|
+
const loadExtendedConfig = configPath => {
|
|
72
|
+
let dirConfig = loadSubConfigFile(configPath);
|
|
73
|
+
|
|
74
|
+
if (dirConfig.extends) {
|
|
75
|
+
const isRootConfig = dirConfig.extends === rootConfig.path;
|
|
76
|
+
const {
|
|
77
|
+
options,
|
|
78
|
+
excludes
|
|
79
|
+
} = isRootConfig ? rootConfig.config : addConfig(dirConfig.extends);
|
|
80
|
+
dirConfig = extendConfig({
|
|
81
|
+
options,
|
|
82
|
+
excludes
|
|
83
|
+
}, dirConfig);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return dirConfig;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const addConfig = configPath => {
|
|
90
|
+
const {
|
|
91
|
+
dir
|
|
92
|
+
} = _path.default.parse(configPath);
|
|
93
|
+
|
|
94
|
+
if (dirConfigMap[dir]) {
|
|
95
|
+
return dirConfigMap[dir];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
dirConfigMap[dir] = loadExtendedConfig(configPath);
|
|
99
|
+
return dirConfigMap[dir];
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const extendConfig = (toExtend, current) => ({
|
|
103
|
+
// $FlowFixMe[exponential-spread]
|
|
104
|
+
options: { ...toExtend.options,
|
|
105
|
+
...current.options
|
|
106
|
+
},
|
|
107
|
+
excludes: Array.from(new Set([...toExtend.excludes, ...current.excludes]))
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
filesResponse.trim().split('\n').forEach(configPath => {
|
|
111
|
+
const {
|
|
112
|
+
dir
|
|
113
|
+
} = _path.default.parse(configPath);
|
|
114
|
+
|
|
115
|
+
if (dir && !dirConfigMap[dir]) {
|
|
116
|
+
dirConfigMap[dir] = loadExtendedConfig(configPath);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
return dirConfigMap;
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* Loads a .json 'introspection query response', or a .graphql schema definition.
|
|
123
|
+
*/
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
exports.loadDirConfigFiles = loadDirConfigFiles;
|
|
127
|
+
|
|
53
128
|
const getSchemas = schemaFilePath => {
|
|
54
129
|
const raw = _fs.default.readFileSync(schemaFilePath, 'utf8');
|
|
55
130
|
|
|
@@ -71,4 +146,15 @@ const getSchemas = schemaFilePath => {
|
|
|
71
146
|
};
|
|
72
147
|
|
|
73
148
|
exports.getSchemas = getSchemas;
|
|
149
|
+
|
|
150
|
+
const validateOptions = (configFile, options) => {
|
|
151
|
+
if (options) {
|
|
152
|
+
const externalOptionsKeys = ['pragma', 'loosePragma', 'ignorePragma', 'scalars', 'strictNullability', 'regenerateCommand', 'readOnlyArray', 'splitTypes', 'generatedDirectory', 'exportAllObjectTypes', 'typeFileName', 'experimentalEnums'];
|
|
153
|
+
Object.keys(options).forEach(k => {
|
|
154
|
+
if (!externalOptionsKeys.includes(k)) {
|
|
155
|
+
throw new Error(`Invalid option in config file ${configFile}: ${k}. Allowed options: ${externalOptionsKeys.join(', ')}`);
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
};
|
|
74
160
|
//# sourceMappingURL=config.js.map
|
package/dist/cli/config.js.flow
CHANGED
|
@@ -51,30 +51,7 @@ export const loadConfigFile = (configFile: string): CliConfig => {
|
|
|
51
51
|
);
|
|
52
52
|
}
|
|
53
53
|
});
|
|
54
|
-
|
|
55
|
-
const externalOptionsKeys = [
|
|
56
|
-
'pragma',
|
|
57
|
-
'loosePragma',
|
|
58
|
-
'ignorePragma',
|
|
59
|
-
'scalars',
|
|
60
|
-
'strictNullability',
|
|
61
|
-
'regenerateCommand',
|
|
62
|
-
'readOnlyArray',
|
|
63
|
-
'splitTypes',
|
|
64
|
-
'generatedDirectory',
|
|
65
|
-
'exportAllObjectTypes',
|
|
66
|
-
'typeFileName',
|
|
67
|
-
];
|
|
68
|
-
Object.keys(data.options).forEach((k) => {
|
|
69
|
-
if (!externalOptionsKeys.includes(k)) {
|
|
70
|
-
throw new Error(
|
|
71
|
-
`Invalid option in config file ${configFile}: ${k}. Allowed options: ${externalOptionsKeys.join(
|
|
72
|
-
', ',
|
|
73
|
-
)}`,
|
|
74
|
-
);
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
}
|
|
54
|
+
validateOptions(configFile, data.options ?? {});
|
|
78
55
|
return {
|
|
79
56
|
options: data.options ?? {},
|
|
80
57
|
excludes: data.excludes?.map((string) => new RegExp(string)) ?? [],
|
|
@@ -85,6 +62,93 @@ export const loadConfigFile = (configFile: string): CliConfig => {
|
|
|
85
62
|
};
|
|
86
63
|
};
|
|
87
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Subdirectory config to extend or overwrite higher-level config.
|
|
67
|
+
* @param {string} extends - Path from root; optional field for a config file in a subdirectory. If left blank, config file will overwrite root for directory.
|
|
68
|
+
*/
|
|
69
|
+
type JSONSubConfig = {
|
|
70
|
+
excludes?: Array<string>,
|
|
71
|
+
options?: ExternalOptions,
|
|
72
|
+
extends?: string,
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
type SubConfig = {
|
|
76
|
+
excludes: Array<RegExp>,
|
|
77
|
+
options: ExternalOptions,
|
|
78
|
+
extends?: string,
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export const loadSubConfigFile = (configFile: string): SubConfig => {
|
|
82
|
+
const jsonData = fs.readFileSync(configFile, 'utf8');
|
|
83
|
+
// eslint-disable-next-line flowtype-errors/uncovered
|
|
84
|
+
const data: JSONSubConfig = JSON.parse(jsonData);
|
|
85
|
+
const toplevelKeys = ['excludes', 'options', 'extends'];
|
|
86
|
+
Object.keys(data).forEach((k) => {
|
|
87
|
+
if (!toplevelKeys.includes(k)) {
|
|
88
|
+
throw new Error(
|
|
89
|
+
`Invalid attribute in non-root config file ${configFile}: ${k}. Allowed attributes: ${toplevelKeys.join(
|
|
90
|
+
', ',
|
|
91
|
+
)}`,
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
validateOptions(configFile, data.options ?? {});
|
|
96
|
+
return {
|
|
97
|
+
excludes: data.excludes?.map((string) => new RegExp(string)) ?? [],
|
|
98
|
+
options: data.options ?? {},
|
|
99
|
+
extends: data.extends ?? '',
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
export const loadDirConfigFiles = (
|
|
104
|
+
filesResponse: string,
|
|
105
|
+
rootConfig: {path: string, config: CliConfig},
|
|
106
|
+
): {[dir: string]: SubConfig} => {
|
|
107
|
+
const dirConfigMap: {[key: string]: SubConfig} = {};
|
|
108
|
+
|
|
109
|
+
// TODO: circular extends will cause infinite loop... consider instrumenting code to monitor for loops in the future?
|
|
110
|
+
const loadExtendedConfig = (configPath: string): SubConfig => {
|
|
111
|
+
let dirConfig = loadSubConfigFile(configPath);
|
|
112
|
+
if (dirConfig.extends) {
|
|
113
|
+
const isRootConfig = dirConfig.extends === rootConfig.path;
|
|
114
|
+
const {options, excludes} = isRootConfig
|
|
115
|
+
? rootConfig.config
|
|
116
|
+
: addConfig(dirConfig.extends);
|
|
117
|
+
dirConfig = extendConfig({options, excludes}, dirConfig);
|
|
118
|
+
}
|
|
119
|
+
return dirConfig;
|
|
120
|
+
};
|
|
121
|
+
const addConfig = (configPath) => {
|
|
122
|
+
const {dir} = path.parse(configPath);
|
|
123
|
+
if (dirConfigMap[dir]) {
|
|
124
|
+
return dirConfigMap[dir];
|
|
125
|
+
}
|
|
126
|
+
dirConfigMap[dir] = loadExtendedConfig(configPath);
|
|
127
|
+
return dirConfigMap[dir];
|
|
128
|
+
};
|
|
129
|
+
const extendConfig = (
|
|
130
|
+
toExtend: SubConfig,
|
|
131
|
+
current: SubConfig,
|
|
132
|
+
): SubConfig => ({
|
|
133
|
+
// $FlowFixMe[exponential-spread]
|
|
134
|
+
options: {...toExtend.options, ...current.options},
|
|
135
|
+
excludes: Array.from(
|
|
136
|
+
new Set([...toExtend.excludes, ...current.excludes]),
|
|
137
|
+
),
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
filesResponse
|
|
141
|
+
.trim()
|
|
142
|
+
.split('\n')
|
|
143
|
+
.forEach((configPath) => {
|
|
144
|
+
const {dir} = path.parse(configPath);
|
|
145
|
+
if (dir && !dirConfigMap[dir]) {
|
|
146
|
+
dirConfigMap[dir] = loadExtendedConfig(configPath);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
return dirConfigMap;
|
|
150
|
+
};
|
|
151
|
+
|
|
88
152
|
/**
|
|
89
153
|
* Loads a .json 'introspection query response', or a .graphql schema definition.
|
|
90
154
|
*/
|
|
@@ -110,3 +174,34 @@ export const getSchemas = (schemaFilePath: string): [GraphQLSchema, Schema] => {
|
|
|
110
174
|
return [schemaForValidation, schemaForTypeGeneration];
|
|
111
175
|
}
|
|
112
176
|
};
|
|
177
|
+
|
|
178
|
+
const validateOptions = (
|
|
179
|
+
configFile: string,
|
|
180
|
+
options: ExternalOptions,
|
|
181
|
+
): void => {
|
|
182
|
+
if (options) {
|
|
183
|
+
const externalOptionsKeys = [
|
|
184
|
+
'pragma',
|
|
185
|
+
'loosePragma',
|
|
186
|
+
'ignorePragma',
|
|
187
|
+
'scalars',
|
|
188
|
+
'strictNullability',
|
|
189
|
+
'regenerateCommand',
|
|
190
|
+
'readOnlyArray',
|
|
191
|
+
'splitTypes',
|
|
192
|
+
'generatedDirectory',
|
|
193
|
+
'exportAllObjectTypes',
|
|
194
|
+
'typeFileName',
|
|
195
|
+
'experimentalEnums',
|
|
196
|
+
];
|
|
197
|
+
Object.keys(options).forEach((k) => {
|
|
198
|
+
if (!externalOptionsKeys.includes(k)) {
|
|
199
|
+
throw new Error(
|
|
200
|
+
`Invalid option in config file ${configFile}: ${k}. Allowed options: ${externalOptionsKeys.join(
|
|
201
|
+
', ',
|
|
202
|
+
)}`,
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
};
|
package/dist/cli/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/config.js"],"names":["loadConfigFile","configFile","data","JSON","parse","fs","readFileSync","toplevelKeys","Object","keys","forEach","k","includes","Error","join","options","externalOptionsKeys","excludes","map","string","RegExp","schemaFilePath","path","isAbsolute","dirname","dumpOperations","getSchemas","raw","endsWith","schemaForValidation","queryResponse","descriptions","schemaForTypeGeneration","introspectionData"],"mappings":"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","sourcesContent":["// @flow\nimport type {ExternalOptions} from '../generateTypeFiles';\nimport type {Schema} from '../types';\nimport type {GraphQLSchema} from 'graphql/type/schema';\n\nimport {schemaFromIntrospectionData} from '../schemaFromIntrospectionData';\n\nimport fs from 'fs';\nimport {\n buildClientSchema,\n buildSchema,\n getIntrospectionQuery,\n graphqlSync,\n type IntrospectionQuery,\n} from 'graphql';\nimport path from 'path';\n\nexport type CliConfig = {\n excludes: Array<RegExp>,\n schemaFilePath: string,\n dumpOperations?: string,\n options: ExternalOptions,\n};\n\n/**\n * This is the json-compatible form of the config\n * object.\n */\ntype JSONConfig = {\n excludes?: Array<string>,\n schemaFilePath: string,\n options?: ExternalOptions,\n dumpOperations?: string,\n};\n\nexport const loadConfigFile = (configFile: string): CliConfig => {\n // eslint-disable-next-line flowtype-errors/uncovered\n const data: JSONConfig = JSON.parse(fs.readFileSync(configFile, 'utf8'));\n const toplevelKeys = [\n 'excludes',\n 'schemaFilePath',\n 'options',\n 'dumpOperations',\n ];\n Object.keys(data).forEach((k) => {\n if (!toplevelKeys.includes(k)) {\n throw new Error(\n `Invalid attribute in config file ${configFile}: ${k}. Allowed attributes: ${toplevelKeys.join(\n ', ',\n )}`,\n );\n }\n });\n if (data.options) {\n const externalOptionsKeys = [\n 'pragma',\n 'loosePragma',\n 'ignorePragma',\n 'scalars',\n 'strictNullability',\n 'regenerateCommand',\n 'readOnlyArray',\n 'splitTypes',\n 'generatedDirectory',\n 'exportAllObjectTypes',\n 'typeFileName',\n ];\n Object.keys(data.options).forEach((k) => {\n if (!externalOptionsKeys.includes(k)) {\n throw new Error(\n `Invalid option in config file ${configFile}: ${k}. Allowed options: ${externalOptionsKeys.join(\n ', ',\n )}`,\n );\n }\n });\n }\n return {\n options: data.options ?? {},\n excludes: data.excludes?.map((string) => new RegExp(string)) ?? [],\n schemaFilePath: path.isAbsolute(data.schemaFilePath)\n ? data.schemaFilePath\n : path.join(path.dirname(configFile), data.schemaFilePath),\n dumpOperations: data.dumpOperations,\n };\n};\n\n/**\n * Loads a .json 'introspection query response', or a .graphql schema definition.\n */\nexport const getSchemas = (schemaFilePath: string): [GraphQLSchema, Schema] => {\n const raw = fs.readFileSync(schemaFilePath, 'utf8');\n if (schemaFilePath.endsWith('.graphql')) {\n const schemaForValidation = buildSchema(raw);\n const queryResponse = graphqlSync(\n schemaForValidation,\n getIntrospectionQuery({descriptions: true}),\n );\n const schemaForTypeGeneration = schemaFromIntrospectionData(\n // eslint-disable-next-line flowtype-errors/uncovered\n ((queryResponse.data: any): IntrospectionQuery),\n );\n return [schemaForValidation, schemaForTypeGeneration];\n } else {\n // eslint-disable-next-line flowtype-errors/uncovered\n const introspectionData: IntrospectionQuery = JSON.parse(raw);\n const schemaForValidation = buildClientSchema(introspectionData);\n const schemaForTypeGeneration =\n schemaFromIntrospectionData(introspectionData);\n return [schemaForValidation, schemaForTypeGeneration];\n }\n};\n"],"file":"config.js"}
|
|
1
|
+
{"version":3,"sources":["../../src/cli/config.js"],"names":["loadConfigFile","configFile","data","JSON","parse","fs","readFileSync","toplevelKeys","Object","keys","forEach","k","includes","Error","join","validateOptions","options","excludes","map","string","RegExp","schemaFilePath","path","isAbsolute","dirname","dumpOperations","loadSubConfigFile","jsonData","extends","loadDirConfigFiles","filesResponse","rootConfig","dirConfigMap","loadExtendedConfig","configPath","dirConfig","isRootConfig","config","addConfig","extendConfig","dir","toExtend","current","Array","from","Set","trim","split","getSchemas","raw","endsWith","schemaForValidation","queryResponse","descriptions","schemaForTypeGeneration","introspectionData","externalOptionsKeys"],"mappings":"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","sourcesContent":["// @flow\nimport type {ExternalOptions} from '../generateTypeFiles';\nimport type {Schema} from '../types';\nimport type {GraphQLSchema} from 'graphql/type/schema';\n\nimport {schemaFromIntrospectionData} from '../schemaFromIntrospectionData';\n\nimport fs from 'fs';\nimport {\n buildClientSchema,\n buildSchema,\n getIntrospectionQuery,\n graphqlSync,\n type IntrospectionQuery,\n} from 'graphql';\nimport path from 'path';\n\nexport type CliConfig = {\n excludes: Array<RegExp>,\n schemaFilePath: string,\n dumpOperations?: string,\n options: ExternalOptions,\n};\n\n/**\n * This is the json-compatible form of the config\n * object.\n */\ntype JSONConfig = {\n excludes?: Array<string>,\n schemaFilePath: string,\n options?: ExternalOptions,\n dumpOperations?: string,\n};\n\nexport const loadConfigFile = (configFile: string): CliConfig => {\n // eslint-disable-next-line flowtype-errors/uncovered\n const data: JSONConfig = JSON.parse(fs.readFileSync(configFile, 'utf8'));\n const toplevelKeys = [\n 'excludes',\n 'schemaFilePath',\n 'options',\n 'dumpOperations',\n ];\n Object.keys(data).forEach((k) => {\n if (!toplevelKeys.includes(k)) {\n throw new Error(\n `Invalid attribute in config file ${configFile}: ${k}. Allowed attributes: ${toplevelKeys.join(\n ', ',\n )}`,\n );\n }\n });\n validateOptions(configFile, data.options ?? {});\n return {\n options: data.options ?? {},\n excludes: data.excludes?.map((string) => new RegExp(string)) ?? [],\n schemaFilePath: path.isAbsolute(data.schemaFilePath)\n ? data.schemaFilePath\n : path.join(path.dirname(configFile), data.schemaFilePath),\n dumpOperations: data.dumpOperations,\n };\n};\n\n/**\n * Subdirectory config to extend or overwrite higher-level config.\n * @param {string} extends - Path from root; optional field for a config file in a subdirectory. If left blank, config file will overwrite root for directory.\n */\ntype JSONSubConfig = {\n excludes?: Array<string>,\n options?: ExternalOptions,\n extends?: string,\n};\n\ntype SubConfig = {\n excludes: Array<RegExp>,\n options: ExternalOptions,\n extends?: string,\n};\n\nexport const loadSubConfigFile = (configFile: string): SubConfig => {\n const jsonData = fs.readFileSync(configFile, 'utf8');\n // eslint-disable-next-line flowtype-errors/uncovered\n const data: JSONSubConfig = JSON.parse(jsonData);\n const toplevelKeys = ['excludes', 'options', 'extends'];\n Object.keys(data).forEach((k) => {\n if (!toplevelKeys.includes(k)) {\n throw new Error(\n `Invalid attribute in non-root config file ${configFile}: ${k}. Allowed attributes: ${toplevelKeys.join(\n ', ',\n )}`,\n );\n }\n });\n validateOptions(configFile, data.options ?? {});\n return {\n excludes: data.excludes?.map((string) => new RegExp(string)) ?? [],\n options: data.options ?? {},\n extends: data.extends ?? '',\n };\n};\n\nexport const loadDirConfigFiles = (\n filesResponse: string,\n rootConfig: {path: string, config: CliConfig},\n): {[dir: string]: SubConfig} => {\n const dirConfigMap: {[key: string]: SubConfig} = {};\n\n // TODO: circular extends will cause infinite loop... consider instrumenting code to monitor for loops in the future?\n const loadExtendedConfig = (configPath: string): SubConfig => {\n let dirConfig = loadSubConfigFile(configPath);\n if (dirConfig.extends) {\n const isRootConfig = dirConfig.extends === rootConfig.path;\n const {options, excludes} = isRootConfig\n ? rootConfig.config\n : addConfig(dirConfig.extends);\n dirConfig = extendConfig({options, excludes}, dirConfig);\n }\n return dirConfig;\n };\n const addConfig = (configPath) => {\n const {dir} = path.parse(configPath);\n if (dirConfigMap[dir]) {\n return dirConfigMap[dir];\n }\n dirConfigMap[dir] = loadExtendedConfig(configPath);\n return dirConfigMap[dir];\n };\n const extendConfig = (\n toExtend: SubConfig,\n current: SubConfig,\n ): SubConfig => ({\n // $FlowFixMe[exponential-spread]\n options: {...toExtend.options, ...current.options},\n excludes: Array.from(\n new Set([...toExtend.excludes, ...current.excludes]),\n ),\n });\n\n filesResponse\n .trim()\n .split('\\n')\n .forEach((configPath) => {\n const {dir} = path.parse(configPath);\n if (dir && !dirConfigMap[dir]) {\n dirConfigMap[dir] = loadExtendedConfig(configPath);\n }\n });\n return dirConfigMap;\n};\n\n/**\n * Loads a .json 'introspection query response', or a .graphql schema definition.\n */\nexport const getSchemas = (schemaFilePath: string): [GraphQLSchema, Schema] => {\n const raw = fs.readFileSync(schemaFilePath, 'utf8');\n if (schemaFilePath.endsWith('.graphql')) {\n const schemaForValidation = buildSchema(raw);\n const queryResponse = graphqlSync(\n schemaForValidation,\n getIntrospectionQuery({descriptions: true}),\n );\n const schemaForTypeGeneration = schemaFromIntrospectionData(\n // eslint-disable-next-line flowtype-errors/uncovered\n ((queryResponse.data: any): IntrospectionQuery),\n );\n return [schemaForValidation, schemaForTypeGeneration];\n } else {\n // eslint-disable-next-line flowtype-errors/uncovered\n const introspectionData: IntrospectionQuery = JSON.parse(raw);\n const schemaForValidation = buildClientSchema(introspectionData);\n const schemaForTypeGeneration =\n schemaFromIntrospectionData(introspectionData);\n return [schemaForValidation, schemaForTypeGeneration];\n }\n};\n\nconst validateOptions = (\n configFile: string,\n options: ExternalOptions,\n): void => {\n if (options) {\n const externalOptionsKeys = [\n 'pragma',\n 'loosePragma',\n 'ignorePragma',\n 'scalars',\n 'strictNullability',\n 'regenerateCommand',\n 'readOnlyArray',\n 'splitTypes',\n 'generatedDirectory',\n 'exportAllObjectTypes',\n 'typeFileName',\n 'experimentalEnums',\n ];\n Object.keys(options).forEach((k) => {\n if (!externalOptionsKeys.includes(k)) {\n throw new Error(\n `Invalid option in config file ${configFile}: ${k}. Allowed options: ${externalOptionsKeys.join(\n ', ',\n )}`,\n );\n }\n });\n }\n};\n"],"file":"config.js"}
|
package/dist/cli/run.js
CHANGED
|
@@ -23,6 +23,8 @@ var _validation = require("graphql/validation");
|
|
|
23
23
|
|
|
24
24
|
var _path = _interopRequireWildcard(require("path"));
|
|
25
25
|
|
|
26
|
+
var _utils = require("./utils");
|
|
27
|
+
|
|
26
28
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
27
29
|
|
|
28
30
|
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; }
|
|
@@ -58,7 +60,17 @@ Usage: graphql-flow [configFile.json] [filesToCrawl...]`);
|
|
|
58
60
|
process.exit(1); // eslint-disable-line flowtype-errors/uncovered
|
|
59
61
|
}
|
|
60
62
|
|
|
61
|
-
const config = (0, _config.loadConfigFile)(configFile);
|
|
63
|
+
const config = (0, _config.loadConfigFile)(configFile); // find file paths ending with "graphql-flow.config.json"
|
|
64
|
+
|
|
65
|
+
const subConfigsQuery = () => (0, _child_process.execSync)('git ls-files "*graphql-flow.config.json"', {
|
|
66
|
+
encoding: 'utf8',
|
|
67
|
+
cwd: process.cwd()
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
const subConfigMap = (0, _config.loadDirConfigFiles)(subConfigsQuery(), {
|
|
71
|
+
config,
|
|
72
|
+
path: configFile
|
|
73
|
+
});
|
|
62
74
|
const [schemaForValidation, schemaForTypeGeneration] = (0, _config.getSchemas)(config.schemaFilePath);
|
|
63
75
|
const inputFiles = cliFiles.length ? cliFiles : findGraphqlTagReferences(process.cwd());
|
|
64
76
|
/** Step (2) */
|
|
@@ -117,8 +129,14 @@ Object.keys(resolved).forEach(k => {
|
|
|
117
129
|
document,
|
|
118
130
|
raw
|
|
119
131
|
} = resolved[k];
|
|
132
|
+
let fileConfig = config;
|
|
133
|
+
const closestConfigPath = (0, _utils.longestMatchingPath)(raw.loc.path, Object.keys(subConfigMap)); // get longest match in the case of nested subconfigs
|
|
134
|
+
|
|
135
|
+
if (closestConfigPath) {
|
|
136
|
+
fileConfig = subConfigMap[closestConfigPath];
|
|
137
|
+
}
|
|
120
138
|
|
|
121
|
-
if (
|
|
139
|
+
if (fileConfig.excludes.some(rx => rx.test(raw.loc.path))) {
|
|
122
140
|
return; // skip
|
|
123
141
|
}
|
|
124
142
|
|
|
@@ -134,7 +152,7 @@ Object.keys(resolved).forEach(k => {
|
|
|
134
152
|
printedOperations.push(printed);
|
|
135
153
|
}
|
|
136
154
|
|
|
137
|
-
const processedOptions = (0, _generateTypeFiles.processPragmas)(
|
|
155
|
+
const processedOptions = (0, _generateTypeFiles.processPragmas)(fileConfig.options, rawSource);
|
|
138
156
|
|
|
139
157
|
if (!processedOptions) {
|
|
140
158
|
return;
|
package/dist/cli/run.js.flow
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import {generateTypeFiles, processPragmas} from '../generateTypeFiles';
|
|
5
5
|
import {processFiles} from '../parser/parse';
|
|
6
6
|
import {resolveDocuments} from '../parser/resolve';
|
|
7
|
-
import {getSchemas, loadConfigFile} from './config';
|
|
7
|
+
import {loadDirConfigFiles, getSchemas, loadConfigFile} from './config';
|
|
8
8
|
|
|
9
9
|
import {addTypenameToDocument} from 'apollo-utilities'; // eslint-disable-line flowtype-errors/uncovered
|
|
10
10
|
|
|
@@ -15,6 +15,7 @@ import {print} from 'graphql/language/printer';
|
|
|
15
15
|
import {validate} from 'graphql/validation';
|
|
16
16
|
import path from 'path';
|
|
17
17
|
import {dirname} from 'path';
|
|
18
|
+
import {longestMatchingPath} from './utils';
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* This CLI tool executes the following steps:
|
|
@@ -59,6 +60,17 @@ Usage: graphql-flow [configFile.json] [filesToCrawl...]`);
|
|
|
59
60
|
|
|
60
61
|
const config = loadConfigFile(configFile);
|
|
61
62
|
|
|
63
|
+
// find file paths ending with "graphql-flow.config.json"
|
|
64
|
+
const subConfigsQuery = () =>
|
|
65
|
+
execSync('git ls-files "*graphql-flow.config.json"', {
|
|
66
|
+
encoding: 'utf8',
|
|
67
|
+
cwd: process.cwd(),
|
|
68
|
+
});
|
|
69
|
+
const subConfigMap = loadDirConfigFiles(subConfigsQuery(), {
|
|
70
|
+
config,
|
|
71
|
+
path: configFile,
|
|
72
|
+
});
|
|
73
|
+
|
|
62
74
|
const [schemaForValidation, schemaForTypeGeneration] = getSchemas(
|
|
63
75
|
config.schemaFilePath,
|
|
64
76
|
);
|
|
@@ -116,7 +128,17 @@ const printedOperations: Array<string> = [];
|
|
|
116
128
|
|
|
117
129
|
Object.keys(resolved).forEach((k) => {
|
|
118
130
|
const {document, raw} = resolved[k];
|
|
119
|
-
|
|
131
|
+
|
|
132
|
+
let fileConfig = config;
|
|
133
|
+
const closestConfigPath = longestMatchingPath(
|
|
134
|
+
raw.loc.path,
|
|
135
|
+
Object.keys(subConfigMap),
|
|
136
|
+
); // get longest match in the case of nested subconfigs
|
|
137
|
+
if (closestConfigPath) {
|
|
138
|
+
fileConfig = subConfigMap[closestConfigPath];
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (fileConfig.excludes.some((rx) => rx.test(raw.loc.path))) {
|
|
120
142
|
return; // skip
|
|
121
143
|
}
|
|
122
144
|
const hasNonFragments = document.definitions.some(
|
|
@@ -131,7 +153,7 @@ Object.keys(resolved).forEach((k) => {
|
|
|
131
153
|
printedOperations.push(printed);
|
|
132
154
|
}
|
|
133
155
|
|
|
134
|
-
const processedOptions = processPragmas(
|
|
156
|
+
const processedOptions = processPragmas(fileConfig.options, rawSource);
|
|
135
157
|
if (!processedOptions) {
|
|
136
158
|
return;
|
|
137
159
|
}
|