@depup/graphql-codegen__cli 6.2.1-depup.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/README.md +51 -0
- package/changes.json +90 -0
- package/cjs/bin.js +13 -0
- package/cjs/cli.js +64 -0
- package/cjs/codegen.js +388 -0
- package/cjs/config.js +370 -0
- package/cjs/documentTransforms.js +63 -0
- package/cjs/generate-and-save.js +153 -0
- package/cjs/graphql-config.js +67 -0
- package/cjs/hooks.js +93 -0
- package/cjs/index.js +13 -0
- package/cjs/init/helpers.js +90 -0
- package/cjs/init/index.js +62 -0
- package/cjs/init/plugins.js +136 -0
- package/cjs/init/questions.js +177 -0
- package/cjs/init/targets.js +45 -0
- package/cjs/init/types.js +15 -0
- package/cjs/load.js +102 -0
- package/cjs/package.json +1 -0
- package/cjs/plugins.js +43 -0
- package/cjs/presets.js +50 -0
- package/cjs/utils/abort-controller-polyfill.js +99 -0
- package/cjs/utils/cli-error.js +24 -0
- package/cjs/utils/debugging.js +22 -0
- package/cjs/utils/file-system.js +24 -0
- package/cjs/utils/get-latest-version.js +14 -0
- package/cjs/utils/helpers.js +12 -0
- package/cjs/utils/logger.js +24 -0
- package/cjs/utils/patterns.js +235 -0
- package/cjs/utils/watcher.js +244 -0
- package/esm/bin.js +11 -0
- package/esm/cli.js +37 -0
- package/esm/codegen.js +384 -0
- package/esm/config.js +357 -0
- package/esm/documentTransforms.js +59 -0
- package/esm/generate-and-save.js +149 -0
- package/esm/graphql-config.js +62 -0
- package/esm/hooks.js +89 -0
- package/esm/index.js +7 -0
- package/esm/init/helpers.js +82 -0
- package/esm/init/index.js +59 -0
- package/esm/init/plugins.js +133 -0
- package/esm/init/questions.js +172 -0
- package/esm/init/targets.js +42 -0
- package/esm/init/types.js +12 -0
- package/esm/load.js +97 -0
- package/esm/plugins.js +40 -0
- package/esm/presets.js +47 -0
- package/esm/utils/abort-controller-polyfill.js +96 -0
- package/esm/utils/cli-error.js +20 -0
- package/esm/utils/debugging.js +17 -0
- package/esm/utils/file-system.js +17 -0
- package/esm/utils/get-latest-version.js +11 -0
- package/esm/utils/helpers.js +9 -0
- package/esm/utils/logger.js +18 -0
- package/esm/utils/patterns.js +226 -0
- package/esm/utils/watcher.js +239 -0
- package/package.json +205 -0
- package/typings/bin.d.cts +2 -0
- package/typings/bin.d.ts +2 -0
- package/typings/cli.d.cts +2 -0
- package/typings/cli.d.ts +2 -0
- package/typings/codegen.d.cts +6 -0
- package/typings/codegen.d.ts +6 -0
- package/typings/config.d.cts +152 -0
- package/typings/config.d.ts +152 -0
- package/typings/documentTransforms.d.cts +3 -0
- package/typings/documentTransforms.d.ts +3 -0
- package/typings/generate-and-save.d.cts +10 -0
- package/typings/generate-and-save.d.ts +10 -0
- package/typings/graphql-config.d.cts +3 -0
- package/typings/graphql-config.d.ts +3 -0
- package/typings/hooks.d.cts +11 -0
- package/typings/hooks.d.ts +11 -0
- package/typings/index.d.cts +8 -0
- package/typings/index.d.ts +8 -0
- package/typings/init/helpers.d.cts +10 -0
- package/typings/init/helpers.d.ts +10 -0
- package/typings/init/index.d.cts +1 -0
- package/typings/init/index.d.ts +1 -0
- package/typings/init/plugins.d.cts +2 -0
- package/typings/init/plugins.d.ts +2 -0
- package/typings/init/questions.d.cts +13 -0
- package/typings/init/questions.d.ts +13 -0
- package/typings/init/targets.d.cts +2 -0
- package/typings/init/targets.d.ts +2 -0
- package/typings/init/types.d.cts +30 -0
- package/typings/init/types.d.ts +30 -0
- package/typings/load.d.cts +15 -0
- package/typings/load.d.ts +15 -0
- package/typings/plugins.d.cts +2 -0
- package/typings/plugins.d.ts +2 -0
- package/typings/presets.d.cts +5 -0
- package/typings/presets.d.ts +5 -0
- package/typings/utils/abort-controller-polyfill.d.cts +5 -0
- package/typings/utils/abort-controller-polyfill.d.ts +5 -0
- package/typings/utils/cli-error.d.cts +10 -0
- package/typings/utils/cli-error.d.ts +10 -0
- package/typings/utils/debugging.d.cts +3 -0
- package/typings/utils/debugging.d.ts +3 -0
- package/typings/utils/file-system.d.cts +8 -0
- package/typings/utils/file-system.d.ts +8 -0
- package/typings/utils/get-latest-version.d.cts +6 -0
- package/typings/utils/get-latest-version.d.ts +6 -0
- package/typings/utils/helpers.d.cts +1 -0
- package/typings/utils/helpers.d.ts +1 -0
- package/typings/utils/logger.d.cts +5 -0
- package/typings/utils/logger.d.ts +5 -0
- package/typings/utils/patterns.d.cts +91 -0
- package/typings/utils/patterns.d.ts +91 -0
- package/typings/utils/watcher.d.cts +16 -0
- package/typings/utils/watcher.d.ts +16 -0
package/cjs/config.js
ADDED
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CodegenContext = void 0;
|
|
4
|
+
exports.generateSearchPlaces = generateSearchPlaces;
|
|
5
|
+
exports.loadCodegenConfig = loadCodegenConfig;
|
|
6
|
+
exports.loadContext = loadContext;
|
|
7
|
+
exports.buildOptions = buildOptions;
|
|
8
|
+
exports.parseArgv = parseArgv;
|
|
9
|
+
exports.createContext = createContext;
|
|
10
|
+
exports.updateContextWithCliFlags = updateContextWithCliFlags;
|
|
11
|
+
exports.ensureContext = ensureContext;
|
|
12
|
+
const tslib_1 = require("tslib");
|
|
13
|
+
const crypto_1 = require("crypto");
|
|
14
|
+
const fs_1 = require("fs");
|
|
15
|
+
const module_1 = require("module");
|
|
16
|
+
const path_1 = require("path");
|
|
17
|
+
const plugin_helpers_1 = require("@graphql-codegen/plugin-helpers");
|
|
18
|
+
const cosmiconfig_1 = require("cosmiconfig");
|
|
19
|
+
const jiti_1 = require("jiti");
|
|
20
|
+
const graphql_1 = require("graphql");
|
|
21
|
+
const string_env_interpolation_1 = require("string-env-interpolation");
|
|
22
|
+
const yaml_1 = tslib_1.__importDefault(require("yaml"));
|
|
23
|
+
const yargs_1 = tslib_1.__importDefault(require("yargs"));
|
|
24
|
+
const graphql_config_js_1 = require("./graphql-config.js");
|
|
25
|
+
const load_js_1 = require("./load.js");
|
|
26
|
+
const { lstat } = fs_1.promises;
|
|
27
|
+
function generateSearchPlaces(moduleName) {
|
|
28
|
+
const extensions = ['json', 'yaml', 'yml', 'js', 'ts', 'config.js'];
|
|
29
|
+
// gives codegen.json...
|
|
30
|
+
const regular = extensions.map(ext => `${moduleName}.${ext}`);
|
|
31
|
+
// gives .codegenrc.json... but no .codegenrc.config.js
|
|
32
|
+
const dot = extensions.filter(ext => ext !== 'config.js').map(ext => `.${moduleName}rc.${ext}`);
|
|
33
|
+
return [...regular.concat(dot), 'package.json'];
|
|
34
|
+
}
|
|
35
|
+
function customLoader(ext) {
|
|
36
|
+
return async function loader(filepath, content) {
|
|
37
|
+
if (typeof process !== 'undefined' && 'env' in process) {
|
|
38
|
+
content = (0, string_env_interpolation_1.env)(content);
|
|
39
|
+
}
|
|
40
|
+
if (ext === 'json') {
|
|
41
|
+
return cosmiconfig_1.defaultLoaders['.json'](filepath, content);
|
|
42
|
+
}
|
|
43
|
+
if (ext === 'yaml') {
|
|
44
|
+
try {
|
|
45
|
+
const result = yaml_1.default.parse(content, { prettyErrors: true, merge: true });
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
error.message = `YAML Error in ${filepath}:\n${error.message}`;
|
|
50
|
+
throw error;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (ext === 'js') {
|
|
54
|
+
return cosmiconfig_1.defaultLoaders['.js'](filepath, content);
|
|
55
|
+
}
|
|
56
|
+
if (ext === 'ts') {
|
|
57
|
+
const jitiLoader = (0, jiti_1.createJiti)('');
|
|
58
|
+
return jitiLoader.import(filepath, { default: true });
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
async function loadCodegenConfig({ configFilePath, moduleName, searchPlaces: additionalSearchPlaces, packageProp, loaders: customLoaders, }) {
|
|
63
|
+
configFilePath ||= process.cwd();
|
|
64
|
+
moduleName ||= 'codegen';
|
|
65
|
+
packageProp ||= moduleName;
|
|
66
|
+
const cosmi = (0, cosmiconfig_1.cosmiconfig)(moduleName, {
|
|
67
|
+
searchPlaces: generateSearchPlaces(moduleName).concat(additionalSearchPlaces || []),
|
|
68
|
+
packageProp,
|
|
69
|
+
loaders: {
|
|
70
|
+
'.json': customLoader('json'),
|
|
71
|
+
'.yaml': customLoader('yaml'),
|
|
72
|
+
'.yml': customLoader('yaml'),
|
|
73
|
+
'.js': customLoader('js'),
|
|
74
|
+
'.ts': customLoader('ts'),
|
|
75
|
+
'.mts': customLoader('ts'),
|
|
76
|
+
'.cts': customLoader('ts'),
|
|
77
|
+
noExt: customLoader('yaml'),
|
|
78
|
+
...customLoaders,
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
const pathStats = await lstat(configFilePath);
|
|
82
|
+
return pathStats.isDirectory() ? cosmi.search(configFilePath) : cosmi.load(configFilePath);
|
|
83
|
+
}
|
|
84
|
+
async function loadContext(configFilePath) {
|
|
85
|
+
const graphqlConfig = await (0, graphql_config_js_1.findAndLoadGraphQLConfig)(configFilePath);
|
|
86
|
+
if (graphqlConfig) {
|
|
87
|
+
return new CodegenContext({ graphqlConfig });
|
|
88
|
+
}
|
|
89
|
+
const result = await loadCodegenConfig({ configFilePath });
|
|
90
|
+
if (!result) {
|
|
91
|
+
if (configFilePath) {
|
|
92
|
+
throw new Error(`
|
|
93
|
+
Config ${configFilePath} does not exist.
|
|
94
|
+
|
|
95
|
+
$ graphql-codegen --config ${configFilePath}
|
|
96
|
+
|
|
97
|
+
Please make sure the --config points to a correct file.
|
|
98
|
+
`);
|
|
99
|
+
}
|
|
100
|
+
throw new Error(`Unable to find Codegen config file! \n
|
|
101
|
+
Please make sure that you have a configuration file under the current directory!
|
|
102
|
+
`);
|
|
103
|
+
}
|
|
104
|
+
if (result.isEmpty) {
|
|
105
|
+
throw new Error(`Found Codegen config file but it was empty! \n
|
|
106
|
+
Please make sure that you have a valid configuration file under the current directory!
|
|
107
|
+
`);
|
|
108
|
+
}
|
|
109
|
+
return new CodegenContext({
|
|
110
|
+
filepath: result.filepath,
|
|
111
|
+
config: result.config,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
function getCustomConfigPath(cliFlags) {
|
|
115
|
+
const configFile = cliFlags.config;
|
|
116
|
+
return configFile ? (0, path_1.resolve)(process.cwd(), configFile) : null;
|
|
117
|
+
}
|
|
118
|
+
function buildOptions() {
|
|
119
|
+
return {
|
|
120
|
+
c: {
|
|
121
|
+
alias: 'config',
|
|
122
|
+
type: 'string',
|
|
123
|
+
describe: 'Path to GraphQL codegen YAML config file, defaults to "codegen.yml" on the current directory',
|
|
124
|
+
},
|
|
125
|
+
w: {
|
|
126
|
+
alias: 'watch',
|
|
127
|
+
describe: 'Watch for changes and execute generation automatically. You can also specify a glob expression for custom watch list.',
|
|
128
|
+
coerce(watch) {
|
|
129
|
+
if (watch === 'false') {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
if (typeof watch === 'string' || Array.isArray(watch)) {
|
|
133
|
+
return watch;
|
|
134
|
+
}
|
|
135
|
+
return !!watch;
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
r: {
|
|
139
|
+
alias: 'require',
|
|
140
|
+
describe: 'Loads specific require.extensions before running the codegen and reading the configuration',
|
|
141
|
+
type: 'array',
|
|
142
|
+
default: [],
|
|
143
|
+
},
|
|
144
|
+
o: {
|
|
145
|
+
alias: 'overwrite',
|
|
146
|
+
describe: 'Overwrites existing files',
|
|
147
|
+
type: 'boolean',
|
|
148
|
+
},
|
|
149
|
+
s: {
|
|
150
|
+
alias: 'silent',
|
|
151
|
+
describe: 'Suppresses printing errors',
|
|
152
|
+
type: 'boolean',
|
|
153
|
+
},
|
|
154
|
+
e: {
|
|
155
|
+
alias: 'errors-only',
|
|
156
|
+
describe: 'Only print errors',
|
|
157
|
+
type: 'boolean',
|
|
158
|
+
},
|
|
159
|
+
profile: {
|
|
160
|
+
describe: 'Use profiler to measure performance',
|
|
161
|
+
type: 'boolean',
|
|
162
|
+
},
|
|
163
|
+
p: {
|
|
164
|
+
alias: 'project',
|
|
165
|
+
describe: 'Name of a project in GraphQL Config',
|
|
166
|
+
type: 'string',
|
|
167
|
+
},
|
|
168
|
+
v: {
|
|
169
|
+
alias: 'verbose',
|
|
170
|
+
describe: 'output more detailed information about performed tasks',
|
|
171
|
+
type: 'boolean',
|
|
172
|
+
default: false,
|
|
173
|
+
},
|
|
174
|
+
d: {
|
|
175
|
+
alias: 'debug',
|
|
176
|
+
describe: 'Print debug logs to stdout',
|
|
177
|
+
type: 'boolean',
|
|
178
|
+
default: false,
|
|
179
|
+
},
|
|
180
|
+
'emit-legacy-common-js-imports': {
|
|
181
|
+
describe: 'Emit legacy CommonJS imports (deprecated, use import-extension instead)',
|
|
182
|
+
type: 'boolean',
|
|
183
|
+
},
|
|
184
|
+
'import-extension': {
|
|
185
|
+
describe: 'Extension to append to imports (e.g., .js, .mjs, or empty string for no extension)',
|
|
186
|
+
type: 'string',
|
|
187
|
+
},
|
|
188
|
+
'ignore-no-documents': {
|
|
189
|
+
describe: 'Suppress errors for no documents',
|
|
190
|
+
type: 'boolean',
|
|
191
|
+
},
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
function parseArgv(argv = process.argv) {
|
|
195
|
+
return (0, yargs_1.default)(argv).options(buildOptions()).parse(argv);
|
|
196
|
+
}
|
|
197
|
+
async function createContext(cliFlags = parseArgv(process.argv)) {
|
|
198
|
+
if (cliFlags.require && cliFlags.require.length > 0) {
|
|
199
|
+
const relativeRequire = (0, module_1.createRequire)(process.cwd());
|
|
200
|
+
await Promise.all(cliFlags.require.map(mod => Promise.resolve(`${relativeRequire.resolve(mod, {
|
|
201
|
+
paths: [process.cwd()],
|
|
202
|
+
})}`).then(s => tslib_1.__importStar(require(s)))));
|
|
203
|
+
}
|
|
204
|
+
const customConfigPath = getCustomConfigPath(cliFlags);
|
|
205
|
+
const context = await loadContext(customConfigPath);
|
|
206
|
+
updateContextWithCliFlags(context, cliFlags);
|
|
207
|
+
return context;
|
|
208
|
+
}
|
|
209
|
+
function updateContextWithCliFlags(context, cliFlags) {
|
|
210
|
+
const config = {
|
|
211
|
+
configFilePath: context.filepath,
|
|
212
|
+
};
|
|
213
|
+
if (cliFlags.watch !== undefined) {
|
|
214
|
+
config.watch = cliFlags.watch;
|
|
215
|
+
}
|
|
216
|
+
if (cliFlags.overwrite === true) {
|
|
217
|
+
config.overwrite = cliFlags.overwrite;
|
|
218
|
+
}
|
|
219
|
+
if (cliFlags.silent === true) {
|
|
220
|
+
config.silent = cliFlags.silent;
|
|
221
|
+
}
|
|
222
|
+
if (cliFlags.verbose === true || process.env.VERBOSE) {
|
|
223
|
+
config.verbose = true;
|
|
224
|
+
}
|
|
225
|
+
if (cliFlags.debug === true || process.env.DEBUG) {
|
|
226
|
+
config.debug = true;
|
|
227
|
+
}
|
|
228
|
+
if (cliFlags.errorsOnly === true) {
|
|
229
|
+
config.errorsOnly = cliFlags.errorsOnly;
|
|
230
|
+
}
|
|
231
|
+
if (cliFlags['ignore-no-documents'] !== undefined) {
|
|
232
|
+
// for some reason parsed value is `'false'` string so this ensure it always is a boolean.
|
|
233
|
+
config.ignoreNoDocuments = cliFlags['ignore-no-documents'] === true;
|
|
234
|
+
}
|
|
235
|
+
if (cliFlags['emit-legacy-common-js-imports'] !== undefined) {
|
|
236
|
+
// for some reason parsed value is `'false'` string so this ensure it always is a boolean.
|
|
237
|
+
config.emitLegacyCommonJSImports = cliFlags['emit-legacy-common-js-imports'] === true;
|
|
238
|
+
}
|
|
239
|
+
if (cliFlags['import-extension'] !== undefined) {
|
|
240
|
+
config.importExtension = cliFlags['import-extension'];
|
|
241
|
+
}
|
|
242
|
+
if (cliFlags.project) {
|
|
243
|
+
context.useProject(cliFlags.project);
|
|
244
|
+
}
|
|
245
|
+
if (cliFlags.profile === true) {
|
|
246
|
+
context.useProfiler();
|
|
247
|
+
}
|
|
248
|
+
if (cliFlags.check === true) {
|
|
249
|
+
context.enableCheckMode();
|
|
250
|
+
}
|
|
251
|
+
context.updateConfig(config);
|
|
252
|
+
}
|
|
253
|
+
class CodegenContext {
|
|
254
|
+
_config;
|
|
255
|
+
_graphqlConfig;
|
|
256
|
+
config;
|
|
257
|
+
_project;
|
|
258
|
+
_checkMode = false;
|
|
259
|
+
_pluginContext = {};
|
|
260
|
+
cwd;
|
|
261
|
+
filepath;
|
|
262
|
+
profiler;
|
|
263
|
+
profilerOutput;
|
|
264
|
+
checkModeStaleFiles = [];
|
|
265
|
+
constructor({ config, graphqlConfig, filepath, }) {
|
|
266
|
+
this._config = config;
|
|
267
|
+
this._graphqlConfig = graphqlConfig;
|
|
268
|
+
this.filepath = this._graphqlConfig ? this._graphqlConfig.filepath : filepath;
|
|
269
|
+
this.cwd = this._graphqlConfig ? this._graphqlConfig.dirpath : process.cwd();
|
|
270
|
+
this.profiler = (0, plugin_helpers_1.createNoopProfiler)();
|
|
271
|
+
}
|
|
272
|
+
useProject(name) {
|
|
273
|
+
this._project = name;
|
|
274
|
+
}
|
|
275
|
+
getConfig(extraConfig) {
|
|
276
|
+
if (!this.config) {
|
|
277
|
+
if (this._graphqlConfig) {
|
|
278
|
+
const project = this._graphqlConfig.getProject(this._project);
|
|
279
|
+
this.config = {
|
|
280
|
+
...project.extension('codegen'),
|
|
281
|
+
schema: project.schema,
|
|
282
|
+
documents: project.documents,
|
|
283
|
+
pluginContext: this._pluginContext,
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
this.config = { ...this._config, pluginContext: this._pluginContext };
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return {
|
|
291
|
+
...extraConfig,
|
|
292
|
+
...this.config,
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
updateConfig(config) {
|
|
296
|
+
this.config = {
|
|
297
|
+
...this.getConfig(),
|
|
298
|
+
...config,
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
enableCheckMode() {
|
|
302
|
+
this._checkMode = true;
|
|
303
|
+
}
|
|
304
|
+
get checkMode() {
|
|
305
|
+
return this._checkMode;
|
|
306
|
+
}
|
|
307
|
+
useProfiler() {
|
|
308
|
+
this.profiler = (0, plugin_helpers_1.createProfiler)();
|
|
309
|
+
const now = new Date(); // 2011-10-05T14:48:00.000Z
|
|
310
|
+
const datetime = now.toISOString().split('.')[0]; // 2011-10-05T14:48:00
|
|
311
|
+
const datetimeNormalized = datetime.replace(/-|:/g, ''); // 20111005T144800
|
|
312
|
+
this.profilerOutput = `codegen-${datetimeNormalized}.json`;
|
|
313
|
+
}
|
|
314
|
+
getPluginContext() {
|
|
315
|
+
return this._pluginContext;
|
|
316
|
+
}
|
|
317
|
+
async loadSchema(pointer) {
|
|
318
|
+
const config = this.getConfig(load_js_1.defaultSchemaLoadOptions);
|
|
319
|
+
if (this._graphqlConfig) {
|
|
320
|
+
// TODO: SchemaWithLoader won't work here
|
|
321
|
+
return addHashToSchema(this._graphqlConfig
|
|
322
|
+
.getProject(this._project)
|
|
323
|
+
.loadSchema(pointer, 'GraphQLSchema', { ...config, ...config.config }));
|
|
324
|
+
}
|
|
325
|
+
return addHashToSchema((0, load_js_1.loadSchema)(pointer, config));
|
|
326
|
+
}
|
|
327
|
+
async loadDocuments(pointer) {
|
|
328
|
+
const config = this.getConfig(load_js_1.defaultDocumentsLoadOptions);
|
|
329
|
+
if (this._graphqlConfig) {
|
|
330
|
+
// TODO: pointer won't work here
|
|
331
|
+
return addHashToDocumentFiles(this._graphqlConfig.getProject(this._project).loadDocuments(pointer, { ...config, ...config.config }));
|
|
332
|
+
}
|
|
333
|
+
return addHashToDocumentFiles((0, load_js_1.loadDocuments)(pointer, config));
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
exports.CodegenContext = CodegenContext;
|
|
337
|
+
function ensureContext(input) {
|
|
338
|
+
return input instanceof CodegenContext ? input : new CodegenContext({ config: input });
|
|
339
|
+
}
|
|
340
|
+
function hashContent(content, encoding = 'hex') {
|
|
341
|
+
return (0, crypto_1.createHash)('sha256').update(content).digest(encoding);
|
|
342
|
+
}
|
|
343
|
+
function hashSchema(schema) {
|
|
344
|
+
return hashContent((0, graphql_1.print)((0, plugin_helpers_1.getCachedDocumentNodeFromSchema)(schema)));
|
|
345
|
+
}
|
|
346
|
+
function addHashToSchema(schemaPromise) {
|
|
347
|
+
return schemaPromise.then(schema => {
|
|
348
|
+
// It's consumed later on. The general purpose is to use it for caching.
|
|
349
|
+
if (!schema.extensions) {
|
|
350
|
+
schema.extensions = {};
|
|
351
|
+
}
|
|
352
|
+
schema.extensions['hash'] = hashSchema(schema);
|
|
353
|
+
return schema;
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
function hashDocument(doc) {
|
|
357
|
+
if (doc.rawSDL) {
|
|
358
|
+
return hashContent(doc.rawSDL);
|
|
359
|
+
}
|
|
360
|
+
if (doc.document) {
|
|
361
|
+
return hashContent((0, graphql_1.print)(doc.document));
|
|
362
|
+
}
|
|
363
|
+
return null;
|
|
364
|
+
}
|
|
365
|
+
function addHashToDocumentFiles(documentFilesPromise) {
|
|
366
|
+
return documentFilesPromise.then(documentFiles => documentFiles.map(doc => {
|
|
367
|
+
doc.hash = hashDocument(doc);
|
|
368
|
+
return doc;
|
|
369
|
+
}));
|
|
370
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getDocumentTransform = getDocumentTransform;
|
|
4
|
+
exports.getDocumentTransformByName = getDocumentTransformByName;
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
async function getDocumentTransform(documentTransform, loader, defaultName) {
|
|
7
|
+
if (typeof documentTransform === 'string') {
|
|
8
|
+
const transformObject = await getDocumentTransformByName(documentTransform, loader);
|
|
9
|
+
return { name: documentTransform, transformObject };
|
|
10
|
+
}
|
|
11
|
+
if (isTransformObject(documentTransform)) {
|
|
12
|
+
return { name: defaultName, transformObject: documentTransform };
|
|
13
|
+
}
|
|
14
|
+
if (isTransformFileConfig(documentTransform)) {
|
|
15
|
+
const name = Object.keys(documentTransform)[0];
|
|
16
|
+
const transformObject = await getDocumentTransformByName(name, loader);
|
|
17
|
+
return { name, transformObject, config: Object.values(documentTransform)[0] };
|
|
18
|
+
}
|
|
19
|
+
throw new Error(`
|
|
20
|
+
An unknown format document transform: '${defaultName}'.
|
|
21
|
+
`);
|
|
22
|
+
}
|
|
23
|
+
function isTransformObject(config) {
|
|
24
|
+
return typeof config === 'object' && config.transform && typeof config.transform === 'function';
|
|
25
|
+
}
|
|
26
|
+
function isTransformFileConfig(config) {
|
|
27
|
+
const keys = Object.keys(config);
|
|
28
|
+
return keys.length === 1 && typeof keys[0] === 'string';
|
|
29
|
+
}
|
|
30
|
+
async function getDocumentTransformByName(name, loader) {
|
|
31
|
+
const possibleNames = [
|
|
32
|
+
`@graphql-codegen/${name}`,
|
|
33
|
+
`@graphql-codegen/${name}-document-transform`,
|
|
34
|
+
name,
|
|
35
|
+
(0, path_1.resolve)(process.cwd(), name),
|
|
36
|
+
];
|
|
37
|
+
const possibleModules = possibleNames.concat((0, path_1.resolve)(process.cwd(), name));
|
|
38
|
+
for (const moduleName of possibleModules) {
|
|
39
|
+
try {
|
|
40
|
+
return await loader(moduleName);
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
if (err.code !== 'MODULE_NOT_FOUND' && err.code !== 'ERR_MODULE_NOT_FOUND') {
|
|
44
|
+
throw new Error(`
|
|
45
|
+
Unable to load document transform matching '${name}'.
|
|
46
|
+
Reason:
|
|
47
|
+
${err.message}
|
|
48
|
+
`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const possibleNamesMsg = possibleNames
|
|
53
|
+
.map(name => `
|
|
54
|
+
- ${name}
|
|
55
|
+
`.trimEnd())
|
|
56
|
+
.join('');
|
|
57
|
+
throw new Error(`
|
|
58
|
+
Unable to find document transform matching '${name}'
|
|
59
|
+
Install one of the following packages:
|
|
60
|
+
|
|
61
|
+
${possibleNamesMsg}
|
|
62
|
+
`);
|
|
63
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generate = generate;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const crypto_1 = require("crypto");
|
|
6
|
+
const path_1 = require("path");
|
|
7
|
+
const log_symbols_1 = tslib_1.__importDefault(require("log-symbols"));
|
|
8
|
+
const codegen_js_1 = require("./codegen.js");
|
|
9
|
+
const config_js_1 = require("./config.js");
|
|
10
|
+
const hooks_js_1 = require("./hooks.js");
|
|
11
|
+
const debugging_js_1 = require("./utils/debugging.js");
|
|
12
|
+
const file_system_js_1 = require("./utils/file-system.js");
|
|
13
|
+
const watcher_js_1 = require("./utils/watcher.js");
|
|
14
|
+
const logger_js_1 = require("./utils/logger.js");
|
|
15
|
+
const hash = (content) => (0, crypto_1.createHash)('sha1').update(content).digest('base64');
|
|
16
|
+
async function generate(input, saveToFile = true) {
|
|
17
|
+
const context = (0, config_js_1.ensureContext)(input);
|
|
18
|
+
const config = context.getConfig();
|
|
19
|
+
await context.profiler.run(() => (0, hooks_js_1.lifecycleHooks)(config.hooks).afterStart(), 'Lifecycle: afterStart');
|
|
20
|
+
let previouslyGeneratedFilenames = [];
|
|
21
|
+
function removeStaleFiles(config, generationResult) {
|
|
22
|
+
const filenames = generationResult.map(o => o.filename);
|
|
23
|
+
// find stale files from previous build which are not present in current build
|
|
24
|
+
const staleFilenames = previouslyGeneratedFilenames.filter(f => !filenames.includes(f));
|
|
25
|
+
for (const filename of staleFilenames) {
|
|
26
|
+
if (shouldOverwrite(config, filename)) {
|
|
27
|
+
(0, file_system_js_1.unlinkFile)(filename, err => {
|
|
28
|
+
const prettyFilename = filename.replace(`${input.cwd || process.cwd()}/`, '');
|
|
29
|
+
if (err) {
|
|
30
|
+
(0, debugging_js_1.debugLog)(`Cannot remove stale file: ${prettyFilename}\n${err}`);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
(0, debugging_js_1.debugLog)(`Removed stale file: ${prettyFilename}`);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
previouslyGeneratedFilenames = filenames;
|
|
39
|
+
}
|
|
40
|
+
const recentOutputHash = new Map();
|
|
41
|
+
async function writeOutput(generationResult) {
|
|
42
|
+
if (!saveToFile) {
|
|
43
|
+
return generationResult;
|
|
44
|
+
}
|
|
45
|
+
if (config.watch) {
|
|
46
|
+
removeStaleFiles(config, generationResult);
|
|
47
|
+
}
|
|
48
|
+
await context.profiler.run(async () => {
|
|
49
|
+
await (0, hooks_js_1.lifecycleHooks)(config.hooks).beforeAllFileWrite(generationResult.map(r => r.filename));
|
|
50
|
+
}, 'Lifecycle: beforeAllFileWrite');
|
|
51
|
+
await context.profiler.run(() => Promise.all(generationResult.map(async (result) => {
|
|
52
|
+
const previousHash = recentOutputHash.get(result.filename) || (await hashFile(result.filename));
|
|
53
|
+
const exists = previousHash !== null;
|
|
54
|
+
// Store previous hash to avoid reading from disk again
|
|
55
|
+
if (previousHash) {
|
|
56
|
+
recentOutputHash.set(result.filename, previousHash);
|
|
57
|
+
}
|
|
58
|
+
if (!shouldOverwrite(config, result.filename) && exists) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
let content = result.content || '';
|
|
62
|
+
const currentHash = hash(content);
|
|
63
|
+
if (previousHash && currentHash === previousHash) {
|
|
64
|
+
(0, debugging_js_1.debugLog)(`Skipping file (${result.filename}) writing due to indentical hash...`);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
// skip updating file in dry mode
|
|
68
|
+
if (context.checkMode) {
|
|
69
|
+
context.checkModeStaleFiles.push(result.filename);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (content.length === 0) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
const absolutePath = (0, path_1.isAbsolute)(result.filename)
|
|
76
|
+
? result.filename
|
|
77
|
+
: (0, path_1.join)(input.cwd || process.cwd(), result.filename);
|
|
78
|
+
const basedir = (0, path_1.dirname)(absolutePath);
|
|
79
|
+
await (0, file_system_js_1.mkdirp)(basedir);
|
|
80
|
+
content = await (0, hooks_js_1.lifecycleHooks)(result.hooks).beforeOneFileWrite(absolutePath, content);
|
|
81
|
+
content = await (0, hooks_js_1.lifecycleHooks)(config.hooks).beforeOneFileWrite(absolutePath, content);
|
|
82
|
+
if (content !== result.content) {
|
|
83
|
+
result.content = content;
|
|
84
|
+
// compare the prettified content with the previous hash
|
|
85
|
+
// to compare the content with an existing prettified file
|
|
86
|
+
if (hash(content) === previousHash) {
|
|
87
|
+
(0, debugging_js_1.debugLog)(`Skipping file (${result.filename}) writing due to indentical hash after prettier...`);
|
|
88
|
+
// the modified content is NOT stored in recentOutputHash
|
|
89
|
+
// so a diff can already be detected before executing the hook
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
await (0, file_system_js_1.writeFile)(absolutePath, result.content);
|
|
94
|
+
recentOutputHash.set(result.filename, currentHash);
|
|
95
|
+
await (0, hooks_js_1.lifecycleHooks)(result.hooks).afterOneFileWrite(result.filename);
|
|
96
|
+
await (0, hooks_js_1.lifecycleHooks)(config.hooks).afterOneFileWrite(result.filename);
|
|
97
|
+
})), 'Write files');
|
|
98
|
+
await context.profiler.run(() => (0, hooks_js_1.lifecycleHooks)(config.hooks).afterAllFileWrite(generationResult.map(r => r.filename)), 'Lifecycle: afterAllFileWrite');
|
|
99
|
+
return generationResult;
|
|
100
|
+
}
|
|
101
|
+
// watch mode
|
|
102
|
+
if (config.watch) {
|
|
103
|
+
return (0, watcher_js_1.createWatcher)(context, writeOutput).runningWatcher;
|
|
104
|
+
}
|
|
105
|
+
const { result: outputFiles, error } = await context.profiler.run(() => (0, codegen_js_1.executeCodegen)(context), 'executeCodegen');
|
|
106
|
+
if (error) {
|
|
107
|
+
// If all generation failed, just throw to return non-zero code.
|
|
108
|
+
if (outputFiles.length === 0) {
|
|
109
|
+
throw error;
|
|
110
|
+
}
|
|
111
|
+
// If partial success, but partial output is not allowed, throw to return non-zero code.
|
|
112
|
+
if (!config.allowPartialOutputs) {
|
|
113
|
+
(0, logger_js_1.getLogger)().error(` ${log_symbols_1.default.error} One or more errors occurred, no files were generated. To allow output on errors, set config.allowPartialOutputs=true`);
|
|
114
|
+
throw error;
|
|
115
|
+
}
|
|
116
|
+
// If partial success, and partial output is allowed, warn and proceed to write to files.
|
|
117
|
+
(0, logger_js_1.getLogger)().warn(` ${log_symbols_1.default.warning} One or more errors occurred, some files were generated. To prevent any output on errors, set config.allowPartialOutputs=false`);
|
|
118
|
+
}
|
|
119
|
+
await context.profiler.run(() => writeOutput(outputFiles), 'writeOutput');
|
|
120
|
+
await context.profiler.run(() => (0, hooks_js_1.lifecycleHooks)(config.hooks).beforeDone(), 'Lifecycle: beforeDone');
|
|
121
|
+
if (context.profilerOutput) {
|
|
122
|
+
await (0, file_system_js_1.writeFile)((0, path_1.join)(context.cwd, context.profilerOutput), JSON.stringify(context.profiler.collect()));
|
|
123
|
+
}
|
|
124
|
+
return outputFiles;
|
|
125
|
+
}
|
|
126
|
+
function shouldOverwrite(config, outputPath) {
|
|
127
|
+
const globalValue = config.overwrite === undefined ? true : !!config.overwrite;
|
|
128
|
+
const outputConfig = config.generates[outputPath];
|
|
129
|
+
if (!outputConfig) {
|
|
130
|
+
(0, debugging_js_1.debugLog)(`Couldn't find a config of ${outputPath}`);
|
|
131
|
+
return globalValue;
|
|
132
|
+
}
|
|
133
|
+
if (isConfiguredOutput(outputConfig) && typeof outputConfig.overwrite === 'boolean') {
|
|
134
|
+
return outputConfig.overwrite;
|
|
135
|
+
}
|
|
136
|
+
return globalValue;
|
|
137
|
+
}
|
|
138
|
+
function isConfiguredOutput(output) {
|
|
139
|
+
return typeof output.plugins !== 'undefined';
|
|
140
|
+
}
|
|
141
|
+
async function hashFile(filePath) {
|
|
142
|
+
try {
|
|
143
|
+
return hash(await (0, file_system_js_1.readFile)(filePath));
|
|
144
|
+
}
|
|
145
|
+
catch (err) {
|
|
146
|
+
if (err && err.code === 'ENOENT') {
|
|
147
|
+
// return null if file does not exist
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
// rethrow unexpected errors
|
|
151
|
+
throw err;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CodegenExtension = void 0;
|
|
4
|
+
exports.findAndLoadGraphQLConfig = findAndLoadGraphQLConfig;
|
|
5
|
+
const apollo_engine_loader_1 = require("@graphql-tools/apollo-engine-loader");
|
|
6
|
+
const code_file_loader_1 = require("@graphql-tools/code-file-loader");
|
|
7
|
+
const git_loader_1 = require("@graphql-tools/git-loader");
|
|
8
|
+
const github_loader_1 = require("@graphql-tools/github-loader");
|
|
9
|
+
const graphql_config_1 = require("graphql-config");
|
|
10
|
+
const CodegenExtension = (api) => {
|
|
11
|
+
// Schema
|
|
12
|
+
api.loaders.schema.register(new code_file_loader_1.CodeFileLoader({
|
|
13
|
+
pluckConfig: {
|
|
14
|
+
skipIndent: true,
|
|
15
|
+
},
|
|
16
|
+
}));
|
|
17
|
+
api.loaders.schema.register(new git_loader_1.GitLoader());
|
|
18
|
+
api.loaders.schema.register(new github_loader_1.GithubLoader());
|
|
19
|
+
api.loaders.schema.register(new apollo_engine_loader_1.ApolloEngineLoader());
|
|
20
|
+
// Documents
|
|
21
|
+
api.loaders.documents.register(new code_file_loader_1.CodeFileLoader({
|
|
22
|
+
pluckConfig: {
|
|
23
|
+
skipIndent: true,
|
|
24
|
+
},
|
|
25
|
+
}));
|
|
26
|
+
api.loaders.documents.register(new git_loader_1.GitLoader());
|
|
27
|
+
api.loaders.documents.register(new github_loader_1.GithubLoader());
|
|
28
|
+
return {
|
|
29
|
+
name: 'codegen',
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
exports.CodegenExtension = CodegenExtension;
|
|
33
|
+
async function findAndLoadGraphQLConfig(filepath) {
|
|
34
|
+
const config = await (0, graphql_config_1.loadConfig)({
|
|
35
|
+
filepath,
|
|
36
|
+
rootDir: process.cwd(),
|
|
37
|
+
extensions: [exports.CodegenExtension],
|
|
38
|
+
throwOnEmpty: false,
|
|
39
|
+
throwOnMissing: false,
|
|
40
|
+
});
|
|
41
|
+
if (isGraphQLConfig(config)) {
|
|
42
|
+
return config;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// Kamil: user might load a config that is not GraphQL Config
|
|
46
|
+
// so we need to check if it's a regular config or not
|
|
47
|
+
function isGraphQLConfig(config) {
|
|
48
|
+
if (!config) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
return config.getDefault().hasExtension('codegen');
|
|
53
|
+
}
|
|
54
|
+
catch { }
|
|
55
|
+
try {
|
|
56
|
+
for (const projectName in config.projects) {
|
|
57
|
+
if (Object.prototype.hasOwnProperty.call(config.projects, projectName)) {
|
|
58
|
+
const project = config.projects[projectName];
|
|
59
|
+
if (project.hasExtension('codegen')) {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
catch { }
|
|
66
|
+
return false;
|
|
67
|
+
}
|