@graphql-codegen/cli 2.6.5-alpha-acacb9e7a.0 → 2.6.5-alpha-2f4ab8fa6.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,9 +1,15 @@
1
- import { DetailedError, createNoopProfiler, createProfiler, getCachedDocumentNodeFromSchema, normalizeInstanceOrArray, normalizeConfig, isDetailedError, normalizeOutputParam } from '@graphql-codegen/plugin-helpers';
1
+ import { isDetailedError, DetailedError, createNoopProfiler, createProfiler, getCachedDocumentNodeFromSchema, normalizeInstanceOrArray, normalizeConfig, 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';
4
11
  import { print, GraphQLError } from 'graphql';
5
12
  import path, { resolve, extname, join, delimiter, sep, dirname, isAbsolute, relative } from 'path';
6
- import { dummyLogger } from 'ts-log';
7
13
  import { cosmiconfig, defaultLoaders } from 'cosmiconfig';
8
14
  import { env } from 'string-env-interpolation';
9
15
  import yargs from 'yargs';
@@ -22,17 +28,204 @@ import { createRequire } from 'module';
22
28
  import fs, { promises, unlink, writeFileSync, readFileSync } from 'fs';
23
29
  import { createHash } from 'crypto';
24
30
  import { cpus } from 'os';
25
- import { Listr } from 'listr2';
31
+ import Listr from 'listr';
26
32
  import { exec } from 'child_process';
27
33
  import isGlob from 'is-glob';
28
34
  import debounce from 'debounce';
29
- import logSymbols from 'log-symbols';
30
35
  import mkdirp from 'mkdirp';
31
36
  import inquirer from 'inquirer';
32
- import chalk from 'chalk';
33
37
  import detectIndent from 'detect-indent';
34
38
  import getLatestVersion from 'latest-version';
35
39
 
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
+
36
229
  async function getPluginByName(name, pluginLoader) {
37
230
  const possibleNames = [
38
231
  `@graphql-codegen/${name}`,
@@ -114,22 +307,6 @@ async function getPresetByName(name, loader) {
114
307
  `);
115
308
  }
116
309
 
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
-
133
310
  const CodegenExtension = (api) => {
134
311
  // Schema
135
312
  api.loaders.schema.register(new CodeFileLoader({
@@ -546,6 +723,27 @@ function addHashToDocumentFiles(documentFilesPromise) {
546
723
  }));
547
724
  }
548
725
 
726
+ function isListrError(err) {
727
+ return err.name === 'ListrError' && Array.isArray(err.errors) && err.errors.length > 0;
728
+ }
729
+ function cliError(err, exitOnError = true) {
730
+ let msg;
731
+ if (err instanceof Error) {
732
+ msg = err.message || err.toString();
733
+ }
734
+ else if (typeof err === 'string') {
735
+ msg = err;
736
+ }
737
+ else {
738
+ msg = JSON.stringify(err);
739
+ }
740
+ // eslint-disable-next-line no-console
741
+ console.error(msg);
742
+ if (exitOnError) {
743
+ process.exit(1);
744
+ }
745
+ }
746
+
549
747
  const makeDefaultLoader = (from) => {
550
748
  if (fs.statSync(from).isDirectory()) {
551
749
  from = path.join(from, '__fake.js');
@@ -573,12 +771,39 @@ async function executeCodegen(input) {
573
771
  const config = context.getConfig();
574
772
  const pluginContext = context.getPluginContext();
575
773
  const result = [];
774
+ const commonListrOptions = {
775
+ exitOnError: true,
776
+ };
777
+ let listr;
778
+ if (process.env.VERBOSE) {
779
+ listr = new Listr({
780
+ ...commonListrOptions,
781
+ renderer: 'verbose',
782
+ nonTTYRenderer: 'verbose',
783
+ });
784
+ }
785
+ else if (process.env.NODE_ENV === 'test') {
786
+ listr = new Listr({
787
+ ...commonListrOptions,
788
+ renderer: 'silent',
789
+ nonTTYRenderer: 'silent',
790
+ });
791
+ }
792
+ else {
793
+ listr = new Listr({
794
+ ...commonListrOptions,
795
+ renderer: config.silent ? 'silent' : config.errorsOnly ? ErrorRenderer : Renderer,
796
+ nonTTYRenderer: config.silent ? 'silent' : 'default',
797
+ collapse: true,
798
+ clearOutput: false,
799
+ });
800
+ }
576
801
  let rootConfig = {};
577
802
  let rootSchemas;
578
803
  let rootDocuments;
579
804
  const generates = {};
580
805
  const cache = createCache();
581
- function wrapTask(task, source, taskName, ctx) {
806
+ function wrapTask(task, source, taskName) {
582
807
  return () => {
583
808
  return context.profiler.run(async () => {
584
809
  try {
@@ -588,7 +813,6 @@ async function executeCodegen(input) {
588
813
  if (source && !(error instanceof GraphQLError)) {
589
814
  error.source = source;
590
815
  }
591
- ctx.errors.push(error);
592
816
  throw error;
593
817
  }
594
818
  }, taskName);
@@ -659,109 +883,123 @@ async function executeCodegen(input) {
659
883
  `);
660
884
  }
661
885
  }
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
886
+ listr.add({
887
+ title: 'Parse configuration',
888
+ task: () => normalize(),
889
+ });
890
+ listr.add({
891
+ title: 'Generate outputs',
892
+ task: () => {
893
+ return new Listr(Object.keys(generates).map(filename => {
894
+ const outputConfig = generates[filename];
895
+ const hasPreset = !!outputConfig.preset;
896
+ return {
897
+ title: hasPreset
675
898
  ? `Generate to ${filename} (using EXPERIMENTAL preset "${outputConfig.preset}")`
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
- }
899
+ : `Generate ${filename}`,
900
+ task: () => {
901
+ let outputSchemaAst;
902
+ let outputSchema;
903
+ const outputFileTemplateConfig = outputConfig.config || {};
904
+ let outputDocuments = [];
905
+ const outputSpecificSchemas = normalizeInstanceOrArray(outputConfig.schema);
906
+ const outputSpecificDocuments = normalizeInstanceOrArray(outputConfig.documents);
907
+ return new Listr([
908
+ {
909
+ title: 'Load GraphQL schemas',
910
+ task: wrapTask(async () => {
911
+ debugLog(`[CLI] Loading Schemas`);
912
+ const schemaPointerMap = {};
913
+ const allSchemaUnnormalizedPointers = [...rootSchemas, ...outputSpecificSchemas];
914
+ for (const unnormalizedPtr of allSchemaUnnormalizedPointers) {
915
+ if (typeof unnormalizedPtr === 'string') {
916
+ schemaPointerMap[unnormalizedPtr] = {};
700
917
  }
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
- }
918
+ else if (typeof unnormalizedPtr === 'object') {
919
+ Object.assign(schemaPointerMap, unnormalizedPtr);
727
920
  }
728
- const hash = JSON.stringify(documentPointerMap);
729
- const result = await cache('documents', hash, async () => {
730
- const documents = await context.loadDocuments(documentPointerMap);
731
- return {
732
- documents,
733
- };
734
- });
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),
921
+ }
922
+ const hash = JSON.stringify(schemaPointerMap);
923
+ const result = await cache('schema', hash, async () => {
924
+ const outputSchemaAst = await context.loadSchema(schemaPointerMap);
925
+ const outputSchema = getCachedDocumentNodeFromSchema(outputSchemaAst);
926
+ return {
927
+ outputSchemaAst,
928
+ outputSchema,
929
+ };
930
+ });
931
+ outputSchemaAst = await result.outputSchemaAst;
932
+ outputSchema = result.outputSchema;
933
+ }, filename, `Load GraphQL schemas: ${filename}`),
934
+ },
935
+ {
936
+ title: 'Load GraphQL documents',
937
+ task: wrapTask(async () => {
938
+ debugLog(`[CLI] Loading Documents`);
939
+ // get different cache for shared docs and output specific docs
940
+ const documentPointerMap = {};
941
+ const allDocumentsUnnormalizedPointers = [...rootDocuments, ...outputSpecificDocuments];
942
+ for (const unnormalizedPtr of allDocumentsUnnormalizedPointers) {
943
+ if (typeof unnormalizedPtr === 'string') {
944
+ documentPointerMap[unnormalizedPtr] = {};
945
+ }
946
+ else if (typeof unnormalizedPtr === 'object') {
947
+ Object.assign(documentPointerMap, unnormalizedPtr);
948
+ }
949
+ }
950
+ const hash = JSON.stringify(documentPointerMap);
951
+ const result = await cache('documents', hash, async () => {
952
+ const documents = await context.loadDocuments(documentPointerMap);
953
+ return {
954
+ documents,
760
955
  };
761
- const outputs = hasPreset
762
- ? await context.profiler.run(async () => preset.buildGeneratesSection({
763
- baseOutputDir: filename,
764
- presetConfig: outputConfig.presetConfig || {},
956
+ });
957
+ outputDocuments = await result.documents;
958
+ }, filename, `Load GraphQL documents: ${filename}`),
959
+ },
960
+ {
961
+ title: 'Generate',
962
+ task: wrapTask(async () => {
963
+ debugLog(`[CLI] Generating output`);
964
+ const normalizedPluginsArray = normalizeConfig(outputConfig.plugins);
965
+ const pluginLoader = config.pluginLoader || makeDefaultLoader(context.cwd);
966
+ const pluginPackages = await Promise.all(normalizedPluginsArray.map(plugin => getPluginByName(Object.keys(plugin)[0], pluginLoader)));
967
+ const pluginMap = {};
968
+ const preset = hasPreset
969
+ ? typeof outputConfig.preset === 'string'
970
+ ? await getPresetByName(outputConfig.preset, makeDefaultLoader(context.cwd))
971
+ : outputConfig.preset
972
+ : null;
973
+ pluginPackages.forEach((pluginPackage, i) => {
974
+ const plugin = normalizedPluginsArray[i];
975
+ const name = Object.keys(plugin)[0];
976
+ pluginMap[name] = pluginPackage;
977
+ });
978
+ const mergedConfig = {
979
+ ...rootConfig,
980
+ ...(typeof outputFileTemplateConfig === 'string'
981
+ ? { value: outputFileTemplateConfig }
982
+ : outputFileTemplateConfig),
983
+ };
984
+ let outputs = [];
985
+ if (hasPreset) {
986
+ outputs = await context.profiler.run(async () => preset.buildGeneratesSection({
987
+ baseOutputDir: filename,
988
+ presetConfig: outputConfig.presetConfig || {},
989
+ plugins: normalizedPluginsArray,
990
+ schema: outputSchema,
991
+ schemaAst: outputSchemaAst,
992
+ documents: outputDocuments,
993
+ config: mergedConfig,
994
+ pluginMap,
995
+ pluginContext,
996
+ profiler: context.profiler,
997
+ }), `Build Generates Section: ${filename}`);
998
+ }
999
+ else {
1000
+ outputs = [
1001
+ {
1002
+ filename,
765
1003
  plugins: normalizedPluginsArray,
766
1004
  schema: outputSchema,
767
1005
  schemaAst: outputSchemaAst,
@@ -770,67 +1008,50 @@ async function executeCodegen(input) {
770
1008
  pluginMap,
771
1009
  pluginContext,
772
1010
  profiler: context.profiler,
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
- },
813
- },
814
- ], {
815
- rendererOptions: {
816
- clearOutput: false,
817
- collapse: true,
1011
+ },
1012
+ ];
1013
+ }
1014
+ const process = async (outputArgs) => {
1015
+ const output = await codegen({
1016
+ ...outputArgs,
1017
+ cache,
1018
+ });
1019
+ result.push({
1020
+ filename: outputArgs.filename,
1021
+ content: output,
1022
+ hooks: outputConfig.hooks || {},
1023
+ });
1024
+ };
1025
+ await context.profiler.run(() => Promise.all(outputs.map(process)), `Codegen: ${filename}`);
1026
+ }, filename, `Generate: ${filename}`),
1027
+ },
1028
+ ], {
1029
+ // it stops when one of tasks failed
1030
+ exitOnError: true,
1031
+ });
1032
+ },
1033
+ };
1034
+ }), {
1035
+ // it doesn't stop when one of tasks failed, to finish at least some of outputs
1036
+ exitOnError: false,
1037
+ concurrent: cpus().length,
1038
+ });
818
1039
  },
819
- ctx: { errors: [] },
820
- rendererSilent: isTest || config.silent,
821
- exitOnError: true,
822
1040
  });
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;
1041
+ try {
1042
+ await listr.run();
1043
+ }
1044
+ catch (err) {
1045
+ if (isListrError(err)) {
1046
+ const allErrs = err.errors.map(subErr => isDetailedError(subErr)
1047
+ ? `${subErr.message} for "${subErr.source}"${subErr.details}`
1048
+ : subErr.message || subErr.toString());
1049
+ const newErr = new AggregateError(err.errors, `${err.message} ${allErrs.join('\n\n')}`);
1050
+ // Best-effort to all stack traces for debugging
1051
+ newErr.stack = `${newErr.stack}\n\n${err.errors.map(subErr => subErr.stack).join('\n\n')}`;
1052
+ throw newErr;
1053
+ }
1054
+ throw err;
834
1055
  }
835
1056
  return result;
836
1057
  }
