structu-rex
Version:
Framework agnostic UI design system builder (Atomic Design, containers/UI, hooks, presenters)
177 lines (174 loc) • 6.11 kB
JavaScript
;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
// src/cli/plopfile.ts
var import_node_path = __toESM(require("path"));
var TIERS = {
atom: { folder: "atoms", suffix: "atom", base: "Atom" },
mol: { folder: "molecules", suffix: "mol", base: "Molecule" },
org: { folder: "organisms", suffix: "org", base: "Organism" },
tpl: { folder: "templates", suffix: "tpl", base: "Template" },
pg: { folder: "pages", suffix: "pg", base: "Page" }
};
module.exports = function(plop) {
plop.setHelper("folder", (t) => TIERS[t].folder);
plop.setHelper("suffix", (t) => TIERS[t].suffix);
plop.setHelper("base", (t) => TIERS[t].base);
plop.setGenerator("component", {
description: "Genera un componente Structurex (Atom/Mol/Org/\u2026) ",
prompts: [
{
type: "input",
name: "name",
message: "Nombre del componente (PascalCase):",
validate: (v) => /^[A-Z][A-Za-z0-9]+$/.test(v) || "El nombre debe estar en PascalCase."
},
{
type: "list",
name: "tier",
message: "Tipo de componente:",
choices: [
{ name: "Atom", value: "atom" },
{ name: "Molecule", value: "mol" },
{ name: "Organism", value: "org" },
{ name: "Template", value: "tpl" },
{ name: "Page", value: "pg" }
]
},
{
type: "confirm",
name: "withContainer",
message: "\xBFDesea un Container?",
default: false
},
{
type: "confirm",
name: "withTest",
message: "\xBFDesea un Test?",
default: true
}
],
actions: (ans) => {
const { tier, withContainer, withTest } = ans;
const { folder, suffix, base } = TIERS[tier];
const tplData = { base, suffix, folder };
const dir = `src/${folder}/{{pascalCase name}}`;
const acts = [
/* 1. types.ts ------------------------------------------------------ */
{
type: "add",
path: `${dir}/types.ts`,
templateFile: import_node_path.default.resolve(__dirname, "templates/atom-types.hbs"),
data: tplData
},
/* 2. clase Atom|Mol|… --------------------------------------------- */
{
type: "add",
path: `${dir}/{{pascalCase name}}.${suffix}.tsx`,
templateFile: import_node_path.default.resolve(__dirname, "templates/atom-class.hbs"),
data: tplData
},
/* 3. wrapper index.ts --------------------------------------------- */
{
type: "add",
path: `${dir}/index.ts`,
templateFile: import_node_path.default.resolve(__dirname, "templates/atom-index.hbs"),
data: tplData
}
];
if (withContainer) {
acts.push({
type: "add",
path: `${dir}/{{pascalCase name}}.ctn.ts`,
templateFile: import_node_path.default.resolve(__dirname, "templates/container.hbs"),
data: tplData
});
}
if (withTest) {
acts.push({
type: "add",
path: `test/${folder}/{{pascalCase name}}.test.tsx`,
templateFile: import_node_path.default.resolve(__dirname, "templates/test.hbs"),
data: tplData
});
}
acts.push(
{
type: "add",
path: `src/${folder}/index.ts`,
skipIfExists: true,
template: "// AUTO-EXPORTS\n"
},
{
// ⬇️ usamos 'append', pero lo casteamos para que TS no proteste
...{
type: "append",
path: `src/${folder}/index.ts`,
pattern: /(\/\/ AUTO-EXPORTS\n?)/,
template: `export * from './{{pascalCase name}}';
$1`
}
}
);
acts.push(
{
type: "add",
path: "src/index.ts",
skipIfExists: true,
template: `export * from './config';
export * from './core';
// AUTO-EXPORTS
`
},
{
...{
type: "append",
path: "src/index.ts",
pattern: /(\/\/ AUTO-EXPORTS\n?)/,
template: `export * from './${folder}/{{pascalCase name}}';
$1`
}
}
);
return acts;
}
});
plop.setGenerator("hook", {
description: "Genera un hook reusable (useX)",
prompts: [{ type: "input", name: "name", message: "Nombre del hook (PascalCase):" }],
actions: [{
type: "add",
path: "src/hooks/use{{pascalCase name}}.ts",
templateFile: import_node_path.default.resolve(__dirname, "templates/hook.hbs")
}]
});
plop.setGenerator("presenter", {
description: "Genera un presenter (DTO \u2192 ViewModel)",
prompts: [{ type: "input", name: "name", message: "Nombre del presenter (PascalCase):" }],
actions: [{
type: "add",
path: "src/presenters/{{pascalCase name}}Presenter.ts",
templateFile: import_node_path.default.resolve(__dirname, "templates/presenter.hbs")
}]
});
};