UNPKG

8.54 kBJavaScriptView Raw
1import { debugLog } from 'graphql-codegen-plugin-helpers';
2import { codegen, mergeSchemas } from 'graphql-codegen-core';
3import * as Listr from 'listr';
4import { normalizeOutputParam, normalizeInstanceOrArray, normalizeConfig } from './helpers';
5import { prettify } from './utils/prettier';
6import { Renderer } from './utils/listr-renderer';
7import { DetailedError } from './errors';
8import { loadSchema, loadDocuments } from './load';
9import { GraphQLError } from 'graphql';
10import { getPluginByName } from './plugins';
11export const defaultPluginLoader = (mod) => import(mod);
12export 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 /* Load Require extensions */
46 const requireExtensions = normalizeInstanceOrArray(config.require);
47 for (const mod of requireExtensions) {
48 await import(mod);
49 }
50 /* Root templates-config */
51 rootConfig = config.config || {};
52 /* Normalize root "schema" field */
53 rootSchemas = normalizeInstanceOrArray(config.schema);
54 /* Normalize root "documents" field */
55 rootDocuments = normalizeInstanceOrArray(config.documents);
56 /* Normalize "generators" field */
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 // it stops when one of tasks failed
179 exitOnError: true
180 });
181 }
182 })), {
183 // it doesn't stop when one of tasks failed, to finish at least some of outputs
184 exitOnError: false,
185 // run 4 at once
186 concurrent: 4
187 });
188 }
189 });
190 await listr.run();
191 return result;
192}
193//# sourceMappingURL=codegen.js.map
\No newline at end of file