UNPKG

graphqldoc

Version:
189 lines (188 loc) 10.4 kB
"use strict"; 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()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const path = require("path"); const fs = require("fs"); const glob = require("glob"); const deepmerge = require("deepmerge"); const mustache_1 = require("mustache"); const utility_1 = require("./utility"); const fs_1 = require("./utility/fs"); const schema_loader_1 = require("./schema-loader"); const command_1 = require("@2fd/command"); const graphqldocPackageJson = require(path.resolve(__dirname, '../package.json')); class GraphQLDocumentor extends command_1.Command { constructor() { super(...arguments); this.description = graphqldocPackageJson.description + ' v' + graphqldocPackageJson.version; this.params = new command_1.NoParams(); this.flags = [ new command_1.ValueFlag('configFile', ['-c', '--config'], 'Configuration file [./package.json].', String, './package.json'), new command_1.ValueFlag('endpoint', ['-e', '--endpoint'], 'Graphql http endpoint ["https://domain.com/graphql"].'), new command_1.ListValueFlag('headers', ['-x', '--header'], 'HTTP header for request (use with --endpoint). ["Authorization: Token cb8795e7"].'), new command_1.ListValueFlag('queries', ['-q', '--query'], 'HTTP querystring for request (use with --endpoint) ["token=cb8795e7"].'), new command_1.ValueFlag('schemaFile', ['-s', '--schema', '--schema-file'], 'Graphql Schema file ["./schema.json"].'), new command_1.ListValueFlag('plugins', ['-p', '--plugin'], 'Use plugins [default=graphqldoc/plugins/default].'), new command_1.ValueFlag('template', ['-t', '--template'], 'Use template [default=graphqldoc/template/slds].'), new command_1.ValueFlag('output', ['-o', '--output'], 'Output directory.'), new command_1.ValueFlag('data', ['-d', '--data'], 'Inject custom data.', JSON.parse, {}), new command_1.ValueFlag('baseUrl', ['-b', '--base-url'], 'Base url for templates.'), new command_1.BooleanFlag('force', ['-f', '--force'], 'Delete outputDirectory if exists.'), new command_1.BooleanFlag('verbose', ['-v', '--verbose'], 'Output more information.'), new command_1.BooleanFlag('version', ['-V', '--version'], 'Show graphqldoc version.'), ]; } action(input, out) { return __awaiter(this, void 0, void 0, function* () { const output = new utility_1.Output(out, input.flags); try { if (input.flags.version) return output.out.log('graphqldoc v%s', graphqldocPackageJson.version); // Load project info const projectPackageJSON = yield this.getProjectPackage(input); // Load Schema const schema = yield this.getSchema(projectPackageJSON); // Load plugins const plugins = this.getPluginInstances(projectPackageJSON.graphqldoc.plugins, schema, projectPackageJSON, graphqldocPackageJson); projectPackageJSON.graphqldoc.plugins .forEach(plugin => output.info('use plugin', plugin)); // Collect assets const assets = yield utility_1.Plugin.collectAssets(plugins); assets .forEach(asset => output.info('use asset', path.relative(process.cwd(), asset))); // Ensure Output directory output.info('output directory', path.relative(process.cwd(), projectPackageJSON.graphqldoc.output)); yield this.ensureOutputDirectory(projectPackageJSON.graphqldoc.output, projectPackageJSON.graphqldoc.force); // Create Output directory yield fs_1.createBuildDirectory(projectPackageJSON.graphqldoc.output, projectPackageJSON.graphqldoc.template, assets); // Collect partials const partials = yield this.getTemplatePartials(projectPackageJSON.graphqldoc.template); // Render index.html output.info('render', 'index'); yield this.renderFile(projectPackageJSON, partials, plugins); // Render types const renderTypes = [] .concat(schema.types || []) .concat(schema.directives || []) .map((type) => { output.info('render', type.name); return this.renderFile(projectPackageJSON, partials, plugins, type); }); const files = yield Promise.all(renderTypes); output.ok('complete', String(files.length + 1 /* index.html */) + ' files generated.'); } catch (err) { output.error(err); } }); } ensureOutputDirectory(dir, force) { return __awaiter(this, void 0, void 0, function* () { try { const stats = fs.statSync(dir); if (!stats.isDirectory()) return Promise.reject(new Error('Unexpected output: ' + dir + ' is not a directory.')); if (!force) return Promise.reject(new Error(dir + ' already exists (delete it or use the --force flag)')); return fs_1.removeBuildDirectory(dir); } catch (err) { return err.code === 'ENOENT' ? Promise.resolve() : Promise.reject(err); } }); } getProjectPackage(input) { let packageJSON; try { packageJSON = require(path.resolve(input.flags.configFile)); } catch (err) { packageJSON = {}; } packageJSON.graphqldoc = deepmerge(input.flags, packageJSON.graphqldoc || {}); if (packageJSON.graphqldoc.data) { const data = packageJSON.graphqldoc.data; packageJSON.graphqldoc = deepmerge(data, packageJSON.graphqldoc); } if (packageJSON.graphqldoc.plugins.length === 0) packageJSON.graphqldoc.plugins = ['graphqldoc/plugins/default']; packageJSON.graphqldoc.baseUrl = packageJSON.graphqldoc.baseUrl || './'; packageJSON.graphqldoc.template = fs_1.resolve(packageJSON.graphqldoc.template || 'graphqldoc/template/slds'); packageJSON.graphqldoc.output = path.resolve(packageJSON.graphqldoc.output); packageJSON.graphqldoc.version = graphqldocPackageJson.version; if (!packageJSON.graphqldoc.output) return Promise.reject(new Error('Flag output (-o, --output) is required')); return Promise.resolve(packageJSON); } getPluginInstances(paths, schema, projectPackageJSON, graphqldocPackageJson) { return paths .map(path => { const absolutePaths = fs_1.resolve(path); const Plugin = require(absolutePaths).default; return typeof Plugin === 'function' ? // plugins as contructor new Plugin(schema, projectPackageJSON, graphqldocPackageJson) : // plugins plain object Plugin; }); } getTemplatePartials(templateDir) { return __awaiter(this, void 0, void 0, function* () { const files = yield new Promise((resolve, reject) => glob('**/*.mustache', { cwd: templateDir }, (err, files) => err ? reject(err) : resolve(files))); const partials = {}; yield Promise.all(files.map(file => { const name = path.basename(file, '.mustache'); return fs_1.readFile(path.resolve(templateDir, file), 'utf8') .then(content => partials[name] = content); })); if (!partials.index) throw new Error('The index partial is missing (file ' + path.resolve(templateDir, 'index.mustache') + ' not found).'); return partials; }); } getSchema(projectPackage) { return __awaiter(this, void 0, void 0, function* () { if (projectPackage.graphqldoc.schemaFile) { const schemaFileExt = path.extname(projectPackage.graphqldoc.schemaFile); switch (schemaFileExt) { case '.json': return schema_loader_1.jsonSchemaLoader(projectPackage.graphqldoc); case '.gql': case '.gqls': case '.graphqls': case '.graphql': return schema_loader_1.idlSchemaLoader(projectPackage.graphqldoc); case '.js': return schema_loader_1.jsSchemaLoader(projectPackage.graphqldoc); default: return Promise.reject(new Error('Unexpected schema extension name: ' + schemaFileExt)); } } else if (projectPackage.graphqldoc.endpoint) { return schema_loader_1.httpSchemaLoader(projectPackage.graphqldoc); } else { return Promise.reject(new Error('Endpoint (--endpoint, -e) or Schema File (--schema, -s) are require.')); } }); } renderFile(projectPackageJSON, partials, plugins, type) { return __awaiter(this, void 0, void 0, function* () { const templateData = yield utility_1.createData(projectPackageJSON, graphqldocPackageJson, plugins, type); const file = type ? utility_1.getFilenameOf(type) : 'index.html'; const filepath = path.resolve(projectPackageJSON.graphqldoc.output, file); return yield fs_1.writeFile(filepath, mustache_1.render(partials.index, templateData, partials)); }); } } exports.GraphQLDocumentor = GraphQLDocumentor;