UNPKG

tsplot

Version:

A CLI and tooling library to plot Typescript project information to different template targets.

165 lines 9.27 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.output = exports.interpolateOutputPath = exports.getConfinedProjectViewFromMemberOrDefault = exports.getProjectView = exports.getTsConfigPath = exports.setupConsola = exports.setupSharedOptions = void 0; const tslib_1 = require("tslib"); const commander_1 = require("commander"); const consola_1 = require("consola"); const fs_extra_1 = require("fs-extra"); const os_1 = require("os"); const path_1 = require("path"); const process = require("process"); const lib_1 = require("../../lib"); const interpolation_1 = require("./interpolation"); /** @internal */ const MEMBER_TYPES = Object.values(lib_1.MemberKind); /** @internal */ const DEFAULT_DEPTH = 42; /** @internal */ function setupSharedOptions(command) { return (command .option('-p, --project <path>', 'path to the tsconfig.json file of the project', './tsconfig.json') .option('-o, --output <path>', 'path to the output file') .option('--from <members...>', 'the entry member to start the dependency resolution from') // todo: .option('--to <members...>', 'the exit members to stop resolving the dependency graph at') .option('--depth <depth>', 'the depth limit of the dependency resolution, when using the "from" option', (value) => parseInt(value, 10), DEFAULT_DEPTH) .option('--reverse', 'reverses the dependency graph resolution when using the "from" option to get dependents', false) .option('--split', 'splits the output into multiple files when using the "from" option') .option('--include <paths...>', 'file paths that shall be included in the view') .option('--exclude <paths...>', 'file paths that shall be included in the view') .addOption(new commander_1.Option('--includeKind <kinds...>', 'member kind that shall be included in the view').choices(Object.values(lib_1.MemberKind))) .addOption(new commander_1.Option('--excludeKind <kinds...>', 'member kind that shall be included in the view').choices(Object.values(lib_1.MemberKind))) .option('--includeDecoratedBy <decorators...>', 'decorators that shall be included in the view') .option('--excludeDecoratedBy <decorators...>', 'decorators that shall be included in the view') .option('--includeName <names...>', 'member name pattern that shall be included in the view') .option('--excludeName <names...>', 'member name pattern that shall be included in the view') .option('-d, --debug', 'output extra debugging logs') .option('-s, --silent', 'output nothing but the result') // <editor-fold desc="Deprecated"> .option('--includeNames <names...>', 'DEPRECATED! use --includeName instead') .option('--excludeNames <names...>', 'DEPRECATED! use --excludeName instead') .addOption(new commander_1.Option('--includeTypes <kinds...>', 'DEPRECATED! use --includeKind instead').choices(Object.values(lib_1.MemberKind))) .addOption(new commander_1.Option('--excludeTypes <kinds...>', 'DEPRECATED! use --excludeKind instead').choices(Object.values(lib_1.MemberKind))) // </editor-fold> ); } exports.setupSharedOptions = setupSharedOptions; /** * @internal * @returns A function that restores the original log level and options of consola */ function setupConsola(options) { const { level: consolaLogLevel, options: consolaOptions } = consola_1.consola; const restoreFn = () => { consola_1.consola.options = consolaOptions; consola_1.consola.level = consolaLogLevel; }; consola_1.consola.options.formatOptions.date = false; consola_1.consola.options.formatOptions.compact = true; if (options.debug) consola_1.consola.level = 4; if (options.silent) consola_1.consola.level = -999; return restoreFn; } exports.setupConsola = setupConsola; /** @internal */ function getTsConfigPath(options = commander_1.program.opts()) { return (0, path_1.resolve)(process.cwd(), options.project); } exports.getTsConfigPath = getTsConfigPath; /** @internal */ function getProjectView(options) { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s; const isRelevantSourceFile = (f) => { return !f.isDeclarationFile && !f.fileName.includes('node_modules'); }; const tsConfigPath = getTsConfigPath(options); const projectView = new lib_1.ProjectView({ tsConfigPath, paths: options === null || options === void 0 ? void 0 : options.paths, sourceFileFilter: [ isRelevantSourceFile, (0, lib_1.includeSourceFiles)(...((_a = options.include) !== null && _a !== void 0 ? _a : [])), (0, lib_1.excludeSourceFiles)(...((_b = options.exclude) !== null && _b !== void 0 ? _b : [])), ], memberFilter: [ (0, lib_1.includeMemberKindOf)(...((_d = (_c = options.includeKind) !== null && _c !== void 0 ? _c : options.includeTypes) !== null && _d !== void 0 ? _d : [])), (0, lib_1.excludeMemberKindOf)(...((_f = (_e = options.excludeKind) !== null && _e !== void 0 ? _e : options.excludeTypes) !== null && _f !== void 0 ? _f : [])), (0, lib_1.includeDecoratedBy)(...((_g = options.includeDecoratedBy) !== null && _g !== void 0 ? _g : [])), (0, lib_1.excludeDecoratedBy)(...((_h = options.excludeDecoratedBy) !== null && _h !== void 0 ? _h : [])), (0, lib_1.includeMemberName)(...((_k = (_j = options.includeName) !== null && _j !== void 0 ? _j : options.includeNames) !== null && _k !== void 0 ? _k : [])), (0, lib_1.excludeMemberName)(...((_m = (_l = options.excludeName) !== null && _l !== void 0 ? _l : options.excludeNames) !== null && _m !== void 0 ? _m : [])), ], }); const isPartialView = [ options.from, options.include, options.exclude, (_o = options.includeKind) !== null && _o !== void 0 ? _o : options.includeTypes, (_p = options.excludeKind) !== null && _p !== void 0 ? _p : options.excludeTypes, options.includeDecoratedBy, options.excludeDecoratedBy, (_q = options.includeName) !== null && _q !== void 0 ? _q : options.includeNames, (_r = options.excludeName) !== null && _r !== void 0 ? _r : options.excludeNames, ].some((arr) => arr === null || arr === void 0 ? void 0 : arr.length); if (isPartialView) consola_1.consola.info("note: you're generating a partial view of the project"); const isFromUnset = !((_s = options.from) === null || _s === void 0 ? void 0 : _s.length); if (isFromUnset && options.reverse) consola_1.consola.warn('the "reverse" option is ignored because the "from" option is not set'); if (isFromUnset && options.depth !== DEFAULT_DEPTH) consola_1.consola.warn('the "depth" option is ignored because the "from" option is not set'); if (isFromUnset && options.split) consola_1.consola.warn('the "split" option is ignored because the "from" option is not set'); return projectView; } exports.getProjectView = getProjectView; /** @internal */ function getConfinedProjectViewFromMemberOrDefault(projectView, options) { var _a; return tslib_1.__awaiter(this, void 0, void 0, function* () { const deferred = (_a = options === null || options === void 0 ? void 0 : options.from) === null || _a === void 0 ? void 0 : _a.map((f) => projectView.getMemberByName(f)).filter(Boolean).map((m) => { return !(options === null || options === void 0 ? void 0 : options.reverse) ? projectView.getDependencyMembers(m, options) : projectView.getDependentMembers(m, options); }); const members = deferred && (yield Promise.all(deferred)).flat(); if (!members) return projectView; return lib_1.ProjectView.withOverride({ oldView: projectView, members, }); }); } exports.getConfinedProjectViewFromMemberOrDefault = getConfinedProjectViewFromMemberOrDefault; /** * @internal * @experimental */ function interpolateOutputPath(output, values) { const { memberName } = values; if (!memberName) return output; return interpolation_1.INTERPOLATION_REGEX.test(output) ? (0, interpolation_1.interpolate)(output, values) : (0, interpolation_1.insertBeforeExtension)(output, memberName.toString()); } exports.interpolateOutputPath = interpolateOutputPath; /** @internal */ function output(data, options) { return tslib_1.__awaiter(this, void 0, void 0, function* () { if (options.output) { const outputPath = (0, path_1.resolve)(process.cwd(), options.output); consola_1.consola.info(`writing output to "${outputPath}"...`); if (!data) consola_1.consola.warn('It appears that the output is empty. Please make sure that the project ' + 'graph is not empty and that the diagram renderer is working as expected.'); yield (0, fs_extra_1.outputFile)(outputPath, data, 'utf-8'); } else { process.stdout.write(data + os_1.EOL); } }); } exports.output = output; //# sourceMappingURL=shared-options.js.map