@graphql-codegen/cli 2.6.3 → 2.6.5-alpha-acacb9e7a.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/index.mjs CHANGED
@@ -1,15 +1,9 @@
1
- import { isDetailedError, DetailedError, createNoopProfiler, createProfiler, getCachedDocumentNodeFromSchema, normalizeInstanceOrArray, normalizeConfig, normalizeOutputParam } from '@graphql-codegen/plugin-helpers';
1
+ import { DetailedError, createNoopProfiler, createProfiler, getCachedDocumentNodeFromSchema, normalizeInstanceOrArray, normalizeConfig, isDetailedError, normalizeOutputParam } from '@graphql-codegen/plugin-helpers';
2
2
  import { codegen } from '@graphql-codegen/core';
3
3
  import { AggregateError, isValidPath } from '@graphql-tools/utils';
4
- import chalk from 'chalk';
5
- import logSymbols from 'log-symbols';
6
- import ansiEscapes from 'ansi-escapes';
7
- import wrapAnsi from 'wrap-ansi';
8
- import { stripIndent } from 'common-tags';
9
- import { dummyLogger } from 'ts-log';
10
- import UpdateRenderer from 'listr-update-renderer';
11
4
  import { print, GraphQLError } from 'graphql';
12
5
  import path, { resolve, extname, join, delimiter, sep, dirname, isAbsolute, relative } from 'path';
6
+ import { dummyLogger } from 'ts-log';
13
7
  import { cosmiconfig, defaultLoaders } from 'cosmiconfig';
14
8
  import { env } from 'string-env-interpolation';
15
9
  import yargs from 'yargs';
@@ -28,202 +22,16 @@ import { createRequire } from 'module';
28
22
  import fs, { promises, unlink, writeFileSync, readFileSync } from 'fs';
29
23
  import { createHash } from 'crypto';
30
24
  import { cpus } from 'os';
31
- import Listr from 'listr';
25
+ import { Listr } from 'listr2';
32
26
  import { exec } from 'child_process';
33
27
  import isGlob from 'is-glob';
34
28
  import debounce from 'debounce';
29
+ import logSymbols from 'log-symbols';
35
30
  import mkdirp from 'mkdirp';
36
31
  import inquirer from 'inquirer';
32
+ import chalk from 'chalk';
37
33
  import detectIndent from 'detect-indent';
