@graphql-codegen/cli 2.6.4-alpha-b6ec5b6d1.0 → 2.6.5-alpha-d6416b45e.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,204 +22,17 @@ 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
34
  import getLatestVersion from 'latest-version';
39
35
 
40
- /**
41
- Indent each line in a string.
42
- @param string - The string to indent.
43
- @param count - How many times you want `options.indent` repeated. Default: `1`.
44
- @example
45
- ```
46
- import indentString from 'indent-string';
47
- indentString('Unicorns\nRainbows', 4);
48
- //=> ' Unicorns\n Rainbows'
49
- indentString('Unicorns\nRainbows', 4, {indent: '♥'});
50
- //=> '♥♥♥♥Unicorns\n♥♥♥♥Rainbows'
51
- ```
52
- */
53
- function indentString(string, count = 1, options = {}) {
54
- const { indent = ' ', includeEmptyLines = false } = options;
55
- if (typeof string !== 'string') {
56
- throw new TypeError(`Expected \`input\` to be a \`string\`, got \`${typeof string}\``);
57
- }
58
- if (typeof count !== 'number') {
59
- throw new TypeError(`Expected \`count\` to be a \`number\`, got \`${typeof count}\``);
60
- }
61
- if (count < 0) {
62
- throw new RangeError(`Expected \`count\` to be at least 0, got \`${count}\``);
63
- }
64
- if (typeof indent !== 'string') {
65
- throw new TypeError(`Expected \`options.indent\` to be a \`string\`, got \`${typeof indent}\``);
66
- }
67
- if (count === 0) {
68
- return string;
69
- }
70
- const regex = includeEmptyLines ? /^/gm : /^(?!\s*$)/gm;
71
- return string.replace(regex, indent.repeat(count));
72
- }
73
-
74
- let logger;
75
- function getLogger() {
76
- return logger || dummyLogger;
77
- }
78
- useWinstonLogger();
79
- function useWinstonLogger() {
80
- if (logger && logger.levels) {
81
- return;
82
- }
83
- logger = console;
84
- }
85
-
86
- let queue = [];
87
- function debugLog(message, ...meta) {
88
- if (!process.env.GQL_CODEGEN_NODEBUG && process.env.DEBUG !== undefined) {
89
- queue.push({
90
- message,
91
- meta,
92
- });
93
- }
94
- }
95
- function printLogs() {
96
- if (!process.env.GQL_CODEGEN_NODEBUG && process.env.DEBUG !== undefined) {
97
- queue.forEach(log => {
98
- getLogger().info(log.message, ...log.meta);
99
- });
100
- resetLogs();
101
- }
102
- }
103
- function resetLogs() {
104
- queue = [];
105
- }
106
-
107
- class Renderer {
108
- constructor(tasks, options) {
109
- this.updateRenderer = new UpdateRenderer(tasks, options);
110
- }
111
- render() {
112
- return this.updateRenderer.render();
113
- }
114
- end(err) {
115
- this.updateRenderer.end(err);
116
- if (typeof err === 'undefined') {
117
- logUpdate.clear();
118
- return;
119
- }
120
- // persist the output
121
- logUpdate.done();
122
- // show errors
123
- if (err) {
124
- const errorCount = err.errors ? err.errors.length : 0;
125
- if (errorCount > 0) {
126
- const count = indentString(chalk.red.bold(`Found ${errorCount} error${errorCount > 1 ? 's' : ''}`), 1);
127
- const details = err.errors
128
- .map(error => {
129
- debugLog(`[CLI] Exited with an error`, error);
130
- return { msg: isDetailedError(error) ? error.details : null, rawError: error };
131
- })
132
- .map(({ msg, rawError }, i) => {
133
- const source = err.errors[i].source;
134
- msg = msg ? chalk.gray(indentString(stripIndent(`${msg}`), 4)) : null;
135
- const stack = rawError.stack ? chalk.gray(indentString(stripIndent(rawError.stack), 4)) : null;
136
- if (source) {
137
- const sourceOfError = typeof source === 'string' ? source : source.name;
138
- const title = indentString(`${logSymbols.error} ${sourceOfError}`, 2);
139
- return [title, msg, stack, stack].filter(Boolean).join('\n');
140
- }
141
- return [msg, stack].filter(Boolean).join('\n');
142
- })
143
- .join('\n\n');
144
- logUpdate.emit(['', count, details, ''].join('\n\n'));
145
- }
146
- else {
147
- const details = err.details ? err.details : '';
148
- logUpdate.emit(`${chalk.red.bold(`${indentString(err.message, 2)}`)}\n${details}\n${chalk.grey(err.stack)}`);
149
- }
150
- }
151
- logUpdate.done();
152
- printLogs();
153
- }
154
- }
155
- const render = tasks => {
156
- for (const task of tasks) {
157
- task.subscribe(event => {
158
- if (event.type === 'SUBTASKS') {
159
- render(task.subtasks);
160
- return;
161
- }
162
- if (event.type === 'DATA') {
163
- logUpdate.emit(chalk.dim(`${event.data}`));
164
- }
165
- logUpdate.done();
166
- }, err => {
167
- logUpdate.emit(err);
168
- logUpdate.done();
169
- });
170
- }
171
- };
172
- class ErrorRenderer {
173
- constructor(tasks, _options) {
174
- this.tasks = tasks;
175
- }
176
- render() {
177
- render(this.tasks);
178
- }
179
- static get nonTTY() {
180
- return true;
181
- }
182
- end() { }
183
- }
184
- class LogUpdate {
185
- constructor() {
186
- this.stream = process.stdout;
187
- // state
188
- this.previousLineCount = 0;
189
- this.previousOutput = '';
190
- this.previousWidth = this.getWidth();
191
- }
192
- emit(...args) {
193
- let output = args.join(' ') + '\n';
194
- const width = this.getWidth();
195
- if (output === this.previousOutput && this.previousWidth === width) {
196
- return;
197
- }
198
- this.previousOutput = output;
199
- this.previousWidth = width;
200
- output = wrapAnsi(output, width, {
201
- trim: false,
202
- hard: true,
203
- wordWrap: false,
204
- });
205
- this.stream.write(ansiEscapes.eraseLines(this.previousLineCount) + output);
206
- this.previousLineCount = output.split('\n').length;
207
- }
208
- clear() {
209
- this.stream.write(ansiEscapes.eraseLines(this.previousLineCount));
210
- this.previousOutput = '';
211
- this.previousWidth = this.getWidth();
212
- this.previousLineCount = 0;
213
- }
214
- done() {
215
- this.previousOutput = '';
216
- this.previousWidth = this.getWidth();
217
- this.previousLineCount = 0;
218
- }
219
- getWidth() {
220
- const { columns } = this.stream;
221
- if (!columns) {
222
- return 80;
223
- }
224
- return columns;
225
- }
226
- }
227
- const logUpdate = new LogUpdate();
228
-
229
36
  async function getPluginByName(name, pluginLoader) {
230
37
  const possibleNames = [
231
38
  `@graphql-codegen/${name}`,
@@ -307,6 +114,22 @@ async function getPresetByName(name, loader) {
307
114
  `);
308
115
  }
309
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
+
310
133
  const CodegenExtension = (api) => {
311
134
  // Schema
312
135
  api.loaders.schema.register(new CodeFileLoader({
@@ -723,33 +546,6 @@ function addHashToDocumentFiles(documentFilesPromise) {
723
546
  }));
724
547
  }
725
548
 
726
- const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
727
- const isNode = typeof process !== 'undefined' && process.versions != null && process.versions.node != null;
728
-
729
- function isListrError(err) {
730
- return err.name === 'ListrError' && Array.isArray(err.errors) && err.errors.length > 0;
731
- }
732
- function cliError(err, exitOnError = true) {
733
- let msg;
734
- if (err instanceof Error) {
735
- msg = err.message || err.toString();
736
- }
737
- else if (typeof err === 'string') {
738
- msg = err;
739
- }
740
- else {
741
- msg = JSON.stringify(err);
742
- }
743
- // eslint-disable-next-line no-console
744
- console.error(msg);
745
- if (exitOnError && isNode) {
746
- process.exit(1);
747
- }
748
- else if (exitOnError && isBrowser) {
749
- throw err;
750
- }
751
- }
752
-
753
549
  const makeDefaultLoader = (from) => {
754
550
  if (fs.statSync(from).isDirectory()) {
755
551
  from = path.join(from, '__fake.js');
@@ -777,39 +573,12 @@ async function executeCodegen(input) {
777
573
  const config = context.getConfig();
778
574
  const pluginContext = context.getPluginContext();
779
575
  const result = [];
780
- const commonListrOptions = {
781
- exitOnError: true,
782
- };
783
- let listr;
784
- if (process.env.VERBOSE) {
785
- listr = new Listr({
786
- ...commonListrOptions,
787
- renderer: 'verbose',
788
- nonTTYRenderer: 'verbose',
789
- });
790
- }
791
- else if (process.env.NODE_ENV === 'test') {
792
- listr = new Listr({
793
- ...commonListrOptions,
794
- renderer: 'silent',
795
- nonTTYRenderer: 'silent',
796
- });
797
- }
798
- else {
799
- listr = new Listr({
800
- ...commonListrOptions,
801
- renderer: config.silent ? 'silent' : config.errorsOnly ? ErrorRenderer : Renderer,
802
- nonTTYRenderer: config.silent ? 'silent' : 'default',
803
- collapse: true,
804
- clearOutput: false,
805
- });
806
- }
807
576
  let rootConfig = {};
808
577
  let rootSchemas;
809
578
  let rootDocuments;
810
579
  const generates = {};
811
580
  const cache = createCache();
812
- function wrapTask(task, source, taskName) {
581
+ function wrapTask(task, source, taskName, ctx) {
813
582
  return () => {
814
583
  return context.profiler.run(async () => {
815
584
  try {
@@ -819,6 +588,7 @@ async function executeCodegen(input) {
819
588
  if (source && !(error instanceof GraphQLError)) {
820
589
  error.source = source;
821
590
  }
591
+ ctx.errors.push(error);
822
592
  throw error;
823
593
  }
824
594
  }, taskName);
@@ -889,119 +659,109 @@ async function executeCodegen(input) {
889
659
  `);
890
660
  }
891
661
  }
