@graphql-codegen/cli 2.6.0-alpha-bbecef04a.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 +100 -72
- package/codegen.d.ts +0 -1
- package/config.d.ts +2 -5
- package/index.js +100 -72
- package/index.mjs +99 -71
- package/load.d.ts +1 -1
- package/package.json +4 -4
- package/utils/file-system.d.ts +3 -3
package/bin.js
CHANGED
|
@@ -53,10 +53,11 @@ const yaml = _interopDefault(require('yaml'));
|
|
|
53
53
|
const module$1 = require('module');
|
|
54
54
|
const fs = require('fs');
|
|
55
55
|
const fs__default = _interopDefault(fs);
|
|
56
|
+
const os = require('os');
|
|
56
57
|
const Listr = _interopDefault(require('listr'));
|
|
57
58
|
const isGlob = _interopDefault(require('is-glob'));
|
|
58
59
|
const debounce = _interopDefault(require('debounce'));
|
|
59
|
-
const
|
|
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'));
|
|
@@ -505,30 +506,20 @@ async function loadSchema(schemaPointers, config) {
|
|
|
505
506
|
|
|
506
507
|
${e.message || e}
|
|
507
508
|
${e.stack || ''}
|
|
508
|
-
|
|
509
|
+
|
|
509
510
|
GraphQL Code Generator supports:
|
|
510
511
|
- ES Modules and CommonJS exports (export as default or named export "schema")
|
|
511
512
|
- Introspection JSON File
|
|
512
513
|
- URL of GraphQL endpoint
|
|
513
514
|
- Multiple files with type definitions (glob expression)
|
|
514
515
|
- String in config file
|
|
515
|
-
|
|
516
|
+
|
|
516
517
|
Try to use one of above options and run codegen again.
|
|
517
|
-
|
|
518
|
+
|
|
518
519
|
`);
|
|
519
520
|
}
|
|
520
521
|
}
|
|
521
|
-
|
|
522
|
-
return Promise.all(pointers.map(async (pointer) => {
|
|
523
|
-
const userLoader = (await makeDefaultLoader(process.cwd())(pointer.require)).default;
|
|
524
|
-
const documents = userLoader(pointer.config || {}, schema);
|
|
525
|
-
return documents;
|
|
526
|
-
})).then(results => [].concat(...results));
|
|
527
|
-
};
|
|
528
|
-
const isRequirePointer = (pointer) => {
|
|
529
|
-
return typeof pointer === 'object' && 'require' in pointer;
|
|
530
|
-
};
|
|
531
|
-
async function loadDocuments(documentPointers, config, schema) {
|
|
522
|
+
async function loadDocuments(documentPointers, config) {
|
|
532
523
|
const loaders = [
|
|
533
524
|
new codeFileLoader.CodeFileLoader({
|
|
534
525
|
pluckConfig: {
|
|
@@ -547,35 +538,14 @@ async function loadDocuments(documentPointers, config, schema) {
|
|
|
547
538
|
}
|
|
548
539
|
ignore.push(path.join(process.cwd(), generatePath));
|
|
549
540
|
}
|
|
550
|
-
const
|
|
551
|
-
const requestPointers = [];
|
|
552
|
-
if (Array.isArray(documentPointers)) {
|
|
553
|
-
documentPointers.forEach(pointer => {
|
|
554
|
-
if (isRequirePointer(pointer)) {
|
|
555
|
-
requestPointers.push(pointer);
|
|
556
|
-
}
|
|
557
|
-
else {
|
|
558
|
-
loaderPointers.push(pointer);
|
|
559
|
-
}
|
|
560
|
-
});
|
|
561
|
-
}
|
|
562
|
-
else {
|
|
563
|
-
if (isRequirePointer(documentPointers)) {
|
|
564
|
-
requestPointers.push(documentPointers);
|
|
565
|
-
}
|
|
566
|
-
else {
|
|
567
|
-
loaderPointers.push(documentPointers);
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
const loadedFromToolkit = await load.loadDocuments(loaderPointers, {
|
|
541
|
+
const loadedFromToolkit = await load.loadDocuments(documentPointers, {
|
|
571
542
|
...defaultDocumentsLoadOptions,
|
|
572
543
|
ignore,
|
|
573
544
|
loaders,
|
|
574
545
|
...config,
|
|
575
546
|
...config.config,
|
|
576
547
|
});
|
|
577
|
-
|
|
578
|
-
return [...loadedFromToolkit, ...loadedAlterantively];
|
|
548
|
+
return loadedFromToolkit;
|
|
579
549
|
}
|
|
580
550
|
|
|
581
551
|
const { lstat } = fs.promises;
|
|
@@ -760,6 +730,32 @@ function updateContextWithCliFlags(context, cliFlags) {
|
|
|
760
730
|
class CodegenContext {
|
|
761
731
|
constructor({ config, graphqlConfig, filepath, }) {
|
|
762
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
|
+
});
|
|
763
759
|
this._config = config;
|
|
764
760
|
this._graphqlConfig = graphqlConfig;
|
|
765
761
|
this.filepath = this._graphqlConfig ? this._graphqlConfig.filepath : filepath;
|
|
@@ -805,27 +801,28 @@ class CodegenContext {
|
|
|
805
801
|
getPluginContext() {
|
|
806
802
|
return this._pluginContext;
|
|
807
803
|
}
|
|
808
|
-
async loadSchema(pointer) {
|
|
809
|
-
const config = this.getConfig(defaultSchemaLoadOptions);
|
|
810
|
-
if (this._graphqlConfig) {
|
|
811
|
-
// TODO: SchemaWithLoader won't work here
|
|
812
|
-
return this._graphqlConfig.getProject(this._project).loadSchema(pointer, 'GraphQLSchema', config);
|
|
813
|
-
}
|
|
814
|
-
return loadSchema(pointer, config);
|
|
815
|
-
}
|
|
816
|
-
async loadDocuments(input) {
|
|
817
|
-
const config = this.getConfig(defaultDocumentsLoadOptions);
|
|
818
|
-
if (this._graphqlConfig) {
|
|
819
|
-
// TODO: pointer won't work here
|
|
820
|
-
const documents = await this._graphqlConfig.getProject(this._project).loadDocuments(input.pointer, config);
|
|
821
|
-
return documents;
|
|
822
|
-
}
|
|
823
|
-
return loadDocuments(input.pointer, config, input.schema);
|
|
824
|
-
}
|
|
825
804
|
}
|
|
826
805
|
function ensureContext(input) {
|
|
827
806
|
return input instanceof CodegenContext ? input : new CodegenContext({ config: input });
|
|
828
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
|
+
}
|
|
829
826
|
|
|
830
827
|
const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
|
|
831
828
|
const isNode = typeof process !== 'undefined' && process.versions != null && process.versions.node != null;
|
|
@@ -924,7 +921,7 @@ async function executeCodegen(input) {
|
|
|
924
921
|
const documentsLoadingCache = createCache(async function (hash) {
|
|
925
922
|
const documents = await context.loadDocuments(JSON.parse(hash));
|
|
926
923
|
return {
|
|
927
|
-
documents,
|
|
924
|
+
documents: documents,
|
|
928
925
|
};
|
|
929
926
|
});
|
|
930
927
|
function wrapTask(task, source, taskName) {
|
|
@@ -1055,7 +1052,7 @@ async function executeCodegen(input) {
|
|
|
1055
1052
|
debugLog(`[CLI] Loading Documents`);
|
|
1056
1053
|
// get different cache for shared docs and output specific docs
|
|
1057
1054
|
const results = await Promise.all([rootDocuments, outputSpecificDocuments].map(docs => {
|
|
1058
|
-
const hash = JSON.stringify(
|
|
1055
|
+
const hash = JSON.stringify(docs);
|
|
1059
1056
|
return documentsLoadingCache.load(hash);
|
|
1060
1057
|
}));
|
|
1061
1058
|
const documents = [];
|
|
@@ -1139,8 +1136,7 @@ async function executeCodegen(input) {
|
|
|
1139
1136
|
}), {
|
|
1140
1137
|
// it doesn't stop when one of tasks failed, to finish at least some of outputs
|
|
1141
1138
|
exitOnError: false,
|
|
1142
|
-
|
|
1143
|
-
concurrent: 4,
|
|
1139
|
+
concurrent: os.cpus().length,
|
|
1144
1140
|
});
|
|
1145
1141
|
},
|
|
1146
1142
|
});
|
|
@@ -1287,22 +1283,22 @@ const createWatcher = (initalContext, onNext) => {
|
|
|
1287
1283
|
});
|
|
1288
1284
|
};
|
|
1289
1285
|
|
|
1290
|
-
function
|
|
1291
|
-
return
|
|
1286
|
+
function writeFile(filepath, content) {
|
|
1287
|
+
return fsExtra.writeFile(filepath, content);
|
|
1292
1288
|
}
|
|
1293
|
-
function
|
|
1294
|
-
return
|
|
1289
|
+
function readFile(filepath) {
|
|
1290
|
+
return fsExtra.readFile(filepath, 'utf-8');
|
|
1295
1291
|
}
|
|
1296
|
-
function fileExists(filePath) {
|
|
1292
|
+
async function fileExists(filePath) {
|
|
1297
1293
|
try {
|
|
1298
|
-
return
|
|
1294
|
+
return (await fsExtra.stat(filePath)).isFile();
|
|
1299
1295
|
}
|
|
1300
1296
|
catch (err) {
|
|
1301
1297
|
return false;
|
|
1302
1298
|
}
|
|
1303
1299
|
}
|
|
1304
1300
|
function unlinkFile(filePath, cb) {
|
|
1305
|
-
|
|
1301
|
+
fsExtra.unlink(filePath, cb);
|
|
1306
1302
|
}
|
|
1307
1303
|
|
|
1308
1304
|
const hash = (content) => crypto.createHash('sha1').update(content).digest('base64');
|
|
@@ -1317,7 +1313,7 @@ async function generate(input, saveToFile = true) {
|
|
|
1317
1313
|
const staleFilenames = previouslyGeneratedFilenames.filter(f => !filenames.includes(f));
|
|
1318
1314
|
staleFilenames.forEach(filename => {
|
|
1319
1315
|
if (shouldOverwrite(config, filename)) {
|
|
1320
|
-
unlinkFile(filename, err => {
|
|
1316
|
+
return unlinkFile(filename, err => {
|
|
1321
1317
|
const prettyFilename = filename.replace(`${input.cwd || process.cwd()}/`, '');
|
|
1322
1318
|
if (err) {
|
|
1323
1319
|
debugLog(`Cannot remove stale file: ${prettyFilename}\n${err}`);
|
|
@@ -1338,7 +1334,39 @@ async function generate(input, saveToFile = true) {
|
|
|
1338
1334
|
if (config.watch) {
|
|
1339
1335
|
removeStaleFiles(config, generationResult);
|
|
1340
1336
|
}
|
|
1341
|
-
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');
|
|
1342
1370
|
await context.profiler.run(() => Promise.all(generationResult.map(async (result) => {
|
|
1343
1371
|
const exists = fileExists(result.filename);
|
|
1344
1372
|
if (!shouldOverwrite(config, result.filename) && exists) {
|
|
@@ -1348,7 +1376,7 @@ async function generate(input, saveToFile = true) {
|
|
|
1348
1376
|
const currentHash = hash(content);
|
|
1349
1377
|
let previousHash = recentOutputHash.get(result.filename);
|
|
1350
1378
|
if (!previousHash && exists) {
|
|
1351
|
-
previousHash = hash(
|
|
1379
|
+
previousHash = hash(await readFile(result.filename));
|
|
1352
1380
|
}
|
|
1353
1381
|
if (previousHash && currentHash === previousHash) {
|
|
1354
1382
|
debugLog(`Skipping file (${result.filename}) writing due to identical hash...`);
|
|
@@ -1361,11 +1389,11 @@ async function generate(input, saveToFile = true) {
|
|
|
1361
1389
|
const basedir = path.dirname(result.filename);
|
|
1362
1390
|
await lifecycleHooks(result.hooks).beforeOneFileWrite(result.filename);
|
|
1363
1391
|
await lifecycleHooks(config.hooks).beforeOneFileWrite(result.filename);
|
|
1364
|
-
mkdirp.sync(basedir);
|
|
1392
|
+
fsExtra.mkdirp.sync(basedir);
|
|
1365
1393
|
const absolutePath = path.isAbsolute(result.filename)
|
|
1366
1394
|
? result.filename
|
|
1367
1395
|
: path.join(input.cwd || process.cwd(), result.filename);
|
|
1368
|
-
|
|
1396
|
+
await writeFile(absolutePath, result.content);
|
|
1369
1397
|
await lifecycleHooks(result.hooks).afterOneFileWrite(result.filename);
|
|
1370
1398
|
await lifecycleHooks(config.hooks).afterOneFileWrite(result.filename);
|
|
1371
1399
|
})), 'Write files');
|
|
@@ -1380,7 +1408,7 @@ async function generate(input, saveToFile = true) {
|
|
|
1380
1408
|
await context.profiler.run(() => writeOutput(outputFiles), 'writeOutput');
|
|
1381
1409
|
await context.profiler.run(() => lifecycleHooks(config.hooks).beforeDone(), 'Lifecycle: beforeDone');
|
|
1382
1410
|
if (context.profilerOutput) {
|
|
1383
|
-
|
|
1411
|
+
await writeFile(path.join(context.cwd, context.profilerOutput), JSON.stringify(context.profiler.collect()));
|
|
1384
1412
|
}
|
|
1385
1413
|
return outputFiles;
|
|
1386
1414
|
}
|
package/codegen.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
import { Types } from '@graphql-codegen/plugin-helpers';
|
|
2
2
|
import { CodegenContext } from './config';
|
|
3
|
-
export declare const makeDefaultLoader: (from: string) => (mod: string) => Promise<any>;
|
|
4
3
|
export declare function executeCodegen(input: CodegenContext | Types.Config): Promise<Types.FileOutput[]>;
|
package/config.d.ts
CHANGED
|
@@ -110,10 +110,7 @@ export declare class CodegenContext {
|
|
|
110
110
|
getPluginContext(): {
|
|
111
111
|
[key: string]: any;
|
|
112
112
|
};
|
|
113
|
-
loadSchema(
|
|
114
|
-
loadDocuments(input:
|
|
115
|
-
pointer: Types.OperationDocument[];
|
|
116
|
-
schema: GraphQLSchema;
|
|
117
|
-
}): Promise<Types.DocumentFile[]>;
|
|
113
|
+
loadSchema: (input: Types.Schema) => Promise<GraphQLSchema>;
|
|
114
|
+
loadDocuments: (input: Types.OperationDocument[]) => Promise<import("graphql-config").Source[]>;
|
|
118
115
|
}
|
|
119
116
|
export declare function ensureContext(input: CodegenContext | Types.Config): CodegenContext;
|
package/index.js
CHANGED
|
@@ -53,11 +53,12 @@ const yaml = _interopDefault(require('yaml'));
|
|
|
53
53
|
const module$1 = require('module');
|
|
54
54
|
const fs = require('fs');
|
|
55
55
|
const fs__default = _interopDefault(fs);
|
|
56
|
+
const os = require('os');
|
|
56
57
|
const Listr = _interopDefault(require('listr'));
|
|
57
58
|
const child_process = require('child_process');
|
|
58
59
|
const isGlob = _interopDefault(require('is-glob'));
|
|
59
60
|
const debounce = _interopDefault(require('debounce'));
|
|
60
|
-
const
|
|
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'));
|
|
@@ -423,30 +424,20 @@ async function loadSchema(schemaPointers, config) {
|
|
|
423
424
|
|
|
424
425
|
${e.message || e}
|
|
425
426
|
${e.stack || ''}
|
|
426
|
-
|
|
427
|
+
|
|
427
428
|
GraphQL Code Generator supports:
|
|
428
429
|
- ES Modules and CommonJS exports (export as default or named export "schema")
|
|
429
430
|
- Introspection JSON File
|
|
430
431
|
- URL of GraphQL endpoint
|
|
431
432
|
- Multiple files with type definitions (glob expression)
|
|
432
433
|
- String in config file
|
|
433
|
-
|
|
434
|
+
|
|
434
435
|
Try to use one of above options and run codegen again.
|
|
435
|
-
|
|
436
|
+
|
|
436
437
|
`);
|
|
437
438
|
}
|
|
438
439
|
}
|
|
439
|
-
|
|
440
|
-
return Promise.all(pointers.map(async (pointer) => {
|
|
441
|
-
const userLoader = (await makeDefaultLoader(process.cwd())(pointer.require)).default;
|
|
442
|
-
const documents = userLoader(pointer.config || {}, schema);
|
|
443
|
-
return documents;
|
|
444
|
-
})).then(results => [].concat(...results));
|
|
445
|
-
};
|
|
446
|
-
const isRequirePointer = (pointer) => {
|
|
447
|
-
return typeof pointer === 'object' && 'require' in pointer;
|
|
448
|
-
};
|
|
449
|
-
async function loadDocuments(documentPointers, config, schema) {
|
|
440
|
+
async function loadDocuments(documentPointers, config) {
|
|
450
441
|
const loaders = [
|
|
451
442
|
new codeFileLoader.CodeFileLoader({
|
|
452
443
|
pluckConfig: {
|
|
@@ -465,35 +456,14 @@ async function loadDocuments(documentPointers, config, schema) {
|
|
|
465
456
|
}
|
|
466
457
|
ignore.push(path.join(process.cwd(), generatePath));
|
|
467
458
|
}
|
|
468
|
-
const
|
|
469
|
-
const requestPointers = [];
|
|
470
|
-
if (Array.isArray(documentPointers)) {
|
|
471
|
-
documentPointers.forEach(pointer => {
|
|
472
|
-
if (isRequirePointer(pointer)) {
|
|
473
|
-
requestPointers.push(pointer);
|
|
474
|
-
}
|
|
475
|
-
else {
|
|
476
|
-
loaderPointers.push(pointer);
|
|
477
|
-
}
|
|
478
|
-
});
|
|
479
|
-
}
|
|
480
|
-
else {
|
|
481
|
-
if (isRequirePointer(documentPointers)) {
|
|
482
|
-
requestPointers.push(documentPointers);
|
|
483
|
-
}
|
|
484
|
-
else {
|
|
485
|
-
loaderPointers.push(documentPointers);
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
const loadedFromToolkit = await load.loadDocuments(loaderPointers, {
|
|
459
|
+
const loadedFromToolkit = await load.loadDocuments(documentPointers, {
|
|
489
460
|
...defaultDocumentsLoadOptions,
|
|
490
461
|
ignore,
|
|
491
462
|
loaders,
|
|
492
463
|
...config,
|
|
493
464
|
...config.config,
|
|
494
465
|
});
|
|
495
|
-
|
|
496
|
-
return [...loadedFromToolkit, ...loadedAlterantively];
|
|
466
|
+
return loadedFromToolkit;
|
|
497
467
|
}
|
|
498
468
|
|
|
499
469
|
const { lstat } = fs.promises;
|
|
@@ -678,6 +648,32 @@ function updateContextWithCliFlags(context, cliFlags) {
|
|
|
678
648
|
class CodegenContext {
|
|
679
649
|
constructor({ config, graphqlConfig, filepath, }) {
|
|
680
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
|
+
});
|
|
681
677
|
this._config = config;
|
|
682
678
|
this._graphqlConfig = graphqlConfig;
|
|
683
679
|
this.filepath = this._graphqlConfig ? this._graphqlConfig.filepath : filepath;
|
|
@@ -723,27 +719,28 @@ class CodegenContext {
|
|
|
723
719
|
getPluginContext() {
|
|
724
720
|
return this._pluginContext;
|
|
725
721
|
}
|
|
726
|
-
async loadSchema(pointer) {
|
|
727
|
-
const config = this.getConfig(defaultSchemaLoadOptions);
|
|
728
|
-
if (this._graphqlConfig) {
|
|
729
|
-
// TODO: SchemaWithLoader won't work here
|
|
730
|
-
return this._graphqlConfig.getProject(this._project).loadSchema(pointer, 'GraphQLSchema', config);
|
|
731
|
-
}
|
|
732
|
-
return loadSchema(pointer, config);
|
|
733
|
-
}
|
|
734
|
-
async loadDocuments(input) {
|
|
735
|
-
const config = this.getConfig(defaultDocumentsLoadOptions);
|
|
736
|
-
if (this._graphqlConfig) {
|
|
737
|
-
// TODO: pointer won't work here
|
|
738
|
-
const documents = await this._graphqlConfig.getProject(this._project).loadDocuments(input.pointer, config);
|
|
739
|
-
return documents;
|
|
740
|
-
}
|
|
741
|
-
return loadDocuments(input.pointer, config, input.schema);
|
|
742
|
-
}
|
|
743
722
|
}
|
|
744
723
|
function ensureContext(input) {
|
|
745
724
|
return input instanceof CodegenContext ? input : new CodegenContext({ config: input });
|
|
746
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
|
+
}
|
|
747
744
|
|
|
748
745
|
const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
|
|
749
746
|
const isNode = typeof process !== 'undefined' && process.versions != null && process.versions.node != null;
|
|
@@ -842,7 +839,7 @@ async function executeCodegen(input) {
|
|
|
842
839
|
const documentsLoadingCache = createCache(async function (hash) {
|
|
843
840
|
const documents = await context.loadDocuments(JSON.parse(hash));
|
|
844
841
|
return {
|
|
845
|
-
documents,
|
|
842
|
+
documents: documents,
|
|
846
843
|
};
|
|
847
844
|
});
|
|
848
845
|
function wrapTask(task, source, taskName) {
|
|
@@ -973,7 +970,7 @@ async function executeCodegen(input) {
|
|
|
973
970
|
debugLog(`[CLI] Loading Documents`);
|
|
974
971
|
// get different cache for shared docs and output specific docs
|
|
975
972
|
const results = await Promise.all([rootDocuments, outputSpecificDocuments].map(docs => {
|
|
976
|
-
const hash = JSON.stringify(
|
|
973
|
+
const hash = JSON.stringify(docs);
|
|
977
974
|
return documentsLoadingCache.load(hash);
|
|
978
975
|
}));
|
|
979
976
|
const documents = [];
|
|
@@ -1057,8 +1054,7 @@ async function executeCodegen(input) {
|
|
|
1057
1054
|
}), {
|
|
1058
1055
|
// it doesn't stop when one of tasks failed, to finish at least some of outputs
|
|
1059
1056
|
exitOnError: false,
|
|
1060
|
-
|
|
1061
|
-
concurrent: 4,
|
|
1057
|
+
concurrent: os.cpus().length,
|
|
1062
1058
|
});
|
|
1063
1059
|
},
|
|
1064
1060
|
});
|
|
@@ -1288,22 +1284,22 @@ const createWatcher = (initalContext, onNext) => {
|
|
|
1288
1284
|
});
|
|
1289
1285
|
};
|
|
1290
1286
|
|
|
1291
|
-
function
|
|
1292
|
-
return
|
|
1287
|
+
function writeFile(filepath, content) {
|
|
1288
|
+
return fsExtra.writeFile(filepath, content);
|
|
1293
1289
|
}
|
|
1294
|
-
function
|
|
1295
|
-
return
|
|
1290
|
+
function readFile(filepath) {
|
|
1291
|
+
return fsExtra.readFile(filepath, 'utf-8');
|
|
1296
1292
|
}
|
|
1297
|
-
function fileExists(filePath) {
|
|
1293
|
+
async function fileExists(filePath) {
|
|
1298
1294
|
try {
|
|
1299
|
-
return
|
|
1295
|
+
return (await fsExtra.stat(filePath)).isFile();
|
|
1300
1296
|
}
|
|
1301
1297
|
catch (err) {
|
|
1302
1298
|
return false;
|
|
1303
1299
|
}
|
|
1304
1300
|
}
|
|
1305
1301
|
function unlinkFile(filePath, cb) {
|
|
1306
|
-
|
|
1302
|
+
fsExtra.unlink(filePath, cb);
|
|
1307
1303
|
}
|
|
1308
1304
|
|
|
1309
1305
|
const hash = (content) => crypto.createHash('sha1').update(content).digest('base64');
|
|
@@ -1318,7 +1314,7 @@ async function generate(input, saveToFile = true) {
|
|
|
1318
1314
|
const staleFilenames = previouslyGeneratedFilenames.filter(f => !filenames.includes(f));
|
|
1319
1315
|
staleFilenames.forEach(filename => {
|
|
1320
1316
|
if (shouldOverwrite(config, filename)) {
|
|
1321
|
-
unlinkFile(filename, err => {
|
|
1317
|
+
return unlinkFile(filename, err => {
|
|
1322
1318
|
const prettyFilename = filename.replace(`${input.cwd || process.cwd()}/`, '');
|
|
1323
1319
|
if (err) {
|
|
1324
1320
|
debugLog(`Cannot remove stale file: ${prettyFilename}\n${err}`);
|
|
@@ -1339,7 +1335,39 @@ async function generate(input, saveToFile = true) {
|
|
|
1339
1335
|
if (config.watch) {
|
|
1340
1336
|
removeStaleFiles(config, generationResult);
|
|
1341
1337
|
}
|
|
1342
|
-
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');
|
|
1343
1371
|
await context.profiler.run(() => Promise.all(generationResult.map(async (result) => {
|
|
1344
1372
|
const exists = fileExists(result.filename);
|
|
1345
1373
|
if (!shouldOverwrite(config, result.filename) && exists) {
|
|
@@ -1349,7 +1377,7 @@ async function generate(input, saveToFile = true) {
|
|
|
1349
1377
|
const currentHash = hash(content);
|
|
1350
1378
|
let previousHash = recentOutputHash.get(result.filename);
|
|
1351
1379
|
if (!previousHash && exists) {
|
|
1352
|
-
previousHash = hash(
|
|
1380
|
+
previousHash = hash(await readFile(result.filename));
|
|
1353
1381
|
}
|
|
1354
1382
|
if (previousHash && currentHash === previousHash) {
|
|
1355
1383
|
debugLog(`Skipping file (${result.filename}) writing due to identical hash...`);
|
|
@@ -1362,11 +1390,11 @@ async function generate(input, saveToFile = true) {
|
|
|
1362
1390
|
const basedir = path.dirname(result.filename);
|
|
1363
1391
|
await lifecycleHooks(result.hooks).beforeOneFileWrite(result.filename);
|
|
1364
1392
|
await lifecycleHooks(config.hooks).beforeOneFileWrite(result.filename);
|
|
1365
|
-
mkdirp.sync(basedir);
|
|
1393
|
+
fsExtra.mkdirp.sync(basedir);
|
|
1366
1394
|
const absolutePath = path.isAbsolute(result.filename)
|
|
1367
1395
|
? result.filename
|
|
1368
1396
|
: path.join(input.cwd || process.cwd(), result.filename);
|
|
1369
|
-
|
|
1397
|
+
await writeFile(absolutePath, result.content);
|
|
1370
1398
|
await lifecycleHooks(result.hooks).afterOneFileWrite(result.filename);
|
|
1371
1399
|
await lifecycleHooks(config.hooks).afterOneFileWrite(result.filename);
|
|
1372
1400
|
})), 'Write files');
|
|
@@ -1381,7 +1409,7 @@ async function generate(input, saveToFile = true) {
|
|
|
1381
1409
|
await context.profiler.run(() => writeOutput(outputFiles), 'writeOutput');
|
|
1382
1410
|
await context.profiler.run(() => lifecycleHooks(config.hooks).beforeDone(), 'Lifecycle: beforeDone');
|
|
1383
1411
|
if (context.profilerOutput) {
|
|
1384
|
-
|
|
1412
|
+
await writeFile(path.join(context.cwd, context.profilerOutput), JSON.stringify(context.profiler.collect()));
|
|
1385
1413
|
}
|
|
1386
1414
|
return outputFiles;
|
|
1387
1415
|
}
|
package/index.mjs
CHANGED
|
@@ -25,12 +25,13 @@ import { JsonFileLoader } from '@graphql-tools/json-file-loader';
|
|
|
25
25
|
import { UrlLoader } from '@graphql-tools/url-loader';
|
|
26
26
|
import yaml from 'yaml';
|
|
27
27
|
import { createRequire } from 'module';
|
|
28
|
-
import fs, { promises, writeFileSync, readFileSync
|
|
28
|
+
import fs, { promises, writeFileSync, readFileSync } from 'fs';
|
|
29
|
+
import { cpus } from 'os';
|
|
29
30
|
import Listr from 'listr';
|
|
30
31
|
import { exec } from 'child_process';
|
|
31
32
|
import isGlob from 'is-glob';
|
|
32
33
|
import debounce from 'debounce';
|
|
33
|
-
import mkdirp from '
|
|
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';
|
|
@@ -396,30 +397,20 @@ async function loadSchema(schemaPointers, config) {
|
|
|
396
397
|
|
|
397
398
|
${e.message || e}
|
|
398
399
|
${e.stack || ''}
|
|
399
|
-
|
|
400
|
+
|
|
400
401
|
GraphQL Code Generator supports:
|
|
401
402
|
- ES Modules and CommonJS exports (export as default or named export "schema")
|
|
402
403
|
- Introspection JSON File
|
|
403
404
|
- URL of GraphQL endpoint
|
|
404
405
|
- Multiple files with type definitions (glob expression)
|
|
405
406
|
- String in config file
|
|
406
|
-
|
|
407
|
+
|
|
407
408
|
Try to use one of above options and run codegen again.
|
|
408
|
-
|
|
409
|
+
|
|
409
410
|
`);
|
|
410
411
|
}
|
|
411
412
|
}
|
|
412
|
-
|
|
413
|
-
return Promise.all(pointers.map(async (pointer) => {
|
|
414
|
-
const userLoader = (await makeDefaultLoader(process.cwd())(pointer.require)).default;
|
|
415
|
-
const documents = userLoader(pointer.config || {}, schema);
|
|
416
|
-
return documents;
|
|
417
|
-
})).then(results => [].concat(...results));
|
|
418
|
-
};
|
|
419
|
-
const isRequirePointer = (pointer) => {
|
|
420
|
-
return typeof pointer === 'object' && 'require' in pointer;
|
|
421
|
-
};
|
|
422
|
-
async function loadDocuments(documentPointers, config, schema) {
|
|
413
|
+
async function loadDocuments(documentPointers, config) {
|
|
423
414
|
const loaders = [
|
|
424
415
|
new CodeFileLoader({
|
|
425
416
|
pluckConfig: {
|
|
@@ -438,35 +429,14 @@ async function loadDocuments(documentPointers, config, schema) {
|
|
|
438
429
|
}
|
|
439
430
|
ignore.push(join(process.cwd(), generatePath));
|
|
440
431
|
}
|
|
441
|
-
const
|
|
442
|
-
const requestPointers = [];
|
|
443
|
-
if (Array.isArray(documentPointers)) {
|
|
444
|
-
documentPointers.forEach(pointer => {
|
|
445
|
-
if (isRequirePointer(pointer)) {
|
|
446
|
-
requestPointers.push(pointer);
|
|
447
|
-
}
|
|
448
|
-
else {
|
|
449
|
-
loaderPointers.push(pointer);
|
|
450
|
-
}
|
|
451
|
-
});
|
|
452
|
-
}
|
|
453
|
-
else {
|
|
454
|
-
if (isRequirePointer(documentPointers)) {
|
|
455
|
-
requestPointers.push(documentPointers);
|
|
456
|
-
}
|
|
457
|
-
else {
|
|
458
|
-
loaderPointers.push(documentPointers);
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
const loadedFromToolkit = await loadDocuments$1(loaderPointers, {
|
|
432
|
+
const loadedFromToolkit = await loadDocuments$1(documentPointers, {
|
|
462
433
|
...defaultDocumentsLoadOptions,
|
|
463
434
|
ignore,
|
|
464
435
|
loaders,
|
|
465
436
|
...config,
|
|
466
437
|
...config.config,
|
|
467
438
|
});
|
|
468
|
-
|
|
469
|
-
return [...loadedFromToolkit, ...loadedAlterantively];
|
|
439
|
+
return loadedFromToolkit;
|
|
470
440
|
}
|
|
471
441
|
|
|
472
442
|
const { lstat } = promises;
|
|
@@ -651,6 +621,32 @@ function updateContextWithCliFlags(context, cliFlags) {
|
|
|
651
621
|
class CodegenContext {
|
|
652
622
|
constructor({ config, graphqlConfig, filepath, }) {
|
|
653
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
|
+
});
|
|
654
650
|
this._config = config;
|
|
655
651
|
this._graphqlConfig = graphqlConfig;
|
|
656
652
|
this.filepath = this._graphqlConfig ? this._graphqlConfig.filepath : filepath;
|
|
@@ -696,27 +692,28 @@ class CodegenContext {
|
|
|
696
692
|
getPluginContext() {
|
|
697
693
|
return this._pluginContext;
|
|
698
694
|
}
|
|
699
|
-
async loadSchema(pointer) {
|
|
700
|
-
const config = this.getConfig(defaultSchemaLoadOptions);
|
|
701
|
-
if (this._graphqlConfig) {
|
|
702
|
-
// TODO: SchemaWithLoader won't work here
|
|
703
|
-
return this._graphqlConfig.getProject(this._project).loadSchema(pointer, 'GraphQLSchema', config);
|
|
704
|
-
}
|
|
705
|
-
return loadSchema(pointer, config);
|
|
706
|
-
}
|
|
707
|
-
async loadDocuments(input) {
|
|
708
|
-
const config = this.getConfig(defaultDocumentsLoadOptions);
|
|
709
|
-
if (this._graphqlConfig) {
|
|
710
|
-
// TODO: pointer won't work here
|
|
711
|
-
const documents = await this._graphqlConfig.getProject(this._project).loadDocuments(input.pointer, config);
|
|
712
|
-
return documents;
|
|
713
|
-
}
|
|
714
|
-
return loadDocuments(input.pointer, config, input.schema);
|
|
715
|
-
}
|
|
716
695
|
}
|
|
717
696
|
function ensureContext(input) {
|
|
718
697
|
return input instanceof CodegenContext ? input : new CodegenContext({ config: input });
|
|
719
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
|
+
}
|
|
720
717
|
|
|
721
718
|
const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
|
|
722
719
|
const isNode = typeof process !== 'undefined' && process.versions != null && process.versions.node != null;
|
|
@@ -815,7 +812,7 @@ async function executeCodegen(input) {
|
|
|
815
812
|
const documentsLoadingCache = createCache(async function (hash) {
|
|
816
813
|
const documents = await context.loadDocuments(JSON.parse(hash));
|
|
817
814
|
return {
|
|
818
|
-
documents,
|
|
815
|
+
documents: documents,
|
|
819
816
|
};
|
|
820
817
|
});
|
|
821
818
|
function wrapTask(task, source, taskName) {
|
|
@@ -946,7 +943,7 @@ async function executeCodegen(input) {
|
|
|
946
943
|
debugLog(`[CLI] Loading Documents`);
|
|
947
944
|
// get different cache for shared docs and output specific docs
|
|
948
945
|
const results = await Promise.all([rootDocuments, outputSpecificDocuments].map(docs => {
|
|
949
|
-
const hash = JSON.stringify(
|
|
946
|
+
const hash = JSON.stringify(docs);
|
|
950
947
|
return documentsLoadingCache.load(hash);
|
|
951
948
|
}));
|
|
952
949
|
const documents = [];
|
|
@@ -1030,8 +1027,7 @@ async function executeCodegen(input) {
|
|
|
1030
1027
|
}), {
|
|
1031
1028
|
// it doesn't stop when one of tasks failed, to finish at least some of outputs
|
|
1032
1029
|
exitOnError: false,
|
|
1033
|
-
|
|
1034
|
-
concurrent: 4,
|
|
1030
|
+
concurrent: cpus().length,
|
|
1035
1031
|
});
|
|
1036
1032
|
},
|
|
1037
1033
|
});
|
|
@@ -1261,15 +1257,15 @@ const createWatcher = (initalContext, onNext) => {
|
|
|
1261
1257
|
});
|
|
1262
1258
|
};
|
|
1263
1259
|
|
|
1264
|
-
function
|
|
1265
|
-
return
|
|
1260
|
+
function writeFile(filepath, content) {
|
|
1261
|
+
return writeFile$1(filepath, content);
|
|
1266
1262
|
}
|
|
1267
|
-
function
|
|
1268
|
-
return
|
|
1263
|
+
function readFile(filepath) {
|
|
1264
|
+
return readFile$1(filepath, 'utf-8');
|
|
1269
1265
|
}
|
|
1270
|
-
function fileExists(filePath) {
|
|
1266
|
+
async function fileExists(filePath) {
|
|
1271
1267
|
try {
|
|
1272
|
-
return
|
|
1268
|
+
return (await stat(filePath)).isFile();
|
|
1273
1269
|
}
|
|
1274
1270
|
catch (err) {
|
|
1275
1271
|
return false;
|
|
@@ -1291,7 +1287,7 @@ async function generate(input, saveToFile = true) {
|
|
|
1291
1287
|
const staleFilenames = previouslyGeneratedFilenames.filter(f => !filenames.includes(f));
|
|
1292
1288
|
staleFilenames.forEach(filename => {
|
|
1293
1289
|
if (shouldOverwrite(config, filename)) {
|
|
1294
|
-
unlinkFile(filename, err => {
|
|
1290
|
+
return unlinkFile(filename, err => {
|
|
1295
1291
|
const prettyFilename = filename.replace(`${input.cwd || process.cwd()}/`, '');
|
|
1296
1292
|
if (err) {
|
|
1297
1293
|
debugLog(`Cannot remove stale file: ${prettyFilename}\n${err}`);
|
|
@@ -1312,7 +1308,39 @@ async function generate(input, saveToFile = true) {
|
|
|
1312
1308
|
if (config.watch) {
|
|
1313
1309
|
removeStaleFiles(config, generationResult);
|
|
1314
1310
|
}
|
|
1315
|
-
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');
|
|
1316
1344
|
await context.profiler.run(() => Promise.all(generationResult.map(async (result) => {
|
|
1317
1345
|
const exists = fileExists(result.filename);
|
|
1318
1346
|
if (!shouldOverwrite(config, result.filename) && exists) {
|
|
@@ -1322,7 +1350,7 @@ async function generate(input, saveToFile = true) {
|
|
|
1322
1350
|
const currentHash = hash(content);
|
|
1323
1351
|
let previousHash = recentOutputHash.get(result.filename);
|
|
1324
1352
|
if (!previousHash && exists) {
|
|
1325
|
-
previousHash = hash(
|
|
1353
|
+
previousHash = hash(await readFile(result.filename));
|
|
1326
1354
|
}
|
|
1327
1355
|
if (previousHash && currentHash === previousHash) {
|
|
1328
1356
|
debugLog(`Skipping file (${result.filename}) writing due to identical hash...`);
|
|
@@ -1339,7 +1367,7 @@ async function generate(input, saveToFile = true) {
|
|
|
1339
1367
|
const absolutePath = isAbsolute(result.filename)
|
|
1340
1368
|
? result.filename
|
|
1341
1369
|
: join(input.cwd || process.cwd(), result.filename);
|
|
1342
|
-
|
|
1370
|
+
await writeFile(absolutePath, result.content);
|
|
1343
1371
|
await lifecycleHooks(result.hooks).afterOneFileWrite(result.filename);
|
|
1344
1372
|
await lifecycleHooks(config.hooks).afterOneFileWrite(result.filename);
|
|
1345
1373
|
})), 'Write files');
|
|
@@ -1354,7 +1382,7 @@ async function generate(input, saveToFile = true) {
|
|
|
1354
1382
|
await context.profiler.run(() => writeOutput(outputFiles), 'writeOutput');
|
|
1355
1383
|
await context.profiler.run(() => lifecycleHooks(config.hooks).beforeDone(), 'Lifecycle: beforeDone');
|
|
1356
1384
|
if (context.profilerOutput) {
|
|
1357
|
-
|
|
1385
|
+
await writeFile(join(context.cwd, context.profilerOutput), JSON.stringify(context.profiler.collect()));
|
|
1358
1386
|
}
|
|
1359
1387
|
return outputFiles;
|
|
1360
1388
|
}
|
package/load.d.ts
CHANGED
|
@@ -12,4 +12,4 @@ export declare const defaultDocumentsLoadOptions: {
|
|
|
12
12
|
skipGraphQLImport: boolean;
|
|
13
13
|
};
|
|
14
14
|
export declare function loadSchema(schemaPointers: UnnormalizedTypeDefPointer, config: Types.Config): Promise<GraphQLSchema>;
|
|
15
|
-
export declare function loadDocuments(documentPointers: UnnormalizedTypeDefPointer | UnnormalizedTypeDefPointer[], config: Types.Config
|
|
15
|
+
export declare function loadDocuments(documentPointers: UnnormalizedTypeDefPointer | UnnormalizedTypeDefPointer[], config: Types.Config): Promise<Types.DocumentFile[]>;
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graphql-codegen/cli",
|
|
3
|
-
"version": "2.6.0-alpha-
|
|
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.
|
|
9
|
-
"@graphql-codegen/plugin-helpers": "2.4.
|
|
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/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;
|