tsplot
Version:
A CLI and tooling library to plot Typescript project information to different template targets.
165 lines • 9.27 kB
JavaScript
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
;