@barcidev/ngx-autogen 0.1.36 → 0.1.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barcidev/ngx-autogen",
3
- "version": "0.1.36",
3
+ "version": "0.1.38",
4
4
  "description": "A collection of Angular schematics for essential functionalities.",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -1,3 +1,2 @@
1
1
  import { Rule } from "@angular-devkit/schematics";
2
- import { NgAddSchemaOptions } from "./schema";
3
- export declare function ngAdd(options: NgAddSchemaOptions): Rule;
2
+ export declare function ngAdd(): Rule;
@@ -2,105 +2,48 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ngAdd = ngAdd;
4
4
  const schematics_1 = require("@angular-devkit/schematics");
5
- const tasks_1 = require("@angular-devkit/schematics/tasks");
6
- function ngAdd(options) {
7
- return (tree, _context) => {
8
- const packagePath = "/package.json";
9
- const buffer = tree.read(packagePath);
10
- if (!buffer) {
11
- throw new schematics_1.SchematicsException("Could not find package.json. Make sure you are in the root of an Angular project.");
12
- }
13
- const packageJson = JSON.parse(buffer.toString());
14
- const angularCoreVer = packageJson.dependencies["@angular/core"] ||
15
- packageJson.devDependencies["@angular/core"];
16
- if (!angularCoreVer) {
17
- throw new schematics_1.SchematicsException("The version of @angular/core could not be determined. Please ensure that Angular is installed in your project.");
18
- }
19
- const mainVersion = parseInt(angularCoreVer.replace(/[^\d.]/g, "").split(".")[0], 10);
20
- if (mainVersion < 20) {
21
- _context.logger.error(`❌ Error: @barcidev/ngx-autogen requires Angular v20 or higher. Detected: v${mainVersion}`);
22
- return tree; // Stop execution
23
- }
24
- const ngrxVersion = `^${mainVersion}.0.0`;
25
- _context.logger.info(`📦 Configuring dependencies for Angular v${mainVersion}...`);
26
- const packageName = "@barcidev/ngx-autogen";
27
- packageJson.dependencies = Object.assign(Object.assign({}, packageJson.dependencies), { "@ngrx/signals": ngrxVersion });
28
- if (packageJson.dependencies[packageName]) {
29
- const currentVer = packageJson.dependencies[packageName];
30
- delete packageJson.dependencies[packageName];
31
- packageJson.devDependencies = Object.assign(Object.assign({}, packageJson.devDependencies), { [packageName]: currentVer });
32
- }
33
- packageJson.dependencies = sortObjectKeys(packageJson.dependencies);
34
- packageJson.devDependencies = sortObjectKeys(packageJson.devDependencies);
35
- tree.overwrite(packagePath, JSON.stringify(packageJson, null, 2));
36
- updateAngularJson(tree, options);
37
- updateTsConfig(tree);
38
- _context.addTask(new tasks_1.NodePackageInstallTask());
39
- return tree;
5
+ const LIBRARY_NAME = "@barcidev/ngx-autogen";
6
+ function ngAdd() {
7
+ return () => {
8
+ return (0, schematics_1.chain)([cleanupPackageJson(), registerInAngularJson()]);
40
9
  };
41
10
  }
42
- function sortObjectKeys(obj) {
43
- return Object.keys(obj)
44
- .sort()
45
- .reduce((result, key) => {
46
- result[key] = obj[key];
47
- return result;
48
- }, {});
49
- }
50
- function updateAngularJson(tree, options) {
51
- const path = "/angular.json";
52
- const buffer = tree.read(path);
53
- if (!buffer)
54
- return;
55
- const workspace = JSON.parse(buffer.toString());
56
- if (!workspace.cli)
57
- workspace.cli = {};
58
- const collections = workspace.cli.schematicCollections || [];
59
- if (!collections.includes("@barcidev/ngx-autogen")) {
60
- collections.push("@barcidev/ngx-autogen");
61
- workspace.cli.schematicCollections = collections;
62
- }
63
- if (!workspace.schematics)
64
- workspace.schematics = {};
65
- workspace.schematics["@barcidev/ngx-autogen:all"] = {
66
- pk: options.pk,
67
- lang: options.lang,
11
+ /**
12
+ * Regla: Mueve la lib a devDependencies
13
+ */
14
+ function cleanupPackageJson() {
15
+ return (tree) => {
16
+ var _a, _b;
17
+ const content = (_a = tree.read("package.json")) === null || _a === void 0 ? void 0 : _a.toString();
18
+ if (!content)
19
+ return tree;
20
+ const json = JSON.parse(content);
21
+ if ((_b = json.dependencies) === null || _b === void 0 ? void 0 : _b[LIBRARY_NAME]) {
22
+ const ver = json.dependencies[LIBRARY_NAME];
23
+ delete json.dependencies[LIBRARY_NAME];
24
+ json.devDependencies = Object.assign(Object.assign({}, json.devDependencies), { [LIBRARY_NAME]: ver });
25
+ tree.overwrite("package.json", JSON.stringify(json, null, 2));
26
+ }
27
+ return tree;
68
28
  };
69
- tree.overwrite(path, JSON.stringify(workspace, null, 2));
70
29
  }
71
30
  /**
72
- * Configura los Paths en el tsconfig.json para permitir el uso de @shared/*
31
+ * Regla: Configura la CLI de Angular
73
32
  */
74
- function updateTsConfig(tree) {
75
- const tsConfigPath = "/tsconfig.json";
76
- const path = tree.exists(tsConfigPath) ? tsConfigPath : "/tsconfig.app.json";
77
- const buffer = tree.read(path);
78
- if (!buffer)
79
- return;
80
- let contentText = buffer.toString();
81
- // Limpieza manual de comentarios para evitar que JSON.parse falle
82
- const cleanJson = contentText.replace(/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm, "$1");
83
- let tsconfig;
84
- try {
85
- tsconfig = JSON.parse(cleanJson);
86
- }
87
- catch (e) {
88
- // Si falla, intentamos parsearlo tal cual por si no tiene comentarios
89
- try {
90
- tsconfig = JSON.parse(contentText);
33
+ function registerInAngularJson() {
34
+ return (tree) => {
35
+ const buffer = tree.read("angular.json");
36
+ if (!buffer)
37
+ return tree;
38
+ const json = JSON.parse(buffer.toString());
39
+ json.cli = json.cli || {};
40
+ const collections = json.cli.schematicCollections || [];
41
+ if (!collections.includes(LIBRARY_NAME)) {
42
+ collections.push(LIBRARY_NAME);
43
+ json.cli.schematicCollections = collections;
44
+ tree.overwrite("angular.json", JSON.stringify(json, null, 2));
91
45
  }
92
- catch (innerError) {
93
- throw new schematics_1.SchematicsException(`No se pudo parsear ${path}. Asegúrate de que es un JSON válido.`);
94
- }
95
- }
96
- // Configurar los paths
97
- tsconfig.compilerOptions = tsconfig.compilerOptions || {};
98
- tsconfig.compilerOptions.paths = tsconfig.compilerOptions.paths || {};
99
- const sharedAlias = "@shared-state/*";
100
- const sharedPath = ["src/app/shared/state/*"];
101
- if (!tsconfig.compilerOptions.paths[sharedAlias]) {
102
- tsconfig.compilerOptions.paths[sharedAlias] = sharedPath;
103
- tree.overwrite(path, JSON.stringify(tsconfig, null, 2));
104
- }
46
+ return tree;
47
+ };
105
48
  }
106
49
  //# sourceMappingURL=index.js.map
@@ -3,18 +3,6 @@
3
3
  "$id": "ng-add-schema",
4
4
  "type": "object",
5
5
  "properties": {
6
- "pk": {
7
- "type": "string",
8
- "description": "The name of the default Primary Key (e.g., id, cod, uuid); default is 'id'.",
9
- "x-prompt": "What is the name of the default Primary Key (e.g., id, cod, uuid)?",
10
- "default": "id"
11
- },
12
- "lang":{
13
- "type": "string",
14
- "description": "The default language for the application (en, es); default is 'en'.",
15
- "x-prompt": "What is the default language for the application (en, es)?",
16
- "default": "en"
17
- }
18
6
  },
19
7
  "required": ["pk"]
20
8
  }
@@ -12,40 +12,98 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.signalStore = signalStore;
13
13
  const core_1 = require("@angular-devkit/core");
14
14
  const schematics_1 = require("@angular-devkit/schematics");
15
+ const tasks_1 = require("@angular-devkit/schematics/tasks");
16
+ const dependencies_1 = require("@schematics/angular/utility/dependencies");
15
17
  const workspace_1 = require("@schematics/angular/utility/workspace");
18
+ const jsonc_parser_1 = require("jsonc-parser");
16
19
  const file_actions_1 = require("../../common/file-actions");
17
20
  const pluralize_1 = require("../../common/pluralize");
21
+ const NGRX_SIGNALS = "@ngrx/signals";
18
22
  function signalStore(options) {
19
23
  return (tree) => __awaiter(this, void 0, void 0, function* () {
20
- var _a;
21
24
  const workspace = yield (0, workspace_1.getWorkspace)(tree);
22
- const globalConfig = (_a = workspace.extensions.schematics) === null || _a === void 0 ? void 0 : _a["@barcidev/ngx-autogen:all"];
23
- if (globalConfig && globalConfig.pk && !options.pk) {
24
- options.pk = globalConfig.pk;
25
- }
26
- // En tu función signalStore
27
- // 1. Obtener la ruta absoluta del sistema donde se ejecuta el comando
28
- const fullPath = process.cwd();
29
- // 2. Buscar la posición de 'src' para limpiar la ruta
30
- const srcIndex = fullPath.lastIndexOf("src");
31
- let relativePath = "";
32
- if (srcIndex !== -1) {
33
- // Extraemos de 'src' en adelante (ej: src/app/features/billing)
34
- relativePath = fullPath.substring(srcIndex);
35
- }
36
- else {
37
- // Si no encuentra 'src' (estás en la raíz), usamos el path por defecto
38
- relativePath = (0, core_1.join)((0, core_1.normalize)("src"), "app");
39
- }
40
- // 3. Normalizar y asegurar que termine en 'state'
41
- let movePath = (0, core_1.normalize)(relativePath);
42
- if (!movePath.endsWith("state")) {
43
- movePath = (0, core_1.join)(movePath, "state");
44
- }
45
- options.path = movePath;
46
- const indexPath = (0, core_1.join)(movePath, "index.ts");
47
- const nameDash = core_1.strings.dasherize(options.name);
48
- const entityName = core_1.strings.classify(options.name);
25
+ // 1. Preparar contexto y opciones enriquecidas
26
+ const context = resolveStoreContext(workspace, options);
27
+ const project = workspace.projects.get(context.projectName);
28
+ const projectRoot = (project === null || project === void 0 ? void 0 : project.sourceRoot) || "src";
29
+ const { angularVersion } = getProjectMetadata(tree);
30
+ // 2. Orquestar la ejecución
31
+ return (0, schematics_1.chain)([
32
+ ensureNgrxSignals(angularVersion),
33
+ updateIndexFile(context),
34
+ generateStoreFiles(context),
35
+ (0, file_actions_1.mergeFilesSmart)("./files/entity", "src/app/shared/state", context.options, tree),
36
+ updateAngularJson(context.options),
37
+ updateTsConfigRule(projectRoot),
38
+ (host, context) => {
39
+ context.addTask(new tasks_1.NodePackageInstallTask());
40
+ context.logger.info("🚀 Entorno preparado con éxito.");
41
+ return host;
42
+ },
43
+ ]);
44
+ });
45
+ }
46
+ /**
47
+ * --- LÓGICA DE EXTRACCIÓN Y PREPARACIÓN ---
48
+ */
49
+ function getProjectMetadata(tree) {
50
+ var _a, _b;
51
+ const buffer = tree.read("package.json");
52
+ if (!buffer)
53
+ throw new schematics_1.SchematicsException("No se encontró package.json");
54
+ const packageJson = JSON.parse(buffer.toString());
55
+ const angularCore = ((_a = packageJson.dependencies) === null || _a === void 0 ? void 0 : _a["@angular/core"]) ||
56
+ ((_b = packageJson.devDependencies) === null || _b === void 0 ? void 0 : _b["@angular/core"]);
57
+ const angularVersion = parseInt(angularCore.replace(/[^\d.]/g, "").split(".")[0], 10);
58
+ return { angularVersion };
59
+ }
60
+ function resolveStoreContext(workspace, options) {
61
+ var _a;
62
+ // Configuración Global de PK
63
+ const globalConfig = (_a = workspace.extensions.schematics) === null || _a === void 0 ? void 0 : _a["@barcidev/ngx-autogen:all"];
64
+ const pk = options.pk || (globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.pk) || "id";
65
+ // Resolución de Rutas (Lógica de Directorio Actual)
66
+ const fullPath = process.cwd();
67
+ const srcIndex = fullPath.lastIndexOf("src");
68
+ let relativePath = srcIndex !== -1
69
+ ? fullPath.substring(srcIndex)
70
+ : (0, core_1.join)((0, core_1.normalize)("src"), "app");
71
+ let movePath = (0, core_1.normalize)(relativePath);
72
+ if (!movePath.endsWith("state"))
73
+ movePath = (0, core_1.join)(movePath, "state");
74
+ // Resolución de Proyecto
75
+ const projectName = options.project ||
76
+ workspace.extensions.defaultProject ||
77
+ Array.from(workspace.projects.keys())[0];
78
+ return {
79
+ options: Object.assign(Object.assign({}, options), { pk, path: movePath, project: projectName }),
80
+ projectName,
81
+ movePath,
82
+ indexPath: (0, core_1.join)(movePath, "index.ts"),
83
+ nameDash: core_1.strings.dasherize(options.name),
84
+ entityName: core_1.strings.classify(options.name),
85
+ };
86
+ }
87
+ /**
88
+ * --- REGLAS DE TRANSFORMACIÓN ---
89
+ */
90
+ /**
91
+ * Regla: Añade @ngrx/signals si no existe
92
+ */
93
+ function ensureNgrxSignals(version) {
94
+ return (tree) => {
95
+ (0, dependencies_1.addPackageJsonDependency)(tree, {
96
+ type: dependencies_1.NodeDependencyType.Default,
97
+ name: NGRX_SIGNALS,
98
+ version: `^${version}.0.0`,
99
+ overwrite: false, // NO sobreescribe si ya está instalado
100
+ });
101
+ return tree;
102
+ };
103
+ }
104
+ function updateIndexFile(ctx) {
105
+ return (tree) => {
106
+ const { options, indexPath, nameDash, entityName } = ctx;
49
107
  const entityHeader = `/* ${entityName.toUpperCase()} */`;
50
108
  const exportBlock = [
51
109
  entityHeader,
@@ -54,70 +112,82 @@ function signalStore(options) {
54
112
  `export * from './${nameDash}/${nameDash}.store';`,
55
113
  "",
56
114
  ].join("\n");
57
- let content = "";
58
- if (tree.exists(indexPath)) {
59
- content = tree.read(indexPath).toString();
60
- }
115
+ let content = tree.exists(indexPath)
116
+ ? tree.read(indexPath).toString()
117
+ : "";
61
118
  if (content.includes(entityHeader)) {
62
- const lines = exportBlock.split("\n");
63
- lines.forEach((line) => {
64
- if (line.trim() !== "" && !content.includes(line)) {
65
- content += line + "\n";
66
- }
67
- });
119
+ // Evitar duplicados línea por línea
120
+ const newLines = exportBlock
121
+ .split("\n")
122
+ .filter((line) => line.trim() !== "" && !content.includes(line));
123
+ if (newLines.length > 0)
124
+ content += newLines.join("\n") + "\n";
68
125
  }
69
126
  else {
70
127
  content =
71
128
  content.trim() + (content.length > 0 ? "\n\n" : "") + exportBlock;
72
129
  }
73
- if (tree.exists(indexPath)) {
74
- tree.overwrite(indexPath, content);
130
+ tree.exists(indexPath)
131
+ ? tree.overwrite(indexPath, content)
132
+ : tree.create(indexPath, content);
133
+ return tree;
134
+ };
135
+ }
136
+ function generateStoreFiles(ctx) {
137
+ const { options, movePath, nameDash } = ctx;
138
+ const targetPath = (0, core_1.join)(movePath, nameDash);
139
+ const templateUtils = Object.assign(Object.assign(Object.assign({}, core_1.strings), options), { pluralize: (word) => options.lang === "es" ? (0, pluralize_1.pluralizeEs)(word) : (0, pluralize_1.pluralizeEn)(word) });
140
+ const createSource = (srcUrl, dest) => (0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.url)(srcUrl), [(0, schematics_1.applyTemplates)(templateUtils), (0, schematics_1.move)(dest)]));
141
+ return (0, schematics_1.chain)([
142
+ createSource("./files/state/store", targetPath),
143
+ createSource("./files/state/services", (0, core_1.join)(targetPath, options.grouped ? "services" : "")),
144
+ createSource("./files/state/models", (0, core_1.join)(targetPath, options.grouped ? "models" : "")),
145
+ ]);
146
+ }
147
+ function updateTsConfigRule(root) {
148
+ return (tree, context) => {
149
+ var _a, _b;
150
+ const tsConfigPath = tree.exists("/tsconfig.app.json")
151
+ ? "/tsconfig.app.json"
152
+ : "/tsconfig.json";
153
+ const buffer = tree.read(tsConfigPath);
154
+ if (!buffer)
155
+ return;
156
+ let content = buffer.toString();
157
+ const modOptions = {
158
+ formattingOptions: { insertSpaces: true, tabSize: 2 },
159
+ };
160
+ // 1. Asegurar baseUrl
161
+ if (!((_a = (0, jsonc_parser_1.parse)(content).compilerOptions) === null || _a === void 0 ? void 0 : _a.baseUrl)) {
162
+ content = (0, jsonc_parser_1.applyEdits)(content, (0, jsonc_parser_1.modify)(content, ["compilerOptions", "baseUrl"], "./", modOptions));
75
163
  }
76
- else {
77
- tree.create(indexPath, content);
164
+ // 2. Calcular path relativo al baseUrl
165
+ const baseUrl = ((_b = (0, jsonc_parser_1.parse)(content).compilerOptions) === null || _b === void 0 ? void 0 : _b.baseUrl) || "./";
166
+ let i18nPath = `${root}/app/shared/state/*`;
167
+ const normalizedBase = baseUrl.replace(/^\.\/|\/$/g, "");
168
+ if (normalizedBase && i18nPath.startsWith(normalizedBase)) {
169
+ i18nPath = i18nPath.replace(normalizedBase, "").replace(/^\//, "");
78
170
  }
79
- // Generar archivos en las carpetas store, services y models
80
- const namePath = (0, core_1.join)(movePath, core_1.strings.dasherize(options.name));
81
- const rules = [];
82
- // store
83
- rules.push((0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.url)("./files/state/store"), [
84
- (0, schematics_1.applyTemplates)(Object.assign(Object.assign(Object.assign({}, core_1.strings), options), { pluralize: (word) => {
85
- switch (options.lang) {
86
- case "es":
87
- return (0, pluralize_1.pluralizeEs)(word);
88
- default:
89
- return (0, pluralize_1.pluralizeEn)(word);
90
- }
91
- }, pk: options.pk || "id" })),
92
- (0, schematics_1.move)(namePath),
93
- ])));
94
- // services
95
- rules.push((0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.url)("./files/state/services"), [
96
- (0, schematics_1.applyTemplates)(Object.assign(Object.assign(Object.assign({}, core_1.strings), options), { pluralize: (word) => {
97
- switch (options.lang) {
98
- case "es":
99
- return (0, pluralize_1.pluralizeEs)(word);
100
- default:
101
- return (0, pluralize_1.pluralizeEn)(word);
102
- }
103
- }, pk: options.pk || "id" })),
104
- (0, schematics_1.move)((0, core_1.join)(namePath, options.grouped ? "services" : "")),
105
- ])));
106
- // models
107
- rules.push((0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.url)("./files/state/models"), [
108
- (0, schematics_1.applyTemplates)(Object.assign(Object.assign(Object.assign({}, core_1.strings), options), { pluralize: (word) => {
109
- switch (options.lang) {
110
- case "es":
111
- return (0, pluralize_1.pluralizeEs)(word);
112
- default:
113
- return (0, pluralize_1.pluralizeEn)(word);
114
- }
115
- }, pk: options.pk || "id" })),
116
- (0, schematics_1.move)((0, core_1.join)(namePath, options.grouped ? "models" : "")),
117
- ])));
118
- // common entity
119
- rules.push((0, file_actions_1.mergeFilesSmart)("./files/entity", "src/app/shared/state", options, tree));
120
- return (0, schematics_1.chain)(rules);
121
- });
171
+ // 3. Aplicar alias
172
+ const finalContent = (0, jsonc_parser_1.applyEdits)(content, (0, jsonc_parser_1.modify)(content, ["compilerOptions", "paths", "@shared-state/*"], [i18nPath], modOptions));
173
+ tree.overwrite(tsConfigPath, finalContent);
174
+ context.logger.info(`✅ Alias @shared-state configurado.`);
175
+ };
176
+ }
177
+ function updateAngularJson(options) {
178
+ return (tree) => {
179
+ const path = "/angular.json";
180
+ const buffer = tree.read(path);
181
+ if (!buffer)
182
+ return;
183
+ const workspace = JSON.parse(buffer.toString());
184
+ if (!workspace.schematics)
185
+ workspace.schematics = {};
186
+ workspace.schematics["@barcidev/ngx-autogen:signal-state"] = {
187
+ pk: options.pk,
188
+ lang: options.lang,
189
+ };
190
+ tree.overwrite(path, JSON.stringify(workspace, null, 2));
191
+ };
122
192
  }
