UNPKG

@graphql-inspector/coverage-command

Version:
159 lines (158 loc) • 6.35 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.handler = handler; const fs_1 = require("fs"); const path_1 = require("path"); const graphql_1 = require("graphql"); const commands_1 = require("@graphql-inspector/commands"); const core_1 = require("@graphql-inspector/core"); const logger_1 = require("@graphql-inspector/logger"); function handler({ schema, documents, silent, writePath, }) { const shouldWrite = typeof writePath !== 'undefined'; const coverage = (0, core_1.coverage)(schema, documents.map(doc => new graphql_1.Source((0, graphql_1.print)(doc.document), doc.location))); if (silent !== true) { renderCoverage(coverage); } if (shouldWrite) { if (typeof writePath !== 'string') { throw new Error(`--write is not valid file path: ${writePath}`); } const absPath = (0, commands_1.ensureAbsolute)(writePath); const ext = (0, path_1.extname)(absPath).replace('.', '').toLocaleLowerCase(); let output = undefined; if (ext === 'json') { output = outputJSON(coverage); } if (output) { (0, fs_1.writeFileSync)(absPath, output, 'utf8'); logger_1.Logger.success(`Available at ${absPath}\n`); } else { throw new Error(`Extension ${ext} is not supported`); } } } exports.default = (0, commands_1.createCommand)(api => { const { loaders } = api; return { command: 'coverage <documents> <schema>', describe: 'Schema coverage based on documents', builder(yargs) { return yargs .positional('schema', { describe: 'Point to a schema', type: 'string', demandOption: true, }) .positional('documents', { describe: 'Point to documents', type: 'string', demandOption: true, }) .options({ w: { alias: 'write', describe: 'Write a file with coverage stats', type: 'string', }, s: { alias: 'silent', describe: 'Do not render any stats in the terminal', type: 'boolean', }, }); }, async handler(args) { const writePath = args.write; const silent = args.silent; const { headers, token } = (0, commands_1.parseGlobalArgs)(args); const apolloFederation = args.federation || false; const aws = args.aws || false; const method = args.method?.toUpperCase() || 'POST'; const schema = await loaders.loadSchema(args.schema, { token, headers, method, }, apolloFederation, aws); const documents = await loaders.loadDocuments(args.documents); return handler({ schema, documents, silent, writePath }); }, }; }); function outputJSON(coverage) { return JSON.stringify(coverage, null, 2); } function renderCoverage(coverage) { logger_1.Logger.info('Schema coverage based on documents:\n'); for (const typeName in coverage.types) { if (Object.prototype.hasOwnProperty.call(coverage.types, typeName)) { const typeCoverage = coverage.types[typeName]; logger_1.Logger.log([ logger_1.chalk.grey((0, core_1.getTypePrefix)(typeCoverage.type)), logger_1.chalk.bold(String(typeName)), logger_1.chalk.grey('{'), ].join(' ')); for (const childName in typeCoverage.children) { if (Object.prototype.hasOwnProperty.call(typeCoverage.children, childName)) { const childCoverage = typeCoverage.children[childName]; if (childCoverage.hits) { logger_1.Logger.log([indent(childName, 2), logger_1.chalk.italic.grey(`x ${childCoverage.hits}`)].join(' ')); } else { logger_1.Logger.log([logger_1.chalk.redBright(indent(childName, 2)), logger_1.chalk.italic.grey('x 0')].join(' ')); } } } logger_1.Logger.log(logger_1.chalk.grey('}\n')); } } const logStatsResult = [ { method: 'Types covered', result: `${coverage.stats.numTypes > 0 ? ((coverage.stats.numTypesCovered / coverage.stats.numTypes) * 100).toFixed(1) : 'N/A'}%`, }, { method: 'Types covered fully', result: `${coverage.stats.numTypes > 0 ? ((coverage.stats.numTypesCoveredFully / coverage.stats.numTypes) * 100).toFixed(1) : 'N/A'}%`, }, { method: 'Fields covered', result: `${coverage.stats.numFields > 0 ? ((coverage.stats.numFiledsCovered / coverage.stats.numFields) * 100).toFixed(1) : 'N/A'}%`, }, { method: 'Total Queries', result: String(coverage.stats.numQueries > 0 ? coverage.stats.numQueries : '0'), }, { method: 'Covered Queries', result: String(coverage.stats.numCoveredQueries > 0 ? coverage.stats.numCoveredQueries : '0'), }, { method: 'Total Mutations', result: String(coverage.stats.numMutations > 0 ? coverage.stats.numMutations : '0'), }, { method: 'Covered Mutations', result: String(coverage.stats.numCoveredMutations > 0 ? coverage.stats.numCoveredMutations : '0'), }, { method: 'Total Subscriptions', result: String(coverage.stats.numSubscriptions > 0 ? coverage.stats.numSubscriptions : '0'), }, { method: 'Covered Subscriptions', result: String(coverage.stats.numCoveredSubscriptions > 0 ? coverage.stats.numCoveredSubscriptions : '0'), }, ]; logger_1.Logger.table(logStatsResult); logger_1.Logger.log(``); } function indent(line, space) { return line.padStart(line.length + space, ' '); }