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