@graphql-codegen/cli 7.3.1 → 7.4.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/cjs/codegen.js +9 -0
- package/cjs/generate-and-save.js +37 -26
- package/cjs/version.js +1 -1
- package/esm/codegen.js +9 -0
- package/esm/generate-and-save.js +37 -26
- package/esm/version.js +1 -1
- package/package.json +2 -2
package/cjs/codegen.js
CHANGED
|
@@ -378,6 +378,15 @@ async function executeCodegen(input) {
|
|
|
378
378
|
filename: outputArgs.filename,
|
|
379
379
|
content: output,
|
|
380
380
|
hooks: outputConfig.hooks || {},
|
|
381
|
+
// A preset sets `outputArgs` per output via `buildGeneratesSection`.
|
|
382
|
+
// Fall back to `outputConfig` so plugin outputs can opt in too.
|
|
383
|
+
contentComparison: outputArgs.contentComparison ?? outputConfig.contentComparison,
|
|
384
|
+
// Carry the entry's `overwrite` onto the file so the CLI can honor it per file.
|
|
385
|
+
// Unlike `contentComparison`, this is intentionally not
|
|
386
|
+
// `outputArgs.overwrite ?? outputConfig.overwrite`: presets should not
|
|
387
|
+
// be able to set `overwrite` per file from buildGeneratesSection
|
|
388
|
+
// (a capability this doesn't need).
|
|
389
|
+
overwrite: outputConfig.overwrite,
|
|
381
390
|
});
|
|
382
391
|
};
|
|
383
392
|
await context.profiler.run(() => Promise.all(outputs.map(process)), `Codegen: ${filename}`);
|
package/cjs/generate-and-save.js
CHANGED
|
@@ -17,15 +17,17 @@ async function generate(input, saveToFile = true) {
|
|
|
17
17
|
const context = (0, config_js_1.ensureContext)(input);
|
|
18
18
|
const config = context.getConfig();
|
|
19
19
|
await context.profiler.run(() => (0, hooks_js_1.lifecycleHooks)(config.hooks).afterStart(), 'Lifecycle: afterStart');
|
|
20
|
-
|
|
20
|
+
// Store only the projection (`filename` + `overwrite`) rather than full results, so a
|
|
21
|
+
// file that disappears is still judged by the `overwrite` of the entry that produced it.
|
|
22
|
+
let previouslyGeneratedFiles = [];
|
|
21
23
|
function removeStaleFiles(config, generationResult) {
|
|
22
24
|
const filenames = generationResult.map(o => o.filename);
|
|
23
25
|
// find stale files from previous build which are not present in current build
|
|
24
|
-
const
|
|
25
|
-
for (const
|
|
26
|
-
if (normalizeOverwriteConfig(config,
|
|
27
|
-
(0, file_system_js_1.unlinkFile)(filename, err => {
|
|
28
|
-
const prettyFilename = filename.replace(`${input.cwd || process.cwd()}/`, '');
|
|
26
|
+
const staleFiles = previouslyGeneratedFiles.filter(f => !filenames.includes(f.filename));
|
|
27
|
+
for (const staleFile of staleFiles) {
|
|
28
|
+
if (normalizeOverwriteConfig(config.overwrite, staleFile.overwrite).removeStaleFiles) {
|
|
29
|
+
(0, file_system_js_1.unlinkFile)(staleFile.filename, err => {
|
|
30
|
+
const prettyFilename = staleFile.filename.replace(`${input.cwd || process.cwd()}/`, '');
|
|
29
31
|
if (err) {
|
|
30
32
|
(0, debugging_js_1.debugLog)(`Cannot remove stale file: ${prettyFilename}\n${err}`);
|
|
31
33
|
}
|
|
@@ -35,8 +37,15 @@ async function generate(input, saveToFile = true) {
|
|
|
35
37
|
});
|
|
36
38
|
}
|
|
37
39
|
}
|
|
38
|
-
|
|
40
|
+
previouslyGeneratedFiles = generationResult.map(res => ({
|
|
41
|
+
filename: res.filename,
|
|
42
|
+
overwrite: res.overwrite,
|
|
43
|
+
}));
|
|
39
44
|
}
|
|
45
|
+
// Records the hash of the content codegen last wrote per file. This is always
|
|
46
|
+
// kept up to date; `FileOutput.contentComparison` only decides whether the
|
|
47
|
+
// skip-check trusts this record ('cache-first') or re-reads the file from disk
|
|
48
|
+
// ('disk'), for outputs whose content depends on the file's existing content.
|
|
40
49
|
const recentOutputHash = new Map();
|
|
41
50
|
async function writeOutput(generationResult) {
|
|
42
51
|
if (!saveToFile) {
|
|
@@ -49,13 +58,29 @@ async function generate(input, saveToFile = true) {
|
|
|
49
58
|
await (0, hooks_js_1.lifecycleHooks)(config.hooks).beforeAllFileWrite(generationResult.map(r => r.filename));
|
|
50
59
|
}, 'Lifecycle: beforeAllFileWrite');
|
|
51
60
|
await context.profiler.run(() => Promise.all(generationResult.map(async (result) => {
|
|
52
|
-
|
|
61
|
+
// The "previous" hash the skip-check compares against:
|
|
62
|
+
// - 'cache-first' trusts the in-memory record of what codegen last wrote
|
|
63
|
+
// (falling back to disk when there's no entry).
|
|
64
|
+
// - 'disk' always re-reads the file, because the output's content
|
|
65
|
+
// depends on the file's existing content
|
|
66
|
+
// (e.g. a preset that reads the file and rewrites part of it), so the
|
|
67
|
+
// in-memory record could wrongly skip a write when the file was changed
|
|
68
|
+
// on disk but the regenerated content matches a previous run.
|
|
69
|
+
const previousHash = await (async function getPreviousHash() {
|
|
70
|
+
const { contentComparison = 'cache-first' } = result;
|
|
71
|
+
if (contentComparison === 'disk') {
|
|
72
|
+
return await hashFile(result.filename);
|
|
73
|
+
}
|
|
74
|
+
return recentOutputHash.get(result.filename) || (await hashFile(result.filename));
|
|
75
|
+
})();
|
|
53
76
|
const exists = previousHash !== null;
|
|
54
|
-
//
|
|
77
|
+
// Always update the cache, regardless of `cache-first` or `disk` option,
|
|
78
|
+
// so subsequent runs have consistent entry to compare against
|
|
55
79
|
if (previousHash) {
|
|
56
80
|
recentOutputHash.set(result.filename, previousHash);
|
|
57
81
|
}
|
|
58
|
-
if (!normalizeOverwriteConfig(config, result.
|
|
82
|
+
if (!normalizeOverwriteConfig(config.overwrite, result.overwrite).updateExistingFiles &&
|
|
83
|
+
exists) {
|
|
59
84
|
return;
|
|
60
85
|
}
|
|
61
86
|
let content = result.content || '';
|
|
@@ -132,19 +157,8 @@ async function generate(input, saveToFile = true) {
|
|
|
132
157
|
await writeProfilerOutput();
|
|
133
158
|
return outputFiles;
|
|
134
159
|
}
|
|
135
|
-
function normalizeOverwriteConfig(
|
|
136
|
-
const overwrite =
|
|
137
|
-
const { overwrite: result = true } = config;
|
|
138
|
-
const outputConfig = config.generates[outputPath];
|
|
139
|
-
if (!outputConfig) {
|
|
140
|
-
(0, debugging_js_1.debugLog)(`Couldn't find a config of ${outputPath}`);
|
|
141
|
-
return result;
|
|
142
|
-
}
|
|
143
|
-
if (isConfiguredOutput(outputConfig) && outputConfig.overwrite !== undefined) {
|
|
144
|
-
return outputConfig.overwrite;
|
|
145
|
-
}
|
|
146
|
-
return result;
|
|
147
|
-
})();
|
|
160
|
+
function normalizeOverwriteConfig(configOverwrite, fileOverwrite) {
|
|
161
|
+
const overwrite = fileOverwrite ?? configOverwrite ?? true;
|
|
148
162
|
if (overwrite === true) {
|
|
149
163
|
return {
|
|
150
164
|
removeStaleFiles: true,
|
|
@@ -160,9 +174,6 @@ function normalizeOverwriteConfig(config, outputPath) {
|
|
|
160
174
|
const { removeStaleFiles = true, updateExistingFiles = true } = overwrite;
|
|
161
175
|
return { removeStaleFiles, updateExistingFiles };
|
|
162
176
|
}
|
|
163
|
-
function isConfiguredOutput(output) {
|
|
164
|
-
return typeof output.plugins !== 'undefined';
|
|
165
|
-
}
|
|
166
177
|
async function hashFile(filePath) {
|
|
167
178
|
try {
|
|
168
179
|
return hash(await (0, file_system_js_1.readFile)(filePath));
|
package/cjs/version.js
CHANGED
package/esm/codegen.js
CHANGED
|
@@ -374,6 +374,15 @@ export async function executeCodegen(input) {
|
|
|
374
374
|
filename: outputArgs.filename,
|
|
375
375
|
content: output,
|
|
376
376
|
hooks: outputConfig.hooks || {},
|
|
377
|
+
// A preset sets `outputArgs` per output via `buildGeneratesSection`.
|
|
378
|
+
// Fall back to `outputConfig` so plugin outputs can opt in too.
|
|
379
|
+
contentComparison: outputArgs.contentComparison ?? outputConfig.contentComparison,
|
|
380
|
+
// Carry the entry's `overwrite` onto the file so the CLI can honor it per file.
|
|
381
|
+
// Unlike `contentComparison`, this is intentionally not
|
|
382
|
+
// `outputArgs.overwrite ?? outputConfig.overwrite`: presets should not
|
|
383
|
+
// be able to set `overwrite` per file from buildGeneratesSection
|
|
384
|
+
// (a capability this doesn't need).
|
|
385
|
+
overwrite: outputConfig.overwrite,
|
|
377
386
|
});
|
|
378
387
|
};
|
|
379
388
|
await context.profiler.run(() => Promise.all(outputs.map(process)), `Codegen: ${filename}`);
|
package/esm/generate-and-save.js
CHANGED
|
@@ -13,15 +13,17 @@ export async function generate(input, saveToFile = true) {
|
|
|
13
13
|
const context = ensureContext(input);
|
|
14
14
|
const config = context.getConfig();
|
|
15
15
|
await context.profiler.run(() => lifecycleHooks(config.hooks).afterStart(), 'Lifecycle: afterStart');
|
|
16
|
-
|
|
16
|
+
// Store only the projection (`filename` + `overwrite`) rather than full results, so a
|
|
17
|
+
// file that disappears is still judged by the `overwrite` of the entry that produced it.
|
|
18
|
+
let previouslyGeneratedFiles = [];
|
|
17
19
|
function removeStaleFiles(config, generationResult) {
|
|
18
20
|
const filenames = generationResult.map(o => o.filename);
|
|
19
21
|
// find stale files from previous build which are not present in current build
|
|
20
|
-
const
|
|
21
|
-
for (const
|
|
22
|
-
if (normalizeOverwriteConfig(config,
|
|
23
|
-
unlinkFile(filename, err => {
|
|
24
|
-
const prettyFilename = filename.replace(`${input.cwd || process.cwd()}/`, '');
|
|
22
|
+
const staleFiles = previouslyGeneratedFiles.filter(f => !filenames.includes(f.filename));
|
|
23
|
+
for (const staleFile of staleFiles) {
|
|
24
|
+
if (normalizeOverwriteConfig(config.overwrite, staleFile.overwrite).removeStaleFiles) {
|
|
25
|
+
unlinkFile(staleFile.filename, err => {
|
|
26
|
+
const prettyFilename = staleFile.filename.replace(`${input.cwd || process.cwd()}/`, '');
|
|
25
27
|
if (err) {
|
|
26
28
|
debugLog(`Cannot remove stale file: ${prettyFilename}\n${err}`);
|
|
27
29
|
}
|
|
@@ -31,8 +33,15 @@ export async function generate(input, saveToFile = true) {
|
|
|
31
33
|
});
|
|
32
34
|
}
|
|
33
35
|
}
|
|
34
|
-
|
|
36
|
+
previouslyGeneratedFiles = generationResult.map(res => ({
|
|
37
|
+
filename: res.filename,
|
|
38
|
+
overwrite: res.overwrite,
|
|
39
|
+
}));
|
|
35
40
|
}
|
|
41
|
+
// Records the hash of the content codegen last wrote per file. This is always
|
|
42
|
+
// kept up to date; `FileOutput.contentComparison` only decides whether the
|
|
43
|
+
// skip-check trusts this record ('cache-first') or re-reads the file from disk
|
|
44
|
+
// ('disk'), for outputs whose content depends on the file's existing content.
|
|
36
45
|
const recentOutputHash = new Map();
|
|
37
46
|
async function writeOutput(generationResult) {
|
|
38
47
|
if (!saveToFile) {
|
|
@@ -45,13 +54,29 @@ export async function generate(input, saveToFile = true) {
|
|
|
45
54
|
await lifecycleHooks(config.hooks).beforeAllFileWrite(generationResult.map(r => r.filename));
|
|
46
55
|
}, 'Lifecycle: beforeAllFileWrite');
|
|
47
56
|
await context.profiler.run(() => Promise.all(generationResult.map(async (result) => {
|
|
48
|
-
|
|
57
|
+
// The "previous" hash the skip-check compares against:
|
|
58
|
+
// - 'cache-first' trusts the in-memory record of what codegen last wrote
|
|
59
|
+
// (falling back to disk when there's no entry).
|
|
60
|
+
// - 'disk' always re-reads the file, because the output's content
|
|
61
|
+
// depends on the file's existing content
|
|
62
|
+
// (e.g. a preset that reads the file and rewrites part of it), so the
|
|
63
|
+
// in-memory record could wrongly skip a write when the file was changed
|
|
64
|
+
// on disk but the regenerated content matches a previous run.
|
|
65
|
+
const previousHash = await (async function getPreviousHash() {
|
|
66
|
+
const { contentComparison = 'cache-first' } = result;
|
|
67
|
+
if (contentComparison === 'disk') {
|
|
68
|
+
return await hashFile(result.filename);
|
|
69
|
+
}
|
|
70
|
+
return recentOutputHash.get(result.filename) || (await hashFile(result.filename));
|
|
71
|
+
})();
|
|
49
72
|
const exists = previousHash !== null;
|
|
50
|
-
//
|
|
73
|
+
// Always update the cache, regardless of `cache-first` or `disk` option,
|
|
74
|
+
// so subsequent runs have consistent entry to compare against
|
|
51
75
|
if (previousHash) {
|
|
52
76
|
recentOutputHash.set(result.filename, previousHash);
|
|
53
77
|
}
|
|
54
|
-
if (!normalizeOverwriteConfig(config, result.
|
|
78
|
+
if (!normalizeOverwriteConfig(config.overwrite, result.overwrite).updateExistingFiles &&
|
|
79
|
+
exists) {
|
|
55
80
|
return;
|
|
56
81
|
}
|
|
57
82
|
let content = result.content || '';
|
|
@@ -128,19 +153,8 @@ export async function generate(input, saveToFile = true) {
|
|
|
128
153
|
await writeProfilerOutput();
|
|
129
154
|
return outputFiles;
|
|
130
155
|
}
|
|
131
|
-
function normalizeOverwriteConfig(
|
|
132
|
-
const overwrite =
|
|
133
|
-
const { overwrite: result = true } = config;
|
|
134
|
-
const outputConfig = config.generates[outputPath];
|
|
135
|
-
if (!outputConfig) {
|
|
136
|
-
debugLog(`Couldn't find a config of ${outputPath}`);
|
|
137
|
-
return result;
|
|
138
|
-
}
|
|
139
|
-
if (isConfiguredOutput(outputConfig) && outputConfig.overwrite !== undefined) {
|
|
140
|
-
return outputConfig.overwrite;
|
|
141
|
-
}
|
|
142
|
-
return result;
|
|
143
|
-
})();
|
|
156
|
+
function normalizeOverwriteConfig(configOverwrite, fileOverwrite) {
|
|
157
|
+
const overwrite = fileOverwrite ?? configOverwrite ?? true;
|
|
144
158
|
if (overwrite === true) {
|
|
145
159
|
return {
|
|
146
160
|
removeStaleFiles: true,
|
|
@@ -156,9 +170,6 @@ function normalizeOverwriteConfig(config, outputPath) {
|
|
|
156
170
|
const { removeStaleFiles = true, updateExistingFiles = true } = overwrite;
|
|
157
171
|
return { removeStaleFiles, updateExistingFiles };
|
|
158
172
|
}
|
|
159
|
-
function isConfiguredOutput(output) {
|
|
160
|
-
return typeof output.plugins !== 'undefined';
|
|
161
|
-
}
|
|
162
173
|
async function hashFile(filePath) {
|
|
163
174
|
try {
|
|
164
175
|
return hash(await readFile(filePath));
|
package/esm/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '7.
|
|
1
|
+
export const version = '7.4.0';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graphql-codegen/cli",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.4.0",
|
|
4
4
|
"peerDependenciesMeta": {
|
|
5
5
|
"@parcel/watcher": {
|
|
6
6
|
"optional": true
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"yargs": "^18.0.0",
|
|
46
46
|
"@graphql-codegen/client-preset": "^6.1.3",
|
|
47
47
|
"@graphql-codegen/core": "^6.2.0",
|
|
48
|
-
"@graphql-codegen/plugin-helpers": "^7.
|
|
48
|
+
"@graphql-codegen/plugin-helpers": "^7.3.0"
|
|
49
49
|
},
|
|
50
50
|
"repository": {
|
|
51
51
|
"type": "git",
|