@graphql-codegen/cli 2.5.0-alpha-c9cbc7d69.0 → 2.6.0-alpha-679ebe9ab.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'));
@@ -796,6 +797,33 @@ function ensureContext(input) {
796
797
  return input instanceof CodegenContext ? input : new CodegenContext({ config: input });
797
798
  }
798
799
 
800
+ const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
801
+ const isNode = typeof process !== 'undefined' && process.versions != null && process.versions.node != null;
802
+
803
+ function isListrError(err) {
804
+ return err.name === 'ListrError' && Array.isArray(err.errors) && err.errors.length > 0;
805
+ }
806
+ function cliError(err, exitOnError = true) {
807
+ let msg;
808
+ if (err instanceof Error) {
809
+ msg = err.message || err.toString();
810
+ }
811
+ else if (typeof err === 'string') {
812
+ msg = err;
813
+ }
814
+ else {
815
+ msg = JSON.stringify(err);
816
+ }
817
+ // eslint-disable-next-line no-console
818
+ console.error(msg);
819
+ if (exitOnError && isNode) {
820
+ process.exit(1);
821
+ }
822
+ else if (exitOnError && isBrowser) {
823
+ throw err;
824
+ }
825
+ }
826
+
799
827
  const makeDefaultLoader = (from) => {
800
828
  if (fs__default.statSync(from).isDirectory()) {
801
829
  from = path__default.join(from, '__fake.js');
@@ -1081,12 +1109,25 @@ async function executeCodegen(input) {
1081
1109
  }), {
1082
1110
  // it doesn't stop when one of tasks failed, to finish at least some of outputs
1083
1111
  exitOnError: false,
1084
- // run 4 at once
1085
- concurrent: 4,
1112
+ concurrent: os.cpus().length,
1086
1113
  });
1087
1114
  },
1088
1115
  });
1089
- await listr.run();
1116
+ try {
1117
+ await listr.run();
1118
+ }
1119
+ catch (err) {
1120
+ if (isListrError(err)) {
1121
+ const allErrs = err.errors.map(subErr => pluginHelpers.isDetailedError(subErr)
1122
+ ? `${subErr.message} for "${subErr.source}"${subErr.details}`
1123
+ : subErr.message || subErr.toString());
1124
+ const newErr = new utils.AggregateError(err.errors, `${err.message} ${allErrs.join('\n\n')}`);
1125
+ // Best-effort to all stack traces for debugging
1126
+ newErr.stack = `${newErr.stack}\n\n${err.errors.map(subErr => subErr.stack).join('\n\n')}`;
1127
+ throw newErr;
1128
+ }
1129
+ throw err;
1130
+ }
1090
1131
  return result;
1091
1132
  }
1092
1133
 
@@ -1215,22 +1256,22 @@ const createWatcher = (initalContext, onNext) => {
1215
1256
  });
1216
1257
  };
1217
1258
 
