1 | import { debugLog } from 'graphql-codegen-plugin-helpers';
|
2 | import { codegen, mergeSchemas } from 'graphql-codegen-core';
|
3 | import * as Listr from 'listr';
|
4 | import { normalizeOutputParam, normalizeInstanceOrArray, normalizeConfig } from './helpers';
|
5 | import { prettify } from './utils/prettier';
|
6 | import { Renderer } from './utils/listr-renderer';
|
7 | import { DetailedError } from './errors';
|
8 | import { loadSchema, loadDocuments } from './load';
|
9 | import { GraphQLError } from 'graphql';
|
10 | import { getPluginByName } from './plugins';
|
11 | export const defaultPluginLoader = (mod) => import(mod);
|
12 | export async function executeCodegen(config) {
|
13 | function wrapTask(task, source) {
|
14 | return async () => {
|
15 | try {
|
16 | await task();
|
17 | }
|
18 | catch (error) {
|
19 | if (source && !(error instanceof GraphQLError)) {
|
20 | error.source = source;
|
21 | }
|
22 | throw error;
|
23 | }
|
24 | };
|
25 | }
|
26 | const result = [];
|
27 | const commonListrOptions = {
|
28 | exitOnError: true
|
29 | };
|
30 | let listr;
|
31 | if (process.env.VERBOSE) {
|
32 | listr = new Listr(Object.assign({}, commonListrOptions, { renderer: 'verbose', nonTTYRenderer: 'verbose' }));
|
33 | }
|
34 | else if (process.env.NODE_ENV === 'test') {
|
35 | listr = new Listr(Object.assign({}, commonListrOptions, { renderer: 'silent', nonTTYRenderer: 'silent' }));
|
36 | }
|
37 | else {
|
38 | listr = new Listr(Object.assign({}, commonListrOptions, { renderer: config.silent ? 'silent' : Renderer, nonTTYRenderer: config.silent ? 'silent' : 'default', collapse: true, clearOutput: false }));
|
39 | }
|
40 | let rootConfig = {};
|
41 | let rootSchemas;
|
42 | let rootDocuments;
|
43 | let generates = {};
|
44 | async function normalize() {
|
45 |
|
46 | const requireExtensions = normalizeInstanceOrArray(config.require);
|
47 | for (const mod of requireExtensions) {
|
48 | await import(mod);
|
49 | }
|
50 |
|
51 | rootConfig = config.config || {};
|
52 |
|
53 | rootSchemas = normalizeInstanceOrArray(config.schema);
|
54 |
|
55 | rootDocuments = normalizeInstanceOrArray(config.documents);
|
56 |
|
57 | const generateKeys = Object.keys(config.generates);
|
58 | if (generateKeys.length === 0) {
|
59 | throw new DetailedError('Invalid Codegen Configuration!', `
|
60 | Please make sure that your codegen config file contains the "generates" field, with a specification for the plugins you need.
|
61 |
|
62 | It should looks like that:
|
63 |
|
64 | schema:
|
65 | - my-schema.graphql
|
66 | generates:
|
67 | my-file.ts:
|
68 | - plugin1
|
69 | - plugin2
|
70 | - plugin3
|
71 | `);
|
72 | }
|
73 | for (const filename of generateKeys) {
|
74 | generates[filename] = normalizeOutputParam(config.generates[filename]);
|
75 | if (generates[filename].plugins.length === 0) {
|
76 | throw new DetailedError('Invalid Codegen Configuration!', `
|
77 | Please make sure that your codegen config file has defined plugins list for output "${filename}".
|
78 |
|
79 | It should looks like that:
|
80 |
|
81 | schema:
|
82 | - my-schema.graphql
|
83 | generates:
|
84 | my-file.ts:
|
85 | - plugin1
|
86 | - plugin2
|
87 | - plugin3
|
88 | `);
|
89 | }
|
90 | }
|
91 | if (rootSchemas.length === 0 && Object.keys(generates).some(filename => generates[filename].schema.length === 0)) {
|
92 | throw new DetailedError('Invalid Codegen Configuration!', `
|
93 | Please make sure that your codegen config file contains either the "schema" field
|
94 | or every generated file has its own "schema" field.
|
95 |
|
96 | It should looks like that:
|
97 | schema:
|
98 | - my-schema.graphql
|
99 |
|
100 | or:
|
101 | generates:
|
102 | path/to/output:
|
103 | schema: my-schema.graphql
|
104 | `);
|
105 | }
|
106 | }
|
107 | listr.add({
|
108 | title: 'Parse configuration',
|
109 | task: () => normalize()
|
110 | });
|
111 | listr.add({
|
112 | title: 'Generate outputs',
|
113 | task: () => {
|
114 | return new Listr(Object.keys(generates).map((filename, i) => ({
|
115 | title: `Generate ${filename}`,
|
116 | task: () => {
|
117 | const outputConfig = generates[filename];
|
118 | const outputFileTemplateConfig = outputConfig.config || {};
|
119 | const outputDocuments = [];
|
120 | let outputSchema;
|
121 | const outputSpecificSchemas = normalizeInstanceOrArray(outputConfig.schema);
|
122 | const outputSpecificDocuments = normalizeInstanceOrArray(outputConfig.documents);
|
123 | return new Listr([
|
124 | {
|
125 | title: 'Load GraphQL schemas',
|
126 | task: wrapTask(async () => {
|
127 | debugLog(`[CLI] Loading Schemas`);
|
128 | const allSchemas = [
|
129 | ...rootSchemas.map(pointToScehma => loadSchema(pointToScehma, config)),
|
130 | ...outputSpecificSchemas.map(pointToScehma => loadSchema(pointToScehma, config))
|
131 | ];
|
132 | if (allSchemas.length > 0) {
|
133 | outputSchema = await mergeSchemas(await Promise.all(allSchemas));
|
134 | }
|
135 | }, filename)
|
136 | },
|
137 | {
|
138 | title: 'Load GraphQL documents',
|
139 | task: wrapTask(async () => {
|
140 | debugLog(`[CLI] Loading Documents`);
|
141 | const allDocuments = [...rootDocuments, ...outputSpecificDocuments];
|
142 | for (const docDef of allDocuments) {
|
143 | const documents = await loadDocuments(docDef, config);
|
144 | if (documents.length > 0) {
|
145 | outputDocuments.push(...documents);
|
146 | }
|
147 | }
|
148 | }, filename)
|
149 | },
|
150 | {
|
151 | title: 'Generate',
|
152 | task: wrapTask(async () => {
|
153 | debugLog(`[CLI] Generating output`);
|
154 | const normalizedPluginsArray = normalizeConfig(outputConfig.plugins);
|
155 | const pluginLoader = config.pluginLoader || defaultPluginLoader;
|
156 | const pluginPackages = await Promise.all(normalizedPluginsArray.map(plugin => getPluginByName(Object.keys(plugin)[0], pluginLoader)));
|
157 | const pluginMap = {};
|
158 | pluginPackages.forEach((pluginPackage, i) => {
|
159 | const plugin = normalizedPluginsArray[i];
|
160 | const name = Object.keys(plugin)[0];
|
161 | pluginMap[name] = pluginPackage;
|
162 | });
|
163 | const output = await codegen({
|
164 | filename,
|
165 | plugins: normalizedPluginsArray,
|
166 | schema: outputSchema,
|
167 | documents: outputDocuments,
|
168 | config: Object.assign({}, rootConfig, outputFileTemplateConfig),
|
169 | pluginMap
|
170 | });
|
171 | result.push({
|
172 | filename,
|
173 | content: await prettify(filename, output)
|
174 | });
|
175 | }, filename)
|
176 | }
|
177 | ], {
|
178 |
|
179 | exitOnError: true
|
180 | });
|
181 | }
|
182 | })), {
|
183 |
|
184 | exitOnError: false,
|
185 |
|
186 | concurrent: 4
|
187 | });
|
188 | }
|
189 | });
|
190 | await listr.run();
|
191 | return result;
|
192 | }
|
193 |
|
\ | No newline at end of file |