UNPKG

16.6 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 var _a, possibleTargets, answers, config, relativePath;
138 return __generator(this, function (_b) {
139 switch (_b.label) {
140 case 0:
141 log("\n Welcome to " + chalk_1.default.bold('GraphQL Code Generator') + "!\n Answer few questions and we will setup everything for you.\n ");
142 return [4 /*yield*/, guessTargets()];
143 case 1:
144 possibleTargets = _b.sent();
145 return [4 /*yield*/, inquirer.prompt([
146 {
147 type: 'checkbox',
148 name: 'targets',
149 message: "What type of application are you building?",
150 choices: [
151 {
152 name: 'Backend - API or server',
153 key: 'backend',
154 value: [Tags.server],
155 checked: possibleTargets.Server
156 },
157 {
158 name: 'Application built with Angular',
159 key: 'angular',
160 value: [Tags.angular, Tags.client],
161 checked: possibleTargets.Angular
162 },
163 {
164 name: 'Application built with React',
165 key: 'react',
166 value: [Tags.react, Tags.client],
167 checked: possibleTargets.React
168 },
169 {
170 name: 'Application built with other framework or vanilla JS',
171 key: 'client',
172 value: [Tags.client],
173 checked: false
174 }
175 ]
176 },
177 {
178 type: 'input',
179 name: 'schema',
180 message: 'Where is your schema?:',
181 suffix: chalk_1.default.grey(' (path or url)'),
182 default: 'https://localhost:4000',
183 validate: function (str) { return str.length > 0; }
184 },
185 {
186 type: 'input',
187 name: 'documents',
188 message: 'Where are your operations and fragments?:',
189 when: function (answers) { return answers.targets.includes(Tags.client); },
190 default: '**/*.graphql',
191 validate: function (str) { return str.length > 0; }
192 },
193 {
194 type: 'checkbox',
195 name: 'plugins',
196 message: 'Pick plugins:',
197 choices: function (answers) {
198 // flatten targets
199 // I can't find an API in Inquirer that would do that
200 answers.targets = [].concat.apply([], answers.targets);
201 return plugins
202 .filter(function (p) { return p.available(answers.targets); })
203 .map(function (p) {
204 return {
205 name: p.name,
206 value: p,
207 checked: p.value === 'typescript-common'
208 };
209 });
210 },
211 validate: function (plugins) { return plugins.length > 0; }
212 },
213 {
214 type: 'input',
215 name: 'output',
216 message: 'Where to write the output:',
217 default: 'src/generated/graphql.ts',
218 validate: function (str) { return str.length > 0; }
219 },
220 {
221 type: 'confirm',
222 name: 'introspection',
223 message: 'Do you want to generate an introspection file?'
224 },
225 {
226 type: 'input',
227 name: 'config',
228 message: 'How to name the config file?',
229 default: 'codegen.yml',
230 validate: function (str) {
231 var isNotEmpty = str.length > 0;
232 var hasCorrectExtension = ['json', 'yml', 'yaml'].some(function (ext) { return str.toLocaleLowerCase().endsWith("." + ext); });
233 return isNotEmpty && hasCorrectExtension;
234 }
235 },
236 {
237 type: 'input',
238 name: 'script',
239 message: 'What script in package.json should run the codegen?',
240 validate: function (str) { return str.length > 0; }
241 }
242 ])];
243 case 2:
244 answers = _b.sent();
245 config = {
246 overwrite: true,
247 schema: answers.schema,
248 documents: answers.targets.includes(Tags.client) ? answers.documents : null,
249 generates: (_a = {},
250 _a[answers.output] = {
251 plugins: answers.plugins.map(function (p) { return p.value; })
252 },
253 _a)
254 };
255 // introspection
256 if (answers.introspection) {
257 addIntrospection(config);
258 }
259 relativePath = writeConfig(answers, config).relativePath;
260 // write package.json
261 writePackage(answers, relativePath);
262 // Emit status to the terminal
263 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 ");
264 return [2 /*return*/];
265 }
266 });
267 });
268}
269exports.init = init;
270// adds an introspection to `generates`
271function addIntrospection(config) {
272 config.generates['./graphql.schema.json'] = {
273 plugins: ['introspection']
274 };
275}
276// Parses config and writes it to a file
277function writeConfig(answers, config) {
278 var ext = answers.config.toLocaleLowerCase().endsWith('.json') ? 'json' : 'yml';
279 var content = ext === 'json' ? JSON.stringify(config) : YAML.stringify(config);
280 var fullPath = path_1.resolve(process.cwd(), answers.config);
281 var relativePath = path_1.relative(process.cwd(), answers.config);
282 fs_1.writeFileSync(fullPath, content, {
283 encoding: 'utf-8'
284 });
285 return {
286 relativePath: relativePath,
287 fullPath: fullPath
288 };
289}
290// Updates package.json (script and plugins as dependencies)
291function writePackage(answers, configLocation) {
292 // script
293 var pkgPath = path_1.resolve(process.cwd(), 'package.json');
294 var pkgContent = fs_1.readFileSync(pkgPath, {
295 encoding: 'utf-8'
296 });
297 var pkg = JSON.parse(pkgContent);
298 var indent = detectIndent(pkgContent).indent;
299 if (!pkg.scripts) {
300 pkg.scripts = {};
301 }
302 pkg.scripts[answers.script] = "gql-gen --config " + configLocation;
303 // plugin
304 if (!pkg.devDependencies) {
305 pkg.devDependencies = {};
306 }
307 // read codegen's version
308 var version = JSON.parse(fs_1.readFileSync(path_1.resolve(__dirname, '../package.json'), {
309 encoding: 'utf-8'
310 })).version;
311 answers.plugins.forEach(function (plugin) {
312 pkg.devDependencies[plugin.package] = version;
313 });
314 fs_1.writeFileSync(pkgPath, JSON.stringify(pkg, null, indent));
315}
316function guessTargets() {
317 return __awaiter(this, void 0, void 0, function () {
318 var _a, pkg, dependencies;
319 return __generator(this, function (_b) {
320 pkg = JSON.parse(fs_1.readFileSync(path_1.resolve(process.cwd(), 'package.json'), {
321 encoding: 'utf-8'
322 }));
323 dependencies = Object.keys(__assign({}, pkg.dependencies, pkg.devDependencies));
324 return [2 /*return*/, (_a = {},
325 _a[Tags.angular] = isAngular(dependencies),
326 _a[Tags.react] = isReact(dependencies),
327 _a[Tags.client] = false,
328 _a[Tags.server] = false,
329 _a[Tags.typescript] = isTypescript(dependencies),
330 _a)];
331 });
332 });
333}
334function isAngular(dependencies) {
335 return dependencies.includes('@angular/core');
336}
337function isReact(dependencies) {
338 return dependencies.includes('react');
339}
340function isTypescript(dependencies) {
341 return dependencies.includes('typescript');
342}
343//# sourceMappingURL=init.js.map
\No newline at end of file