123
193
  //# sourceMappingURL=index.js.map
@@ -1,6 +1,7 @@
1
1
  export interface StoreSchemaOptions {
2
2
  name: string;
3
3
  path?: string;
4
+ project?: string;
4
5
  grouped: boolean;
5
6
  pk?: string;
6
7
  lang: "en" | "es";
@@ -19,15 +19,17 @@
19
19
  "description": "Whether the files should be grouped in subfolders.",
20
20
  "default": false
21
21
  },
22
- "lang": {
22
+ "pk": {
23
23
  "type": "string",
24
- "description": "Language for pluralization ('en' for English, 'es' for Spanish).",
25
- "enum": ["en", "es"],
26
- "default": "en"
24
+ "description": "The name of the default Primary Key (e.g., id, cod, uuid); default is 'id'.",
25
+ "x-prompt": "What is the name of the default Primary Key (e.g., id, cod, uuid)?",
26
+ "default": "id"
27
27
  },
28
- "pk": {
28
+ "lang":{
29
29
  "type": "string",
30
- "description": "Name of the primary key."
30
+ "description": "The default language for the application (en, es); default is 'en'.",
31
+ "x-prompt": "What is the default language for the application (en, es)?",
32
+ "default": "en"
31
33
  }
32
34
  },
33
35
  "required": ["name"]