@decaf-ts/utils
Version:
module management utils for decaf-ts
140 lines • 5.37 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Command = void 0;
const input_1 = require("./../input/input.cjs");
const constants_1 = require("./constants.cjs");
const fs_1 = require("./../utils/fs.cjs");
const common_1 = require("./../output/common.cjs");
const logging_1 = require("@decaf-ts/logging");
/**
* @class Command
* @abstract
* @template I - The type of input options for the command.
* @template R - The return type of the command execution.
* @memberOf module:utils
* @description Abstract base class for command implementation.
* @summary Provides a structure for creating command-line interface commands with input handling, logging, and execution flow.
*
* @param {string} name - The name of the command.
* @param {CommandOptions<I>} [inputs] - The input options for the command.
* @param {string[]} [requirements] - The list of required dependencies for the command.
*/
class Command extends logging_1.LoggedClass {
constructor(name, inputs = {}, requirements = []) {
super();
this.name = name;
this.inputs = inputs;
this.requirements = requirements;
if (!Command.log) {
Object.defineProperty(Command, "log", {
writable: false,
value: logging_1.Logging.for(Command.name),
});
}
this.inputs = Object.assign({}, constants_1.DefaultCommandOptions, inputs);
}
/**
* @protected
* @async
* @description Checks if all required dependencies are present.
* @summary Retrieves the list of dependencies and compares it against the required dependencies for the command.
* @returns {Promise<void>} A promise that resolves when the check is complete.
*
* @mermaid
* sequenceDiagram
* participant Command
* participant getDependencies
* participant Set
* Command->>getDependencies: Call
* getDependencies-->>Command: Return {prod, dev, peer}
* Command->>Set: Create Set from prod, dev, peer
* Set-->>Command: Return unique dependencies
* Command->>Command: Compare against requirements
* alt Missing dependencies
* Command->>Command: Add to missing list
* end
* Note over Command: If missing.length > 0, handle missing dependencies
*/
async checkRequirements() {
const { prod, dev, peer } = await (0, fs_1.getDependencies)();
const missing = [];
const fullList = Array.from(new Set([...prod, ...dev, ...peer]).values()).map((d) => d.name);
for (const dep of this.requirements)
if (!fullList.includes(dep))
missing.push(dep);
if (!missing.length)
return;
}
/**
* @protected
* @description Provides help information for the command.
* @summary This method should be overridden in derived classes to provide specific help information.
* @param {ParseArgsResult} args - The parsed command-line arguments.
* @returns {void}
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
help(args) {
return this.log.info(`This is help. I'm no use because I should have been overridden.`);
}
/**
* @async
* @description Executes the command.
* @summary This method handles the overall execution flow of the command, including parsing arguments,
* setting up logging, checking for version or help requests, and running the command.
* @returns {Promise<R | string | void>} A promise that resolves with the command's result.
*
* @mermaid
* sequenceDiagram
* participant Command
* participant UserInput
* participant Logging
* participant getPackageVersion
* participant printBanner
* Command->>UserInput: parseArgs(inputs)
* UserInput-->>Command: Return ParseArgsResult
* Command->>Command: Process options
* Command->>Logging: setConfig(options)
* alt version requested
* Command->>getPackageVersion: Call
* getPackageVersion-->>Command: Return version
* else help requested
* Command->>Command: help(args)
* else banner requested
* Command->>printBanner: Call
* end
* Command->>Command: run(args)
* alt error occurs
* Command->>Command: Log error
* end
* Command-->>Command: Return result
*/
async execute() {
const args = input_1.UserInput.parseArgs(this.inputs);
const env = logging_1.LoggedEnvironment.accumulate(constants_1.DefaultCommandValues).accumulate(args.values);
const { version, help, banner } = env;
if (version) {
return (0, fs_1.getPackageVersion)();
}
if (help) {
return this.help(args);
}
if (banner)
(0, common_1.printBanner)(this.log.for(common_1.printBanner, {
timestamp: false,
style: false,
context: false,
logLevel: false,
}));
let result;
// eslint-disable-next-line no-useless-catch
try {
result = await this.run(env);
}
catch (e) {
throw e;
}
return result;
}
}
exports.Command = Command;
//# sourceMappingURL=command.js.map