UNPKG

angel-manager

Version:

<p align="center"> <img src="angel-manager.webp" alt="Angel Manager" width="300"> </p>

176 lines (149 loc) 4.89 kB
import { Command } from "commander"; import { Liquid } from "liquidjs"; import fs from "fs"; import path from "path"; import { camelCase, snakeCase, kebabCase, pascalCase } from "change-case"; import pluralize from "pluralize"; import { BaseCommand, Arg } from "@core"; import { generateArgsString, argsObject } from "./templateArgs"; import { __dirname } from "./reactUtils"; import { getConfigFile } from "./fsUtils"; export const transformArgs = ( args: string[], expectedArgs: Arg[] ): typeof argsObject => { const result = JSON.parse(JSON.stringify(argsObject)); args.forEach((arg, index) => { if (typeof arg !== "string" && typeof arg !== "number") return; const { name: attribute, type } = expectedArgs[index]; if (type === "number") { result.base[attribute] = Number(arg); return; } result.base[attribute] = arg; const camel = camelCase(arg); const kebab = kebabCase(arg); const snake = snakeCase(arg); const pascal = pascalCase(arg); result.camel[attribute] = camel; result.kebab[attribute] = kebab; result.snake[attribute] = snake; result.pascal[attribute] = pascal; result.plural.camel[attribute] = pluralize(camel); result.plural.kebab[attribute] = pluralize(kebab); result.plural.snake[attribute] = pluralize(snake); result.plural.pascal[attribute] = pluralize(pascal); }); return result; }; export const defineNewCommand = ( program: Command, command: BaseCommand, __dirname: string ): void => { program .command(`${command.commandName} ${generateArgsString(command.args())}`) .description(command.description) .action(async (...args) => { const definedArgs = command.args(); if (args.length - 2 !== definedArgs.length) { console.warn( `Warning: Expected ${definedArgs.length} arguments but received ${args.length}.` ); } let argsObject = transformArgs(args, definedArgs); command.run({ arguments: argsObject, __dirname }); }); }; function createScaffoldingDirectories(userRoot: string): void { const directories = [ path.join(userRoot, "src/scaffolding"), path.join(userRoot, "src/scaffolding/architecture"), path.join(userRoot, "src/scaffolding/commands"), ]; directories.forEach((dir) => { if (!fs.existsSync(dir)) { fs.mkdirSync(dir, { recursive: true }); } }); console.log("Scaffolding directory initialized successfully!"); } function replicateDirectoryStructure( sourceDir: string, targetDir: string ): void { if (!fs.existsSync(sourceDir)) { return; } if (!fs.existsSync(targetDir)) { fs.mkdirSync(targetDir, { recursive: true }); } const items = fs.readdirSync(sourceDir); items.forEach((item) => { const sourcePath = path.join(sourceDir, item); const targetPath = path.join(targetDir, item); if (fs.statSync(sourcePath).isDirectory()) { if (!fs.existsSync(targetPath)) { fs.mkdirSync(targetPath, { recursive: true }); } replicateDirectoryStructure(sourcePath, targetPath); } }); } export const buildDefaultCommands = ( program: Command, userRoot: string ): void => { const engine = new Liquid(); const templatePath = path.join(__dirname, "templates/command.liquid"); const templateContent = fs.readFileSync(templatePath, "utf8"); /* Initialize the scaffolding directory */ program .command("init") .description("Initializes the required directories") .action(() => { createScaffoldingDirectories(userRoot); }); /* Applies the scaffolding/architecture directory structure */ program .command("apply") .description("Applies the modeled architecture") .action(() => { const sourceDir = path.join( userRoot, "src", "scaffolding", "architecture" ); const targetDir = path.join(userRoot, "src"); replicateDirectoryStructure(sourceDir, targetDir); console.log("Modeled architecture applied successfully!"); }); /* Create Commands */ program .command("create:command <commandName>") .description("Creates a new command") .action(async (...args) => { const templateArgs = transformArgs(args, [ { name: "commandName", type: "string" }, ]); const configData = await getConfigFile(); try { await engine .parseAndRender(templateContent, { ...templateArgs, model: { ...configData }, }) .then((output) => { const outputPath = path.join( userRoot, `src/scaffolding/commands/${templateArgs.plural.pascal.commandName}.ts` ); fs.writeFileSync(outputPath, output); console.log("Command created successfully!"); }); } catch (err) { throw err; } }); };