@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 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 utils = require('@graphql-tools/utils');
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
- const allDocuments = [...rootDocuments, ...outputSpecificDocuments];
999
- const hash = JSON.stringify(allDocuments);
1000
- const result = await documentsLoadingCache.load(hash);
1001
- const documents = result.documents;
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
- // run 4 at once
1082
- concurrent: 4,
1139
+ concurrent: os.cpus().length,
1083
1140
  });
1084
1141
  },
1085
1142
  });
1086
- await listr.run();
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 writeSync(filepath, content) {
1216
- return fs.writeFileSync(filepath, content);
1286
+ function writeFile(filepath, content) {
1287
+ return fsExtra.writeFile(filepath, content);
1217
1288
  }
1218
- function readSync(filepath) {
1219
- return fs.readFileSync(filepath, 'utf-8');
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 fs.statSync(filePath).isFile();
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
- fs.unlink(filePath, cb);
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(() => lifecycleHooks(config.hooks).beforeAllFileWrite(generationResult.map(r => r.filename)), 'Lifecycle: beforeAllFileWrite');
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(readSync(result.filename));
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
- writeSync(absolutePath, result.content);
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
- writeSync(path.join(context.cwd, context.profilerOutput), JSON.stringify(context.profiler.collect()));
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(pointer: Types.Schema): Promise<GraphQLSchema>;
114
- loadDocuments(pointer: Types.OperationDocument[]): Promise<Types.DocumentFile[]>;
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 utils = require('@graphql-tools/utils');
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
- const allDocuments = [...rootDocuments, ...outputSpecificDocuments];
917
- const hash = JSON.stringify(allDocuments);
918
- const result = await documentsLoadingCache.load(hash);
919
- const documents = result.documents;
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
- // run 4 at once
1000
- concurrent: 4,
1057
+ concurrent: os.cpus().length,
1001
1058
  });
1002
1059
  },
1003
1060
  });
1004
- await listr.run();
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 writeSync(filepath, content) {
1217
- return fs.writeFileSync(filepath, content);
1287
+ function writeFile(filepath, content) {
1288
+ return fsExtra.writeFile(filepath, content);
1218
1289
  }
1219
- function readSync(filepath) {
1220
- return fs.readFileSync(filepath, 'utf-8');
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 fs.statSync(filePath).isFile();
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
- fs.unlink(filePath, cb);
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(() => lifecycleHooks(config.hooks).beforeAllFileWrite(generationResult.map(r => r.filename)), 'Lifecycle: beforeAllFileWrite');
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(readSync(result.filename));
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
- writeSync(absolutePath, result.content);
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
- writeSync(path.join(context.cwd, context.profilerOutput), JSON.stringify(context.profiler.collect()));
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, statSync, unlink } from 'fs';
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 { isValidPath } from '@graphql-tools/utils';
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
- const allDocuments = [...rootDocuments, ...outputSpecificDocuments];
890
- const hash = JSON.stringify(allDocuments);
891
- const result = await documentsLoadingCache.load(hash);
892
- const documents = result.documents;
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
- // run 4 at once
973
- concurrent: 4,
1030
+ concurrent: cpus().length,
974
1031
  });
975
1032
  },
976
1033
  });
977
- await listr.run();
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 writeSync(filepath, content) {
1190
- return writeFileSync(filepath, content);
1260
+ function writeFile(filepath, content) {
1261
+ return writeFile$1(filepath, content);
1191
1262
  }
1192
- function readSync(filepath) {
1193
- return readFileSync(filepath, 'utf-8');
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 statSync(filePath).isFile();
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(() => lifecycleHooks(config.hooks).beforeAllFileWrite(generationResult.map(r => r.filename)), 'Lifecycle: beforeAllFileWrite');
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(readSync(result.filename));
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
- writeSync(absolutePath, result.content);
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
- writeSync(join(context.cwd, context.profilerOutput), JSON.stringify(context.profiler.collect()));
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.5.0-alpha-fc06eb8e7.0",
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-alpha-fc06eb8e7.0",
9
- "@graphql-codegen/plugin-helpers": "2.4.0-alpha-fc06eb8e7.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",
@@ -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 {};
@@ -1,4 +1,4 @@
1
- export declare function writeSync(filepath: string, content: string): void;
2
- export declare function readSync(filepath: string): string;
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;