38
-
39
- /**
40
- Indent each line in a string.
41
- @param string - The string to indent.
42
- @param count - How many times you want `options.indent` repeated. Default: `1`.
43
- @example
44
- ```
45
- import indentString from 'indent-string';
46
- indentString('Unicorns\nRainbows', 4);
47
- //=> ' Unicorns\n Rainbows'
48
- indentString('Unicorns\nRainbows', 4, {indent: '♥'});
49
- //=> '♥♥♥♥Unicorns\n♥♥♥♥Rainbows'
50
- ```
51
- */
52
- function indentString(string, count = 1, options = {}) {
53
- const { indent = ' ', includeEmptyLines = false } = options;
54
- if (typeof string !== 'string') {
55
- throw new TypeError(`Expected \`input\` to be a \`string\`, got \`${typeof string}\``);
56
- }
57
- if (typeof count !== 'number') {
58
- throw new TypeError(`Expected \`count\` to be a \`number\`, got \`${typeof count}\``);
59
- }
60
- if (count < 0) {
61
- throw new RangeError(`Expected \`count\` to be at least 0, got \`${count}\``);
62
- }
63
- if (typeof indent !== 'string') {
64
- throw new TypeError(`Expected \`options.indent\` to be a \`string\`, got \`${typeof indent}\``);
65
- }
66
- if (count === 0) {
67
- return string;
68
- }
69
- const regex = includeEmptyLines ? /^/gm : /^(?!\s*$)/gm;
70
- return string.replace(regex, indent.repeat(count));
71
- }
72
-
73
- let logger;
74
- function getLogger() {
75
- return logger || dummyLogger;
76
- }
77
- useWinstonLogger();
78
- function useWinstonLogger() {
79
- if (logger && logger.levels) {
80
- return;
81
- }
82
- logger = console;
83
- }
84
-
85
- let queue = [];
86
- function debugLog(message, ...meta) {
87
- if (!process.env.GQL_CODEGEN_NODEBUG && process.env.DEBUG !== undefined) {
88
- queue.push({
89
- message,
90
- meta,
91
- });
92
- }
93
- }
94
- function printLogs() {
95
- if (!process.env.GQL_CODEGEN_NODEBUG && process.env.DEBUG !== undefined) {
96
- queue.forEach(log => {
97
- getLogger().info(log.message, ...log.meta);
98
- });
99
- resetLogs();
100
- }
101
- }
102
- function resetLogs() {
103
- queue = [];
104
- }
105
-
106
- class Renderer {
107
- constructor(tasks, options) {
108
- this.updateRenderer = new UpdateRenderer(tasks, options);
109
- }
110
- render() {
111
- return this.updateRenderer.render();
112
- }
113
- end(err) {
114
- this.updateRenderer.end(err);
115
- if (typeof err === 'undefined') {
116
- logUpdate.clear();
117
- return;
118
- }
119
- // persist the output
120
- logUpdate.done();
121
- // show errors
122
- if (err) {
123
- const errorCount = err.errors ? err.errors.length : 0;
124
- if (errorCount > 0) {
125
- const count = indentString(chalk.red.bold(`Found ${errorCount} error${errorCount > 1 ? 's' : ''}`), 1);
126
- const details = err.errors
127
- .map(error => {
128
- debugLog(`[CLI] Exited with an error`, error);
129
- return { msg: isDetailedError(error) ? error.details : null, rawError: error };
130
- })
131
- .map(({ msg, rawError }, i) => {
132
- const source = err.errors[i].source;
133
- msg = msg ? chalk.gray(indentString(stripIndent(`${msg}`), 4)) : null;
134
- const stack = rawError.stack ? chalk.gray(indentString(stripIndent(rawError.stack), 4)) : null;
135
- if (source) {
136
- const sourceOfError = typeof source === 'string' ? source : source.name;
137
- const title = indentString(`${logSymbols.error} ${sourceOfError}`, 2);
138
- return [title, msg, stack, stack].filter(Boolean).join('\n');
139
- }
140
- return [msg, stack].filter(Boolean).join('\n');
141
- })
142
- .join('\n\n');
143
- logUpdate.emit(['', count, details, ''].join('\n\n'));
144
- }
145
- else {
146
- const details = err.details ? err.details : '';
147
- logUpdate.emit(`${chalk.red.bold(`${indentString(err.message, 2)}`)}\n${details}\n${chalk.grey(err.stack)}`);
148
- }
149
- }
150
- logUpdate.done();
151
- printLogs();
152
- }
153
- }
154
- const render = tasks => {
155
- for (const task of tasks) {
156
- task.subscribe(event => {
157
- if (event.type === 'SUBTASKS') {
158
- render(task.subtasks);
159
- return;
160
- }
161
- if (event.type === 'DATA') {
162
- logUpdate.emit(chalk.dim(`${event.data}`));
163
- }
164
- logUpdate.done();
165
- }, err => {
166
- logUpdate.emit(err);
167
- logUpdate.done();
168
- });
169
- }
170
- };
171
- class ErrorRenderer {
172
- constructor(tasks, _options) {
173
- this.tasks = tasks;
174
- }
175
- render() {
176
- render(this.tasks);
177
- }
178
- static get nonTTY() {
179
- return true;
180
- }
181
- end() { }
182
- }
183
- class LogUpdate {
184
- constructor() {
185
- this.stream = process.stdout;
186
- // state
187
- this.previousLineCount = 0;
188
- this.previousOutput = '';
189
- this.previousWidth = this.getWidth();
190
- }
191
- emit(...args) {
192
- let output = args.join(' ') + '\n';
193
- const width = this.getWidth();
194
- if (output === this.previousOutput && this.previousWidth === width) {
195
- return;
196
- }
197
- this.previousOutput = output;
198
- this.previousWidth = width;
199
- output = wrapAnsi(output, width, {
200
- trim: false,
201
- hard: true,
202
- wordWrap: false,
203
- });
204
- this.stream.write(ansiEscapes.eraseLines(this.previousLineCount) + output);
205
- this.previousLineCount = output.split('\n').length;
206
- }
207
- clear() {
208
- this.stream.write(ansiEscapes.eraseLines(this.previousLineCount));
209
- this.previousOutput = '';
210
- this.previousWidth = this.getWidth();
211
- this.previousLineCount = 0;
212
- }
213
- done() {
214
- this.previousOutput = '';
215
- this.previousWidth = this.getWidth();
216
- this.previousLineCount = 0;
217
- }
218
- getWidth() {
219
- const { columns } = this.stream;
220
- if (!columns) {
221
- return 80;
222
- }
223
- return columns;
224
- }
225
- }
226
- const logUpdate = new LogUpdate();
34
+ import getLatestVersion from 'latest-version';
227
35
 
