@graphql-codegen/cli 2.6.4 → 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/bin.js +187 -392
- package/index.js +206 -408
- package/index.mjs +207 -409
- package/package.json +2 -7
- package/utils/indentString.d.ts +0 -26
- package/utils/is-browser.d.ts +0 -3
- package/utils/listr-renderer.d.ts +0 -18
package/index.mjs
CHANGED
|
@@ -1,15 +1,9 @@
|
|
|
1
|
-
import {
|
|
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 '
|
|
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
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
const
|
|
902
|
-
|
|
903
|
-
|
|
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
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
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
|
-
|
|
925
|
-
|
|
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
|
-
|
|
929
|
-
|
|
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
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
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
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
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
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
998
|
+
debugLog();
|
|
1222
999
|
const shutdown = () => {
|
|
1223
1000
|
isShutdown = true;
|
|
1224
|
-
debugLog(
|
|
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(
|
|
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(
|
|
1078
|
+
debugLog();
|
|
1302
1079
|
}
|
|
1303
1080
|
else {
|
|
1304
|
-
debugLog(
|
|
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(
|
|
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) {
|