@graphql-codegen/cli 2.6.5-alpha-d6416b45e.0 → 2.6.5-alpha-11e1cf4aa.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.js CHANGED
@@ -26,10 +26,16 @@ function _interopNamespace(e) {
26
26
  const pluginHelpers = require('@graphql-codegen/plugin-helpers');
27
27
  const core = require('@graphql-codegen/core');
28
28
  const utils = require('@graphql-tools/utils');
29
+ const chalk = _interopDefault(require('chalk'));
30
+ const logSymbols = _interopDefault(require('log-symbols'));
31
+ const ansiEscapes = _interopDefault(require('ansi-escapes'));
32
+ const wrapAnsi = _interopDefault(require('wrap-ansi'));
33
+ const commonTags = require('common-tags');
34
+ const tsLog = require('ts-log');
35
+ const UpdateRenderer = _interopDefault(require('listr-update-renderer'));
29
36
  const graphql = require('graphql');
30
37
  const path = require('path');
31
38
  const path__default = _interopDefault(path);
32
- const tsLog = require('ts-log');
33
39
  const cosmiconfig = require('cosmiconfig');
34
40
  const stringEnvInterpolation = require('string-env-interpolation');
35
41
  const yargs = _interopDefault(require('yargs'));
@@ -49,17 +55,204 @@ const fs = require('fs');
49
55
  const fs__default = _interopDefault(fs);
50
56
  const crypto = require('crypto');
51
57
  const os = require('os');
52
- const listr2 = require('listr2');
58
+ const Listr = _interopDefault(require('listr'));
53
59
  const child_process = require('child_process');
54
60
  const isGlob = _interopDefault(require('is-glob'));
55
61
  const debounce = _interopDefault(require('debounce'));
56
- const logSymbols = _interopDefault(require('log-symbols'));
57
62
  const mkdirp = _interopDefault(require('mkdirp'));
58
63
  const inquirer = _interopDefault(require('inquirer'));
59
- const chalk = _interopDefault(require('chalk'));
60
64
  const detectIndent = _interopDefault(require('detect-indent'));
61
65
  const getLatestVersion = _interopDefault(require('latest-version'));
62
66
 
67
+ /**
68
+ Indent each line in a string.
69
+ @param string - The string to indent.
70
+ @param count - How many times you want `options.indent` repeated. Default: `1`.
71
+ @example
72
+ ```
73
+ import indentString from 'indent-string';
74
+ indentString('Unicorns\nRainbows', 4);
75
+ //=> ' Unicorns\n Rainbows'
76
+ indentString('Unicorns\nRainbows', 4, {indent: '♥'});
77
+ //=> '♥♥♥♥Unicorns\n♥♥♥♥Rainbows'
78
+ ```
79
+ */
80
+ function indentString(string, count = 1, options = {}) {
81
+ const { indent = ' ', includeEmptyLines = false } = options;
82
+ if (typeof string !== 'string') {
83
+ throw new TypeError(`Expected \`input\` to be a \`string\`, got \`${typeof string}\``);
84
+ }
85
+ if (typeof count !== 'number') {
86
+ throw new TypeError(`Expected \`count\` to be a \`number\`, got \`${typeof count}\``);
87
+ }
88
+ if (count < 0) {
89
+ throw new RangeError(`Expected \`count\` to be at least 0, got \`${count}\``);
90
+ }
91
+ if (typeof indent !== 'string') {
92
+ throw new TypeError(`Expected \`options.indent\` to be a \`string\`, got \`${typeof indent}\``);
93
+ }
94
+ if (count === 0) {
95
+ return string;
96
+ }
97
+ const regex = includeEmptyLines ? /^/gm : /^(?!\s*$)/gm;
98
+ return string.replace(regex, indent.repeat(count));
99
+ }
100
+
101
+ let logger;
102
+ function getLogger() {
103
+ return logger || tsLog.dummyLogger;
104
+ }
105
+ useWinstonLogger();
106
+ function useWinstonLogger() {
107
+ if (logger && logger.levels) {
108
+ return;
109
+ }
110
+ logger = console;
111
+ }
112
+
113
+ let queue = [];
114
+ function debugLog(message, ...meta) {
115
+ if (!process.env.GQL_CODEGEN_NODEBUG && process.env.DEBUG !== undefined) {
116
+ queue.push({
117
+ message,
118
+ meta,
119
+ });
120
+ }
121
+ }
122
+ function printLogs() {
123
+ if (!process.env.GQL_CODEGEN_NODEBUG && process.env.DEBUG !== undefined) {
124
+ queue.forEach(log => {
125
+ getLogger().info(log.message, ...log.meta);
126
+ });
127
+ resetLogs();
128
+ }
129
+ }
130
+ function resetLogs() {
131
+ queue = [];
132
+ }
133
+
134
+ class Renderer {
135
+ constructor(tasks, options) {
136
+ this.updateRenderer = new UpdateRenderer(tasks, options);
137
+ }
138
+ render() {
139
+ return this.updateRenderer.render();
140
+ }
141
+ end(err) {
142
+ this.updateRenderer.end(err);
143
+ if (typeof err === 'undefined') {
144
+ logUpdate.clear();
145
+ return;
146
+ }
147
+ // persist the output
148
+ logUpdate.done();
149
+ // show errors
150
+ if (err) {
151
+ const errorCount = err.errors ? err.errors.length : 0;
152
+ if (errorCount > 0) {
153
+ const count = indentString(chalk.red.bold(`Found ${errorCount} error${errorCount > 1 ? 's' : ''}`), 1);
154
+ const details = err.errors
155
+ .map(error => {
156
+ debugLog(`[CLI] Exited with an error`, error);
157
+ return { msg: pluginHelpers.isDetailedError(error) ? error.details : null, rawError: error };
158
+ })
159
+ .map(({ msg, rawError }, i) => {
160
+ const source = err.errors[i].source;
161
+ msg = msg ? chalk.gray(indentString(commonTags.stripIndent(`${msg}`), 4)) : null;
162
+ const stack = rawError.stack ? chalk.gray(indentString(commonTags.stripIndent(rawError.stack), 4)) : null;
163
+ if (source) {
164
+ const sourceOfError = typeof source === 'string' ? source : source.name;
165
+ const title = indentString(`${logSymbols.error} ${sourceOfError}`, 2);
166
+ return [title, msg, stack, stack].filter(Boolean).join('\n');
167
+ }
168
+ return [msg, stack].filter(Boolean).join('\n');
169
+ })
170
+ .join('\n\n');
171
+ logUpdate.emit(['', count, details, ''].join('\n\n'));
172
+ }
173
+ else {
174
+ const details = err.details ? err.details : '';
175
+ logUpdate.emit(`${chalk.red.bold(`${indentString(err.message, 2)}`)}\n${details}\n${chalk.grey(err.stack)}`);
176
+ }
177
+ }
178
+ logUpdate.done();
179
+ printLogs();
180
+ }
181
+ }
182
+ const render = tasks => {
183
+ for (const task of tasks) {
184
+ task.subscribe(event => {
185
+ if (event.type === 'SUBTASKS') {
186
+ render(task.subtasks);
187
+ return;
188
+ }
189
+ if (event.type === 'DATA') {
190
+ logUpdate.emit(chalk.dim(`${event.data}`));
191
+ }
192
+ logUpdate.done();
193
+ }, err => {
194
+ logUpdate.emit(err);
195
+ logUpdate.done();
196
+ });
197
+ }
198
+ };
199
+ class ErrorRenderer {
200
+ constructor(tasks, _options) {
201
+ this.tasks = tasks;
202
+ }
203
+ render() {
204
+ render(this.tasks);
205
+ }
206
+ static get nonTTY() {
207
+ return true;
208
+ }
209
+ end() { }
210
+ }
211
+ class LogUpdate {
212
+ constructor() {
213
+ this.stream = process.stdout;
214
+ // state
215
+ this.previousLineCount = 0;
216
+ this.previousOutput = '';
217
+ this.previousWidth = this.getWidth();
218
+ }
219
+ emit(...args) {
220
+ let output = args.join(' ') + '\n';
221
+ const width = this.getWidth();
222
+ if (output === this.previousOutput && this.previousWidth === width) {
223
+ return;
224
+ }
225
+ this.previousOutput = output;
226
+ this.previousWidth = width;
227
+ output = wrapAnsi(output, width, {
228
+ trim: false,
229
+ hard: true,
230
+ wordWrap: false,
231
+ });
232
+ this.stream.write(ansiEscapes.eraseLines(this.previousLineCount) + output);
233
+ this.previousLineCount = output.split('\n').length;
234
+ }
235
+ clear() {
236
+ this.stream.write(ansiEscapes.eraseLines(this.previousLineCount));
237
+ this.previousOutput = '';
238
+ this.previousWidth = this.getWidth();
239
+ this.previousLineCount = 0;
240
+ }
241
+ done() {
242
+ this.previousOutput = '';
243
+ this.previousWidth = this.getWidth();
244
+ this.previousLineCount = 0;
245
+ }
246
+ getWidth() {
247
+ const { columns } = this.stream;
248
+ if (!columns) {
249
+ return 80;
250
+ }
251
+ return columns;
252
+ }
253
+ }
254
+ const logUpdate = new LogUpdate();
255
+
63
256
  async function getPluginByName(name, pluginLoader) {
64
257
  const possibleNames = [
65
258
  `@graphql-codegen/${name}`,
@@ -141,22 +334,6 @@ async function getPresetByName(name, loader) {
141
334
  `);
142
335
  }
143
336
 
144
- let logger;
145
- function getLogger() {
146
- return logger || tsLog.dummyLogger;
147
- }
148
- useWinstonLogger();
149
- function useWinstonLogger() {
150
- if (logger && logger.levels) {
151
- return;
152
- }
153
- logger = console;
154
- }
155
-
156
- function debugLog(message, ...meta) {
157
- if (!process.env.GQL_CODEGEN_NODEBUG && process.env.DEBUG !== undefined) ;
158
- }
159
-
160
337
  const CodegenExtension = (api) => {
161
338
  // Schema
162
339
  api.loaders.schema.register(new codeFileLoader.CodeFileLoader({
@@ -573,6 +750,27 @@ function addHashToDocumentFiles(documentFilesPromise) {
573
750
  }));
574
751
  }
575
752
 
753
+ function isListrError(err) {
754
+ return err.name === 'ListrError' && Array.isArray(err.errors) && err.errors.length > 0;
755
+ }
756
+ function cliError(err, exitOnError = true) {
757
+ let msg;
758
+ if (err instanceof Error) {
759
+ msg = err.message || err.toString();
760
+ }
761
+ else if (typeof err === 'string') {
762
+ msg = err;
763
+ }
764
+ else {
765
+ msg = JSON.stringify(err);
766
+ }
767
+ // eslint-disable-next-line no-console
768
+ console.error(msg);
769
+ if (exitOnError) {
770
+ process.exit(1);
771
+ }
772
+ }
773
+
576
774
  const makeDefaultLoader = (from) => {
577
775
  if (fs__default.statSync(from).isDirectory()) {
578
776
  from = path__default.join(from, '__fake.js');
@@ -600,12 +798,39 @@ async function executeCodegen(input) {
600
798
  const config = context.getConfig();
601
799
  const pluginContext = context.getPluginContext();
602
800
  const result = [];
801
+ const commonListrOptions = {
802
+ exitOnError: true,
803
+ };
804
+ let listr;
805
+ if (process.env.VERBOSE) {
806
+ listr = new Listr({
807
+ ...commonListrOptions,
808
+ renderer: 'verbose',
809
+ nonTTYRenderer: 'verbose',
810
+ });
811
+ }
812
+ else if (process.env.NODE_ENV === 'test') {
813
+ listr = new Listr({
814
+ ...commonListrOptions,
815
+ renderer: 'silent',
816
+ nonTTYRenderer: 'silent',
817
+ });
818
+ }
819
+ else {
820
+ listr = new Listr({
821
+ ...commonListrOptions,
822
+ renderer: config.silent ? 'silent' : config.errorsOnly ? ErrorRenderer : Renderer,
823
+ nonTTYRenderer: config.silent ? 'silent' : 'default',
824
+ collapse: true,
825
+ clearOutput: false,
826
+ });
827
+ }
603
828
  let rootConfig = {};
604
829
  let rootSchemas;
605
830
  let rootDocuments;
606
831
  const generates = {};
607
832
  const cache = createCache();
608
- function wrapTask(task, source, taskName, ctx) {
833
+ function wrapTask(task, source, taskName) {
609
834
  return () => {
610
835
  return context.profiler.run(async () => {
611
836
  try {
@@ -615,7 +840,6 @@ async function executeCodegen(input) {
615
840
  if (source && !(error instanceof graphql.GraphQLError)) {
616
841
  error.source = source;
617
842
  }
618
- ctx.errors.push(error);
619
843
  throw error;
620
844
  }
621
845
  }, taskName);
@@ -686,109 +910,123 @@ async function executeCodegen(input) {
686
910
  `);
687
911
  }
688
912
  }
689
- const isTest = process.env.NODE_ENV === 'test';
690
- const tasks = new listr2.Listr([
691
- {
692
- title: 'Parse Configuration',
693
- task: () => normalize(),
694
- },
695
- {
696
- title: 'Generate outputs',
697
- task: (ctx, task) => {
698
- const generateTasks = Object.keys(generates).map(filename => {
699
- const outputConfig = generates[filename];
700
- const hasPreset = !!outputConfig.preset;
701
- const title = hasPreset
913
+ listr.add({
914
+ title: 'Parse configuration',
915
+ task: () => normalize(),
916
+ });
917
+ listr.add({
918
+ title: 'Generate outputs',
919
+ task: () => {
920
+ return new Listr(Object.keys(generates).map(filename => {
921
+ const outputConfig = generates[filename];
922
+ const hasPreset = !!outputConfig.preset;
923
+ return {
924
+ title: hasPreset
702
925
  ? `Generate to ${filename} (using EXPERIMENTAL preset "${outputConfig.preset}")`
703
- : `Generate ${filename}`;
704
- return {
705
- title,
706
- task: (_, subTask) => {
707
- let outputSchemaAst;
708
- let outputSchema;
709
- const outputFileTemplateConfig = outputConfig.config || {};
710
- let outputDocuments = [];
711
- const outputSpecificSchemas = pluginHelpers.normalizeInstanceOrArray(outputConfig.schema);
712
- const outputSpecificDocuments = pluginHelpers.normalizeInstanceOrArray(outputConfig.documents);
713
- return subTask.newListr([
714
- {
715
- title: 'Load GraphQL schemas',
716
- task: wrapTask(async () => {
717
- debugLog(`[CLI] Loading Schemas`);
718
- const schemaPointerMap = {};
719
- const allSchemaDenormalizedPointers = [...rootSchemas, ...outputSpecificSchemas];
720
- for (const denormalizedPtr of allSchemaDenormalizedPointers) {
721
- if (typeof denormalizedPtr === 'string') {
722
- schemaPointerMap[denormalizedPtr] = {};
723
- }
724
- else if (typeof denormalizedPtr === 'object') {
725
- Object.assign(schemaPointerMap, denormalizedPtr);
726
- }
926
+ : `Generate ${filename}`,
927
+ task: () => {
928
+ let outputSchemaAst;
929
+ let outputSchema;
930
+ const outputFileTemplateConfig = outputConfig.config || {};
931
+ let outputDocuments = [];
932
+ const outputSpecificSchemas = pluginHelpers.normalizeInstanceOrArray(outputConfig.schema);
933
+ const outputSpecificDocuments = pluginHelpers.normalizeInstanceOrArray(outputConfig.documents);
934
+ return new Listr([
935
+ {
936
+ title: 'Load GraphQL schemas',
937
+ task: wrapTask(async () => {
938
+ debugLog(`[CLI] Loading Schemas`);
939
+ const schemaPointerMap = {};
940
+ const allSchemaUnnormalizedPointers = [...rootSchemas, ...outputSpecificSchemas];
941
+ for (const unnormalizedPtr of allSchemaUnnormalizedPointers) {
942
+ if (typeof unnormalizedPtr === 'string') {
943
+ schemaPointerMap[unnormalizedPtr] = {};
727
944
  }
728
- const hash = JSON.stringify(schemaPointerMap);
729
- const result = await cache('schema', hash, async () => {
730
- const outputSchemaAst = await context.loadSchema(schemaPointerMap);
731
- const outputSchema = pluginHelpers.getCachedDocumentNodeFromSchema(outputSchemaAst);
732
- return {
733
- outputSchemaAst,
734
- outputSchema,
735
- };
736
- });
737
- outputSchemaAst = result.outputSchemaAst;
738
- outputSchema = result.outputSchema;
739
- }, filename, `Load GraphQL schemas: ${filename}`, ctx),
740
- },
741
- {
742
- title: 'Load GraphQL documents',
743
- task: wrapTask(async () => {
744
- debugLog(`[CLI] Loading Documents`);
745
- const documentPointerMap = {};
746
- const allDocumentsDenormalizedPointers = [...rootDocuments, ...outputSpecificDocuments];
747
- for (const denormalizedPtr of allDocumentsDenormalizedPointers) {
748
- if (typeof denormalizedPtr === 'string') {
749
- documentPointerMap[denormalizedPtr] = {};
750
- }
751
- else if (typeof denormalizedPtr === 'object') {
752
- Object.assign(documentPointerMap, denormalizedPtr);
753
- }
945
+ else if (typeof unnormalizedPtr === 'object') {
946
+ Object.assign(schemaPointerMap, unnormalizedPtr);
754
947
  }
755
- const hash = JSON.stringify(documentPointerMap);
756
- const result = await cache('documents', hash, async () => {
757
- const documents = await context.loadDocuments(documentPointerMap);
758
- return {
759
- documents,
760
- };
761
- });
762
- outputDocuments = result.documents;
763
- }, filename, `Load GraphQL documents: ${filename}`, ctx),
764
- },
765
- {
766
- title: 'Generate',
767
- task: wrapTask(async () => {
768
- debugLog(`[CLI] Generating output`);
769
- const normalizedPluginsArray = pluginHelpers.normalizeConfig(outputConfig.plugins);
770
- const pluginLoader = config.pluginLoader || makeDefaultLoader(context.cwd);
771
- const pluginPackages = await Promise.all(normalizedPluginsArray.map(plugin => getPluginByName(Object.keys(plugin)[0], pluginLoader)));
772
- const preset = hasPreset
773
- ? typeof outputConfig.preset === 'string'
774
- ? await getPresetByName(outputConfig.preset, makeDefaultLoader(context.cwd))
775
- : outputConfig.preset
776
- : null;
777
- const pluginMap = Object.fromEntries(pluginPackages.map((pkg, i) => {
778
- const plugin = normalizedPluginsArray[i];
779
- const name = Object.keys(plugin)[0];
780
- return [name, pkg];
781
- }));
782
- const mergedConfig = {
783
- ...rootConfig,
784
- ...(typeof outputFileTemplateConfig === 'string'
785
- ? { value: outputFileTemplateConfig }
786
- : outputFileTemplateConfig),
948
+ }
949
+ const hash = JSON.stringify(schemaPointerMap);
950
+ const result = await cache('schema', hash, async () => {
951
+ const outputSchemaAst = await context.loadSchema(schemaPointerMap);
952
+ const outputSchema = pluginHelpers.getCachedDocumentNodeFromSchema(outputSchemaAst);
953
+ return {
954
+ outputSchemaAst,
955
+ outputSchema,
956
+ };
957
+ });
958
+ outputSchemaAst = await result.outputSchemaAst;
959
+ outputSchema = result.outputSchema;
960
+ }, filename, `Load GraphQL schemas: ${filename}`),
961
+ },
962
+ {
963
+ title: 'Load GraphQL documents',
964
+ task: wrapTask(async () => {
965
+ debugLog(`[CLI] Loading Documents`);
966
+ // get different cache for shared docs and output specific docs
967
+ const documentPointerMap = {};
968
+ const allDocumentsUnnormalizedPointers = [...rootDocuments, ...outputSpecificDocuments];
969
+ for (const unnormalizedPtr of allDocumentsUnnormalizedPointers) {
970
+ if (typeof unnormalizedPtr === 'string') {
971
+ documentPointerMap[unnormalizedPtr] = {};
972
+ }
973
+ else if (typeof unnormalizedPtr === 'object') {
974
+ Object.assign(documentPointerMap, unnormalizedPtr);
975
+ }
976
+ }
977
+ const hash = JSON.stringify(documentPointerMap);
978
+ const result = await cache('documents', hash, async () => {
979
+ const documents = await context.loadDocuments(documentPointerMap);
980
+ return {
981
+ documents,
787
982
  };
788
- const outputs = hasPreset
789
- ? await context.profiler.run(async () => preset.buildGeneratesSection({
790
- baseOutputDir: filename,
791
- presetConfig: outputConfig.presetConfig || {},
983
+ });
984
+ outputDocuments = await result.documents;
985
+ }, filename, `Load GraphQL documents: ${filename}`),
986
+ },
987
+ {
988
+ title: 'Generate',
989
+ task: wrapTask(async () => {
990
+ debugLog(`[CLI] Generating output`);
991
+ const normalizedPluginsArray = pluginHelpers.normalizeConfig(outputConfig.plugins);
992
+ const pluginLoader = config.pluginLoader || makeDefaultLoader(context.cwd);
993
+ const pluginPackages = await Promise.all(normalizedPluginsArray.map(plugin => getPluginByName(Object.keys(plugin)[0], pluginLoader)));
994
+ const pluginMap = {};
995
+ const preset = hasPreset
996
+ ? typeof outputConfig.preset === 'string'
997
+ ? await getPresetByName(outputConfig.preset, makeDefaultLoader(context.cwd))
998
+ : outputConfig.preset
999
+ : null;
1000
+ pluginPackages.forEach((pluginPackage, i) => {
1001
+ const plugin = normalizedPluginsArray[i];
1002
+ const name = Object.keys(plugin)[0];
1003
+ pluginMap[name] = pluginPackage;
1004
+ });
1005
+ const mergedConfig = {
1006
+ ...rootConfig,
1007
+ ...(typeof outputFileTemplateConfig === 'string'
1008
+ ? { value: outputFileTemplateConfig }
1009
+ : outputFileTemplateConfig),
1010
+ };
1011
+ let outputs = [];
1012
+ if (hasPreset) {
1013
+ outputs = await context.profiler.run(async () => preset.buildGeneratesSection({
1014
+ baseOutputDir: filename,
1015
+ presetConfig: outputConfig.presetConfig || {},
1016
+ plugins: normalizedPluginsArray,
1017
+ schema: outputSchema,
1018
+ schemaAst: outputSchemaAst,
1019
+ documents: outputDocuments,
1020
+ config: mergedConfig,
1021
+ pluginMap,
1022
+ pluginContext,
1023
+ profiler: context.profiler,
1024
+ }), `Build Generates Section: ${filename}`);
1025
+ }
1026
+ else {
1027
+ outputs = [
1028
+ {
1029
+ filename,
792
1030
  plugins: normalizedPluginsArray,
793
1031
  schema: outputSchema,
794
1032
  schemaAst: outputSchemaAst,
@@ -797,67 +1035,50 @@ async function executeCodegen(input) {
797
1035
  pluginMap,
798
1036
  pluginContext,
799
1037
  profiler: context.profiler,
800
- }), `Build Generates Section: ${filename}`)
801
- : [
802
- {
803
- filename,
804
- plugins: normalizedPluginsArray,
805
- schema: outputSchema,
806
- schemaAst: outputSchemaAst,
807
- documents: outputDocuments,
808
- config: mergedConfig,
809
- pluginMap,
810
- pluginContext,
811
- profiler: context.profiler,
812
- },
813
- ];
814
- const process = async (outputArgs) => {
815
- const output = await core.codegen({
816
- ...outputArgs,
817
- cache,
818
- });
819
- result.push({
820
- filename: outputArgs.filename,
821
- content: output,
822
- hooks: outputConfig.hooks || {},
823
- });
824
- };
825
- await context.profiler.run(() => Promise.all(outputs.map(process)), `Codegen: ${filename}`);
826
- }, filename, `Generate: ${filename}`, ctx),
827
- },
828
- ], {
829
- // it stops when of the tasks failed
830
- exitOnError: true,
831
- });
832
- },
833
- // It doesn't stop when one of tasks failed, to finish at least some of outputs
834
- exitOnError: false,
835
- concurrent: os.cpus().length,
836
- };
837
- });
838
- return task.newListr(generateTasks);
839
- },
840
- },
841
- ], {
842
- rendererOptions: {
843
- clearOutput: false,
844
- collapse: true,
1038
+ },
1039
+ ];
1040
+ }
1041
+ const process = async (outputArgs) => {
1042
+ const output = await core.codegen({
1043
+ ...outputArgs,
1044
+ cache,
1045
+ });
1046
+ result.push({
1047
+ filename: outputArgs.filename,
1048
+ content: output,
1049
+ hooks: outputConfig.hooks || {},
1050
+ });
1051
+ };
1052
+ await context.profiler.run(() => Promise.all(outputs.map(process)), `Codegen: ${filename}`);
1053
+ }, filename, `Generate: ${filename}`),
1054
+ },
1055
+ ], {
1056
+ // it stops when one of tasks failed
1057
+ exitOnError: true,
1058
+ });
1059
+ },
1060
+ };
1061
+ }), {
1062
+ // it doesn't stop when one of tasks failed, to finish at least some of outputs
1063
+ exitOnError: false,
1064
+ concurrent: os.cpus().length,
1065
+ });
845
1066
  },
846
- ctx: { errors: [] },
847
- rendererSilent: isTest || config.silent,
848
- exitOnError: true,
849
1067
  });
850
- // All the errors throw in `listr2` are collected in context
851
- // Running tasks doesn't throw anything
852
- const executedContext = await tasks.run();
853
- if (executedContext.errors.length > 0) {
854
- const errors = executedContext.errors.map(subErr => pluginHelpers.isDetailedError(subErr)
855
- ? `${subErr.message} for "${subErr.source}"${subErr.details}`
856
- : subErr.message || subErr.toString());
857
- const newErr = new utils.AggregateError(executedContext.errors, `${errors.join('\n\n')}`);
858
- // Best-effort to all stack traces for debugging
859
- newErr.stack = `${newErr.stack}\n\n${executedContext.errors.map(subErr => subErr.stack).join('\n\n')}`;
860
- throw newErr;
1068
+ try {
1069
+ await listr.run();
1070
+ }
1071
+ catch (err) {
1072
+ if (isListrError(err)) {
1073
+ const allErrs = err.errors.map(subErr => pluginHelpers.isDetailedError(subErr)
1074
+ ? `${subErr.message} for "${subErr.source}"${subErr.details}`
1075
+ : subErr.message || subErr.toString());
1076
+ const newErr = new utils.AggregateError(err.errors, `${err.message} ${allErrs.join('\n\n')}`);
1077
+ // Best-effort to all stack traces for debugging
1078
+ newErr.stack = `${newErr.stack}\n\n${err.errors.map(subErr => subErr.stack).join('\n\n')}`;
1079
+ throw newErr;
1080
+ }
1081
+ throw err;
861
1082
  }
862
1083
  return result;
863
1084
  }
@@ -917,7 +1138,7 @@ function execShellCommand(cmd) {
917
1138
  });
918
1139
  }
919
1140
  async function executeHooks(hookName, scripts = [], args = []) {
920
- debugLog();
1141
+ debugLog(`Running lifecycle hook "${hookName}" scripts...`);
921
1142
  for (const script of scripts) {
922
1143
  if (typeof script === 'string') {
923
1144
  debugLog(`Running lifecycle hook "${hookName}" script: ${script} with args: ${args.join(' ')}...`);
@@ -951,7 +1172,7 @@ function emitWatching() {
951
1172
  log(`${logSymbols.info} Watching for changes...`);
952
1173
  }
953
1174
  const createWatcher = (initalContext, onNext) => {
954
- debugLog();
1175
+ debugLog(`[Watcher] Starting watcher...`);
955
1176
  let config = initalContext.getConfig();
956
1177
  const files = [initalContext.filepath].filter(a => a);
957
1178
  const documents = pluginHelpers.normalizeInstanceOrArray(config.documents);
@@ -1022,10 +1243,10 @@ const createWatcher = (initalContext, onNext) => {
1022
1243
  atomic: true,
1023
1244
  ignored,
1024
1245
  });
1025
- debugLog();
1246
+ debugLog(`[Watcher] Started`);
1026
1247
  const shutdown = () => {
1027
1248
  isShutdown = true;
1028
- debugLog();
1249
+ debugLog(`[Watcher] Shutting down`);
1029
1250
  log(`Shutting down watch...`);
1030
1251
  watcher.close();
1031
1252
  lifecycleHooks(config.hooks).beforeDone();
@@ -1033,7 +1254,7 @@ const createWatcher = (initalContext, onNext) => {
1033
1254
  // it doesn't matter what has changed, need to run whole process anyway
1034
1255
  watcher.on('all', async (eventName, path$1) => {
1035
1256
  lifecycleHooks(config.hooks).onWatchTriggered(eventName, path$1);
1036
- debugLog();
1257
+ debugLog(`[Watcher] triggered due to a file ${eventName} event: ${path$1}`);
1037
1258
  const fullPath = path.join(process.cwd(), path$1);
1038
1259
  // In ESM require is not defined
1039
1260
  try {
@@ -1102,10 +1323,10 @@ async function generate(input, saveToFile = true) {
1102
1323
  return unlinkFile(filename, err => {
1103
1324
  const prettyFilename = filename.replace(`${input.cwd || process.cwd()}/`, '');
1104
1325
  if (err) {
1105
- debugLog();
1326
+ debugLog(`Cannot remove stale file: ${prettyFilename}\n${err}`);
1106
1327
  }
1107
1328
  else {
1108
- debugLog();
1329
+ debugLog(`Removed stale file: ${prettyFilename}`);
1109
1330
  }
1110
1331
  });
1111
1332
  }
@@ -1172,7 +1393,7 @@ function shouldOverwrite(config, outputPath) {
1172
1393
  const globalValue = config.overwrite === undefined ? true : !!config.overwrite;
1173
1394
  const outputConfig = config.generates[outputPath];
1174
1395
  if (!outputConfig) {
1175
- debugLog();
1396
+ debugLog(`Couldn't find a config of ${outputPath}`);
1176
1397
  return globalValue;
1177
1398
  }
1178
1399
  if (isConfiguredOutput(outputConfig) && typeof outputConfig.overwrite === 'boolean') {
@@ -1633,40 +1854,18 @@ function addIntrospection(config) {
1633
1854
  };
1634
1855
  }
1635
1856
 
1636
- function isListrError(err) {
1637
- return err.name === 'ListrError' && Array.isArray(err.errors) && err.errors.length > 0;
1638
- }
1639
- function cliError(err, exitOnError = true) {
1640
- let msg;
1641
- if (err instanceof Error) {
1642
- msg = err.message || err.toString();
1643
- }
1644
- else if (typeof err === 'string') {
1645
- msg = err;
1646
- }
1647
- else {
1648
- msg = JSON.stringify(err);
1649
- }
1650
- // eslint-disable-next-line no-console
1651
- console.error(msg);
1652
- if (exitOnError) {
1653
- process.exit(1);
1654
- }
1655
- }
1656
-
1657
1857
  async function runCli(cmd) {
1658
1858
  await ensureGraphQlPackage();
1659
- switch (cmd) {
1660
- case 'init':
1661
- return init();
1662
- default: {
1663
- return createContext().then(context => {
1664
- return generate(context).catch(async (error) => {
1665
- await lifecycleHooks(context.getConfig().hooks).onError(error.toString());
1666
- throw error;
1667
- });
1668
- });
1669
- }
1859
+ if (cmd === 'init') {
1860
+ return init();
1861
+ }
1862
+ const context = await createContext();
1863
+ try {
1864
+ return await generate(context);
1865
+ }
1866
+ catch (error) {
1867
+ await lifecycleHooks(context.getConfig().hooks).onError(error.toString());
1868
+ throw error;
1670
1869
  }
1671
1870
  }
1672
1871
  async function ensureGraphQlPackage() {