1218
- function writeSync(filepath, content) {
1219
- return fs.writeFileSync(filepath, content);
1259
+ function writeFile(filepath, content) {
1260
+ return fsExtra.writeFile(filepath, content);
1220
1261
  }
1221
- function readSync(filepath) {
1222
- return fs.readFileSync(filepath, 'utf-8');
1262
+ function readFile(filepath) {
1263
+ return fsExtra.readFile(filepath, 'utf-8');
1223
1264
  }
1224
- function fileExists(filePath) {
1265
+ async function fileExists(filePath) {
1225
1266
  try {
1226
- return fs.statSync(filePath).isFile();
1267
+ return (await fsExtra.stat(filePath)).isFile();
1227
1268
  }
1228
1269
  catch (err) {
1229
1270
  return false;
1230
1271
  }
1231
1272
  }
1232
1273
  function unlinkFile(filePath, cb) {
1233
- fs.unlink(filePath, cb);
1274
+ fsExtra.unlink(filePath, cb);
1234
1275
  }
1235
1276
 
1236
1277
  const hash = (content) => crypto.createHash('sha1').update(content).digest('base64');
@@ -1245,7 +1286,7 @@ async function generate(input, saveToFile = true) {
1245
1286
  const staleFilenames = previouslyGeneratedFilenames.filter(f => !filenames.includes(f));
1246
1287
  staleFilenames.forEach(filename => {
1247
1288
  if (shouldOverwrite(config, filename)) {
1248
- unlinkFile(filename, err => {
1289
+ return unlinkFile(filename, err => {
1249
1290
  const prettyFilename = filename.replace(`${input.cwd || process.cwd()}/`, '');
1250
1291
  if (err) {
1251
1292
  debugLog(`Cannot remove stale file: ${prettyFilename}\n${err}`);
@@ -1266,7 +1307,39 @@ async function generate(input, saveToFile = true) {
1266
1307
  if (config.watch) {
1267
1308
  removeStaleFiles(config, generationResult);
1268
1309
  }
1269
- await context.profiler.run(() => lifecycleHooks(config.hooks).beforeAllFileWrite(generationResult.map(r => r.filename)), 'Lifecycle: beforeAllFileWrite');
1310
+ await context.profiler.run(async () => {
1311
+ await lifecycleHooks(config.hooks).beforeAllFileWrite(generationResult.map(r => r.filename));
1312
+ await Promise.all(generationResult.map(async (result) => {
1313
+ const exists = await fileExists(result.filename);
1314
+ if (!shouldOverwrite(config, result.filename) && exists) {
1315
+ return;
1316
+ }
1317
+ const content = result.content || '';
1318
+ const currentHash = hash(content);
1319
+ let previousHash = recentOutputHash.get(result.filename);
1320
+ if (!previousHash && exists) {
1321
+ previousHash = hash(await readFile(result.filename));
1322
+ }
1323
+ if (previousHash && currentHash === previousHash) {
1324
+ debugLog(`Skipping file (${result.filename}) writing due to indentical hash...`);
1325
+ return;
1326
+ }
1327
+ if (content.length === 0) {
1328
+ return;
1329
+ }
1330
+ recentOutputHash.set(result.filename, currentHash);
1331
+ const basedir = path.dirname(result.filename);
1332
+ await lifecycleHooks(result.hooks).beforeOneFileWrite(result.filename);
1333
+ await lifecycleHooks(config.hooks).beforeOneFileWrite(result.filename);
1334
+ await fsExtra.mkdirp(basedir);
1335
+ const absolutePath = path.isAbsolute(result.filename)
1336
+ ? result.filename
1337
+ : path.join(input.cwd || process.cwd(), result.filename);
1338
+ await writeFile(absolutePath, result.content);
1339
+ await lifecycleHooks(result.hooks).afterOneFileWrite(result.filename);
1340
+ await lifecycleHooks(config.hooks).afterOneFileWrite(result.filename);
1341
+ }));
1342
+ }, 'Lifecycle: beforeAllFileWrite');
1270
1343
  await context.profiler.run(() => Promise.all(generationResult.map(async (result) => {
1271
1344
  const exists = fileExists(result.filename);
1272
1345
  if (!shouldOverwrite(config, result.filename) && exists) {
@@ -1276,7 +1349,7 @@ async function generate(input, saveToFile = true) {
1276
1349
  const currentHash = hash(content);
1277
1350
  let previousHash = recentOutputHash.get(result.filename);
1278
1351
  if (!previousHash && exists) {
1279
- previousHash = hash(readSync(result.filename));
1352
+ previousHash = hash(await readFile(result.filename));
1280
1353
  }
1281
1354
  if (previousHash && currentHash === previousHash) {
1282
1355
  debugLog(`Skipping file (${result.filename}) writing due to identical hash...`);
@@ -1289,11 +1362,11 @@ async function generate(input, saveToFile = true) {
1289
1362
  const basedir = path.dirname(result.filename);
1290
1363
  await lifecycleHooks(result.hooks).beforeOneFileWrite(result.filename);
1291
1364
  await lifecycleHooks(config.hooks).beforeOneFileWrite(result.filename);
1292
- mkdirp.sync(basedir);
1365
+ fsExtra.mkdirp.sync(basedir);
1293
1366
  const absolutePath = path.isAbsolute(result.filename)
1294
1367
  ? result.filename
1295
1368
  : path.join(input.cwd || process.cwd(), result.filename);
1296
- writeSync(absolutePath, result.content);
1369
+ await writeFile(absolutePath, result.content);
1297
1370
  await lifecycleHooks(result.hooks).afterOneFileWrite(result.filename);
1298
1371
  await lifecycleHooks(config.hooks).afterOneFileWrite(result.filename);
1299
1372
  })), 'Write files');
@@ -1308,7 +1381,7 @@ async function generate(input, saveToFile = true) {
1308
1381
  await context.profiler.run(() => writeOutput(outputFiles), 'writeOutput');
1309
1382
  await context.profiler.run(() => lifecycleHooks(config.hooks).beforeDone(), 'Lifecycle: beforeDone');
1310
1383
  if (context.profilerOutput) {
1311
- writeSync(path.join(context.cwd, context.profilerOutput), JSON.stringify(context.profiler.collect()));
1384
+ await writeFile(path.join(context.cwd, context.profilerOutput), JSON.stringify(context.profiler.collect()));
1312
1385
  }
1313
1386
  return outputFiles;
1314
1387
  }
@@ -1808,30 +1881,6 @@ async function ensureGraphQlPackage() {
1808
1881
  }
1809
1882
  }
1810
1883
 
1811
- const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
1812
- const isNode = typeof process !== 'undefined' && process.versions != null && process.versions.node != null;
1813
-
1814
- function cliError(err, exitOnError = true) {
1815
- let msg;
1816
- if (err instanceof Error) {
1817
- msg = err.message || err.toString();
1818
- }
1819
- else if (typeof err === 'string') {
1820
- msg = err;
1821
- }
1822
- else {
1823
- msg = JSON.stringify(err);
1824
- }
1825
- // eslint-disable-next-line no-console
1826
- console.error(msg);
1827
- if (exitOnError && isNode) {
1828
- process.exit(1);
1829
- }
1830
- else if (exitOnError && isBrowser) {
1831
- throw err;
1832
- }
1833
- }
1834
-
1835
1884
  const [, , cmd] = process.argv;
1836
1885
  runCli(cmd)
1837
1886
  .then(() => {
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'));
@@ -714,6 +715,33 @@ function ensureContext(input) {
714
715
  return input instanceof CodegenContext ? input : new CodegenContext({ config: input });
715
716
  }
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
+ }
744
+
717
745
  const makeDefaultLoader = (from) => {
718
746
  if (fs__default.statSync(from).isDirectory()) {
719
747
  from = path__default.join(from, '__fake.js');
@@ -999,12 +1027,25 @@ async function executeCodegen(input) {
999
1027
  }), {
1000
1028
  // it doesn't stop when one of tasks failed, to finish at least some of outputs
1001
1029
  exitOnError: false,
1002
- // run 4 at once
1003
- concurrent: 4,
1030
+ concurrent: os.cpus().length,
1004
1031
  });
1005
1032
  },
1006
1033
  });
1007
- await listr.run();
1034
+ try {
1035
+ await listr.run();
1036
+ }
1037
+ catch (err) {
1038
+ if (isListrError(err)) {
1039
+ const allErrs = err.errors.map(subErr => pluginHelpers.isDetailedError(subErr)
1040
+ ? `${subErr.message} for "${subErr.source}"${subErr.details}`
1041
+ : subErr.message || subErr.toString());
1042
+ const newErr = new utils.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
+ }
1008
1049
  return result;
1009
1050
  }
1010
1051
 
@@ -1216,22 +1257,22 @@ const createWatcher = (initalContext, onNext) => {
1216
1257
  });
1217
1258
  };
1218
1259
 
1219
- function writeSync(filepath, content) {
1220
- return fs.writeFileSync(filepath, content);
1260
+ function writeFile(filepath, content) {
1261
+ return fsExtra.writeFile(filepath, content);
1221
1262
  }
1222
- function readSync(filepath) {
1223
- return fs.readFileSync(filepath, 'utf-8');
1263
+ function readFile(filepath) {
1264
+ return fsExtra.readFile(filepath, 'utf-8');
1224
1265
  }
1225
- function fileExists(filePath) {
1266
+ async function fileExists(filePath) {
1226
1267
  try {
1227
- return fs.statSync(filePath).isFile();
1268
+ return (await fsExtra.stat(filePath)).isFile();
1228
1269
  }
1229
1270
  catch (err) {
1230
1271
  return false;
1231
1272
  }
1232
1273
  }
1233
1274
  function unlinkFile(filePath, cb) {
1234
- fs.unlink(filePath, cb);
1275
+ fsExtra.unlink(filePath, cb);
1235
1276
  }
1236
1277
 
1237
1278
  const hash = (content) => crypto.createHash('sha1').update(content).digest('base64');
@@ -1246,7 +1287,7 @@ async function generate(input, saveToFile = true) {
1246
1287
  const staleFilenames = previouslyGeneratedFilenames.filter(f => !filenames.includes(f));
1247
1288
  staleFilenames.forEach(filename => {
1248
1289
  if (shouldOverwrite(config, filename)) {
1249
- unlinkFile(filename, err => {
1290
+ return unlinkFile(filename, err => {
1250
1291
  const prettyFilename = filename.replace(`${input.cwd || process.cwd()}/`, '');
1251
1292
  if (err) {
1252
1293
  debugLog(`Cannot remove stale file: ${prettyFilename}\n${err}`);
@@ -1267,7 +1308,39 @@ async function generate(input, saveToFile = true) {
1267
1308
  if (config.watch) {
1268
1309
  removeStaleFiles(config, generationResult);
1269
1310
  }
1270
- 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 = path.dirname(result.filename);
1333
+ await lifecycleHooks(result.hooks).beforeOneFileWrite(result.filename);
1334
+ await lifecycleHooks(config.hooks).beforeOneFileWrite(result.filename);
1335
+ await fsExtra.mkdirp(basedir);
1336
+ const absolutePath = path.isAbsolute(result.filename)
1337
+ ? result.filename
1338
+ : path.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');
1271
1344
  await context.profiler.run(() => Promise.all(generationResult.map(async (result) => {
1272
1345
  const exists = fileExists(result.filename);
1273
1346
  if (!shouldOverwrite(config, result.filename) && exists) {
@@ -1277,7 +1350,7 @@ async function generate(input, saveToFile = true) {
1277
1350
  const currentHash = hash(content);
1278
1351
  let previousHash = recentOutputHash.get(result.filename);
1279
1352
  if (!previousHash && exists) {
1280
- previousHash = hash(readSync(result.filename));
1353
+ previousHash = hash(await readFile(result.filename));
1281
1354
  }
1282
1355
  if (previousHash && currentHash === previousHash) {
1283
1356
  debugLog(`Skipping file (${result.filename}) writing due to identical hash...`);
@@ -1290,11 +1363,11 @@ async function generate(input, saveToFile = true) {
1290
1363
  const basedir = path.dirname(result.filename);
1291
1364
  await lifecycleHooks(result.hooks).beforeOneFileWrite(result.filename);
1292
1365
  await lifecycleHooks(config.hooks).beforeOneFileWrite(result.filename);
1293
- mkdirp.sync(basedir);
1366
+ fsExtra.mkdirp.sync(basedir);
1294
1367
  const absolutePath = path.isAbsolute(result.filename)
1295
1368
  ? result.filename
1296
1369
  : path.join(input.cwd || process.cwd(), result.filename);
1297
- writeSync(absolutePath, result.content);
1370
+ await writeFile(absolutePath, result.content);
1298
1371
  await lifecycleHooks(result.hooks).afterOneFileWrite(result.filename);
1299
1372
  await lifecycleHooks(config.hooks).afterOneFileWrite(result.filename);
1300
1373
  })), 'Write files');
@@ -1309,7 +1382,7 @@ async function generate(input, saveToFile = true) {
1309
1382
  await context.profiler.run(() => writeOutput(outputFiles), 'writeOutput');
1310
1383
  await context.profiler.run(() => lifecycleHooks(config.hooks).beforeDone(), 'Lifecycle: beforeDone');
1311
1384
  if (context.profilerOutput) {
1312
- writeSync(path.join(context.cwd, context.profilerOutput), JSON.stringify(context.profiler.collect()));
1385
+ await writeFile(path.join(context.cwd, context.profilerOutput), JSON.stringify(context.profiler.collect()));
1313
1386
  }
1314
1387
  return outputFiles;
1315
1388
  }
@@ -1780,30 +1853,6 @@ function addIntrospection(config) {
1780
1853
  };
1781
1854
  }
1782
1855
 
1783
- const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
1784
- const isNode = typeof process !== 'undefined' && process.versions != null && process.versions.node != null;
1785
-
1786
- function cliError(err, exitOnError = true) {
1787
- let msg;
1788
- if (err instanceof Error) {
1789
- msg = err.message || err.toString();
1790
- }
1791
- else if (typeof err === 'string') {
1792
- msg = err;
1793
- }
1794
- else {
1795
- msg = JSON.stringify(err);
1796
- }
1797
- // eslint-disable-next-line no-console
1798
- console.error(msg);
1799
- if (exitOnError && isNode) {
1800
- process.exit(1);
1801
- }
1802
- else if (exitOnError && isBrowser) {
1803
- throw err;
1804
- }
1805
- }
1806
-
1807
1856
  async function runCli(cmd) {
1808
1857
  await ensureGraphQlPackage();
1809
1858
  switch (cmd) {
@@ -1845,6 +1894,7 @@ exports.findAndLoadGraphQLConfig = findAndLoadGraphQLConfig;
1845
1894
  exports.generate = generate;
1846
1895
  exports.generateSearchPlaces = generateSearchPlaces;
1847
1896
  exports.init = init;
1897
+ exports.isListrError = isListrError;
1848
1898
  exports.loadCodegenConfig = loadCodegenConfig;
1849
1899
  exports.loadContext = loadContext;
1850
1900
  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';
@@ -687,6 +688,33 @@ function ensureContext(input) {
687
688
  return input instanceof CodegenContext ? input : new CodegenContext({ config: input });
688
689
  }
689
690
 
691
+ const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
692
+ const isNode = typeof process !== 'undefined' && process.versions != null && process.versions.node != null;
693
+
694
+ function isListrError(err) {
695
+ return err.name === 'ListrError' && Array.isArray(err.errors) && err.errors.length > 0;
696
+ }
697
+ function cliError(err, exitOnError = true) {
698
+ let msg;
699
+ if (err instanceof Error) {
700
+ msg = err.message || err.toString();
701
+ }
702
+ else if (typeof err === 'string') {
703
+ msg = err;
704
+ }
705
+ else {
706
+ msg = JSON.stringify(err);
707
+ }
708
+ // eslint-disable-next-line no-console
709
+ console.error(msg);
710
+ if (exitOnError && isNode) {
711
+ process.exit(1);
712
+ }
713
+ else if (exitOnError && isBrowser) {
714
+ throw err;
715
+ }
716
+ }
717
+
690
718
  const makeDefaultLoader = (from) => {
691
719
  if (fs.statSync(from).isDirectory()) {
692
720
  from = path.join(from, '__fake.js');
@@ -972,12 +1000,25 @@ async function executeCodegen(input) {
972
1000
  }), {
973
1001
  // it doesn't stop when one of tasks failed, to finish at least some of outputs
974
1002
  exitOnError: false,
975
- // run 4 at once
976
- concurrent: 4,
1003
+ concurrent: cpus().length,
977
1004
  });
978
1005
  },
979
1006
  });
980
- await listr.run();
1007
+ try {
1008
+ await listr.run();
1009
+ }
1010
+ catch (err) {
1011
+ if (isListrError(err)) {
1012
+ const allErrs = err.errors.map(subErr => isDetailedError(subErr)
1013
+ ? `${subErr.message} for "${subErr.source}"${subErr.details}`
1014
+ : subErr.message || subErr.toString());
1015
+ const newErr = new AggregateError(err.errors, `${err.message} ${allErrs.join('\n\n')}`);
1016
+ // Best-effort to all stack traces for debugging
1017
+ newErr.stack = `${newErr.stack}\n\n${err.errors.map(subErr => subErr.stack).join('\n\n')}`;
1018
+ throw newErr;
1019
+ }
1020
+ throw err;
1021
+ }
981
1022
  return result;
982
1023
  }
983
1024
 
@@ -1189,15 +1230,15 @@ const createWatcher = (initalContext, onNext) => {
1189
1230
  });
1190
1231
  };
1191
1232
 
1192
- function writeSync(filepath, content) {
1193
- return writeFileSync(filepath, content);
1233
+ function writeFile(filepath, content) {
1234
+ return writeFile$1(filepath, content);
1194
1235
  }
1195
- function readSync(filepath) {
1196
- return readFileSync(filepath, 'utf-8');
1236
+ function readFile(filepath) {
1237
+ return readFile$1(filepath, 'utf-8');
1197
1238
  }
1198
- function fileExists(filePath) {
1239
+ async function fileExists(filePath) {
1199
1240
  try {
1200
- return statSync(filePath).isFile();
1241
+ return (await stat(filePath)).isFile();
1201
1242
  }
1202
1243
  catch (err) {
1203
1244
  return false;
@@ -1219,7 +1260,7 @@ async function generate(input, saveToFile = true) {
1219
1260
  const staleFilenames = previouslyGeneratedFilenames.filter(f => !filenames.includes(f));
1220
1261
  staleFilenames.forEach(filename => {
1221
1262
  if (shouldOverwrite(config, filename)) {
1222
- unlinkFile(filename, err => {
1263
+ return unlinkFile(filename, err => {
1223
1264
  const prettyFilename = filename.replace(`${input.cwd || process.cwd()}/`, '');
1224
1265
  if (err) {
1225
1266
  debugLog(`Cannot remove stale file: ${prettyFilename}\n${err}`);
@@ -1240,7 +1281,39 @@ async function generate(input, saveToFile = true) {
1240
1281
  if (config.watch) {
1241
1282
  removeStaleFiles(config, generationResult);
1242
1283
  }
1243
- await context.profiler.run(() => lifecycleHooks(config.hooks).beforeAllFileWrite(generationResult.map(r => r.filename)), 'Lifecycle: beforeAllFileWrite');
1284
+ await context.profiler.run(async () => {
1285
+ await lifecycleHooks(config.hooks).beforeAllFileWrite(generationResult.map(r => r.filename));
1286
+ await Promise.all(generationResult.map(async (result) => {
1287
+ const exists = await fileExists(result.filename);
1288
+ if (!shouldOverwrite(config, result.filename) && exists) {
1289
+ return;
1290
+ }
1291
+ const content = result.content || '';
1292
+ const currentHash = hash(content);
1293
+ let previousHash = recentOutputHash.get(result.filename);
1294
+ if (!previousHash && exists) {
1295
+ previousHash = hash(await readFile(result.filename));
1296
+ }
1297
+ if (previousHash && currentHash === previousHash) {
1298
+ debugLog(`Skipping file (${result.filename}) writing due to indentical hash...`);
1299
+ return;
1300
+ }
1301
+ if (content.length === 0) {
1302
+ return;
1303
+ }
1304
+ recentOutputHash.set(result.filename, currentHash);
1305
+ const basedir = dirname(result.filename);
1306
+ await lifecycleHooks(result.hooks).beforeOneFileWrite(result.filename);
1307
+ await lifecycleHooks(config.hooks).beforeOneFileWrite(result.filename);
1308
+ await mkdirp(basedir);
1309
+ const absolutePath = isAbsolute(result.filename)
1310
+ ? result.filename
1311
+ : join(input.cwd || process.cwd(), result.filename);
1312
+ await writeFile(absolutePath, result.content);
1313
+ await lifecycleHooks(result.hooks).afterOneFileWrite(result.filename);
1314
+ await lifecycleHooks(config.hooks).afterOneFileWrite(result.filename);
1315
+ }));
1316
+ }, 'Lifecycle: beforeAllFileWrite');
1244
1317
  await context.profiler.run(() => Promise.all(generationResult.map(async (result) => {
1245
1318
  const exists = fileExists(result.filename);
1246
1319
  if (!shouldOverwrite(config, result.filename) && exists) {
@@ -1250,7 +1323,7 @@ async function generate(input, saveToFile = true) {
1250
1323
  const currentHash = hash(content);
1251
1324
  let previousHash = recentOutputHash.get(result.filename);
1252
1325
  if (!previousHash && exists) {
1253
- previousHash = hash(readSync(result.filename));
1326
+ previousHash = hash(await readFile(result.filename));
1254
1327
  }
1255
1328
  if (previousHash && currentHash === previousHash) {
1256
1329
  debugLog(`Skipping file (${result.filename}) writing due to identical hash...`);
@@ -1267,7 +1340,7 @@ async function generate(input, saveToFile = true) {
1267
1340
  const absolutePath = isAbsolute(result.filename)
1268
1341
  ? result.filename
1269
1342
  : join(input.cwd || process.cwd(), result.filename);
1270
- writeSync(absolutePath, result.content);
1343
+ await writeFile(absolutePath, result.content);
1271
1344
  await lifecycleHooks(result.hooks).afterOneFileWrite(result.filename);
1272
1345
  await lifecycleHooks(config.hooks).afterOneFileWrite(result.filename);
1273
1346
  })), 'Write files');
@@ -1282,7 +1355,7 @@ async function generate(input, saveToFile = true) {
1282
1355
  await context.profiler.run(() => writeOutput(outputFiles), 'writeOutput');
1283
1356
  await context.profiler.run(() => lifecycleHooks(config.hooks).beforeDone(), 'Lifecycle: beforeDone');
1284
1357
  if (context.profilerOutput) {
1285
- writeSync(join(context.cwd, context.profilerOutput), JSON.stringify(context.profiler.collect()));
1358
+ await writeFile(join(context.cwd, context.profilerOutput), JSON.stringify(context.profiler.collect()));
1286
1359
  }
1287
1360
  return outputFiles;
1288
1361
  }
@@ -1753,30 +1826,6 @@ function addIntrospection(config) {
1753
1826
  };
1754
1827
  }
1755
1828
 
1756
- const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
1757
- const isNode = typeof process !== 'undefined' && process.versions != null && process.versions.node != null;
1758
-
1759
- function cliError(err, exitOnError = true) {
1760
- let msg;
1761
- if (err instanceof Error) {
1762
- msg = err.message || err.toString();
1763
- }
1764
- else if (typeof err === 'string') {
1765
- msg = err;
1766
- }
1767
- else {
1768
- msg = JSON.stringify(err);
1769
- }
1770
- // eslint-disable-next-line no-console
1771
- console.error(msg);
1772
- if (exitOnError && isNode) {
1773
- process.exit(1);
1774
- }
1775
- else if (exitOnError && isBrowser) {
1776
- throw err;
1777
- }
1778
- }
1779
-
1780
1829
  async function runCli(cmd) {
1781
1830
  await ensureGraphQlPackage();
1782
1831
  switch (cmd) {
@@ -1806,4 +1855,4 @@ async function ensureGraphQlPackage() {
1806
1855
  }
1807
1856
  }
1808
1857
 
1809
- export { CodegenContext, CodegenExtension, buildOptions, cliError, createContext, ensureContext, ensureGraphQlPackage, executeCodegen, findAndLoadGraphQLConfig, generate, generateSearchPlaces, init, loadCodegenConfig, loadContext, parseArgv, runCli, updateContextWithCliFlags };
1858
+ 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-c9cbc7d69.0",
3
+ "version": "2.6.0-alpha-679ebe9ab.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-c9cbc7d69.0",
9
- "@graphql-codegen/plugin-helpers": "2.4.0-alpha-c9cbc7d69.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;