892
- listr.add({
893
- title: 'Parse configuration',
894
- task: () => normalize(),
895
- });
896
- listr.add({
897
- title: 'Generate outputs',
898
- task: () => {
899
- return new Listr(Object.keys(generates).map(filename => {
900
- const outputConfig = generates[filename];
901
- const hasPreset = !!outputConfig.preset;
902
- return {
903
- 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
904
675
  ? `Generate to ${filename} (using EXPERIMENTAL preset "${outputConfig.preset}")`
905
- : `Generate ${filename}`,
906
- task: () => {
907
- let outputSchemaAst;
908
- let outputSchema;
909
- const outputFileTemplateConfig = outputConfig.config || {};
910
- const outputDocuments = [];
911
- const outputSpecificSchemas = normalizeInstanceOrArray(outputConfig.schema);
912
- const outputSpecificDocuments = normalizeInstanceOrArray(outputConfig.documents);
913
- return new Listr([
914
- {
915
- title: 'Load GraphQL schemas',
916
- task: wrapTask(async () => {
917
- debugLog(`[CLI] Loading Schemas`);
918
- const schemaPointerMap = {};
919
- const allSchemaUnnormalizedPointers = [...rootSchemas, ...outputSpecificSchemas];
920
- for (const unnormalizedPtr of allSchemaUnnormalizedPointers) {
921
- if (typeof unnormalizedPtr === 'string') {
922
- 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
+ }
923
700
  }
924
- else if (typeof unnormalizedPtr === 'object') {
925
- 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
+ }
926
727
  }
927
- }
928
- const hash = JSON.stringify(schemaPointerMap);
929
- const result = await cache('schema', hash, async () => {
930
- const outputSchemaAst = await context.loadSchema(schemaPointerMap);
931
- const outputSchema = getCachedDocumentNodeFromSchema(outputSchemaAst);
932
- return {
933
- outputSchemaAst,
934
- outputSchema,
935
- };
936
- });
937
- outputSchemaAst = await result.outputSchemaAst;
938
- outputSchema = result.outputSchema;
939
- }, filename, `Load GraphQL schemas: ${filename}`),
940
- },
941
- {
942
- title: 'Load GraphQL documents',
943
- task: wrapTask(async () => {
944
- debugLog(`[CLI] Loading Documents`);
945
- // get different cache for shared docs and output specific docs
946
- const results = await Promise.all([rootDocuments, outputSpecificDocuments].map(docs => {
947
- const hash = JSON.stringify(docs);
948
- return cache('documents', hash, async () => {
949
- 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);
950
731
  return {
951
732
  documents,
952
733
  };
953
734
  });
954
- }));
955
- const documents = [];
956
- results.forEach(source => documents.push(...source.documents));
957
- if (documents.length > 0) {
958
- outputDocuments.push(...documents);
959
- }
960
- }, filename, `Load GraphQL documents: ${filename}`),
961
- },
962
- {
963
- title: 'Generate',
964
- task: wrapTask(async () => {
965
- debugLog(`[CLI] Generating output`);
966
- const normalizedPluginsArray = normalizeConfig(outputConfig.plugins);
967
- const pluginLoader = config.pluginLoader || makeDefaultLoader(context.cwd);
968
- const pluginPackages = await Promise.all(normalizedPluginsArray.map(plugin => getPluginByName(Object.keys(plugin)[0], pluginLoader)));
969
- const pluginMap = {};
970
- const preset = hasPreset
971
- ? typeof outputConfig.preset === 'string'
972
- ? await getPresetByName(outputConfig.preset, makeDefaultLoader(context.cwd))
973
- : outputConfig.preset
974
- : null;
975
- pluginPackages.forEach((pluginPackage, i) => {
976
- const plugin = normalizedPluginsArray[i];
977
- const name = Object.keys(plugin)[0];
978
- pluginMap[name] = pluginPackage;
979
- });
980
- const mergedConfig = {
981
- ...rootConfig,
982
- ...(typeof outputFileTemplateConfig === 'string'
983
- ? { value: outputFileTemplateConfig }
984
- : outputFileTemplateConfig),
985
- };
986
- let outputs = [];
987
- if (hasPreset) {
988
- outputs = await context.profiler.run(async () => preset.buildGeneratesSection({
989
- baseOutputDir: filename,
990
- presetConfig: outputConfig.presetConfig || {},
991
- plugins: normalizedPluginsArray,
992
- schema: outputSchema,
993
- schemaAst: outputSchemaAst,
994
- documents: outputDocuments,
995
- config: mergedConfig,
996
- pluginMap,
997
- pluginContext,
998
- profiler: context.profiler,
999
- }), `Build Generates Section: ${filename}`);
1000
- }
1001
- else {
1002
- outputs = [
1003
- {
1004
- 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 || {},
1005
765
  plugins: normalizedPluginsArray,
1006
766
  schema: outputSchema,
1007
767
  schemaAst: outputSchemaAst,
@@ -1010,50 +770,67 @@ async function executeCodegen(input) {
1010
770
  pluginMap,
1011
771
  pluginContext,
1012
772
  profiler: context.profiler,
1013
- },
1014
- ];
1015
- }
1016
- const process = async (outputArgs) => {
1017
- const output = await codegen({
1018
- ...outputArgs,
1019
- cache,
1020
- });
1021
- result.push({
1022
- filename: outputArgs.filename,
1023
- content: output,
1024
- hooks: outputConfig.hooks || {},
1025
- });
1026
- };
1027
- await context.profiler.run(() => Promise.all(outputs.map(process)), `Codegen: ${filename}`);
1028
- }, filename, `Generate: ${filename}`),
1029
- },
1030
- ], {
1031
- // it stops when one of tasks failed
1032
- exitOnError: true,
1033
- });
1034
- },
1035
- };
1036
- }), {
1037
- // it doesn't stop when one of tasks failed, to finish at least some of outputs
1038
- exitOnError: false,
1039
- concurrent: cpus().length,
1040
- });
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
+ },
1041
813
  },
