UNPKG

29.7 kBJavaScriptView Raw
1"use strict";
2var __assign = (this && this.__assign) || function () {
3 __assign = Object.assign || function(t) {
4 for (var s, i = 1, n = arguments.length; i < n; i++) {
5 s = arguments[i];
6 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7 t[p] = s[p];
8 }
9 return t;
10 };
11 return __assign.apply(this, arguments);
12};
13var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14 return new (P || (P = Promise))(function (resolve, reject) {
15 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
16 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
17 function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
18 step((generator = generator.apply(thisArg, _arguments || [])).next());
19 });
20};
21var __generator = (this && this.__generator) || function (thisArg, body) {
22 var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
23 return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
24 function verb(n) { return function (v) { return step([n, v]); }; }
25 function step(op) {
26 if (f) throw new TypeError("Generator is already executing.");
27 while (_) try {
28 if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
29 if (y = 0, t) op = [op[0] & 2, t.value];
30 switch (op[0]) {
31 case 0: case 1: t = op; break;
32 case 4: _.label++; return { value: op[1], done: false };
33 case 5: _.label++; y = op[1]; op = [0]; continue;
34 case 7: op = _.ops.pop(); _.trys.pop(); continue;
35 default:
36 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
37 if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
38 if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
39 if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
40 if (t[2]) _.ops.pop();
41 _.trys.pop(); continue;
42 }
43 op = body.call(thisArg, _);
44 } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
45 if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
46 }
47};
48var _this = this;
49Object.defineProperty(exports, "__esModule", { value: true });
50var document_from_string_1 = require("./loaders/documents/document-from-string");
51var schema_from_string_1 = require("./loaders/schema/schema-from-string");
52var graphql_tools_1 = require("graphql-tools");
53var Listr = require("listr");
54var helpers_1 = require("./helpers");
55var introspection_from_url_1 = require("./loaders/schema/introspection-from-url");
56var introspection_from_file_1 = require("./loaders/schema/introspection-from-file");
57var schema_from_typedefs_1 = require("./loaders/schema/schema-from-typedefs");
58var schema_from_export_1 = require("./loaders/schema/schema-from-export");
59var validate_documents_1 = require("./loaders/documents/validate-documents");
60var prettier_1 = require("./utils/prettier");
61var listr_renderer_1 = require("./utils/listr-renderer");
62var errors_1 = require("./errors");
63var documents_from_glob_1 = require("./loaders/documents/documents-from-glob");
64var documentsHandlers = [new document_from_string_1.DocumentFromString(), new documents_from_glob_1.DocumentsFromGlob()];
65var schemaHandlers = [
66 new introspection_from_url_1.IntrospectionFromUrlLoader(),
67 new introspection_from_file_1.IntrospectionFromFileLoader(),
68 new schema_from_string_1.SchemaFromString(),
69 new schema_from_typedefs_1.SchemaFromTypedefs(),
70 new schema_from_export_1.SchemaFromExport()
71];
72var loadDocuments = function (documentDef, config) { return __awaiter(_this, void 0, void 0, function () {
73 var _i, documentsHandlers_1, handler;
74 return __generator(this, function (_a) {
75 switch (_a.label) {
76 case 0:
77 _i = 0, documentsHandlers_1 = documentsHandlers;
78 _a.label = 1;
79 case 1:
80 if (!(_i < documentsHandlers_1.length)) return [3 /*break*/, 4];
81 handler = documentsHandlers_1[_i];
82 return [4 /*yield*/, handler.canHandle(documentDef)];
83 case 2:
84 if (_a.sent()) {
85 return [2 /*return*/, handler.handle(documentDef, config)];
86 }
87 _a.label = 3;
88 case 3:
89 _i++;
90 return [3 /*break*/, 1];
91 case 4: return [2 /*return*/, []];
92 }
93 });
94}); };
95var loadSchema = function (schemaDef, config) { return __awaiter(_this, void 0, void 0, function () {
96 var _i, schemaHandlers_1, handler, pointToSchema, options;
97 return __generator(this, function (_a) {
98 switch (_a.label) {
99 case 0:
100 _i = 0, schemaHandlers_1 = schemaHandlers;
101 _a.label = 1;
102 case 1:
103 if (!(_i < schemaHandlers_1.length)) return [3 /*break*/, 4];
104 handler = schemaHandlers_1[_i];
105 pointToSchema = null;
106 options = {};
107 if (typeof schemaDef === 'string') {
108 pointToSchema = schemaDef;
109 }
110 else if (typeof schemaDef === 'object') {
111 pointToSchema = Object.keys(schemaDef)[0];
112 options = schemaDef[pointToSchema];
113 }
114 return [4 /*yield*/, handler.canHandle(pointToSchema)];
115 case 2:
116 if (_a.sent()) {
117 return [2 /*return*/, handler.handle(pointToSchema, config, options)];
118 }
119 _a.label = 3;
120 case 3:
121 _i++;
122 return [3 /*break*/, 1];
123 case 4: throw new errors_1.DetailedError('Failed to load schema', "\n Failed to load schema from " + schemaDef + ".\n\n GraphQL Code Generator supports:\n - ES Modules and CommonJS exports\n - Introspection JSON File\n - URL of GraphQL endpoint\n - Multiple files with type definitions\n - String in config file\n\n Try to use one of above options and run codegen again.\n\n ");
124 }
125 });
126}); };
127function mergeSchemas(schemas) {
128 return __awaiter(this, void 0, void 0, function () {
129 return __generator(this, function (_a) {
130 if (schemas.length === 0) {
131 return [2 /*return*/, null];
132 }
133 else if (schemas.length === 1) {
134 return [2 /*return*/, schemas[0]];
135 }
136 else {
137 return [2 /*return*/, graphql_tools_1.mergeSchemas({ schemas: schemas.filter(function (s) { return s; }) })];
138 }
139 return [2 /*return*/];
140 });
141 });
142}
143function executeCodegen(config) {
144 return __awaiter(this, void 0, void 0, function () {
145 function wrapTask(task, source) {
146 var _this = this;
147 return function () { return __awaiter(_this, void 0, void 0, function () {
148 var error_1;
149 return __generator(this, function (_a) {
150 switch (_a.label) {
151 case 0:
152 _a.trys.push([0, 2, , 3]);
153 return [4 /*yield*/, task()];
154 case 1:
155 _a.sent();
156 return [3 /*break*/, 3];
157 case 2:
158 error_1 = _a.sent();
159 if (source) {
160 error_1.source = source;
161 }
162 throw error_1;
163 case 3: return [2 /*return*/];
164 }
165 });
166 }); };
167 }
168 function normalize() {
169 /* Load Require extensions */
170 var requireExtensions = helpers_1.normalizeInstanceOrArray(config.require);
171 requireExtensions.forEach(function (mod) { return require(mod); });
172 /* Root templates-config */
173 rootConfig = config.config || {};
174 /* Normalize root "schema" field */
175 schemas = helpers_1.normalizeInstanceOrArray(config.schema);
176 if (schemas.length === 0) {
177 throw new errors_1.DetailedError('Invalid Codegen Configuration!', "\n Please make sure that your codegen config file contains the \"schema\" field.\n \n It should looks like that:\n\n schema:\n - my-schema.graphql\n ");
178 }
179 /* Normalize root "documents" field */
180 documents = helpers_1.normalizeInstanceOrArray(config.documents);
181 /* Normalize "generators" field */
182 var generateKeys = Object.keys(config.generates);
183 if (generateKeys.length === 0) {
184 throw new errors_1.DetailedError('Invalid Codegen Configuration!', "\n Please make sure that your codegen config file contains the \"generates\" field, with a specification for the plugins you need.\n \n It should looks like that:\n\n schema:\n - my-schema.graphql\n generates:\n my-file.ts:\n - plugin1\n - plugin2\n - plugin3\n ");
185 }
186 for (var _i = 0, generateKeys_1 = generateKeys; _i < generateKeys_1.length; _i++) {
187 var filename = generateKeys_1[_i];
188 generates[filename] = helpers_1.normalizeOutputParam(config.generates[filename]);
189 if (generates[filename].plugins.length === 0) {
190 throw new errors_1.DetailedError('Invalid Codegen Configuration!', "\n Please make sure that your codegen config file has defined plugins list for output \"" + filename + "\".\n \n It should looks like that:\n \n schema:\n - my-schema.graphql\n generates:\n my-file.ts:\n - plugin1\n - plugin2\n - plugin3\n ");
191 }
192 }
193 }
194 function loadRootSchema() {
195 return __awaiter(this, void 0, void 0, function () {
196 var _a;
197 return __generator(this, function (_b) {
198 switch (_b.label) {
199 case 0:
200 _a = mergeSchemas;
201 return [4 /*yield*/, Promise.all(schemas.map(function (pointToScehma) { return loadSchema(pointToScehma, config); }))];
202 case 1: return [4 /*yield*/, _a.apply(void 0, [_b.sent()])];
203 case 2:
204 /* Load root schemas */
205 rootSchema = _b.sent();
206 return [2 /*return*/];
207 }
208 });
209 });
210 }
211 function loadRootDocuments() {
212 return __awaiter(this, void 0, void 0, function () {
213 var _i, documents_1, docDef, documents_2, errors;
214 return __generator(this, function (_a) {
215 switch (_a.label) {
216 case 0:
217 if (!(documents.length > 0)) return [3 /*break*/, 5];
218 _i = 0, documents_1 = documents;
219 _a.label = 1;
220 case 1:
221 if (!(_i < documents_1.length)) return [3 /*break*/, 4];
222 docDef = documents_1[_i];
223 return [4 /*yield*/, loadDocuments(docDef, config)];
224 case 2:
225 documents_2 = _a.sent();
226 if (documents_2.length > 0) {
227 rootDocuments.push.apply(rootDocuments, documents_2);
228 }
229 _a.label = 3;
230 case 3:
231 _i++;
232 return [3 /*break*/, 1];
233 case 4:
234 if (rootSchema) {
235 errors = validate_documents_1.validateGraphQlDocuments(rootSchema, rootDocuments);
236 validate_documents_1.checkValidationErrors(errors);
237 }
238 _a.label = 5;
239 case 5: return [2 /*return*/];
240 }
241 });
242 });
243 }
244 var result, commonListrOptions, verboseOptions, listrOptions, listr, rootConfig, schemas, documents, generates, rootSchema, rootDocuments;
245 return __generator(this, function (_a) {
246 switch (_a.label) {
247 case 0:
248 result = [];
249 commonListrOptions = {
250 exitOnError: true
251 };
252 verboseOptions = __assign({}, commonListrOptions, { renderer: 'verbose', nonTTYRenderer: 'verbose' });
253 listrOptions = __assign({}, commonListrOptions, { renderer: config.silent ? 'silent' : listr_renderer_1.Renderer, nonTTYRenderer: config.silent ? 'silent' : 'default', collapse: true, clearOutput: false });
254 listr = new Listr(process.env.VERBOSE || process.env.NODE_ENV === 'test' ? verboseOptions : listrOptions);
255 rootConfig = {};
256 generates = {};
257 rootDocuments = [];
258 listr.add({
259 title: 'Parse configuration',
260 task: function (ctx) {
261 normalize();
262 ctx.hasSchemas = schemas.length > 0;
263 ctx.hasDocuments = documents.length > 0;
264 }
265 });
266 listr.add({
267 title: 'Load schema',
268 enabled: function (ctx) { return ctx.hasSchemas; },
269 task: wrapTask(loadRootSchema)
270 });
271 listr.add({
272 title: 'Load documents',
273 enabled: function (ctx) { return ctx.hasDocuments; },
274 task: wrapTask(loadRootDocuments)
275 });
276 listr.add({
277 title: 'Generate outputs',
278 task: function () {
279 return new Listr(Object.keys(generates).map(function (filename, i) { return ({
280 title: "Generate " + filename,
281 task: function () {
282 var outputConfig = generates[filename];
283 var outputFileTemplateConfig = outputConfig.config || {};
284 var outputSchema = rootSchema;
285 var outputDocuments = rootDocuments;
286 var outputSpecificSchemas = helpers_1.normalizeInstanceOrArray(outputConfig.schema);
287 var outputSpecificDocuments = helpers_1.normalizeInstanceOrArray(outputConfig.documents);
288 function addSchema() {
289 return __awaiter(this, void 0, void 0, function () {
290 var _a, _b, _c;
291 return __generator(this, function (_d) {
292 switch (_d.label) {
293 case 0:
294 _a = mergeSchemas;
295 _c = (_b = [
296 rootSchema
297 ]).concat;
298 return [4 /*yield*/, Promise.all(outputSpecificSchemas.map(function (pointToScehma) { return loadSchema(pointToScehma, config); }))];
299 case 1: return [4 /*yield*/, _a.apply(void 0, [_c.apply(_b, [(_d.sent())])])];
300 case 2:
301 outputSchema = _d.sent();
302 return [2 /*return*/];
303 }
304 });
305 });
306 }
307 function addDocuments() {
308 return __awaiter(this, void 0, void 0, function () {
309 var additionalDocs, _i, outputSpecificDocuments_1, docDef, documents_3, errors;
310 return __generator(this, function (_a) {
311 switch (_a.label) {
312 case 0:
313 additionalDocs = [];
314 _i = 0, outputSpecificDocuments_1 = outputSpecificDocuments;
315 _a.label = 1;
316 case 1:
317 if (!(_i < outputSpecificDocuments_1.length)) return [3 /*break*/, 4];
318 docDef = outputSpecificDocuments_1[_i];
319 return [4 /*yield*/, loadDocuments(docDef, config)];
320 case 2:
321 documents_3 = _a.sent();
322 if (documents_3.length > 0) {
323 additionalDocs.push.apply(additionalDocs, documents_3);
324 }
325 _a.label = 3;
326 case 3:
327 _i++;
328 return [3 /*break*/, 1];
329 case 4:
330 if (outputSchema) {
331 errors = validate_documents_1.validateGraphQlDocuments(outputSchema, additionalDocs);
332 validate_documents_1.checkValidationErrors(errors);
333 }
334 outputDocuments = rootDocuments.concat(additionalDocs);
335 return [2 /*return*/];
336 }
337 });
338 });
339 }
340 function doGenerateOutput() {
341 return __awaiter(this, void 0, void 0, function () {
342 var normalizedPluginsArray, output;
343 return __generator(this, function (_a) {
344 switch (_a.label) {
345 case 0:
346 normalizedPluginsArray = helpers_1.normalizeConfig(outputConfig.plugins);
347 return [4 /*yield*/, generateOutput({
348 filename: filename,
349 plugins: normalizedPluginsArray,
350 schema: outputSchema,
351 documents: outputDocuments,
352 inheritedConfig: __assign({}, rootConfig, outputFileTemplateConfig)
353 })];
354 case 1:
355 output = _a.sent();
356 result.push(output);
357 return [2 /*return*/];
358 }
359 });
360 });
361 }
362 return new Listr([
363 {
364 title: 'Add related schemas',
365 enabled: function () { return outputSpecificSchemas.length > 0; },
366 task: wrapTask(addSchema, filename)
367 },
368 {
369 title: 'Add related documents',
370 enabled: function () { return outputSpecificDocuments.length > 0; },
371 task: wrapTask(addDocuments, filename)
372 },
373 {
374 title: 'Generate',
375 task: wrapTask(doGenerateOutput, filename)
376 }
377 ], {
378 // it stops when one of tasks failed
379 exitOnError: true
380 });
381 }
382 }); }), {
383 // it doesn't stop when one of tasks failed, to finish at least some of outputs
384 exitOnError: false,
385 // run 4 at once
386 concurrent: 4
387 });
388 }
389 });
390 return [4 /*yield*/, listr.run()];
391 case 1:
392 _a.sent();
393 return [2 /*return*/, result];
394 }
395 });
396 });
397}
398exports.executeCodegen = executeCodegen;
399function generateOutput(options) {
400 return __awaiter(this, void 0, void 0, function () {
401 var output, _i, _a, plugin, name_1, pluginConfig, result, _b;
402 return __generator(this, function (_c) {
403 switch (_c.label) {
404 case 0:
405 output = '';
406 _i = 0, _a = options.plugins;
407 _c.label = 1;
408 case 1:
409 if (!(_i < _a.length)) return [3 /*break*/, 4];
410 plugin = _a[_i];
411 name_1 = Object.keys(plugin)[0];
412 pluginConfig = plugin[name_1];
413 return [4 /*yield*/, executePlugin({
414 name: name_1,
415 config: typeof pluginConfig !== 'object'
416 ? pluginConfig
417 : __assign({}, options.inheritedConfig, pluginConfig),
418 schema: options.schema,
419 documents: options.documents,
420 outputFilename: options.filename,
421 allPlugins: options.plugins
422 })];
423 case 2:
424 result = _c.sent();
425 output += result;
426 _c.label = 3;
427 case 3:
428 _i++;
429 return [3 /*break*/, 1];
430 case 4:
431 _b = { filename: options.filename };
432 return [4 /*yield*/, prettier_1.prettify(options.filename, output)];
433 case 5: return [2 /*return*/, (_b.content = _c.sent(), _b)];
434 }
435 });
436 });
437}
438exports.generateOutput = generateOutput;
439function getPluginByName(name) {
440 return __awaiter(this, void 0, void 0, function () {
441 var possibleNames, _i, possibleNames_1, packageName, possibleNamesMsg;
442 return __generator(this, function (_a) {
443 possibleNames = [
444 "graphql-codegen-" + name,
445 "graphql-codegen-" + name + "-template",
446 "codegen-" + name,
447 "codegen-" + name + "-template",
448 name
449 ];
450 for (_i = 0, possibleNames_1 = possibleNames; _i < possibleNames_1.length; _i++) {
451 packageName = possibleNames_1[_i];
452 try {
453 return [2 /*return*/, require(packageName)];
454 }
455 catch (err) {
456 if (err.message.indexOf("Cannot find module '" + packageName + "'") === -1) {
457 throw new errors_1.DetailedError("Unable to load template plugin matching " + name, "\n Unable to load template plugin matching '" + name + "'.\n Reason: \n " + err.message + "\n ");
458 }
459 }
460 }
461 possibleNamesMsg = possibleNames
462 .map(function (name) {
463 return ("\n - " + name + "\n ").trimRight();
464 })
465 .join('');
466 throw new errors_1.DetailedError("Unable to find template plugin matching " + name, "\n Unable to find template plugin matching '" + name + "'\n Install one of the following packages:\n \n " + possibleNamesMsg + "\n ");
467 });
468 });
469}
470exports.getPluginByName = getPluginByName;
471function executePlugin(options) {
472 return __awaiter(this, void 0, void 0, function () {
473 var pluginPackage, schema, _a, e_1;
474 return __generator(this, function (_b) {
475 switch (_b.label) {
476 case 0: return [4 /*yield*/, getPluginByName(options.name)];
477 case 1:
478 pluginPackage = _b.sent();
479 if (!pluginPackage.plugin || typeof pluginPackage.plugin !== 'function') {
480 throw new errors_1.DetailedError("Invalid Custom Plugin \"" + options.name + "\"", "\n Plugin " + options.name + " does not export a valid JS object with \"plugin\" function.\n\n Make sure your custom plugin is written in the following form:\n\n module.exports = {\n plugin: (schema, documents, config) => {\n return 'my-custom-plugin-content';\n },\n };\n ");
481 }
482 if (!!pluginPackage.addToSchema) return [3 /*break*/, 2];
483 _a = options.schema;
484 return [3 /*break*/, 4];
485 case 2: return [4 /*yield*/, mergeSchemas([
486 options.schema,
487 graphql_tools_1.makeExecutableSchema({
488 typeDefs: pluginPackage.addToSchema,
489 allowUndefinedInResolve: true,
490 resolverValidationOptions: {
491 requireResolversForResolveType: false,
492 requireResolversForAllFields: false,
493 requireResolversForNonScalar: false,
494 requireResolversForArgs: false
495 }
496 })
497 ])];
498 case 3:
499 _a = _b.sent();
500 _b.label = 4;
501 case 4:
502 schema = _a;
503 if (!(pluginPackage.validate && typeof pluginPackage.validate === 'function')) return [3 /*break*/, 8];
504 _b.label = 5;
505 case 5:
506 _b.trys.push([5, 7, , 8]);
507 return [4 /*yield*/, pluginPackage.validate(schema, options.documents, options.config, options.outputFilename, options.allPlugins)];
508 case 6:
509 _b.sent();
510 return [3 /*break*/, 8];
511 case 7:
512 e_1 = _b.sent();
513 throw new errors_1.DetailedError("Plugin \"" + options.name + "\" validation failed:", "\n " + e_1.message + "\n ");
514 case 8: return [2 /*return*/, pluginPackage.plugin(schema, options.documents, options.config)];
515 }
516 });
517 });
518}
519exports.executePlugin = executePlugin;
520//# sourceMappingURL=codegen.js.map
\No newline at end of file