228
36
  async function getPluginByName(name, pluginLoader) {
229
37
  const possibleNames = [
@@ -306,6 +114,22 @@ async function getPresetByName(name, loader) {
306
114
  `);
307
115
  }
308
116
 
117
+ let logger;
118
+ function getLogger() {
119
+ return logger || dummyLogger;
120
+ }
121
+ useWinstonLogger();
122
+ function useWinstonLogger() {
123
+ if (logger && logger.levels) {
124
+ return;
125
+ }
126
+ logger = console;
127
+ }
128
+
129
+ function debugLog(message, ...meta) {
130
+ if (!process.env.GQL_CODEGEN_NODEBUG && process.env.DEBUG !== undefined) ;
131
+ }
132
+
309
133
  const CodegenExtension = (api) => {
310
134
  // Schema
311
135
  api.loaders.schema.register(new CodeFileLoader({
@@ -722,33 +546,6 @@ function addHashToDocumentFiles(documentFilesPromise) {
722
546
  }));
723
547
  }
724
548
 
725
- const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
726
- const isNode = typeof process !== 'undefined' && process.versions != null && process.versions.node != null;
727
-
728
- function isListrError(err) {
729
- return err.name === 'ListrError' && Array.isArray(err.errors) && err.errors.length > 0;
730
- }
731
- function cliError(err, exitOnError = true) {
732
- let msg;
733
- if (err instanceof Error) {
734
- msg = err.message || err.toString();
735
- }
736
- else if (typeof err === 'string') {
737
- msg = err;
738
- }
739
- else {
740
- msg = JSON.stringify(err);
741
- }
742
- // eslint-disable-next-line no-console
743
- console.error(msg);
744
- if (exitOnError && isNode) {
745
- process.exit(1);
746
- }
747
- else if (exitOnError && isBrowser) {
748
- throw err;
749
- }
750
- }
751
-
752
549
  const makeDefaultLoader = (from) => {
753
550
  if (fs.statSync(from).isDirectory()) {
754
551
  from = path.join(from, '__fake.js');
@@ -776,39 +573,12 @@ async function executeCodegen(input) {
776
573
  const config = context.getConfig();
777
574
  const pluginContext = context.getPluginContext();
778
575
  const result = [];
779
- const commonListrOptions = {
780
- exitOnError: true,
781
- };
782
- let listr;
783
- if (process.env.VERBOSE) {
784
- listr = new Listr({
785
- ...commonListrOptions,
786
- renderer: 'verbose',
787
- nonTTYRenderer: 'verbose',
788
- });
789
- }
790
- else if (process.env.NODE_ENV === 'test') {
791
- listr = new Listr({
792
- ...commonListrOptions,
793
- renderer: 'silent',
794
- nonTTYRenderer: 'silent',
795
- });
796
- }
797
- else {
798
- listr = new Listr({
799
- ...commonListrOptions,
800
- renderer: config.silent ? 'silent' : config.errorsOnly ? ErrorRenderer : Renderer,
801
- nonTTYRenderer: config.silent ? 'silent' : 'default',
802
- collapse: true,
803
- clearOutput: false,
804
- });
805
- }
806
576
  let rootConfig = {};
807
577
  let rootSchemas;
808
578
  let rootDocuments;
809
579
  const generates = {};
810
580
  const cache = createCache();
811
- function wrapTask(task, source, taskName) {
581
+ function wrapTask(task, source, taskName, ctx) {
812
582
  return () => {
813
583
  return context.profiler.run(async () => {
814
584
  try {
@@ -818,6 +588,7 @@ async function executeCodegen(input) {
818
588
  if (source && !(error instanceof GraphQLError)) {
819
589
  error.source = source;
820
590
  }
591
+ ctx.errors.push(error);
821
592
  throw error;
822
593
  }
823
594
  }, taskName);
@@ -888,119 +659,109 @@ async function executeCodegen(input) {
888
659
  `);
889
660
  }
890
661
  }