814
+ ], {
815
+ rendererOptions: {
816
+ clearOutput: false,
817
+ collapse: true,
818
+ },
819
+ ctx: { errors: [] },
820
+ rendererSilent: isTest || config.silent,
821
+ exitOnError: true,
1042
822
  });
1043
- try {
1044
- await listr.run();
1045
- }
1046
- catch (err) {
1047
- if (isListrError(err)) {
1048
- const allErrs = err.errors.map(subErr => isDetailedError(subErr)
1049
- ? `${subErr.message} for "${subErr.source}"${subErr.details}`
1050
- : subErr.message || subErr.toString());
1051
- const newErr = new AggregateError(err.errors, `${err.message} ${allErrs.join('\n\n')}`);
1052
- // Best-effort to all stack traces for debugging
1053
- newErr.stack = `${newErr.stack}\n\n${err.errors.map(subErr => subErr.stack).join('\n\n')}`;
1054
- throw newErr;
1055
- }
1056
- 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;
1057
834
  }
1058
835
  return result;
1059
836
  }
@@ -1113,7 +890,7 @@ function execShellCommand(cmd) {
1113
890
  });
1114
891
  }
1115
892
  async function executeHooks(hookName, scripts = [], args = []) {
1116
- debugLog(`Running lifecycle hook "${hookName}" scripts...`);
893
+ debugLog();
1117
894
  for (const script of scripts) {
1118
895
  if (typeof script === 'string') {
1119
896
  debugLog(`Running lifecycle hook "${hookName}" script: ${script} with args: ${args.join(' ')}...`);
@@ -1147,7 +924,7 @@ function emitWatching() {
1147
924
  log(`${logSymbols.info} Watching for changes...`);
1148
925
  }
1149
926
  const createWatcher = (initalContext, onNext) => {
1150
- debugLog(`[Watcher] Starting watcher...`);
927
+ debugLog();
1151
928
  let config = initalContext.getConfig();
1152
929
  const files = [initalContext.filepath].filter(a => a);
1153
930
  const documents = normalizeInstanceOrArray(config.documents);
@@ -1218,10 +995,10 @@ const createWatcher = (initalContext, onNext) => {
1218
995
  atomic: true,
1219
996
  ignored,
1220
997
  });
1221
- debugLog(`[Watcher] Started`);
998
+ debugLog();
1222
999
  const shutdown = () => {
1223
1000
  isShutdown = true;
1224
- debugLog(`[Watcher] Shutting down`);
1001
+ debugLog();
1225
1002
  log(`Shutting down watch...`);
1226
1003
  watcher.close();
1227
1004
  lifecycleHooks(config.hooks).beforeDone();
@@ -1229,7 +1006,7 @@ const createWatcher = (initalContext, onNext) => {
1229
1006
  // it doesn't matter what has changed, need to run whole process anyway
1230
1007
  watcher.on('all', async (eventName, path) => {
1231
1008
  lifecycleHooks(config.hooks).onWatchTriggered(eventName, path);
1232
- debugLog(`[Watcher] triggered due to a file ${eventName} event: ${path}`);
1009
+ debugLog();
1233
1010
  const fullPath = join(process.cwd(), path);
1234
1011
  // In ESM require is not defined
1235
1012
  try {
@@ -1298,10 +1075,10 @@ async function generate(input, saveToFile = true) {
1298
1075
  return unlinkFile(filename, err => {
1299
1076
  const prettyFilename = filename.replace(`${input.cwd || process.cwd()}/`, '');
1300
1077
  if (err) {
1301
- debugLog(`Cannot remove stale file: ${prettyFilename}\n${err}`);
1078
+ debugLog();
1302
1079
  }
1303
1080
  else {
1304
- debugLog(`Removed stale file: ${prettyFilename}`);
1081
+ debugLog();
1305
1082
  }
1306
1083
  });
1307
1084
  }
@@ -1368,7 +1145,7 @@ function shouldOverwrite(config, outputPath) {
1368
1145
  const globalValue = config.overwrite === undefined ? true : !!config.overwrite;
1369
1146
  const outputConfig = config.generates[outputPath];
1370
1147
  if (!outputConfig) {
1371
- debugLog(`Couldn't find a config of ${outputPath}`);
1148
+ debugLog();
1372
1149
  return globalValue;
1373
1150
  }
1374
1151
  if (isConfiguredOutput(outputConfig) && typeof outputConfig.overwrite === 'boolean') {
@@ -1829,6 +1606,27 @@ function addIntrospection(config) {
1829
1606
  };
1830
1607
  }
1831
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
+
1832
1630
  async function runCli(cmd) {
1833
1631
  await ensureGraphQlPackage();
1834
1632
  switch (cmd) {