@graphql-codegen/cli 2.5.0-alpha-fc06eb8e7.0 → 2.6.0-alpha-c9d165f6a.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/bin.js +142 -63
- package/config.d.ts +2 -2
- package/index.js +143 -63
- package/index.mjs +142 -63
- package/package.json +4 -4
- package/utils/cli-error.d.ts +10 -0
- package/utils/file-system.d.ts +3 -3
package/bin.js
CHANGED
|
@@ -28,6 +28,7 @@ const path = require('path');
|
|
|
28
28
|
const path__default = _interopDefault(path);
|
|
29
29
|
const pluginHelpers = require('@graphql-codegen/plugin-helpers');
|
|
30
30
|
const core = require('@graphql-codegen/core');
|
|
31
|
+
const utils = require('@graphql-tools/utils');
|
|
31
32
|
const chalk = _interopDefault(require('chalk'));
|
|
32
33
|
const logSymbols = _interopDefault(require('log-symbols'));
|
|
33
34
|
const ansiEscapes = _interopDefault(require('ansi-escapes'));
|
|
@@ -52,11 +53,11 @@ const yaml = _interopDefault(require('yaml'));
|
|
|
52
53
|
const module$1 = require('module');
|
|
53
54
|
const fs = require('fs');
|
|
54
55
|
const fs__default = _interopDefault(fs);
|
|
56
|
+
const os = require('os');
|
|
55
57
|
const Listr = _interopDefault(require('listr'));
|
|
56
58
|
const isGlob = _interopDefault(require('is-glob'));
|
|
57
59
|
const debounce = _interopDefault(require('debounce'));
|
|
58
|
-
const
|
|
59
|
-
const mkdirp = _interopDefault(require('mkdirp'));
|
|
60
|
+
const fsExtra = require('fs-extra');
|
|
60
61
|
const crypto = require('crypto');
|
|
61
62
|
const inquirer = _interopDefault(require('inquirer'));
|
|
62
63
|
const detectIndent = _interopDefault(require('detect-indent'));
|
|
@@ -729,6 +730,32 @@ function updateContextWithCliFlags(context, cliFlags) {
|
|
|
729
730
|
class CodegenContext {
|
|
730
731
|
constructor({ config, graphqlConfig, filepath, }) {
|
|
731
732
|
this._pluginContext = {};
|
|
733
|
+
this.loadSchema = useCache((pointer) => {
|
|
734
|
+
const config = this.getConfig(defaultSchemaLoadOptions);
|
|
735
|
+
if (this._graphqlConfig) {
|
|
736
|
+
// TODO: SchemaWithLoader won't work here
|
|
737
|
+
return this._graphqlConfig.getProject(this._project).loadSchema(pointer, 'GraphQLSchema', config);
|
|
738
|
+
}
|
|
739
|
+
return loadSchema(pointer, config);
|
|
740
|
+
}, {
|
|
741
|
+
cacheKey(pointer) {
|
|
742
|
+
return JSON.stringify(pointer);
|
|
743
|
+
},
|
|
744
|
+
skip: () => { var _a; return !!((_a = this.config) === null || _a === void 0 ? void 0 : _a.watch); },
|
|
745
|
+
});
|
|
746
|
+
this.loadDocuments = useCache((pointer) => {
|
|
747
|
+
const config = this.getConfig(defaultDocumentsLoadOptions);
|
|
748
|
+
if (this._graphqlConfig) {
|
|
749
|
+
// TODO: pointer won't work here
|
|
750
|
+
return this._graphqlConfig.getProject(this._project).loadDocuments(pointer, config);
|
|
751
|
+
}
|
|
752
|
+
return loadDocuments(pointer, config);
|
|
753
|
+
}, {
|
|
754
|
+
cacheKey(pointer) {
|
|
755
|
+
return JSON.stringify(pointer);
|
|
756
|
+
},
|
|
757
|
+
skip: () => { var _a; return !!((_a = this.config) === null || _a === void 0 ? void 0 : _a.watch); },
|
|
758
|
+
});
|
|
732
759
|
this._config = config;
|
|
733
760
|
this._graphqlConfig = graphqlConfig;
|
|
734
761
|
this.filepath = this._graphqlConfig ? this._graphqlConfig.filepath : filepath;
|
|
@@ -774,27 +801,55 @@ class CodegenContext {
|
|
|
774
801
|
getPluginContext() {
|
|
775
802
|
return this._pluginContext;
|
|
776
803
|
}
|
|
777
|
-
async loadSchema(pointer) {
|
|
778
|
-
const config = this.getConfig(defaultSchemaLoadOptions);
|
|
779
|
-
if (this._graphqlConfig) {
|
|
780
|
-
// TODO: SchemaWithLoader won't work here
|
|
781
|
-
return this._graphqlConfig.getProject(this._project).loadSchema(pointer, 'GraphQLSchema', config);
|
|
782
|
-
}
|
|
783
|
-
return loadSchema(pointer, config);
|
|
784
|
-
}
|
|
785
|
-
async loadDocuments(pointer) {
|
|
786
|
-
const config = this.getConfig(defaultDocumentsLoadOptions);
|
|
787
|
-
if (this._graphqlConfig) {
|
|
788
|
-
// TODO: pointer won't work here
|
|
789
|
-
const documents = await this._graphqlConfig.getProject(this._project).loadDocuments(pointer, config);
|
|
790
|
-
return documents;
|
|
791
|
-
}
|
|
792
|
-
return loadDocuments(pointer, config);
|
|
793
|
-
}
|
|
794
804
|
}
|
|
795
805
|
function ensureContext(input) {
|
|
796
806
|
return input instanceof CodegenContext ? input : new CodegenContext({ config: input });
|
|
797
807
|
}
|
|
808
|
+
/**
|
|
809
|
+
* The goal here is to avoid loading the same schema or documents across projects.
|
|
810
|
+
*/
|
|
811
|
+
function useCache(originalFunction, { cacheKey, skip = () => false }) {
|
|
812
|
+
if (skip()) {
|
|
813
|
+
return originalFunction;
|
|
814
|
+
}
|
|
815
|
+
const cache = new Map();
|
|
816
|
+
return (input) => {
|
|
817
|
+
const key = cacheKey(input);
|
|
818
|
+
if (cache.has(key)) {
|
|
819
|
+
return cache.get(key);
|
|
820
|
+
}
|
|
821
|
+
const result = originalFunction(input);
|
|
822
|
+
cache.set(key, result);
|
|
823
|
+
return result;
|
|
824
|
+
};
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
|
|
828
|
+
const isNode = typeof process !== 'undefined' && process.versions != null && process.versions.node != null;
|
|
829
|
+
|
|
830
|
+
function isListrError(err) {
|
|
831
|
+
return err.name === 'ListrError' && Array.isArray(err.errors) && err.errors.length > 0;
|
|
832
|
+
}
|
|
833
|
+
function cliError(err, exitOnError = true) {
|
|
834
|
+
let msg;
|
|
835
|
+
if (err instanceof Error) {
|
|
836
|
+
msg = err.message || err.toString();
|
|
837
|
+
}
|
|
838
|
+
else if (typeof err === 'string') {
|
|
839
|
+
msg = err;
|
|
840
|
+
}
|
|
841
|
+
else {
|
|
842
|
+
msg = JSON.stringify(err);
|
|
843
|
+
}
|
|
844
|
+
// eslint-disable-next-line no-console
|
|
845
|
+
console.error(msg);
|
|
846
|
+
if (exitOnError && isNode) {
|
|
847
|
+
process.exit(1);
|
|
848
|
+
}
|
|
849
|
+
else if (exitOnError && isBrowser) {
|
|
850
|
+
throw err;
|
|
851
|
+
}
|
|
852
|
+
}
|
|
798
853
|
|
|
799
854
|
const makeDefaultLoader = (from) => {
|
|
800
855
|
if (fs__default.statSync(from).isDirectory()) {
|
|
@@ -995,10 +1050,13 @@ async function executeCodegen(input) {
|
|
|
995
1050
|
title: 'Load GraphQL documents',
|
|
996
1051
|
task: wrapTask(async () => {
|
|
997
1052
|
debugLog(`[CLI] Loading Documents`);
|
|
998
|
-
|
|
999
|
-
const
|
|
1000
|
-
|
|
1001
|
-
|
|
1053
|
+
// get different cache for shared docs and output specific docs
|
|
1054
|
+
const results = await Promise.all([rootDocuments, outputSpecificDocuments].map(docs => {
|
|
1055
|
+
const hash = JSON.stringify(docs);
|
|
1056
|
+
return documentsLoadingCache.load(hash);
|
|
1057
|
+
}));
|
|
1058
|
+
const documents = [];
|
|
1059
|
+
results.forEach(source => documents.push(...source.documents));
|
|
1002
1060
|
if (documents.length > 0) {
|
|
1003
1061
|
outputDocuments.push(...documents);
|
|
1004
1062
|
}
|
|
@@ -1078,12 +1136,25 @@ async function executeCodegen(input) {
|
|
|
1078
1136
|
}), {
|
|
1079
1137
|
// it doesn't stop when one of tasks failed, to finish at least some of outputs
|
|
1080
1138
|
exitOnError: false,
|
|
1081
|
-
|
|
1082
|
-
concurrent: 4,
|
|
1139
|
+
concurrent: os.cpus().length,
|
|
1083
1140
|
});
|
|
1084
1141
|
},
|
|
1085
1142
|
});
|
|
1086
|
-
|
|
1143
|
+
try {
|
|
1144
|
+
await listr.run();
|
|
1145
|
+
}
|
|
1146
|
+
catch (err) {
|
|
1147
|
+
if (isListrError(err)) {
|
|
1148
|
+
const allErrs = err.errors.map(subErr => pluginHelpers.isDetailedError(subErr)
|
|
1149
|
+
? `${subErr.message} for "${subErr.source}"${subErr.details}`
|
|
1150
|
+
: subErr.message || subErr.toString());
|
|
1151
|
+
const newErr = new utils.AggregateError(err.errors, `${err.message} ${allErrs.join('\n\n')}`);
|
|
1152
|
+
// Best-effort to all stack traces for debugging
|
|
1153
|
+
newErr.stack = `${newErr.stack}\n\n${err.errors.map(subErr => subErr.stack).join('\n\n')}`;
|
|
1154
|
+
throw newErr;
|
|
1155
|
+
}
|
|
1156
|
+
throw err;
|
|
1157
|
+
}
|
|
1087
1158
|
return result;
|
|
1088
1159
|
}
|
|
1089
1160
|
|
|
@@ -1212,22 +1283,22 @@ const createWatcher = (initalContext, onNext) => {
|
|
|
1212
1283
|
});
|
|
1213
1284
|
};
|
|
1214
1285
|
|
|
1215
|
-
function
|
|
1216
|
-
return
|
|
1286
|
+
function writeFile(filepath, content) {
|
|
1287
|
+
return fsExtra.writeFile(filepath, content);
|
|
1217
1288
|
}
|
|
1218
|
-
function
|
|
1219
|
-
return
|
|
1289
|
+
function readFile(filepath) {
|
|
1290
|
+
return fsExtra.readFile(filepath, 'utf-8');
|
|
1220
1291
|
}
|
|
1221
|
-
function fileExists(filePath) {
|
|
1292
|
+
async function fileExists(filePath) {
|
|
1222
1293
|
try {
|
|
1223
|
-
return
|
|
1294
|
+
return (await fsExtra.stat(filePath)).isFile();
|
|
1224
1295
|
}
|
|
1225
1296
|
catch (err) {
|
|
1226
1297
|
return false;
|
|
1227
1298
|
}
|
|
1228
1299
|
}
|
|
1229
1300
|
function unlinkFile(filePath, cb) {
|
|
1230
|
-
|
|
1301
|
+
fsExtra.unlink(filePath, cb);
|
|
1231
1302
|
}
|
|
1232
1303
|
|
|
1233
1304
|
const hash = (content) => crypto.createHash('sha1').update(content).digest('base64');
|
|
@@ -1242,7 +1313,7 @@ async function generate(input, saveToFile = true) {
|
|
|
1242
1313
|
const staleFilenames = previouslyGeneratedFilenames.filter(f => !filenames.includes(f));
|
|
1243
1314
|
staleFilenames.forEach(filename => {
|
|
1244
1315
|
if (shouldOverwrite(config, filename)) {
|
|
1245
|
-
unlinkFile(filename, err => {
|
|
1316
|
+
return unlinkFile(filename, err => {
|
|
1246
1317
|
const prettyFilename = filename.replace(`${input.cwd || process.cwd()}/`, '');
|
|
1247
1318
|
if (err) {
|
|
1248
1319
|
debugLog(`Cannot remove stale file: ${prettyFilename}\n${err}`);
|
|
@@ -1263,7 +1334,39 @@ async function generate(input, saveToFile = true) {
|
|
|
1263
1334
|
if (config.watch) {
|
|
1264
1335
|
removeStaleFiles(config, generationResult);
|
|
1265
1336
|
}
|
|
1266
|
-
await context.profiler.run(
|
|
1337
|
+
await context.profiler.run(async () => {
|
|
1338
|
+
await lifecycleHooks(config.hooks).beforeAllFileWrite(generationResult.map(r => r.filename));
|
|
1339
|
+
await Promise.all(generationResult.map(async (result) => {
|
|
1340
|
+
const exists = await fileExists(result.filename);
|
|
1341
|
+
if (!shouldOverwrite(config, result.filename) && exists) {
|
|
1342
|
+
return;
|
|
1343
|
+
}
|
|
1344
|
+
const content = result.content || '';
|
|
1345
|
+
const currentHash = hash(content);
|
|
1346
|
+
let previousHash = recentOutputHash.get(result.filename);
|
|
1347
|
+
if (!previousHash && exists) {
|
|
1348
|
+
previousHash = hash(await readFile(result.filename));
|
|
1349
|
+
}
|
|
1350
|
+
if (previousHash && currentHash === previousHash) {
|
|
1351
|
+
debugLog(`Skipping file (${result.filename}) writing due to indentical hash...`);
|
|
1352
|
+
return;
|
|
1353
|
+
}
|
|
1354
|
+
if (content.length === 0) {
|
|
1355
|
+
return;
|
|
1356
|
+
}
|
|
1357
|
+
recentOutputHash.set(result.filename, currentHash);
|
|
1358
|
+
const basedir = path.dirname(result.filename);
|
|
1359
|
+
await lifecycleHooks(result.hooks).beforeOneFileWrite(result.filename);
|
|
1360
|
+
await lifecycleHooks(config.hooks).beforeOneFileWrite(result.filename);
|
|
1361
|
+
await fsExtra.mkdirp(basedir);
|
|
1362
|
+
const absolutePath = path.isAbsolute(result.filename)
|
|
1363
|
+
? result.filename
|
|
1364
|
+
: path.join(input.cwd || process.cwd(), result.filename);
|
|
1365
|
+
await writeFile(absolutePath, result.content);
|
|
1366
|
+
await lifecycleHooks(result.hooks).afterOneFileWrite(result.filename);
|
|
1367
|
+
await lifecycleHooks(config.hooks).afterOneFileWrite(result.filename);
|
|
1368
|
+
}));
|
|
1369
|
+
}, 'Lifecycle: beforeAllFileWrite');
|
|
1267
1370
|
await context.profiler.run(() => Promise.all(generationResult.map(async (result) => {
|
|
1268
1371
|
const exists = fileExists(result.filename);
|
|
1269
1372
|
if (!shouldOverwrite(config, result.filename) && exists) {
|
|
@@ -1273,7 +1376,7 @@ async function generate(input, saveToFile = true) {
|
|
|
1273
1376
|
const currentHash = hash(content);
|
|
1274
1377
|
let previousHash = recentOutputHash.get(result.filename);
|
|
1275
1378
|
if (!previousHash && exists) {
|
|
1276
|
-
previousHash = hash(
|
|
1379
|
+
previousHash = hash(await readFile(result.filename));
|
|
1277
1380
|
}
|
|
1278
1381
|
if (previousHash && currentHash === previousHash) {
|
|
1279
1382
|
debugLog(`Skipping file (${result.filename}) writing due to identical hash...`);
|
|
@@ -1286,11 +1389,11 @@ async function generate(input, saveToFile = true) {
|
|
|
1286
1389
|
const basedir = path.dirname(result.filename);
|
|
1287
1390
|
await lifecycleHooks(result.hooks).beforeOneFileWrite(result.filename);
|
|
1288
1391
|
await lifecycleHooks(config.hooks).beforeOneFileWrite(result.filename);
|
|
1289
|
-
mkdirp.sync(basedir);
|
|
1392
|
+
fsExtra.mkdirp.sync(basedir);
|
|
1290
1393
|
const absolutePath = path.isAbsolute(result.filename)
|
|
1291
1394
|
? result.filename
|
|
1292
1395
|
: path.join(input.cwd || process.cwd(), result.filename);
|
|
1293
|
-
|
|
1396
|
+
await writeFile(absolutePath, result.content);
|
|
1294
1397
|
await lifecycleHooks(result.hooks).afterOneFileWrite(result.filename);
|
|
1295
1398
|
await lifecycleHooks(config.hooks).afterOneFileWrite(result.filename);
|
|
1296
1399
|
})), 'Write files');
|
|
@@ -1305,7 +1408,7 @@ async function generate(input, saveToFile = true) {
|
|
|
1305
1408
|
await context.profiler.run(() => writeOutput(outputFiles), 'writeOutput');
|
|
1306
1409
|
await context.profiler.run(() => lifecycleHooks(config.hooks).beforeDone(), 'Lifecycle: beforeDone');
|
|
1307
1410
|
if (context.profilerOutput) {
|
|
1308
|
-
|
|
1411
|
+
await writeFile(path.join(context.cwd, context.profilerOutput), JSON.stringify(context.profiler.collect()));
|
|
1309
1412
|
}
|
|
1310
1413
|
return outputFiles;
|
|
1311
1414
|
}
|
|
@@ -1805,30 +1908,6 @@ async function ensureGraphQlPackage() {
|
|
|
1805
1908
|
}
|
|
1806
1909
|
}
|
|
1807
1910
|
|
|
1808
|
-
const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
|
|
1809
|
-
const isNode = typeof process !== 'undefined' && process.versions != null && process.versions.node != null;
|
|
1810
|
-
|
|
1811
|
-
function cliError(err, exitOnError = true) {
|
|
1812
|
-
let msg;
|
|
1813
|
-
if (err instanceof Error) {
|
|
1814
|
-
msg = err.message || err.toString();
|
|
1815
|
-
}
|
|
1816
|
-
else if (typeof err === 'string') {
|
|
1817
|
-
msg = err;
|
|
1818
|
-
}
|
|
1819
|
-
else {
|
|
1820
|
-
msg = JSON.stringify(err);
|
|
1821
|
-
}
|
|
1822
|
-
// eslint-disable-next-line no-console
|
|
1823
|
-
console.error(msg);
|
|
1824
|
-
if (exitOnError && isNode) {
|
|
1825
|
-
process.exit(1);
|
|
1826
|
-
}
|
|
1827
|
-
else if (exitOnError && isBrowser) {
|
|
1828
|
-
throw err;
|
|
1829
|
-
}
|
|
1830
|
-
}
|
|
1831
|
-
|
|
1832
1911
|
const [, , cmd] = process.argv;
|
|
1833
1912
|
runCli(cmd)
|
|
1834
1913
|
.then(() => {
|
package/config.d.ts
CHANGED
|
@@ -110,7 +110,7 @@ export declare class CodegenContext {
|
|
|
110
110
|
getPluginContext(): {
|
|
111
111
|
[key: string]: any;
|
|
112
112
|
};
|
|
113
|
-
loadSchema(
|
|
114
|
-
loadDocuments(
|
|
113
|
+
loadSchema: (input: Types.Schema) => Promise<GraphQLSchema>;
|
|
114
|
+
loadDocuments: (input: Types.OperationDocument[]) => Promise<import("graphql-config").Source[]>;
|
|
115
115
|
}
|
|
116
116
|
export declare function ensureContext(input: CodegenContext | Types.Config): CodegenContext;
|
package/index.js
CHANGED
|
@@ -25,6 +25,7 @@ function _interopNamespace(e) {
|
|
|
25
25
|
|
|
26
26
|
const pluginHelpers = require('@graphql-codegen/plugin-helpers');
|
|
27
27
|
const core = require('@graphql-codegen/core');
|
|
28
|
+
const utils = require('@graphql-tools/utils');
|
|
28
29
|
const chalk = _interopDefault(require('chalk'));
|
|
29
30
|
const logSymbols = _interopDefault(require('log-symbols'));
|
|
30
31
|
const ansiEscapes = _interopDefault(require('ansi-escapes'));
|
|
@@ -52,12 +53,12 @@ const yaml = _interopDefault(require('yaml'));
|
|
|
52
53
|
const module$1 = require('module');
|
|
53
54
|
const fs = require('fs');
|
|
54
55
|
const fs__default = _interopDefault(fs);
|
|
56
|
+
const os = require('os');
|
|
55
57
|
const Listr = _interopDefault(require('listr'));
|
|
56
58
|
const child_process = require('child_process');
|
|
57
59
|
const isGlob = _interopDefault(require('is-glob'));
|
|
58
60
|
const debounce = _interopDefault(require('debounce'));
|
|
59
|
-
const
|
|
60
|
-
const mkdirp = _interopDefault(require('mkdirp'));
|
|
61
|
+
const fsExtra = require('fs-extra');
|
|
61
62
|
const crypto = require('crypto');
|
|
62
63
|
const inquirer = _interopDefault(require('inquirer'));
|
|
63
64
|
const detectIndent = _interopDefault(require('detect-indent'));
|
|
@@ -647,6 +648,32 @@ function updateContextWithCliFlags(context, cliFlags) {
|
|
|
647
648
|
class CodegenContext {
|
|
648
649
|
constructor({ config, graphqlConfig, filepath, }) {
|
|
649
650
|
this._pluginContext = {};
|
|
651
|
+
this.loadSchema = useCache((pointer) => {
|
|
652
|
+
const config = this.getConfig(defaultSchemaLoadOptions);
|
|
653
|
+
if (this._graphqlConfig) {
|
|
654
|
+
// TODO: SchemaWithLoader won't work here
|
|
655
|
+
return this._graphqlConfig.getProject(this._project).loadSchema(pointer, 'GraphQLSchema', config);
|
|
656
|
+
}
|
|
657
|
+
return loadSchema(pointer, config);
|
|
658
|
+
}, {
|
|
659
|
+
cacheKey(pointer) {
|
|
660
|
+
return JSON.stringify(pointer);
|
|
661
|
+
},
|
|
662
|
+
skip: () => { var _a; return !!((_a = this.config) === null || _a === void 0 ? void 0 : _a.watch); },
|
|
663
|
+
});
|
|
664
|
+
this.loadDocuments = useCache((pointer) => {
|
|
665
|
+
const config = this.getConfig(defaultDocumentsLoadOptions);
|
|
666
|
+
if (this._graphqlConfig) {
|
|
667
|
+
// TODO: pointer won't work here
|
|
668
|
+
return this._graphqlConfig.getProject(this._project).loadDocuments(pointer, config);
|
|
669
|
+
}
|
|
670
|
+
return loadDocuments(pointer, config);
|
|
671
|
+
}, {
|
|
672
|
+
cacheKey(pointer) {
|
|
673
|
+
return JSON.stringify(pointer);
|
|
674
|
+
},
|
|
675
|
+
skip: () => { var _a; return !!((_a = this.config) === null || _a === void 0 ? void 0 : _a.watch); },
|
|
676
|
+
});
|
|
650
677
|
this._config = config;
|
|
651
678
|
this._graphqlConfig = graphqlConfig;
|
|
652
679
|
this.filepath = this._graphqlConfig ? this._graphqlConfig.filepath : filepath;
|
|
@@ -692,27 +719,55 @@ class CodegenContext {
|
|
|
692
719
|
getPluginContext() {
|
|
693
720
|
return this._pluginContext;
|
|
694
721
|
}
|
|
695
|
-
async loadSchema(pointer) {
|
|
696
|
-
const config = this.getConfig(defaultSchemaLoadOptions);
|
|
697
|
-
if (this._graphqlConfig) {
|
|
698
|
-
// TODO: SchemaWithLoader won't work here
|
|
699
|
-
return this._graphqlConfig.getProject(this._project).loadSchema(pointer, 'GraphQLSchema', config);
|
|
700
|
-
}
|
|
701
|
-
return loadSchema(pointer, config);
|
|
702
|
-
}
|
|
703
|
-
async loadDocuments(pointer) {
|
|
704
|
-
const config = this.getConfig(defaultDocumentsLoadOptions);
|
|
705
|
-
if (this._graphqlConfig) {
|
|
706
|
-
// TODO: pointer won't work here
|
|
707
|
-
const documents = await this._graphqlConfig.getProject(this._project).loadDocuments(pointer, config);
|
|
708
|
-
return documents;
|
|
709
|
-
}
|
|
710
|
-
return loadDocuments(pointer, config);
|
|
711
|
-
}
|
|
712
722
|
}
|
|
713
723
|
function ensureContext(input) {
|
|
714
724
|
return input instanceof CodegenContext ? input : new CodegenContext({ config: input });
|
|
715
725
|
}
|
|
726
|
+
/**
|
|
727
|
+
* The goal here is to avoid loading the same schema or documents across projects.
|
|
728
|
+
*/
|
|
729
|
+
function useCache(originalFunction, { cacheKey, skip = () => false }) {
|
|
730
|
+
if (skip()) {
|
|
731
|
+
return originalFunction;
|
|
732
|
+
}
|
|
733
|
+
const cache = new Map();
|
|
734
|
+
return (input) => {
|
|
735
|
+
const key = cacheKey(input);
|
|
736
|
+
if (cache.has(key)) {
|
|
737
|
+
return cache.get(key);
|
|
738
|
+
}
|
|
739
|
+
const result = originalFunction(input);
|
|
740
|
+
cache.set(key, result);
|
|
741
|
+
return result;
|
|
742
|
+
};
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
|
|
746
|
+
const isNode = typeof process !== 'undefined' && process.versions != null && process.versions.node != null;
|
|
747
|
+
|
|
748
|
+
function isListrError(err) {
|
|
749
|
+
return err.name === 'ListrError' && Array.isArray(err.errors) && err.errors.length > 0;
|
|
750
|
+
}
|
|
751
|
+
function cliError(err, exitOnError = true) {
|
|
752
|
+
let msg;
|
|
753
|
+
if (err instanceof Error) {
|
|
754
|
+
msg = err.message || err.toString();
|
|
755
|
+
}
|
|
756
|
+
else if (typeof err === 'string') {
|
|
757
|
+
msg = err;
|
|
758
|
+
}
|
|
759
|
+
else {
|
|
760
|
+
msg = JSON.stringify(err);
|
|
761
|
+
}
|
|
762
|
+
// eslint-disable-next-line no-console
|
|
763
|
+
console.error(msg);
|
|
764
|
+
if (exitOnError && isNode) {
|
|
765
|
+
process.exit(1);
|
|
766
|
+
}
|
|
767
|
+
else if (exitOnError && isBrowser) {
|
|
768
|
+
throw err;
|
|
769
|
+
}
|
|
770
|
+
}
|
|
716
771
|
|
|
717
772
|
const makeDefaultLoader = (from) => {
|
|
718
773
|
if (fs__default.statSync(from).isDirectory()) {
|
|
@@ -913,10 +968,13 @@ async function executeCodegen(input) {
|
|
|
913
968
|
title: 'Load GraphQL documents',
|
|
914
969
|
task: wrapTask(async () => {
|
|
915
970
|
debugLog(`[CLI] Loading Documents`);
|
|
916
|
-
|
|
917
|
-
const
|
|
918
|
-
|
|
919
|
-
|
|
971
|
+
// get different cache for shared docs and output specific docs
|
|
972
|
+
const results = await Promise.all([rootDocuments, outputSpecificDocuments].map(docs => {
|
|
973
|
+
const hash = JSON.stringify(docs);
|
|
974
|
+
return documentsLoadingCache.load(hash);
|
|
975
|
+
}));
|
|
976
|
+
const documents = [];
|
|
977
|
+
results.forEach(source => documents.push(...source.documents));
|
|
920
978
|
if (documents.length > 0) {
|
|
921
979
|
outputDocuments.push(...documents);
|
|
922
980
|
}
|
|
@@ -996,12 +1054,25 @@ async function executeCodegen(input) {
|
|
|
996
1054
|
}), {
|
|
997
1055
|
// it doesn't stop when one of tasks failed, to finish at least some of outputs
|
|
998
1056
|
exitOnError: false,
|
|
999
|
-
|
|
1000
|
-
concurrent: 4,
|
|
1057
|
+
concurrent: os.cpus().length,
|
|
1001
1058
|
});
|
|
1002
1059
|
},
|
|
1003
1060
|
});
|
|
1004
|
-
|
|
1061
|
+
try {
|
|
1062
|
+
await listr.run();
|
|
1063
|
+
}
|
|
1064
|
+
catch (err) {
|
|
1065
|
+
if (isListrError(err)) {
|
|
1066
|
+
const allErrs = err.errors.map(subErr => pluginHelpers.isDetailedError(subErr)
|
|
1067
|
+
? `${subErr.message} for "${subErr.source}"${subErr.details}`
|
|
1068
|
+
: subErr.message || subErr.toString());
|
|
1069
|
+
const newErr = new utils.AggregateError(err.errors, `${err.message} ${allErrs.join('\n\n')}`);
|
|
1070
|
+
// Best-effort to all stack traces for debugging
|
|
1071
|
+
newErr.stack = `${newErr.stack}\n\n${err.errors.map(subErr => subErr.stack).join('\n\n')}`;
|
|
1072
|
+
throw newErr;
|
|
1073
|
+
}
|
|
1074
|
+
throw err;
|
|
1075
|
+
}
|
|
1005
1076
|
return result;
|
|
1006
1077
|
}
|
|
1007
1078
|
|
|
@@ -1213,22 +1284,22 @@ const createWatcher = (initalContext, onNext) => {
|
|
|
1213
1284
|
});
|
|
1214
1285
|
};
|
|
1215
1286
|
|
|
1216
|
-
function
|
|
1217
|
-
return
|
|
1287
|
+
function writeFile(filepath, content) {
|
|
1288
|
+
return fsExtra.writeFile(filepath, content);
|
|
1218
1289
|
}
|
|
1219
|
-
function
|
|
1220
|
-
return
|
|
1290
|
+
function readFile(filepath) {
|
|
1291
|
+
return fsExtra.readFile(filepath, 'utf-8');
|
|
1221
1292
|
}
|
|
1222
|
-
function fileExists(filePath) {
|
|
1293
|
+
async function fileExists(filePath) {
|
|
1223
1294
|
try {
|
|
1224
|
-
return
|
|
1295
|
+
return (await fsExtra.stat(filePath)).isFile();
|
|
1225
1296
|
}
|
|
1226
1297
|
catch (err) {
|
|
1227
1298
|
return false;
|
|
1228
1299
|
}
|
|
1229
1300
|
}
|
|
1230
1301
|
function unlinkFile(filePath, cb) {
|
|
1231
|
-
|
|
1302
|
+
fsExtra.unlink(filePath, cb);
|
|
1232
1303
|
}
|
|
1233
1304
|
|
|
1234
1305
|
const hash = (content) => crypto.createHash('sha1').update(content).digest('base64');
|
|
@@ -1243,7 +1314,7 @@ async function generate(input, saveToFile = true) {
|
|
|
1243
1314
|
const staleFilenames = previouslyGeneratedFilenames.filter(f => !filenames.includes(f));
|
|
1244
1315
|
staleFilenames.forEach(filename => {
|
|
1245
1316
|
if (shouldOverwrite(config, filename)) {
|
|
1246
|
-
unlinkFile(filename, err => {
|
|
1317
|
+
return unlinkFile(filename, err => {
|
|
1247
1318
|
const prettyFilename = filename.replace(`${input.cwd || process.cwd()}/`, '');
|
|
1248
1319
|
if (err) {
|
|
1249
1320
|
debugLog(`Cannot remove stale file: ${prettyFilename}\n${err}`);
|
|
@@ -1264,7 +1335,39 @@ async function generate(input, saveToFile = true) {
|
|
|
1264
1335
|
if (config.watch) {
|
|
1265
1336
|
removeStaleFiles(config, generationResult);
|
|
1266
1337
|
}
|
|
1267
|
-
await context.profiler.run(
|
|
1338
|
+
await context.profiler.run(async () => {
|
|
1339
|
+
await lifecycleHooks(config.hooks).beforeAllFileWrite(generationResult.map(r => r.filename));
|
|
1340
|
+
await Promise.all(generationResult.map(async (result) => {
|
|
1341
|
+
const exists = await fileExists(result.filename);
|
|
1342
|
+
if (!shouldOverwrite(config, result.filename) && exists) {
|
|
1343
|
+
return;
|
|
1344
|
+
}
|
|
1345
|
+
const content = result.content || '';
|
|
1346
|
+
const currentHash = hash(content);
|
|
1347
|
+
let previousHash = recentOutputHash.get(result.filename);
|
|
1348
|
+
if (!previousHash && exists) {
|
|
1349
|
+
previousHash = hash(await readFile(result.filename));
|
|
1350
|
+
}
|
|
1351
|
+
if (previousHash && currentHash === previousHash) {
|
|
1352
|
+
debugLog(`Skipping file (${result.filename}) writing due to indentical hash...`);
|
|
1353
|
+
return;
|
|
1354
|
+
}
|
|
1355
|
+
if (content.length === 0) {
|
|
1356
|
+
return;
|
|
1357
|
+
}
|
|
1358
|
+
recentOutputHash.set(result.filename, currentHash);
|
|
1359
|
+
const basedir = path.dirname(result.filename);
|
|
1360
|
+
await lifecycleHooks(result.hooks).beforeOneFileWrite(result.filename);
|
|
1361
|
+
await lifecycleHooks(config.hooks).beforeOneFileWrite(result.filename);
|
|
1362
|
+
await fsExtra.mkdirp(basedir);
|
|
1363
|
+
const absolutePath = path.isAbsolute(result.filename)
|
|
1364
|
+
? result.filename
|
|
1365
|
+
: path.join(input.cwd || process.cwd(), result.filename);
|
|
1366
|
+
await writeFile(absolutePath, result.content);
|
|
1367
|
+
await lifecycleHooks(result.hooks).afterOneFileWrite(result.filename);
|
|
1368
|
+
await lifecycleHooks(config.hooks).afterOneFileWrite(result.filename);
|
|
1369
|
+
}));
|
|
1370
|
+
}, 'Lifecycle: beforeAllFileWrite');
|
|
1268
1371
|
await context.profiler.run(() => Promise.all(generationResult.map(async (result) => {
|
|
1269
1372
|
const exists = fileExists(result.filename);
|
|
1270
1373
|
if (!shouldOverwrite(config, result.filename) && exists) {
|
|
@@ -1274,7 +1377,7 @@ async function generate(input, saveToFile = true) {
|
|
|
1274
1377
|
const currentHash = hash(content);
|
|
1275
1378
|
let previousHash = recentOutputHash.get(result.filename);
|
|
1276
1379
|
if (!previousHash && exists) {
|
|
1277
|
-
previousHash = hash(
|
|
1380
|
+
previousHash = hash(await readFile(result.filename));
|
|
1278
1381
|
}
|
|
1279
1382
|
if (previousHash && currentHash === previousHash) {
|
|
1280
1383
|
debugLog(`Skipping file (${result.filename}) writing due to identical hash...`);
|
|
@@ -1287,11 +1390,11 @@ async function generate(input, saveToFile = true) {
|
|
|
1287
1390
|
const basedir = path.dirname(result.filename);
|
|
1288
1391
|
await lifecycleHooks(result.hooks).beforeOneFileWrite(result.filename);
|
|
1289
1392
|
await lifecycleHooks(config.hooks).beforeOneFileWrite(result.filename);
|
|
1290
|
-
mkdirp.sync(basedir);
|
|
1393
|
+
fsExtra.mkdirp.sync(basedir);
|
|
1291
1394
|
const absolutePath = path.isAbsolute(result.filename)
|
|
1292
1395
|
? result.filename
|
|
1293
1396
|
: path.join(input.cwd || process.cwd(), result.filename);
|
|
1294
|
-
|
|
1397
|
+
await writeFile(absolutePath, result.content);
|
|
1295
1398
|
await lifecycleHooks(result.hooks).afterOneFileWrite(result.filename);
|
|
1296
1399
|
await lifecycleHooks(config.hooks).afterOneFileWrite(result.filename);
|
|
1297
1400
|
})), 'Write files');
|
|
@@ -1306,7 +1409,7 @@ async function generate(input, saveToFile = true) {
|
|
|
1306
1409
|
await context.profiler.run(() => writeOutput(outputFiles), 'writeOutput');
|
|
1307
1410
|
await context.profiler.run(() => lifecycleHooks(config.hooks).beforeDone(), 'Lifecycle: beforeDone');
|
|
1308
1411
|
if (context.profilerOutput) {
|
|
1309
|
-
|
|
1412
|
+
await writeFile(path.join(context.cwd, context.profilerOutput), JSON.stringify(context.profiler.collect()));
|
|
1310
1413
|
}
|
|
1311
1414
|
return outputFiles;
|
|
1312
1415
|
}
|
|
@@ -1777,30 +1880,6 @@ function addIntrospection(config) {
|
|
|
1777
1880
|
};
|
|
1778
1881
|
}
|
|
1779
1882
|
|
|
1780
|
-
const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
|
|
1781
|
-
const isNode = typeof process !== 'undefined' && process.versions != null && process.versions.node != null;
|
|
1782
|
-
|
|
1783
|
-
function cliError(err, exitOnError = true) {
|
|
1784
|
-
let msg;
|
|
1785
|
-
if (err instanceof Error) {
|
|
1786
|
-
msg = err.message || err.toString();
|
|
1787
|
-
}
|
|
1788
|
-
else if (typeof err === 'string') {
|
|
1789
|
-
msg = err;
|
|
1790
|
-
}
|
|
1791
|
-
else {
|
|
1792
|
-
msg = JSON.stringify(err);
|
|
1793
|
-
}
|
|
1794
|
-
// eslint-disable-next-line no-console
|
|
1795
|
-
console.error(msg);
|
|
1796
|
-
if (exitOnError && isNode) {
|
|
1797
|
-
process.exit(1);
|
|
1798
|
-
}
|
|
1799
|
-
else if (exitOnError && isBrowser) {
|
|
1800
|
-
throw err;
|
|
1801
|
-
}
|
|
1802
|
-
}
|
|
1803
|
-
|
|
1804
1883
|
async function runCli(cmd) {
|
|
1805
1884
|
await ensureGraphQlPackage();
|
|
1806
1885
|
switch (cmd) {
|
|
@@ -1842,6 +1921,7 @@ exports.findAndLoadGraphQLConfig = findAndLoadGraphQLConfig;
|
|
|
1842
1921
|
exports.generate = generate;
|
|
1843
1922
|
exports.generateSearchPlaces = generateSearchPlaces;
|
|
1844
1923
|
exports.init = init;
|
|
1924
|
+
exports.isListrError = isListrError;
|
|
1845
1925
|
exports.loadCodegenConfig = loadCodegenConfig;
|
|
1846
1926
|
exports.loadContext = loadContext;
|
|
1847
1927
|
exports.parseArgv = parseArgv;
|
package/index.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { isDetailedError, DetailedError, createNoopProfiler, createProfiler, normalizeInstanceOrArray, normalizeConfig, normalizeOutputParam, getCachedDocumentNodeFromSchema } from '@graphql-codegen/plugin-helpers';
|
|
2
2
|
import { codegen } from '@graphql-codegen/core';
|
|
3
|
+
import { AggregateError, isValidPath } from '@graphql-tools/utils';
|
|
3
4
|
import chalk from 'chalk';
|
|
4
5
|
import logSymbols from 'log-symbols';
|
|
5
6
|
import ansiEscapes from 'ansi-escapes';
|
|
@@ -24,13 +25,13 @@ import { JsonFileLoader } from '@graphql-tools/json-file-loader';
|
|
|
24
25
|
import { UrlLoader } from '@graphql-tools/url-loader';
|
|
25
26
|
import yaml from 'yaml';
|
|
26
27
|
import { createRequire } from 'module';
|
|
27
|
-
import fs, { promises, writeFileSync, readFileSync
|
|
28
|
+
import fs, { promises, writeFileSync, readFileSync } from 'fs';
|
|
29
|
+
import { cpus } from 'os';
|
|
28
30
|
import Listr from 'listr';
|
|
29
31
|
import { exec } from 'child_process';
|
|
30
32
|
import isGlob from 'is-glob';
|
|
31
33
|
import debounce from 'debounce';
|
|
32
|
-
import {
|
|
33
|
-
import mkdirp from 'mkdirp';
|
|
34
|
+
import { writeFile as writeFile$1, readFile as readFile$1, stat, unlink, mkdirp } from 'fs-extra';
|
|
34
35
|
import { createHash } from 'crypto';
|
|
35
36
|
import inquirer from 'inquirer';
|
|
36
37
|
import detectIndent from 'detect-indent';
|
|
@@ -620,6 +621,32 @@ function updateContextWithCliFlags(context, cliFlags) {
|
|
|
620
621
|
class CodegenContext {
|
|
621
622
|
constructor({ config, graphqlConfig, filepath, }) {
|
|
622
623
|
this._pluginContext = {};
|
|
624
|
+
this.loadSchema = useCache((pointer) => {
|
|
625
|
+
const config = this.getConfig(defaultSchemaLoadOptions);
|
|
626
|
+
if (this._graphqlConfig) {
|
|
627
|
+
// TODO: SchemaWithLoader won't work here
|
|
628
|
+
return this._graphqlConfig.getProject(this._project).loadSchema(pointer, 'GraphQLSchema', config);
|
|
629
|
+
}
|
|
630
|
+
return loadSchema(pointer, config);
|
|
631
|
+
}, {
|
|
632
|
+
cacheKey(pointer) {
|
|
633
|
+
return JSON.stringify(pointer);
|
|
634
|
+
},
|
|
635
|
+
skip: () => { var _a; return !!((_a = this.config) === null || _a === void 0 ? void 0 : _a.watch); },
|
|
636
|
+
});
|
|
637
|
+
this.loadDocuments = useCache((pointer) => {
|
|
638
|
+
const config = this.getConfig(defaultDocumentsLoadOptions);
|
|
639
|
+
if (this._graphqlConfig) {
|
|
640
|
+
// TODO: pointer won't work here
|
|
641
|
+
return this._graphqlConfig.getProject(this._project).loadDocuments(pointer, config);
|
|
642
|
+
}
|
|
643
|
+
return loadDocuments(pointer, config);
|
|
644
|
+
}, {
|
|
645
|
+
cacheKey(pointer) {
|
|
646
|
+
return JSON.stringify(pointer);
|
|
647
|
+
},
|
|
648
|
+
skip: () => { var _a; return !!((_a = this.config) === null || _a === void 0 ? void 0 : _a.watch); },
|
|
649
|
+
});
|
|
623
650
|
this._config = config;
|
|
624
651
|
this._graphqlConfig = graphqlConfig;
|
|
625
652
|
this.filepath = this._graphqlConfig ? this._graphqlConfig.filepath : filepath;
|
|
@@ -665,27 +692,55 @@ class CodegenContext {
|
|
|
665
692
|
getPluginContext() {
|
|
666
693
|
return this._pluginContext;
|
|
667
694
|
}
|
|
668
|
-
async loadSchema(pointer) {
|
|
669
|
-
const config = this.getConfig(defaultSchemaLoadOptions);
|
|
670
|
-
if (this._graphqlConfig) {
|
|
671
|
-
// TODO: SchemaWithLoader won't work here
|
|
672
|
-
return this._graphqlConfig.getProject(this._project).loadSchema(pointer, 'GraphQLSchema', config);
|
|
673
|
-
}
|
|
674
|
-
return loadSchema(pointer, config);
|
|
675
|
-
}
|
|
676
|
-
async loadDocuments(pointer) {
|
|
677
|
-
const config = this.getConfig(defaultDocumentsLoadOptions);
|
|
678
|
-
if (this._graphqlConfig) {
|
|
679
|
-
// TODO: pointer won't work here
|
|
680
|
-
const documents = await this._graphqlConfig.getProject(this._project).loadDocuments(pointer, config);
|
|
681
|
-
return documents;
|
|
682
|
-
}
|
|
683
|
-
return loadDocuments(pointer, config);
|
|
684
|
-
}
|
|
685
695
|
}
|
|
686
696
|
function ensureContext(input) {
|
|
687
697
|
return input instanceof CodegenContext ? input : new CodegenContext({ config: input });
|
|
688
698
|
}
|
|
699
|
+
/**
|
|
700
|
+
* The goal here is to avoid loading the same schema or documents across projects.
|
|
701
|
+
*/
|
|
702
|
+
function useCache(originalFunction, { cacheKey, skip = () => false }) {
|
|
703
|
+
if (skip()) {
|
|
704
|
+
return originalFunction;
|
|
705
|
+
}
|
|
706
|
+
const cache = new Map();
|
|
707
|
+
return (input) => {
|
|
708
|
+
const key = cacheKey(input);
|
|
709
|
+
if (cache.has(key)) {
|
|
710
|
+
return cache.get(key);
|
|
711
|
+
}
|
|
712
|
+
const result = originalFunction(input);
|
|
713
|
+
cache.set(key, result);
|
|
714
|
+
return result;
|
|
715
|
+
};
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
|
|
719
|
+
const isNode = typeof process !== 'undefined' && process.versions != null && process.versions.node != null;
|
|
720
|
+
|
|
721
|
+
function isListrError(err) {
|
|
722
|
+
return err.name === 'ListrError' && Array.isArray(err.errors) && err.errors.length > 0;
|
|
723
|
+
}
|
|
724
|
+
function cliError(err, exitOnError = true) {
|
|
725
|
+
let msg;
|
|
726
|
+
if (err instanceof Error) {
|
|
727
|
+
msg = err.message || err.toString();
|
|
728
|
+
}
|
|
729
|
+
else if (typeof err === 'string') {
|
|
730
|
+
msg = err;
|
|
731
|
+
}
|
|
732
|
+
else {
|
|
733
|
+
msg = JSON.stringify(err);
|
|
734
|
+
}
|
|
735
|
+
// eslint-disable-next-line no-console
|
|
736
|
+
console.error(msg);
|
|
737
|
+
if (exitOnError && isNode) {
|
|
738
|
+
process.exit(1);
|
|
739
|
+
}
|
|
740
|
+
else if (exitOnError && isBrowser) {
|
|
741
|
+
throw err;
|
|
742
|
+
}
|
|
743
|
+
}
|
|
689
744
|
|
|
690
745
|
const makeDefaultLoader = (from) => {
|
|
691
746
|
if (fs.statSync(from).isDirectory()) {
|
|
@@ -886,10 +941,13 @@ async function executeCodegen(input) {
|
|
|
886
941
|
title: 'Load GraphQL documents',
|
|
887
942
|
task: wrapTask(async () => {
|
|
888
943
|
debugLog(`[CLI] Loading Documents`);
|
|
889
|
-
|
|
890
|
-
const
|
|
891
|
-
|
|
892
|
-
|
|
944
|
+
// get different cache for shared docs and output specific docs
|
|
945
|
+
const results = await Promise.all([rootDocuments, outputSpecificDocuments].map(docs => {
|
|
946
|
+
const hash = JSON.stringify(docs);
|
|
947
|
+
return documentsLoadingCache.load(hash);
|
|
948
|
+
}));
|
|
949
|
+
const documents = [];
|
|
950
|
+
results.forEach(source => documents.push(...source.documents));
|
|
893
951
|
if (documents.length > 0) {
|
|
894
952
|
outputDocuments.push(...documents);
|
|
895
953
|
}
|
|
@@ -969,12 +1027,25 @@ async function executeCodegen(input) {
|
|
|
969
1027
|
}), {
|
|
970
1028
|
// it doesn't stop when one of tasks failed, to finish at least some of outputs
|
|
971
1029
|
exitOnError: false,
|
|
972
|
-
|
|
973
|
-
concurrent: 4,
|
|
1030
|
+
concurrent: cpus().length,
|
|
974
1031
|
});
|
|
975
1032
|
},
|
|
976
1033
|
});
|
|
977
|
-
|
|
1034
|
+
try {
|
|
1035
|
+
await listr.run();
|
|
1036
|
+
}
|
|
1037
|
+
catch (err) {
|
|
1038
|
+
if (isListrError(err)) {
|
|
1039
|
+
const allErrs = err.errors.map(subErr => isDetailedError(subErr)
|
|
1040
|
+
? `${subErr.message} for "${subErr.source}"${subErr.details}`
|
|
1041
|
+
: subErr.message || subErr.toString());
|
|
1042
|
+
const newErr = new AggregateError(err.errors, `${err.message} ${allErrs.join('\n\n')}`);
|
|
1043
|
+
// Best-effort to all stack traces for debugging
|
|
1044
|
+
newErr.stack = `${newErr.stack}\n\n${err.errors.map(subErr => subErr.stack).join('\n\n')}`;
|
|
1045
|
+
throw newErr;
|
|
1046
|
+
}
|
|
1047
|
+
throw err;
|
|
1048
|
+
}
|
|
978
1049
|
return result;
|
|
979
1050
|
}
|
|
980
1051
|
|
|
@@ -1186,15 +1257,15 @@ const createWatcher = (initalContext, onNext) => {
|
|
|
1186
1257
|
});
|
|
1187
1258
|
};
|
|
1188
1259
|
|
|
1189
|
-
function
|
|
1190
|
-
return
|
|
1260
|
+
function writeFile(filepath, content) {
|
|
1261
|
+
return writeFile$1(filepath, content);
|
|
1191
1262
|
}
|
|
1192
|
-
function
|
|
1193
|
-
return
|
|
1263
|
+
function readFile(filepath) {
|
|
1264
|
+
return readFile$1(filepath, 'utf-8');
|
|
1194
1265
|
}
|
|
1195
|
-
function fileExists(filePath) {
|
|
1266
|
+
async function fileExists(filePath) {
|
|
1196
1267
|
try {
|
|
1197
|
-
return
|
|
1268
|
+
return (await stat(filePath)).isFile();
|
|
1198
1269
|
}
|
|
1199
1270
|
catch (err) {
|
|
1200
1271
|
return false;
|
|
@@ -1216,7 +1287,7 @@ async function generate(input, saveToFile = true) {
|
|
|
1216
1287
|
const staleFilenames = previouslyGeneratedFilenames.filter(f => !filenames.includes(f));
|
|
1217
1288
|
staleFilenames.forEach(filename => {
|
|
1218
1289
|
if (shouldOverwrite(config, filename)) {
|
|
1219
|
-
unlinkFile(filename, err => {
|
|
1290
|
+
return unlinkFile(filename, err => {
|
|
1220
1291
|
const prettyFilename = filename.replace(`${input.cwd || process.cwd()}/`, '');
|
|
1221
1292
|
if (err) {
|
|
1222
1293
|
debugLog(`Cannot remove stale file: ${prettyFilename}\n${err}`);
|
|
@@ -1237,7 +1308,39 @@ async function generate(input, saveToFile = true) {
|
|
|
1237
1308
|
if (config.watch) {
|
|
1238
1309
|
removeStaleFiles(config, generationResult);
|
|
1239
1310
|
}
|
|
1240
|
-
await context.profiler.run(
|
|
1311
|
+
await context.profiler.run(async () => {
|
|
1312
|
+
await lifecycleHooks(config.hooks).beforeAllFileWrite(generationResult.map(r => r.filename));
|
|
1313
|
+
await Promise.all(generationResult.map(async (result) => {
|
|
1314
|
+
const exists = await fileExists(result.filename);
|
|
1315
|
+
if (!shouldOverwrite(config, result.filename) && exists) {
|
|
1316
|
+
return;
|
|
1317
|
+
}
|
|
1318
|
+
const content = result.content || '';
|
|
1319
|
+
const currentHash = hash(content);
|
|
1320
|
+
let previousHash = recentOutputHash.get(result.filename);
|
|
1321
|
+
if (!previousHash && exists) {
|
|
1322
|
+
previousHash = hash(await readFile(result.filename));
|
|
1323
|
+
}
|
|
1324
|
+
if (previousHash && currentHash === previousHash) {
|
|
1325
|
+
debugLog(`Skipping file (${result.filename}) writing due to indentical hash...`);
|
|
1326
|
+
return;
|
|
1327
|
+
}
|
|
1328
|
+
if (content.length === 0) {
|
|
1329
|
+
return;
|
|
1330
|
+
}
|
|
1331
|
+
recentOutputHash.set(result.filename, currentHash);
|
|
1332
|
+
const basedir = dirname(result.filename);
|
|
1333
|
+
await lifecycleHooks(result.hooks).beforeOneFileWrite(result.filename);
|
|
1334
|
+
await lifecycleHooks(config.hooks).beforeOneFileWrite(result.filename);
|
|
1335
|
+
await mkdirp(basedir);
|
|
1336
|
+
const absolutePath = isAbsolute(result.filename)
|
|
1337
|
+
? result.filename
|
|
1338
|
+
: join(input.cwd || process.cwd(), result.filename);
|
|
1339
|
+
await writeFile(absolutePath, result.content);
|
|
1340
|
+
await lifecycleHooks(result.hooks).afterOneFileWrite(result.filename);
|
|
1341
|
+
await lifecycleHooks(config.hooks).afterOneFileWrite(result.filename);
|
|
1342
|
+
}));
|
|
1343
|
+
}, 'Lifecycle: beforeAllFileWrite');
|
|
1241
1344
|
await context.profiler.run(() => Promise.all(generationResult.map(async (result) => {
|
|
1242
1345
|
const exists = fileExists(result.filename);
|
|
1243
1346
|
if (!shouldOverwrite(config, result.filename) && exists) {
|
|
@@ -1247,7 +1350,7 @@ async function generate(input, saveToFile = true) {
|
|
|
1247
1350
|
const currentHash = hash(content);
|
|
1248
1351
|
let previousHash = recentOutputHash.get(result.filename);
|
|
1249
1352
|
if (!previousHash && exists) {
|
|
1250
|
-
previousHash = hash(
|
|
1353
|
+
previousHash = hash(await readFile(result.filename));
|
|
1251
1354
|
}
|
|
1252
1355
|
if (previousHash && currentHash === previousHash) {
|
|
1253
1356
|
debugLog(`Skipping file (${result.filename}) writing due to identical hash...`);
|
|
@@ -1264,7 +1367,7 @@ async function generate(input, saveToFile = true) {
|
|
|
1264
1367
|
const absolutePath = isAbsolute(result.filename)
|
|
1265
1368
|
? result.filename
|
|
1266
1369
|
: join(input.cwd || process.cwd(), result.filename);
|
|
1267
|
-
|
|
1370
|
+
await writeFile(absolutePath, result.content);
|
|
1268
1371
|
await lifecycleHooks(result.hooks).afterOneFileWrite(result.filename);
|
|
1269
1372
|
await lifecycleHooks(config.hooks).afterOneFileWrite(result.filename);
|
|
1270
1373
|
})), 'Write files');
|
|
@@ -1279,7 +1382,7 @@ async function generate(input, saveToFile = true) {
|
|
|
1279
1382
|
await context.profiler.run(() => writeOutput(outputFiles), 'writeOutput');
|
|
1280
1383
|
await context.profiler.run(() => lifecycleHooks(config.hooks).beforeDone(), 'Lifecycle: beforeDone');
|
|
1281
1384
|
if (context.profilerOutput) {
|
|
1282
|
-
|
|
1385
|
+
await writeFile(join(context.cwd, context.profilerOutput), JSON.stringify(context.profiler.collect()));
|
|
1283
1386
|
}
|
|
1284
1387
|
return outputFiles;
|
|
1285
1388
|
}
|
|
@@ -1750,30 +1853,6 @@ function addIntrospection(config) {
|
|
|
1750
1853
|
};
|
|
1751
1854
|
}
|
|
1752
1855
|
|
|
1753
|
-
const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
|
|
1754
|
-
const isNode = typeof process !== 'undefined' && process.versions != null && process.versions.node != null;
|
|
1755
|
-
|
|
1756
|
-
function cliError(err, exitOnError = true) {
|
|
1757
|
-
let msg;
|
|
1758
|
-
if (err instanceof Error) {
|
|
1759
|
-
msg = err.message || err.toString();
|
|
1760
|
-
}
|
|
1761
|
-
else if (typeof err === 'string') {
|
|
1762
|
-
msg = err;
|
|
1763
|
-
}
|
|
1764
|
-
else {
|
|
1765
|
-
msg = JSON.stringify(err);
|
|
1766
|
-
}
|
|
1767
|
-
// eslint-disable-next-line no-console
|
|
1768
|
-
console.error(msg);
|
|
1769
|
-
if (exitOnError && isNode) {
|
|
1770
|
-
process.exit(1);
|
|
1771
|
-
}
|
|
1772
|
-
else if (exitOnError && isBrowser) {
|
|
1773
|
-
throw err;
|
|
1774
|
-
}
|
|
1775
|
-
}
|
|
1776
|
-
|
|
1777
1856
|
async function runCli(cmd) {
|
|
1778
1857
|
await ensureGraphQlPackage();
|
|
1779
1858
|
switch (cmd) {
|
|
@@ -1803,4 +1882,4 @@ async function ensureGraphQlPackage() {
|
|
|
1803
1882
|
}
|
|
1804
1883
|
}
|
|
1805
1884
|
|
|
1806
|
-
export { CodegenContext, CodegenExtension, buildOptions, cliError, createContext, ensureContext, ensureGraphQlPackage, executeCodegen, findAndLoadGraphQLConfig, generate, generateSearchPlaces, init, loadCodegenConfig, loadContext, parseArgv, runCli, updateContextWithCliFlags };
|
|
1885
|
+
export { CodegenContext, CodegenExtension, buildOptions, cliError, createContext, ensureContext, ensureGraphQlPackage, executeCodegen, findAndLoadGraphQLConfig, generate, generateSearchPlaces, init, isListrError, loadCodegenConfig, loadContext, parseArgv, runCli, updateContextWithCliFlags };
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graphql-codegen/cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.0-alpha-c9d165f6a.0",
|
|
4
4
|
"peerDependencies": {
|
|
5
5
|
"graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
|
|
6
6
|
},
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@graphql-codegen/core": "2.5.0
|
|
9
|
-
"@graphql-codegen/plugin-helpers": "2.4.0
|
|
8
|
+
"@graphql-codegen/core": "2.5.0",
|
|
9
|
+
"@graphql-codegen/plugin-helpers": "^2.4.0",
|
|
10
10
|
"@graphql-tools/apollo-engine-loader": "^7.0.5",
|
|
11
11
|
"@graphql-tools/code-file-loader": "^7.0.6",
|
|
12
12
|
"@graphql-tools/git-loader": "^7.0.5",
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
"debounce": "^1.2.0",
|
|
27
27
|
"dependency-graph": "^0.11.0",
|
|
28
28
|
"detect-indent": "^6.0.0",
|
|
29
|
+
"fs-extra": "^9.1.0",
|
|
29
30
|
"glob": "^7.1.6",
|
|
30
31
|
"globby": "^11.0.4",
|
|
31
32
|
"graphql-config": "^4.1.0",
|
|
@@ -37,7 +38,6 @@
|
|
|
37
38
|
"listr-update-renderer": "^0.5.0",
|
|
38
39
|
"log-symbols": "^4.0.0",
|
|
39
40
|
"minimatch": "^3.0.4",
|
|
40
|
-
"mkdirp": "^1.0.4",
|
|
41
41
|
"string-env-interpolation": "^1.0.1",
|
|
42
42
|
"ts-log": "^2.2.3",
|
|
43
43
|
"tslib": "~2.3.0",
|
package/utils/cli-error.d.ts
CHANGED
|
@@ -1 +1,11 @@
|
|
|
1
|
+
import { DetailedError } from '@graphql-codegen/plugin-helpers';
|
|
2
|
+
declare type CompositeError = Error | DetailedError;
|
|
3
|
+
declare type ListrError = Error & {
|
|
4
|
+
errors: CompositeError[];
|
|
5
|
+
};
|
|
6
|
+
export declare function isListrError(err: Error & {
|
|
7
|
+
name?: unknown;
|
|
8
|
+
errors?: unknown;
|
|
9
|
+
}): err is ListrError;
|
|
1
10
|
export declare function cliError(err: any, exitOnError?: boolean): void;
|
|
11
|
+
export {};
|
package/utils/file-system.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare function
|
|
2
|
-
export declare function
|
|
3
|
-
export declare function fileExists(filePath: string): boolean
|
|
1
|
+
export declare function writeFile(filepath: string, content: string): any;
|
|
2
|
+
export declare function readFile(filepath: string): any;
|
|
3
|
+
export declare function fileExists(filePath: string): Promise<boolean>;
|
|
4
4
|
export declare function unlinkFile(filePath: string, cb?: (err?: Error) => any): void;
|