UNPKG

graphql-code-generator

Version:

<p align="center"> <img src="https://github.com/dotansimha/graphql-code-generator/blob/master/logo.png?raw=true" /> </p>

348 lines • 16.8 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { 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; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; Object.defineProperty(exports, "__esModule", { value: true }); var inquirer = require("inquirer"); var chalk_1 = require("chalk"); var path_1 = require("path"); var fs_1 = require("fs"); var YAML = require("json-to-pretty-yaml"); var detectIndent = require("detect-indent"); var Tags; (function (Tags) { Tags["client"] = "Client"; Tags["server"] = "Server"; Tags["typescript"] = "TypeScript"; Tags["angular"] = "Angular"; Tags["react"] = "React"; })(Tags || (Tags = {})); function log() { var msgs = []; for (var _i = 0; _i < arguments.length; _i++) { msgs[_i] = arguments[_i]; } // tslint:disable-next-line console.log.apply(console, msgs); } var plugins = [ { name: "TypeScript Common " + chalk_1.default.italic('(required by client and server plugins)'), package: 'graphql-codegen-typescript-common', value: 'typescript-common', available: function () { return true; } }, { name: "TypeScript Client " + chalk_1.default.italic('(operations and fragments)'), package: 'graphql-codegen-typescript-client', value: 'typescript-client', available: function (tags) { return tags.some(function (tag) { return [Tags.client].includes(tag); }); } }, { name: "TypeScript Server " + chalk_1.default.italic('(GraphQL Schema)'), package: 'graphql-codegen-typescript-server', value: 'typescript-server', available: function (tags) { return tags.some(function (tag) { return [Tags.client, Tags.server].includes(tag); }); } }, { name: "TypeScript Resolvers " + chalk_1.default.italic('(strongly typed resolve functions)'), package: 'graphql-codegen-typescript-resolvers', value: 'typescript-resolvers', available: function (tags) { return tags.some(function (tag) { return [Tags.server].includes(tag); }); } }, { name: "TypeScript Apollo Angular " + chalk_1.default.italic('(GQL services)'), package: 'graphql-codegen-typescript-apollo-angular', value: 'typescript-apollo-angular', available: function (tags) { var hasAngular = tags.includes(Tags.angular); var noReact = !tags.includes(Tags.react); return hasAngular && noReact; } }, { name: "TypeScript React Apollo " + chalk_1.default.italic('(typed components and HOCs)'), package: 'graphql-codegen-typescript-react-apollo', value: 'typescript-react-apollo', available: function (tags) { var hasReact = tags.includes(Tags.react); var noAngular = !tags.includes(Tags.angular); return hasReact && noAngular; } }, { name: "TypeScript MongoDB " + chalk_1.default.italic('(typed MongoDB objects)'), package: 'graphql-codegen-typescript-mongodb', value: 'typescript-mongodb', available: function (tags) { return tags.includes(Tags.server); } }, { name: "TypeScript GraphQL files modules " + chalk_1.default.italic('(declarations for .graphql files)'), package: 'graphql-codegen-typescript-graphql-files-modules', value: 'typescript-graphql-files-modules', available: function (tags) { return tags.includes(Tags.client); } }, { name: "Introspection Fragment Matcher " + chalk_1.default.italic('(for Apollo Client)'), package: 'graphql-codegen-fragment-matcher', value: 'fragment-matcher', available: function (tags) { return tags.includes(Tags.client); } } ]; function init() { return __awaiter(this, void 0, void 0, function () { function normalizeTargets(targets) { return [].concat.apply([], targets); } var _a, possibleTargets, answers, config, relativePath; return __generator(this, function (_b) { switch (_b.label) { case 0: log("\n Welcome to " + chalk_1.default.bold('GraphQL Code Generator') + "!\n Answer few questions and we will setup everything for you.\n "); return [4 /*yield*/, guessTargets()]; case 1: possibleTargets = _b.sent(); return [4 /*yield*/, inquirer.prompt([ { type: 'checkbox', name: 'targets', message: "What type of application are you building?", choices: [ { name: 'Backend - API or server', key: 'backend', value: [Tags.server], checked: possibleTargets.Server }, { name: 'Application built with Angular', key: 'angular', value: [Tags.angular, Tags.client], checked: possibleTargets.Angular }, { name: 'Application built with React', key: 'react', value: [Tags.react, Tags.client], checked: possibleTargets.React }, { name: 'Application built with other framework or vanilla JS', key: 'client', value: [Tags.client], checked: false } ] }, { type: 'input', name: 'schema', message: 'Where is your schema?:', suffix: chalk_1.default.grey(' (path or url)'), default: 'https://localhost:4000', validate: function (str) { return str.length > 0; } }, { type: 'input', name: 'documents', message: 'Where are your operations and fragments?:', when: function (answers) { // flatten targets // I can't find an API in Inquirer that would do that answers.targets = normalizeTargets(answers.targets); return answers.targets.includes(Tags.client); }, default: '**/*.graphql', validate: function (str) { return str.length > 0; } }, { type: 'checkbox', name: 'plugins', message: 'Pick plugins:', choices: function (answers) { return plugins .filter(function (p) { return p.available(answers.targets); }) .map(function (p) { return { name: p.name, value: p, checked: p.value === 'typescript-common' }; }); }, validate: function (plugins) { return plugins.length > 0; } }, { type: 'input', name: 'output', message: 'Where to write the output:', default: 'src/generated/graphql.ts', validate: function (str) { return str.length > 0; } }, { type: 'confirm', name: 'introspection', message: 'Do you want to generate an introspection file?' }, { type: 'input', name: 'config', message: 'How to name the config file?', default: 'codegen.yml', validate: function (str) { var isNotEmpty = str.length > 0; var hasCorrectExtension = ['json', 'yml', 'yaml'].some(function (ext) { return str.toLocaleLowerCase().endsWith("." + ext); }); return isNotEmpty && hasCorrectExtension; } }, { type: 'input', name: 'script', message: 'What script in package.json should run the codegen?', validate: function (str) { return str.length > 0; } } ])]; case 2: answers = _b.sent(); config = { overwrite: true, schema: answers.schema, documents: answers.targets.includes(Tags.client) ? answers.documents : null, generates: (_a = {}, _a[answers.output] = { plugins: answers.plugins.map(function (p) { return p.value; }) }, _a) }; // introspection if (answers.introspection) { addIntrospection(config); } relativePath = writeConfig(answers, config).relativePath; // write package.json writePackage(answers, relativePath); // Emit status to the terminal 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 "); return [2 /*return*/]; } }); }); } exports.init = init; // adds an introspection to `generates` function addIntrospection(config) { config.generates['./graphql.schema.json'] = { plugins: ['introspection'] }; } // Parses config and writes it to a file function writeConfig(answers, config) { var ext = answers.config.toLocaleLowerCase().endsWith('.json') ? 'json' : 'yml'; var content = ext === 'json' ? JSON.stringify(config) : YAML.stringify(config); var fullPath = path_1.resolve(process.cwd(), answers.config); var relativePath = path_1.relative(process.cwd(), answers.config); fs_1.writeFileSync(fullPath, content, { encoding: 'utf-8' }); return { relativePath: relativePath, fullPath: fullPath }; } // Updates package.json (script and plugins as dependencies) function writePackage(answers, configLocation) { // script var pkgPath = path_1.resolve(process.cwd(), 'package.json'); var pkgContent = fs_1.readFileSync(pkgPath, { encoding: 'utf-8' }); var pkg = JSON.parse(pkgContent); var indent = detectIndent(pkgContent).indent; if (!pkg.scripts) { pkg.scripts = {}; } pkg.scripts[answers.script] = "gql-gen --config " + configLocation; // plugin if (!pkg.devDependencies) { pkg.devDependencies = {}; } // read codegen's version var version = JSON.parse(fs_1.readFileSync(path_1.resolve(__dirname, '../package.json'), { encoding: 'utf-8' })).version; answers.plugins.forEach(function (plugin) { pkg.devDependencies[plugin.package] = version; }); fs_1.writeFileSync(pkgPath, JSON.stringify(pkg, null, indent)); } function guessTargets() { return __awaiter(this, void 0, void 0, function () { var _a, pkg, dependencies; return __generator(this, function (_b) { pkg = JSON.parse(fs_1.readFileSync(path_1.resolve(process.cwd(), 'package.json'), { encoding: 'utf-8' })); dependencies = Object.keys(__assign({}, pkg.dependencies, pkg.devDependencies)); return [2 /*return*/, (_a = {}, _a[Tags.angular] = isAngular(dependencies), _a[Tags.react] = isReact(dependencies), _a[Tags.client] = false, _a[Tags.server] = false, _a[Tags.typescript] = isTypescript(dependencies), _a)]; }); }); } function isAngular(dependencies) { return dependencies.includes('@angular/core'); } function isReact(dependencies) { return dependencies.includes('react'); } function isTypescript(dependencies) { return dependencies.includes('typescript'); } //# sourceMappingURL=init.js.map