Plantilla para módulos

This commit is contained in:
David Arranz 2025-09-27 23:38:40 +02:00
parent 520224e508
commit 9efd2518d3
4 changed files with 66 additions and 20 deletions

View File

@ -21,6 +21,7 @@
"devDependencies": { "devDependencies": {
"@biomejs/biome": "1.9.4", "@biomejs/biome": "1.9.4",
"@repo/typescript-config": "workspace:*", "@repo/typescript-config": "workspace:*",
"change-case": "^5.4.4",
"inquirer": "^12.5.2", "inquirer": "^12.5.2",
"plop": "^4.0.4", "plop": "^4.0.4",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",

View File

@ -4,41 +4,81 @@
* - name: agregado principal (usa placeholders en plantillas) * - name: agregado principal (usa placeholders en plantillas)
* - plural: rutas/tabla (override del plural generado) * - 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) { 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", { plop.setGenerator("module", {
description: "Crea un nuevo módulo (bounded context) con un agregado principal", description: "Crea un nuevo módulo (bounded context) con un agregado principal",
prompts: [ prompts: [
{ {
type: "input", type: "input",
name: "module", name: "module",
message: "Nombre del bounded context (kebab-case, p.ej. 'billing'):", message: "Bounded context (kebab-case, p.ej. 'customer-payments'):",
validate: (v) => validate: isKebab,
(!!v && /^[a-z0-9\-]+$/.test(v)) || "Usa kebab-case (letras, números y guiones).", filter: (v) => kebabCase(v),
filter: (v) => plop.getHelper("kebabCase")(v),
}, },
{ {
type: "input", type: "input",
name: "name", name: "name",
message: "Nombre del agregado principal (kebab-case, p.ej. 'customer-invoice'):", message: "Agregado principal (kebab-case, p.ej. 'customer-payment'):",
validate: (v) => validate: isKebab,
(!!v && /^[a-z0-9\-]+$/.test(v)) || "Usa kebab-case (letras, números y guiones).", filter: (v) => kebabCase(v),
filter: (v) => plop.getHelper("kebabCase")(v),
}, },
{ {
type: "input", type: "input",
name: "plural", name: "plural",
message: "Nombre plural para las rutas/tabla (kebab-case):", message: "Plural del agregado (kebab-case) — ENTER para sufijo 's':",
default: (answers) => `${plop.getHelper("kebabCase")(answers.name)}s`, filter: (v, answers) => (v?.trim() ? kebabCase(v) : `${kebabCase(answers.name)}s`),
filter: (v) => plop.getHelper("kebabCase")(v), validate: isKebab,
}, },
], ],
actions: [ 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", type: "addMany",
destination: "modules/{{kebabCase module}}", destination: dest,
base: "templates/new-module", base: "templates/new-module",
templateFiles: "templates/new-module/**", templateFiles: "templates/new-module/**",
abortOnFail: true,
},
];
return actions;
}, },
],
}); });
} }

View File

@ -14,6 +14,9 @@ importers:
'@repo/typescript-config': '@repo/typescript-config':
specifier: workspace:* specifier: workspace:*
version: link:packages/typescript-config version: link:packages/typescript-config
change-case:
specifier: ^5.4.4
version: 5.4.4
inquirer: inquirer:
specifier: ^12.5.2 specifier: ^12.5.2
version: 12.6.3(@types/node@24.0.3) version: 12.6.3(@types/node@24.0.3)
@ -569,6 +572,8 @@ importers:
specifier: ^5.8.3 specifier: ^5.8.3
version: 5.8.3 version: 5.8.3
modules/customer-payments: {}
modules/customers: modules/customers:
dependencies: dependencies:
'@ag-grid-community/locale': '@ag-grid-community/locale':

View File

@ -1,5 +1,5 @@
{ {
"name": "@erp/{{kebabCase name}}", "name": "@erp/{{kebabCase module}}",
"version": "0.1.0", "version": "0.1.0",
"main": "src/index.ts", "main": "src/index.ts",
"scripts": { "scripts": {