891
- listr.add({
892
- title: 'Parse configuration',
893
- task: () => normalize(),
894
- });
895
- listr.add({
896
- title: 'Generate outputs',
897
- task: () => {
898
- return new Listr(Object.keys(generates).map(filename => {
899
- const outputConfig = generates[filename];
900
- const hasPreset = !!outputConfig.preset;
901
- return {
902
- title: hasPreset
662
+ const isTest = process.env.NODE_ENV === 'test';
663
+ const tasks = new Listr([
664
+ {
665
+ title: 'Parse Configuration',
666
+ task: () => normalize(),
667
+ },
668
+ {
669
+ title: 'Generate outputs',
670
+ task: (ctx, task) => {
671
+ const generateTasks = Object.keys(generates).map(filename => {
672
+ const outputConfig = generates[filename];
673
+ const hasPreset = !!outputConfig.preset;
674
+ const title = hasPreset
903
675
  ? `Generate to ${filename} (using EXPERIMENTAL preset "${outputConfig.preset}")`
904
- : `Generate ${filename}`,
905
- task: () => {
906
- let outputSchemaAst;
907
- let outputSchema;
908
- const outputFileTemplateConfig = outputConfig.config || {};
909
- const outputDocuments = [];
910
- const outputSpecificSchemas = normalizeInstanceOrArray(outputConfig.schema);
911
- const outputSpecificDocuments = normalizeInstanceOrArray(outputConfig.documents);
912
- return new Listr([
913
- {
914
- title: 'Load GraphQL schemas',
915
- task: wrapTask(async () => {
916
- debugLog(`[CLI] Loading Schemas`);
917
- const schemaPointerMap = {};
918
- const allSchemaUnnormalizedPointers = [...rootSchemas, ...outputSpecificSchemas];
919
- for (const unnormalizedPtr of allSchemaUnnormalizedPointers) {
920
- if (typeof unnormalizedPtr === 'string') {
921
- schemaPointerMap[unnormalizedPtr] = {};
676
+ : `Generate ${filename}`;
677
+ return {
678
+ title,
679
+ task: (_, subTask) => {
680
+ let outputSchemaAst;
681
+ let outputSchema;
682
+ const outputFileTemplateConfig = outputConfig.config || {};
683
+ let outputDocuments = [];
684
+ const outputSpecificSchemas = normalizeInstanceOrArray(outputConfig.schema);
685
+ const outputSpecificDocuments = normalizeInstanceOrArray(outputConfig.documents);
686
+ return subTask.newListr([
687
+ {
688
+ title: 'Load GraphQL schemas',
689
+ task: wrapTask(async () => {
690
+ debugLog(`[CLI] Loading Schemas`);
691
+ const schemaPointerMap = {};
692
+ const allSchemaDenormalizedPointers = [...rootSchemas, ...outputSpecificSchemas];
693
+ for (const denormalizedPtr of allSchemaDenormalizedPointers) {
694
+ if (typeof denormalizedPtr === 'string') {
695
+ schemaPointerMap[denormalizedPtr] = {};
696
+ }
697
+ else if (typeof denormalizedPtr === 'object') {
698
+ Object.assign(schemaPointerMap, denormalizedPtr);
699
+ }
922
700
  }
923
- else if (typeof unnormalizedPtr === 'object') {
924
- Object.assign(schemaPointerMap, unnormalizedPtr);
701
+ const hash = JSON.stringify(schemaPointerMap);
702
+ const result = await cache('schema', hash, async () => {
703
+ const outputSchemaAst = await context.loadSchema(schemaPointerMap);
704
+ const outputSchema = getCachedDocumentNodeFromSchema(outputSchemaAst);
705
+ return {
706
+ outputSchemaAst,
707
+ outputSchema,
708
+ };
709
+ });
710
+ outputSchemaAst = result.outputSchemaAst;
711
+ outputSchema = result.outputSchema;
712
+ }, filename, `Load GraphQL schemas: ${filename}`, ctx),
713
+ },
714
+ {
715
+ title: 'Load GraphQL documents',
716
+ task: wrapTask(async () => {
717
+ debugLog(`[CLI] Loading Documents`);
718
+ const documentPointerMap = {};
719
+ const allDocumentsDenormalizedPointers = [...rootDocuments, ...outputSpecificDocuments];
720
+ for (const denormalizedPtr of allDocumentsDenormalizedPointers) {
721
+ if (typeof denormalizedPtr === 'string') {
722
+ documentPointerMap[denormalizedPtr] = {};
723
+ }
724
+ else if (typeof denormalizedPtr === 'object') {
725
+ Object.assign(documentPointerMap, denormalizedPtr);
726
+ }
925
727
  }
926
- }
927
- const hash = JSON.stringify(schemaPointerMap);
928
- const result = await cache('schema', hash, async () => {
929
- const outputSchemaAst = await context.loadSchema(schemaPointerMap);
930
- const outputSchema = getCachedDocumentNodeFromSchema(outputSchemaAst);
931
- return {
932
- outputSchemaAst,
933
- outputSchema,
934
- };
935
- });
936
- outputSchemaAst = await result.outputSchemaAst;
937
- outputSchema = result.outputSchema;
938
- }, filename, `Load GraphQL schemas: ${filename}`),
939
- },
940
- {
941
- title: 'Load GraphQL documents',
942
- task: wrapTask(async () => {
943
- debugLog(`[CLI] Loading 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 cache('documents', hash, async () => {
948
- const documents = await context.loadDocuments(docs);
728
+ const hash = JSON.stringify(documentPointerMap);
729
+ const result = await cache('documents', hash, async () => {
730
+ const documents = await context.loadDocuments(documentPointerMap);
949
731
  return {
950
732
  documents,
951
733
  };
952
734
  });
953
- }));
954
- const documents = [];
955
- results.forEach(source => documents.push(...source.documents));
956
- if (documents.length > 0) {
957
- outputDocuments.push(...documents);
958
- }
959
- }, filename, `Load GraphQL documents: ${filename}`),
960
- },
961
- {
962
- title: 'Generate',
963
- task: wrapTask(async () => {
964
- debugLog(`[CLI] Generating output`);
965
- const normalizedPluginsArray = normalizeConfig(outputConfig.plugins);
966
- const pluginLoader = config.pluginLoader || makeDefaultLoader(context.cwd);
967
- const pluginPackages = await Promise.all(normalizedPluginsArray.map(plugin => getPluginByName(Object.keys(plugin)[0], pluginLoader)));
968
- const pluginMap = {};
969
- const preset = hasPreset
970
- ? typeof outputConfig.preset === 'string'
971
- ? await getPresetByName(outputConfig.preset, makeDefaultLoader(context.cwd))
972
- : outputConfig.preset
973
- : null;
974
- pluginPackages.forEach((pluginPackage, i) => {
975
- const plugin = normalizedPluginsArray[i];
976
- const name = Object.keys(plugin)[0];
977
- pluginMap[name] = pluginPackage;
978
- });
979
- const mergedConfig = {
980
- ...rootConfig,
981
- ...(typeof outputFileTemplateConfig === 'string'
982
- ? { value: outputFileTemplateConfig }
983
- : outputFileTemplateConfig),
984
- };
985
- let outputs = [];
986
- if (hasPreset) {
987
- outputs = await context.profiler.run(async () => preset.buildGeneratesSection({
988
- baseOutputDir: filename,
989
- presetConfig: outputConfig.presetConfig || {},
990
- plugins: normalizedPluginsArray,
991
- schema: outputSchema,
992
- schemaAst: outputSchemaAst,
993
- documents: outputDocuments,
994
- config: mergedConfig,
995
- pluginMap,
996
- pluginContext,
997
- profiler: context.profiler,
998
- }), `Build Generates Section: ${filename}`);
999
- }
1000
- else {
1001
- outputs = [
1002
- {
1003
- filename,
735
+ outputDocuments = result.documents;
736
+ }, filename, `Load GraphQL documents: ${filename}`, ctx),
737
+ },
738
+ {
739
+ title: 'Generate',
740
+ task: wrapTask(async () => {
741
+ debugLog(`[CLI] Generating output`);
742
+ const normalizedPluginsArray = normalizeConfig(outputConfig.plugins);
743
+ const pluginLoader = config.pluginLoader || makeDefaultLoader(context.cwd);
744
+ const pluginPackages = await Promise.all(normalizedPluginsArray.map(plugin => getPluginByName(Object.keys(plugin)[0], pluginLoader)));
745
+ const preset = hasPreset
746
+ ? typeof outputConfig.preset === 'string'
747
+ ? await getPresetByName(outputConfig.preset, makeDefaultLoader(context.cwd))
748
+ : outputConfig.preset
749
+ : null;
750
+ const pluginMap = Object.fromEntries(pluginPackages.map((pkg, i) => {
751
+ const plugin = normalizedPluginsArray[i];
752
+ const name = Object.keys(plugin)[0];
753
+ return [name, pkg];
754
+ }));
755
+ const mergedConfig = {
756
+ ...rootConfig,
757
+ ...(typeof outputFileTemplateConfig === 'string'
758
+ ? { value: outputFileTemplateConfig }
759
+ : outputFileTemplateConfig),
760
+ };
761
+ const outputs = hasPreset
762
+ ? await context.profiler.run(async () => preset.buildGeneratesSection({
763
+ baseOutputDir: filename,
764
+ presetConfig: outputConfig.presetConfig || {},
1004
765
  plugins: normalizedPluginsArray,
1005
766
  schema: outputSchema,
1006
767
  schemaAst: outputSchemaAst,
@@ -1009,50 +770,67 @@ async function executeCodegen(input) {
1009
770
  pluginMap,
1010
771
  pluginContext,
1011
772
  profiler: context.profiler,
1012
- },
1013
- ];
1014
- }
1015
- const process = async (outputArgs) => {
1016
- const output = await codegen({
1017
- ...outputArgs,
1018
- cache,
1019
- });
1020
- result.push({
1021
- filename: outputArgs.filename,
1022
- content: output,
1023
- hooks: outputConfig.hooks || {},
1024
- });
1025
- };
1026
- await context.profiler.run(() => Promise.all(outputs.map(process)), `Codegen: ${filename}`);
1027
- }, filename, `Generate: ${filename}`),
1028
- },
1029
- ], {
1030
- // it stops when one of tasks failed
1031
- exitOnError: true,
1032
- });
1033
- },
1034
- };
1035
- }), {
1036
- // it doesn't stop when one of tasks failed, to finish at least some of outputs
1037
- exitOnError: false,
1038
- concurrent: cpus().length,
1039
- });
773
+ }), `Build Generates Section: ${filename}`)
774
+ : [
775
+ {
776
+ filename,
777
+ plugins: normalizedPluginsArray,
778
+ schema: outputSchema,
779
+ schemaAst: outputSchemaAst,
780
+ documents: outputDocuments,
781
+ config: mergedConfig,
782
+ pluginMap,
783
+ pluginContext,
784
+ profiler: context.profiler,
785
+ },
786
+ ];
787
+ const process = async (outputArgs) => {
788
+ const output = await codegen({
789
+ ...outputArgs,
790
+ cache,
791
+ });
792
+ result.push({
793
+ filename: outputArgs.filename,
794
+ content: output,
795
+ hooks: outputConfig.hooks || {},
796
+ });
797
+ };
798
+ await context.profiler.run(() => Promise.all(outputs.map(process)), `Codegen: ${filename}`);
799
+ }, filename, `Generate: ${filename}`, ctx),
800
+ },
801
+ ], {
802
+ // it stops when of the tasks failed
803
+ exitOnError: true,
804
+ });
805
+ },
806
+ // It doesn't stop when one of tasks failed, to finish at least some of outputs
807
+ exitOnError: false,
808
+ concurrent: cpus().length,
809
+ };
810
+ });
811
+ return task.newListr(generateTasks);
812
+ },
1040
813
  },
814
+ ], {
815
+ rendererOptions: {
816
+ clearOutput: false,
817
+ collapse: true,
818
+ },
819
+ ctx: { errors: [] },
820
+ rendererSilent: isTest || config.silent,
821
+ exitOnError: true,
1041
822
  });
1042
- try {
1043
- await listr.run();
1044
- }
1045
- catch (err) {
1046
- if (isListrError(err)) {
1047
- const allErrs = err.errors.map(subErr => isDetailedError(subErr)
1048
- ? `${subErr.message} for "${subErr.source}"${subErr.details}`
1049
- : subErr.message || subErr.toString());
1050
- const newErr = new AggregateError(err.errors, `${err.message} ${allErrs.join('\n\n')}`);
1051
- // Best-effort to all stack traces for debugging
1052
- newErr.stack = `${newErr.stack}\n\n${err.errors.map(subErr => subErr.stack).join('\n\n')}`;
1053
- throw newErr;
1054
- }
1055
- throw err;
823
+ // All the errors throw in `listr2` are collected in context
824
+ // Running tasks doesn't throw anything
825
+ const executedContext = await tasks.run();
826
+ if (executedContext.errors.length > 0) {
827
+ const errors = executedContext.errors.map(subErr => isDetailedError(subErr)
828
+ ? `${subErr.message} for "${subErr.source}"${subErr.details}`
829
+ : subErr.message || subErr.toString());
830
+ const newErr = new AggregateError(executedContext.errors, `${errors.join('\n\n')}`);
831
+ // Best-effort to all stack traces for debugging
832
+ newErr.stack = `${newErr.stack}\n\n${executedContext.errors.map(subErr => subErr.stack).join('\n\n')}`;
833
+ throw newErr;
1056
834
  }
1057
835
  return result;
1058
836
  }
@@ -1112,7 +890,7 @@ function execShellCommand(cmd) {
1112
890
  });
1113
891
  }
1114
892
  async function executeHooks(hookName, scripts = [], args = []) {
1115
- debugLog(`Running lifecycle hook "${hookName}" scripts...`);
893
+ debugLog();
1116
894
  for (const script of scripts) {
1117
895
  if (typeof script === 'string') {
1118
896
  debugLog(`Running lifecycle hook "${hookName}" script: ${script} with args: ${args.join(' ')}...`);
@@ -1146,7 +924,7 @@ function emitWatching() {
1146
924
  log(`${logSymbols.info} Watching for changes...`);
1147
925
  }
1148
926
  const createWatcher = (initalContext, onNext) => {
1149
- debugLog(`[Watcher] Starting watcher...`);
927
+ debugLog();
1150
928
  let config = initalContext.getConfig();
1151
929
  const files = [initalContext.filepath].filter(a => a);
1152
930
  const documents = normalizeInstanceOrArray(config.documents);
@@ -1217,10 +995,10 @@ const createWatcher = (initalContext, onNext) => {
1217
995
  atomic: true,
1218
996
  ignored,
1219
997
  });
1220
- debugLog(`[Watcher] Started`);
998
+ debugLog();
1221
999
  const shutdown = () => {
1222
1000
  isShutdown = true;
1223
- debugLog(`[Watcher] Shutting down`);
1001
+ debugLog();
1224
1002
  log(`Shutting down watch...`);
1225
1003
  watcher.close();
1226
1004
  lifecycleHooks(config.hooks).beforeDone();
@@ -1228,7 +1006,7 @@ const createWatcher = (initalContext, onNext) => {
1228
1006
  // it doesn't matter what has changed, need to run whole process anyway
1229
1007
  watcher.on('all', async (eventName, path) => {
1230
1008
  lifecycleHooks(config.hooks).onWatchTriggered(eventName, path);
1231
- debugLog(`[Watcher] triggered due to a file ${eventName} event: ${path}`);
1009
+ debugLog();
1232
1010
  const fullPath = join(process.cwd(), path);
1233
1011
  // In ESM require is not defined
1234
1012
  try {
@@ -1297,10 +1075,10 @@ async function generate(input, saveToFile = true) {
1297
1075
  return unlinkFile(filename, err => {
1298
1076
  const prettyFilename = filename.replace(`${input.cwd || process.cwd()}/`, '');
1299
1077
  if (err) {
1300
- debugLog(`Cannot remove stale file: ${prettyFilename}\n${err}`);
1078
+ debugLog();
1301
1079
  }
1302
1080
  else {
1303
- debugLog(`Removed stale file: ${prettyFilename}`);
1081
+ debugLog();
1304
1082
  }
1305
1083
  });
1306
1084
  }
@@ -1367,7 +1145,7 @@ function shouldOverwrite(config, outputPath) {
1367
1145
  const globalValue = config.overwrite === undefined ? true : !!config.overwrite;
1368
1146
  const outputConfig = config.generates[outputPath];
1369
1147
  if (!outputConfig) {
1370
- debugLog(`Couldn't find a config of ${outputPath}`);
1148
+ debugLog();
1371
1149
  return globalValue;
1372
1150
  }
1373
1151
  if (isConfiguredOutput(outputConfig) && typeof outputConfig.overwrite === 'boolean') {
@@ -1396,8 +1174,6 @@ async function writeConfig(answers, config) {
1396
1174
  }
1397
1175
  // Updates package.json (script and plugins as dependencies)
1398
1176
  async function writePackage(answers, configLocation) {
1399
- // dynamic import because latest-version is pure ESM
1400
- const getLatestVersion = (await import('latest-version')).default;
1401
1177
  // script
1402
1178
  const pkgPath = resolve(process.cwd(), 'package.json');
1403
1179
  const pkgContent = readFileSync(pkgPath, {
@@ -1830,6 +1606,27 @@ function addIntrospection(config) {
1830
1606
  };
1831
1607
  }
1832
1608
 
1609
+ function isListrError(err) {
1610
+ return err.name === 'ListrError' && Array.isArray(err.errors) && err.errors.length > 0;
1611
+ }
1612
+ function cliError(err, exitOnError = true) {
1613
+ let msg;
1614
+ if (err instanceof Error) {
1615
+ msg = err.message || err.toString();
1616
+ }
1617
+ else if (typeof err === 'string') {
1618
+ msg = err;
1619
+ }
1620
+ else {
1621
+ msg = JSON.stringify(err);
1622
+ }
1623
+ // eslint-disable-next-line no-console
1624
+ console.error(msg);
1625
+ if (exitOnError) {
1626
+ process.exit(1);
1627
+ }
1628
+ }
1629
+
1833
1630
  async function runCli(cmd) {
1834
1631
  await ensureGraphQlPackage();
1835
1632
  switch (cmd) {