@decaf-ts/fabric-weaver
Version:
template for ts projects
111 lines • 13.5 kB
JavaScript
import { Command } from "commander";
import { VERSION } from "../../index";
import { Logging } from "@decaf-ts/logging";
import { addFabricToPath } from "../../utils-old/path";
import { EnvVars } from "../constants/env-vars";
import { printBanner, printBorder } from "../../utils-old/banner";
import fs from "fs";
import path from "path";
import { safeParseInt } from "../../utils/parsers";
/**
* @class BaseCLI
* @description Base class for creating command-line interfaces using Commander
* @summary This class provides a foundation for building CLIs in the Fabric Weaver project.
* It sets up a Commander program with basic configuration and logging.
*
* @example
* class MyCLI extends BaseCLI {
* constructor() {
* super("my-cli", "My CLI description");
* this.setupCommands();
* }
*
* private setupCommands() {
* this.program
* .command("hello")
* .description("Say hello")
* .action(() => console.log("Hello, world!"));
* }
* }
*
* const cli = new MyCLI();
* cli.run();
*/
export class BaseCLI {
/**
* @constructor
* @param {string} name - The name of the CLI program
* @param {string} description - A brief description of the CLI program
*/
constructor(name, description) {
this.program = new Command();
this.log = Logging.for(this.constructor.name);
this.program
.name(name)
.description(description)
.version(VERSION)
.option("-s, --skip-banner", "Suppress the Fabric Weaver banner")
.option("-l, --limiter", "Supress the line after the command output")
.hook("preAction", (cmd) => {
const skipBanner = cmd.opts().skipBanner === true;
const skipLimiter = cmd.opts().limiter === true;
printBanner(skipBanner);
this.log.debug(`Skip banner: ${skipBanner}`);
this.log.debug(`Skip Limiter: ${skipLimiter}`);
this.log.debug(`Starting ${this.program.name()} v${VERSION}`);
addFabricToPath(process.env[EnvVars.FABRIC_BIN_FOLDER]);
})
.hook("postAction", (cmd) => {
const skipLimiter = cmd.opts().limiter === true;
printBorder(skipLimiter);
});
this.sleep();
this.copy();
}
sleep() {
this.program
.command("sleep")
.option("--time <number>", "sleep time in seconds", safeParseInt)
.action(async () => {
const time = this.program.opts().time || 120;
const ms = time * 1000;
await new Promise((resolve) => setTimeout(resolve, ms));
});
}
copy() {
this.program
.command("copy")
.description("Copy a file from origin to destination")
.requiredOption("--origin <string>", "Origin file path")
.requiredOption("--dest <string>", "Destination file path")
.action(async (options) => {
try {
const { origin, dest } = options;
// Check if the origin file exists
if (!fs.existsSync(origin)) {
this.log.error(`Origin file does not exist: ${origin}`);
return;
}
// Ensure the destination directory exists
const destDir = path.dirname(dest);
if (!fs.existsSync(destDir)) {
fs.mkdirSync(destDir, { recursive: true });
}
// Copy the file
fs.copyFileSync(origin, dest);
this.log.info(`File copied successfully from ${origin} to ${dest}`);
}
catch (error) {
this.log.error(`Error copying file: ${error.message}`);
}
});
}
/**
* @method run
* @description Parses the command-line arguments and executes the appropriate command
*/
run() {
this.program.parse(process.argv);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS1jbGkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29yZS9jbGkvYmFzZS1jbGkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNwQyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3RDLE9BQU8sRUFBVSxPQUFPLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDdkQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ2hELE9BQU8sRUFBRSxXQUFXLEVBQUUsV0FBVyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDbEUsT0FBTyxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBQ3BCLE9BQU8sSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUN4QixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFbkQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBdUJHO0FBQ0gsTUFBTSxPQUFnQixPQUFPO0lBSTNCOzs7O09BSUc7SUFDSCxZQUFZLElBQVksRUFBRSxXQUFtQjtRQUMzQyxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7UUFDN0IsSUFBSSxDQUFDLEdBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFOUMsSUFBSSxDQUFDLE9BQU87YUFDVCxJQUFJLENBQUMsSUFBSSxDQUFDO2FBQ1YsV0FBVyxDQUFDLFdBQVcsQ0FBQzthQUN4QixPQUFPLENBQUMsT0FBTyxDQUFDO2FBQ2hCLE1BQU0sQ0FBQyxtQkFBbUIsRUFBRSxtQ0FBbUMsQ0FBQzthQUNoRSxNQUFNLENBQUMsZUFBZSxFQUFFLDJDQUEyQyxDQUFDO2FBQ3BFLElBQUks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LElBQUksQ0FBQyxDQUFDO2dCQUU5QixJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxpQ0FBaUMsTUFBTSxPQUFPLElBQUksRUFBRSxDQUFDLENBQUM7WUFDdEUsQ0FBQztZQUFDLE9BQU8sS0FBYyxFQUFFLENBQUM7Z0JBQ3hCLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLHVCQUF3QixLQUFlLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUNwRSxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ksR0FBRztRQUNSLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNuQyxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21tYW5kIH0gZnJvbSBcImNvbW1hbmRlclwiO1xuaW1wb3J0IHsgVkVSU0lPTiB9IGZyb20gXCIuLi8uLi9pbmRleFwiO1xuaW1wb3J0IHsgTG9nZ2VyLCBMb2dnaW5nIH0gZnJvbSBcIkBkZWNhZi10cy9sb2dnaW5nXCI7XG5pbXBvcnQgeyBhZGRGYWJyaWNUb1BhdGggfSBmcm9tIFwiLi4vLi4vdXRpbHMtb2xkL3BhdGhcIjtcbmltcG9ydCB7IEVudlZhcnMgfSBmcm9tIFwiLi4vY29uc3RhbnRzL2Vudi12YXJzXCI7XG5pbXBvcnQgeyBwcmludEJhbm5lciwgcHJpbnRCb3JkZXIgfSBmcm9tIFwiLi4vLi4vdXRpbHMtb2xkL2Jhbm5lclwiO1xuaW1wb3J0IGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCB7IHNhZmVQYXJzZUludCB9IGZyb20gXCIuLi8uLi91dGlscy9wYXJzZXJzXCI7XG5cbi8qKlxuICogQGNsYXNzIEJhc2VDTElcbiAqIEBkZXNjcmlwdGlvbiBCYXNlIGNsYXNzIGZvciBjcmVhdGluZyBjb21tYW5kLWxpbmUgaW50ZXJmYWNlcyB1c2luZyBDb21tYW5kZXJcbiAqIEBzdW1tYXJ5IFRoaXMgY2xhc3MgcHJvdmlkZXMgYSBmb3VuZGF0aW9uIGZvciBidWlsZGluZyBDTElzIGluIHRoZSBGYWJyaWMgV2VhdmVyIHByb2plY3QuXG4gKiBJdCBzZXRzIHVwIGEgQ29tbWFuZGVyIHByb2dyYW0gd2l0aCBiYXNpYyBjb25maWd1cmF0aW9uIGFuZCBsb2dnaW5nLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjbGFzcyBNeUNMSSBleHRlbmRzIEJhc2VDTEkge1xuICogICBjb25zdHJ1Y3RvcigpIHtcbiAqICAgICBzdXBlcihcIm15LWNsaVwiLCBcIk15IENMSSBkZXNjcmlwdGlvblwiKTtcbiAqICAgICB0aGlzLnNldHVwQ29tbWFuZHMoKTtcbiAqICAgfVxuICpcbiAqICAgcHJpdmF0ZSBzZXR1cENvbW1hbmRzKCkge1xuICogICAgIHRoaXMucHJvZ3JhbVxuICogICAgICAgLmNvbW1hbmQoXCJoZWxsb1wiKVxuICogICAgICAgLmRlc2NyaXB0aW9uKFwiU2F5IGhlbGxvXCIpXG4gKiAgICAgICAuYWN0aW9uKCgpID0+IGNvbnNvbGUubG9nKFwiSGVsbG8sIHdvcmxkIVwiKSk7XG4gKiAgIH1cbiAqIH1cbiAqXG4gKiBjb25zdCBjbGkgPSBuZXcgTXlDTEkoKTtcbiAqIGNsaS5ydW4oKTtcbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEJhc2VDTEkge1xuICBwcm90ZWN0ZWQgcHJvZ3JhbTogQ29tbWFuZDtcbiAgcHJvdGVjdGVkIGxvZzogTG9nZ2VyO1xuXG4gIC8qKlxuICAgKiBAY29uc3RydWN0b3JcbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgQ0xJIHByb2dyYW1cbiAgICogQHBhcmFtIHtzdHJpbmd9IGRlc2NyaXB0aW9uIC0gQSBicmllZiBkZXNjcmlwdGlvbiBvZiB0aGUgQ0xJIHByb2dyYW1cbiAgICovXG4gIGNvbnN0cnVjdG9yKG5hbWU6IHN0cmluZywgZGVzY3JpcHRpb246IHN0cmluZykge1xuICAgIHRoaXMucHJvZ3JhbSA9IG5ldyBDb21tYW5kKCk7XG4gICAgdGhpcy5sb2cgPSBMb2dnaW5nLmZvcih0aGlzLmNvbnN0cnVjdG9yLm5hbWUpO1xuXG4gICAgdGhpcy5wcm9ncmFtXG4gICAgICAubmFtZShuYW1lKVxuICAgICAgLmRlc2NyaXB0aW9uKGRlc2NyaXB0aW9uKVxuICAgICAgLnZlcnNpb24oVkVSU0lPTilcbiAgICAgIC5vcHRpb24oXCItcywgLS1za2lwLWJhbm5lclwiLCBcIlN1cHByZXNzIHRoZSBGYWJyaWMgV2VhdmVyIGJhbm5lclwiKVxuICAgICAgLm9wdGlvbihcIi1sLCAtLWxpbWl0ZXJcIiwgXCJTdXByZXNzIHRoZSBsaW5lIGFmdGVyIHRoZSBjb21tYW5kIG91dHB1dFwiKVxuICAgICAgLmhvb2soXCJwcmVBY3Rpb25cIiwgKGNtZCkgPT4ge1xuICAgICAgICBjb25zdCBza2lwQmFubmVyID0gY21kLm9wdHMoKS5za2lwQmFubmVyID09PSB0cnVlO1xuICAgICAgICBjb25zdCBza2lwTGltaXRlciA9IGNtZC5vcHRzKCkubGltaXRlciA9PT0gdHJ1ZTtcbiAgICAgICAgcHJpbnRCYW5uZXIoc2tpcEJhbm5lcik7XG4gICAgICAgIHRoaXMubG9nLmRlYnVnKGBTa2lwIGJhbm5lcjogJHtza2lwQmFubmVyfWApO1xuICAgICAgICB0aGlzLmxvZy5kZWJ1ZyhgU2tpcCBMaW1pdGVyOiAke3NraXBMaW1pdGVyfWApO1xuICAgICAgICB0aGlzLmxvZy5kZWJ1ZyhgU3RhcnRpbmcgJHt0aGlzLnByb2dyYW0ubmFtZSgpfSB2JHtWRVJTSU9OfWApO1xuICAgICAgICBhZGRGYWJyaWNUb1BhdGgocHJvY2Vzcy5lbnZbRW52VmFycy5GQUJSSUNfQklOX0ZPTERFUl0pO1xuICAgICAgfSlcbiAgICAgIC5ob29rKFwicG9zdEFjdGlvblwiLCAoY21kKSA9PiB7XG4gICAgICAgIGNvbnN0IHNraXBMaW1pdGVyID0gY21kLm9wdHMoKS5saW1pdGVyID09PSB0cnVlO1xuICAgICAgICBwcmludEJvcmRlcihza2lwTGltaXRlcik7XG4gICAgICB9KTtcblxuICAgIHRoaXMuc2xlZXAoKTtcbiAgICB0aGlzLmNvcHkoKTtcbiAgfVxuXG4gIHByaXZhdGUgc2xlZXAoKSB7XG4gICAgdGhpcy5wcm9ncmFtXG4gICAgICAuY29tbWFuZChcInNsZWVwXCIpXG4gICAgICAub3B0aW9uKFwiLS10aW1lIDxudW1iZXI+XCIsIFwic2xlZXAgdGltZSBpbiBzZWNvbmRzXCIsIHNhZmVQYXJzZUludClcbiAgICAgIC5hY3Rpb24oYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCB0aW1lID0gdGhpcy5wcm9ncmFtLm9wdHMoKS50aW1lIHx8IDEyMDtcbiAgICAgICAgY29uc3QgbXMgPSB0aW1lICogMTAwMDtcblxuICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4gc2V0VGltZW91dChyZXNvbHZlLCBtcykpO1xuICAgICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGNvcHkoKSB7XG4gICAgdGhpcy5wcm9ncmFtXG4gICAgICAuY29tbWFuZChcImNvcHlcIilcbiAgICAgIC5kZXNjcmlwdGlvbihcIkNvcHkgYSBmaWxlIGZyb20gb3JpZ2luIHRvIGRlc3RpbmF0aW9uXCIpXG4gICAgICAucmVxdWlyZWRPcHRpb24oXCItLW9yaWdpbiA8c3RyaW5nPlwiLCBcIk9yaWdpbiBmaWxlIHBhdGhcIilcbiAgICAgIC5yZXF1aXJlZE9wdGlvbihcIi0tZGVzdCA8c3RyaW5nPlwiLCBcIkRlc3RpbmF0aW9uIGZpbGUgcGF0aFwiKVxuICAgICAgLmFjdGlvbihhc3luYyAob3B0aW9ucykgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHsgb3JpZ2luLCBkZXN0IH0gPSBvcHRpb25zO1xuXG4gICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIG9yaWdpbiBmaWxlIGV4aXN0c1xuICAgICAgICAgIGlmICghZnMuZXhpc3RzU3luYyhvcmlnaW4pKSB7XG4gICAgICAgICAgICB0aGlzLmxvZy5lcnJvcihgT3JpZ2luIGZpbGUgZG9lcyBub3QgZXhpc3Q6ICR7b3JpZ2lufWApO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIEVuc3VyZSB0aGUgZGVzdGluYXRpb24gZGlyZWN0b3J5IGV4aXN0c1xuICAgICAgICAgIGNvbnN0IGRlc3REaXIgPSBwYXRoLmRpcm5hbWUoZGVzdCk7XG4gICAgICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKGRlc3REaXIpKSB7XG4gICAgICAgICAgICBmcy5ta2RpclN5bmMoZGVzdERpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gQ29weSB0aGUgZmlsZVxuICAgICAgICAgIGZzLmNvcHlGaWxlU3luYyhvcmlnaW4sIGRlc3QpO1xuXG4gICAgICAgICAgdGhpcy5sb2cuaW5mbyhgRmlsZSBjb3BpZWQgc3VjY2Vzc2Z1bGx5IGZyb20gJHtvcmlnaW59IHRvICR7ZGVzdH1gKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgICAgICB0aGlzLmxvZy5lcnJvcihgRXJyb3IgY29weWluZyBmaWxlOiAkeyhlcnJvciBhcyBFcnJvcikubWVzc2FnZX1gKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQG1ldGhvZCBydW5cbiAgICogQGRlc2NyaXB0aW9uIFBhcnNlcyB0aGUgY29tbWFuZC1saW5lIGFyZ3VtZW50cyBhbmQgZXhlY3V0ZXMgdGhlIGFwcHJvcHJpYXRlIGNvbW1hbmRcbiAgICovXG4gIHB1YmxpYyBydW4oKTogdm9pZCB7XG4gICAgdGhpcy5wcm9ncmFtLnBhcnNlKHByb2Nlc3MuYXJndik7XG4gIH1cbn1cbiJdfQ==