UNPKG

16.8 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};
48Object.defineProperty(exports, "__esModule", { value: true });
49var inquirer = require("inquirer");
50var chalk_1 = require("chalk");
51var path_1 = require("path");
52var fs_1 = require("fs");
53var YAML = require("json-to-pretty-yaml");
54var detectIndent = require("detect-indent");
55var Tags;
56(function (Tags) {
57 Tags["client"] = "Client";
58 Tags["server"] = "Server";
59 Tags["typescript"] = "TypeScript";
60 Tags["angular"] = "Angular";
61 Tags["react"] = "React";
62})(Tags || (Tags = {}));
63function log() {
64 var msgs = [];
65 for (var _i = 0; _i < arguments.length; _i++) {
66 msgs[_i] = arguments[_i];
67 }
68 // tslint:disable-next-line
69 console.log.apply(console, msgs);
70}
71var plugins = [
72 {
73 name: "TypeScript Common " + chalk_1.default.italic('(required by client and server plugins)'),
74 package: 'graphql-codegen-typescript-common',
75 value: 'typescript-common',
76 available: function () { return true; }
77 },
78 {
79 name: "TypeScript Client " + chalk_1.default.italic('(operations and fragments)'),
80 package: 'graphql-codegen-typescript-client',
81 value: 'typescript-client',
82 available: function (tags) { return tags.some(function (tag) { return [Tags.client].includes(tag); }); }
83 },
84 {
85 name: "TypeScript Server " + chalk_1.default.italic('(GraphQL Schema)'),
86 package: 'graphql-codegen-typescript-server',
87 value: 'typescript-server',
88 available: function (tags) { return tags.some(function (tag) { return [Tags.client, Tags.server].includes(tag); }); }
89 },
90 {
91 name: "TypeScript Resolvers " + chalk_1.default.italic('(strongly typed resolve functions)'),
92 package: 'graphql-codegen-typescript-resolvers',
93 value: 'typescript-resolvers',
94 available: function (tags) { return tags.some(function (tag) { return [Tags.server].includes(tag); }); }
95 },
96 {
97 name: "TypeScript Apollo Angular " + chalk_1.default.italic('(GQL services)'),
98 package: 'graphql-codegen-typescript-apollo-angular',
99 value: 'typescript-apollo-angular',
100 available: function (tags) {
101 var hasAngular = tags.includes(Tags.angular);
102 var noReact = !tags.includes(Tags.react);
103 return hasAngular && noReact;
104 }
105 },
106 {
107 name: "TypeScript React Apollo " + chalk_1.default.italic('(typed components and HOCs)'),
108 package: 'graphql-codegen-typescript-react-apollo',
109 value: 'typescript-react-apollo',
110 available: function (tags) {
111 var hasReact = tags.includes(Tags.react);
112 var noAngular = !tags.includes(Tags.angular);
113 return hasReact && noAngular;
114 }
115 },
116 {
117 name: "TypeScript MongoDB " + chalk_1.default.italic('(typed MongoDB objects)'),
118 package: 'graphql-codegen-typescript-mongodb',
119 value: 'typescript-mongodb',
120 available: function (tags) { return tags.includes(Tags.server); }
121 },
122 {
123 name: "TypeScript GraphQL files modules " + chalk_1.default.italic('(declarations for .graphql files)'),
124 package: 'graphql-codegen-graphql-files-modules',
125 value: 'typescript-graphql-files-modules',
126 available: function (tags) { return tags.includes(Tags.client); }
127 },
128 {
129 name: "Introspection Fragment Matcher " + chalk_1.default.italic('(for Apollo Client)'),
130 package: 'graphql-codegen-fragment-matcher',
131 value: 'fragment-matcher',
132 available: function (tags) { return tags.includes(Tags.client); }
133 }
134];
135function init() {
136 return __awaiter(this, void 0, void 0, function () {
137 function normalizeTargets(targets) {
138 return [].concat.apply([], targets);
139 }
140 var _a, possibleTargets, answers, config, relativePath;
141 return __generator(this, function (_b) {
142 switch (_b.label) {
143 case 0:
144 log("\n Welcome to " + chalk_1.default.bold('GraphQL Code Generator') + "!\n Answer few questions and we will setup everything for you.\n ");
145 return [4 /*yield*/, guessTargets()];
146 case 1:
147 possibleTargets = _b.sent();
148 return [4 /*yield*/, inquirer.prompt([
149 {
150 type: 'checkbox',
151 name: 'targets',
152 message: "What type of application are you building?",
153 choices: [
154 {
155 name: 'Backend - API or server',
156 key: 'backend',
157 value: [Tags.server],
158 checked: possibleTargets.Server
159 },
160 {
161 name: 'Application built with Angular',
162 key: 'angular',
163 value: [Tags.angular, Tags.client],
164 checked: possibleTargets.Angular
165 },
166 {
167 name: 'Application built with React',
168 key: 'react',
169 value: [Tags.react, Tags.client],
170 checked: possibleTargets.React
171 },
172 {
173 name: 'Application built with other framework or vanilla JS',
174 key: 'client',
175 value: [Tags.client],
176 checked: false
177 }
178 ]
179 },
180 {
181 type: 'input',
182 name: 'schema',
183 message: 'Where is your schema?:',
184 suffix: chalk_1.default.grey(' (path or url)'),
185 default: 'https://localhost:4000',
186 validate: function (str) { return str.length > 0; }
187 },
188 {
189 type: 'input',
190 name: 'documents',
191 message: 'Where are your operations and fragments?:',
192 when: function (answers) {
193 // flatten targets
194 // I can't find an API in Inquirer that would do that
195 answers.targets = normalizeTargets(answers.targets);
196 return answers.targets.includes(Tags.client);
197 },
198 default: '**/*.graphql',
199 validate: function (str) { return str.length > 0; }
200 },
201 {
202 type: 'checkbox',
203 name: 'plugins',
204 message: 'Pick plugins:',
205 choices: function (answers) {
206 return plugins
207 .filter(function (p) { return p.available(answers.targets); })
208 .map(function (p) {
209 return {
210 name: p.name,
211 value: p,
212 checked: p.value === 'typescript-common'
213 };
214 });
215 },
216 validate: function (plugins) { return plugins.length > 0; }
217 },
218 {
219 type: 'input',
220 name: 'output',
221 message: 'Where to write the output:',
222 default: 'src/generated/graphql.ts',
223 validate: function (str) { return str.length > 0; }
224 },
225 {
226 type: 'confirm',
227 name: 'introspection',
228 message: 'Do you want to generate an introspection file?'
229 },
230 {
231 type: 'input',
232 name: 'config',
233 message: 'How to name the config file?',
234 default: 'codegen.yml',
235 validate: function (str) {
236 var isNotEmpty = str.length > 0;
237 var hasCorrectExtension = ['json', 'yml', 'yaml'].some(function (ext) { return str.toLocaleLowerCase().endsWith("." + ext); });
238 return isNotEmpty && hasCorrectExtension;
239 }
240 },
241 {
242 type: 'input',
243 name: 'script',
244 message: 'What script in package.json should run the codegen?',
245 validate: function (str) { return str.length > 0; }
246 }
247 ])];
248 case 2:
249 answers = _b.sent();
250 config = {
251 overwrite: true,
252 schema: answers.schema,
253 documents: answers.targets.includes(Tags.client) ? answers.documents : null,
254 generates: (_a = {},
255 _a[answers.output] = {
256 plugins: answers.plugins.map(function (p) { return p.value; })
257 },
258 _a)
259 };
260 // introspection
261 if (answers.introspection) {
262 addIntrospection(config);
263 }
264 relativePath = writeConfig(answers, config).relativePath;
265 // write package.json
266 writePackage(answers, relativePath);
267 // Emit status to the terminal
268 log("\n Config file generated at " + chalk_1.default.bold(relativePath) + "\n \n " + chalk_1.default.bold('$ npm install') + "\n\n To install the plugins.\n\n " + chalk_1.default.bold("$ npm run " + answers.script) + "\n\n To run GraphQL Code Generator.\n ");
269 return [2 /*return*/];
270 }
271 });
272 });
273}
274exports.init = init;
275// adds an introspection to `generates`
276function addIntrospection(config) {
277 config.generates['./graphql.schema.json'] = {
278 plugins: ['introspection']
279 };
280}
281// Parses config and writes it to a file
282function writeConfig(answers, config) {
283 var ext = answers.config.toLocaleLowerCase().endsWith('.json') ? 'json' : 'yml';
284 var content = ext === 'json' ? JSON.stringify(config) : YAML.stringify(config);
285 var fullPath = path_1.resolve(process.cwd(), answers.config);
286 var relativePath = path_1.relative(process.cwd(), answers.config);
287 fs_1.writeFileSync(fullPath, content, {
288 encoding: 'utf-8'
289 });
290 return {
291 relativePath: relativePath,
292 fullPath: fullPath
293 };
294}
295// Updates package.json (script and plugins as dependencies)
296function writePackage(answers, configLocation) {
297 // script
298 var pkgPath = path_1.resolve(process.cwd(), 'package.json');
299 var pkgContent = fs_1.readFileSync(pkgPath, {
300 encoding: 'utf-8'
301 });
302 var pkg = JSON.parse(pkgContent);
303 var indent = detectIndent(pkgContent).indent;
304 if (!pkg.scripts) {
305 pkg.scripts = {};
306 }
307 pkg.scripts[answers.script] = "gql-gen --config " + configLocation;
308 // plugin
309 if (!pkg.devDependencies) {
310 pkg.devDependencies = {};
311 }
312 // read codegen's version
313 var version = JSON.parse(fs_1.readFileSync(path_1.resolve(__dirname, '../package.json'), {
314 encoding: 'utf-8'
315 })).version;
316 answers.plugins.forEach(function (plugin) {
317 pkg.devDependencies[plugin.package] = version;
318 });
319 fs_1.writeFileSync(pkgPath, JSON.stringify(pkg, null, indent));
320}
321function guessTargets() {
322 return __awaiter(this, void 0, void 0, function () {
323 var _a, pkg, dependencies;
324 return __generator(this, function (_b) {
325 pkg = JSON.parse(fs_1.readFileSync(path_1.resolve(process.cwd(), 'package.json'), {
326 encoding: 'utf-8'
327 }));
328 dependencies = Object.keys(__assign({}, pkg.dependencies, pkg.devDependencies));
329 return [2 /*return*/, (_a = {},
330 _a[Tags.angular] = isAngular(dependencies),
331 _a[Tags.react] = isReact(dependencies),
332 _a[Tags.client] = false,
333 _a[Tags.server] = false,
334 _a[Tags.typescript] = isTypescript(dependencies),
335 _a)];
336 });
337 });
338}
339function isAngular(dependencies) {
340 return dependencies.includes('@angular/core');
341}
342function isReact(dependencies) {
343 return dependencies.includes('react');
344}
345function isTypescript(dependencies) {
346 return dependencies.includes('typescript');
347}
348//# sourceMappingURL=init.js.map
\No newline at end of file