@@ -890,7 +1111,7 @@ function execShellCommand(cmd) {
890
1111
  });
891
1112
  }
892
1113
  async function executeHooks(hookName, scripts = [], args = []) {
893
- debugLog();
1114
+ debugLog(`Running lifecycle hook "${hookName}" scripts...`);
894
1115
  for (const script of scripts) {
895
1116
  if (typeof script === 'string') {
896
1117
  debugLog(`Running lifecycle hook "${hookName}" script: ${script} with args: ${args.join(' ')}...`);
@@ -924,7 +1145,7 @@ function emitWatching() {
924
1145
  log(`${logSymbols.info} Watching for changes...`);
925
1146
  }
926
1147
  const createWatcher = (initalContext, onNext) => {
927
- debugLog();
1148
+ debugLog(`[Watcher] Starting watcher...`);
928
1149
  let config = initalContext.getConfig();
929
1150
  const files = [initalContext.filepath].filter(a => a);
930
1151
  const documents = normalizeInstanceOrArray(config.documents);
@@ -995,10 +1216,10 @@ const createWatcher = (initalContext, onNext) => {
995
1216
  atomic: true,
996
1217
  ignored,
997
1218
  });
998
- debugLog();
1219
+ debugLog(`[Watcher] Started`);
999
1220
  const shutdown = () => {
1000
1221
  isShutdown = true;
1001
- debugLog();
1222
+ debugLog(`[Watcher] Shutting down`);
1002
1223
  log(`Shutting down watch...`);
1003
1224
  watcher.close();
1004
1225
  lifecycleHooks(config.hooks).beforeDone();
@@ -1006,7 +1227,7 @@ const createWatcher = (initalContext, onNext) => {
1006
1227
  // it doesn't matter what has changed, need to run whole process anyway
1007
1228
  watcher.on('all', async (eventName, path) => {
1008
1229
  lifecycleHooks(config.hooks).onWatchTriggered(eventName, path);
1009
- debugLog();
1230
+ debugLog(`[Watcher] triggered due to a file ${eventName} event: ${path}`);
1010
1231
  const fullPath = join(process.cwd(), path);
1011
1232
  // In ESM require is not defined
1012
1233
  try {
@@ -1075,10 +1296,10 @@ async function generate(input, saveToFile = true) {
1075
1296
  return unlinkFile(filename, err => {
1076
1297
  const prettyFilename = filename.replace(`${input.cwd || process.cwd()}/`, '');
1077
1298
  if (err) {
1078
- debugLog();
1299
+ debugLog(`Cannot remove stale file: ${prettyFilename}\n${err}`);
1079
1300
  }
1080
1301
  else {
1081
- debugLog();
1302
+ debugLog(`Removed stale file: ${prettyFilename}`);
1082
1303
  }
1083
1304
  });
1084
1305
  }
@@ -1145,7 +1366,7 @@ function shouldOverwrite(config, outputPath) {
1145
1366
  const globalValue = config.overwrite === undefined ? true : !!config.overwrite;
1146
1367
  const outputConfig = config.generates[outputPath];
1147
1368
  if (!outputConfig) {
1148
- debugLog();
1369
+ debugLog(`Couldn't find a config of ${outputPath}`);
1149
1370
  return globalValue;
1150
1371
  }
1151
1372
  if (isConfiguredOutput(outputConfig) && typeof outputConfig.overwrite === 'boolean') {
@@ -1606,40 +1827,18 @@ function addIntrospection(config) {
1606
1827
  };
1607
1828
  }
1608
1829
 
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
-
1630
1830
  async function runCli(cmd) {
1631
1831
  await ensureGraphQlPackage();
1632
- switch (cmd) {
1633
- case 'init':
1634
- return init();
1635
- default: {
1636
- return createContext().then(context => {
1637
- return generate(context).catch(async (error) => {
1638
- await lifecycleHooks(context.getConfig().hooks).onError(error.toString());
1639
- throw error;
1640
- });
1641
- });
1642
- }
1832
+ if (cmd === 'init') {
1833
+ return init();
1834
+ }
1835
+ const context = await createContext();
1836
+ try {
1837
+ return await generate(context);
1838
+ }
1839
+ catch (error) {
1840
+ await lifecycleHooks(context.getConfig().hooks).onError(error.toString());
1841
+ throw error;
1643
1842
  }
1644
1843
  }
1645
1844
  async function ensureGraphQlPackage() {