From 9efd2518d34a781ec99c3827c0db7c31d60f5bec Mon Sep 17 00:00:00 2001 From: david Date: Sat, 27 Sep 2025 23:38:40 +0200 Subject: [PATCH] =?UTF-8?q?Plantilla=20para=20m=C3=B3dulos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + plopfile.mjs | 78 +++++++++++++++++++++++-------- pnpm-lock.yaml | 5 ++ templates/new-module/package.json | 2 +- 4 files changed, 66 insertions(+), 20 deletions(-) diff --git a/package.json b/package.json index 0bd38be3..88c4fc13 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "devDependencies": { "@biomejs/biome": "1.9.4", "@repo/typescript-config": "workspace:*", + "change-case": "^5.4.4", "inquirer": "^12.5.2", "plop": "^4.0.4", "ts-node": "^10.9.2", diff --git a/plopfile.mjs b/plopfile.mjs index cb2df483..32b656ec 100644 --- a/plopfile.mjs +++ b/plopfile.mjs @@ -4,41 +4,81 @@ * - name: agregado principal (usa placeholders en plantillas) * - plural: rutas/tabla (override del plural generado) */ + +import { + camelCase, + capitalCase, + constantCase, + dotCase, + kebabCase, + pascalCase, + snakeCase, +} from "change-case"; + +/** + * Generador de módulos ERP + * @remarks + * - `module` -> bounded context (carpeta en `modules/`) + * - `name` -> agregado principal (singular) + * - `plural` -> plural del agregado para rutas/tablas (override manual si hace falta) + * - Helpers -> registrados con los nombres usados en las plantillas (.hbs) + */ export default function (plop) { + /** Helpers de casing para usar en hbs */ + plop.setHelper("kebabCase", (s) => kebabCase(String(s || ""))); + plop.setHelper("camelCase", (s) => camelCase(String(s || ""))); + plop.setHelper("pascalCase", (s) => pascalCase(String(s || ""))); + plop.setHelper("snakeCase", (s) => snakeCase(String(s || ""))); + plop.setHelper("constantCase", (s) => constantCase(String(s || ""))); + plop.setHelper("capitalCase", (s) => capitalCase(String(s || ""))); + plop.setHelper("dotCase", (s) => dotCase(String(s || ""))); + + /** Validadores simples */ + const isKebab = (v) => + (!!v && /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/.test(v)) || + "Usa kebab-case (empieza por letra; letras/números/guiones)."; + plop.setGenerator("module", { description: "Crea un nuevo módulo (bounded context) con un agregado principal", prompts: [ { type: "input", name: "module", - message: "Nombre del bounded context (kebab-case, p.ej. 'billing'):", - validate: (v) => - (!!v && /^[a-z0-9\-]+$/.test(v)) || "Usa kebab-case (letras, números y guiones).", - filter: (v) => plop.getHelper("kebabCase")(v), + message: "Bounded context (kebab-case, p.ej. 'customer-payments'):", + validate: isKebab, + filter: (v) => kebabCase(v), }, { type: "input", name: "name", - message: "Nombre del agregado principal (kebab-case, p.ej. 'customer-invoice'):", - validate: (v) => - (!!v && /^[a-z0-9\-]+$/.test(v)) || "Usa kebab-case (letras, números y guiones).", - filter: (v) => plop.getHelper("kebabCase")(v), + message: "Agregado principal (kebab-case, p.ej. 'customer-payment'):", + validate: isKebab, + filter: (v) => kebabCase(v), }, { type: "input", name: "plural", - message: "Nombre plural para las rutas/tabla (kebab-case):", - default: (answers) => `${plop.getHelper("kebabCase")(answers.name)}s`, - filter: (v) => plop.getHelper("kebabCase")(v), - }, - ], - actions: [ - { - type: "addMany", - destination: "modules/{{kebabCase module}}", - base: "templates/new-module", - templateFiles: "templates/new-module/**", + message: "Plural del agregado (kebab-case) — ENTER para sufijo 's':", + filter: (v, answers) => (v?.trim() ? kebabCase(v) : `${kebabCase(answers.name)}s`), + validate: isKebab, }, ], + actions: (answers) => { + const dest = `modules/${kebabCase(answers.module)}`; + /** + * addMany copiará la plantilla completa en la carpeta del bounded context + * usando los placeholders de las plantillas existentes (name/plural). + */ + const actions = [ + { + type: "addMany", + destination: dest, + base: "templates/new-module", + templateFiles: "templates/new-module/**", + abortOnFail: true, + }, + ]; + return actions; + }, }); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 356d8871..bbec61f3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,6 +14,9 @@ importers: '@repo/typescript-config': specifier: workspace:* version: link:packages/typescript-config + change-case: + specifier: ^5.4.4 + version: 5.4.4 inquirer: specifier: ^12.5.2 version: 12.6.3(@types/node@24.0.3) @@ -569,6 +572,8 @@ importers: specifier: ^5.8.3 version: 5.8.3 + modules/customer-payments: {} + modules/customers: dependencies: '@ag-grid-community/locale': diff --git a/templates/new-module/package.json b/templates/new-module/package.json index d44ef494..c8632e6a 100644 --- a/templates/new-module/package.json +++ b/templates/new-module/package.json @@ -1,5 +1,5 @@ { - "name": "@erp/{{kebabCase name}}", + "name": "@erp/{{kebabCase module}}", "version": "0.1.0", "main": "src/index.ts", "scripts": {