@barcidev/ngx-autogen 0.1.4 → 0.1.5

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.4",
3
+ "version": "0.1.5",
4
4
  "description": "A collection of Angular schematics for essential functionalities.",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -53,6 +53,7 @@
53
53
  "typescript": "~5.9.2"
54
54
  },
55
55
  "devDependencies": {
56
+ "@angular-devkit/schematics-cli": "^21.1.2",
56
57
  "@types/jasmine": "~5.1.0",
57
58
  "@types/node": "^20.17.19",
58
59
  "copyfiles": "^2.4.1",
@@ -11,26 +11,20 @@ function ngAdd(options) {
11
11
  throw new schematics_1.SchematicsException("Could not find package.json. Make sure you are in the root of an Angular project.");
12
12
  }
13
13
  const packageJson = JSON.parse(buffer.toString());
14
- // 1. Obtener la versión de Angular Core
15
14
  const angularCoreVer = packageJson.dependencies["@angular/core"] ||
16
15
  packageJson.devDependencies["@angular/core"];
17
16
  if (!angularCoreVer) {
18
17
  throw new schematics_1.SchematicsException("The version of @angular/core could not be determined. Please ensure that Angular is installed in your project.");
19
18
  }
20
19
  const mainVersion = parseInt(angularCoreVer.replace(/[^\d.]/g, "").split(".")[0], 10);
21
- // 2. Validación: NgRx Signals requiere Angular 16+ (v17+ recomendado)
22
- if (mainVersion < 16) {
23
- _context.logger.error(`❌ Error: ngx-essentials requires Angular v16 or higher. Detected: v${mainVersion}`);
20
+ if (mainVersion < 20) {
21
+ _context.logger.error(`❌ Error: ngx-essentials requires Angular v20 or higher. Detected: v${mainVersion}`);
24
22
  return tree; // Stop execution
25
23
  }
26
- // 3. Mapear versión de NgRx (NgRx suele ir a la par con Angular)
27
24
  const ngrxVersion = `^${mainVersion}.0.0`;
28
25
  _context.logger.info(`📦 Configuring dependencies for Angular v${mainVersion}...`);
29
- // 4. Modificar package.json
30
26
  const packageName = "ngx-autogen";
31
- // Inyectar dependencias compatibles
32
27
  packageJson.dependencies = Object.assign(Object.assign({}, packageJson.dependencies), { "@ngrx/signals": ngrxVersion });
33
- // Mover a devDependencies si es necesario
34
28
  if (packageJson.dependencies[packageName]) {
35
29
  const currentVer = packageJson.dependencies[packageName];
36
30
  delete packageJson.dependencies[packageName];
@@ -39,9 +33,8 @@ function ngAdd(options) {
39
33
  packageJson.dependencies = sortObjectKeys(packageJson.dependencies);
40
34
  packageJson.devDependencies = sortObjectKeys(packageJson.devDependencies);
41
35
  tree.overwrite(packagePath, JSON.stringify(packageJson, null, 2));
42
- // 5. Configurar angular.json (Collections y Primary Key)
43
36
  updateAngularJson(tree, options);
44
- // 6. Tarea de instalación
37
+ updateTsConfig(tree);
45
38
  _context.addTask(new tasks_1.NodePackageInstallTask());
46
39
  return tree;
47
40
  };
@@ -71,7 +64,43 @@ function updateAngularJson(tree, options) {
71
64
  workspace.schematics = {};
72
65
  workspace.schematics["ngx-autogen:all"] = {
73
66
  pk: options.pk,
67
+ lang: options.lang,
74
68
  };
75
69
  tree.overwrite(path, JSON.stringify(workspace, null, 2));
76
70
  }
71
+ /**
72
+ * Configura los Paths en el tsconfig.json para permitir el uso de @shared/*
73
+ */
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);
91
+ }
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
+ }
105
+ }
77
106
  //# sourceMappingURL=index.js.map
@@ -1,3 +1,4 @@
1
1
  export interface NgAddSchemaOptions {
2
2
  pk: string;
3
+ lang: string;
3
4
  }
@@ -8,6 +8,12 @@
8
8
  "description": "The name of the default Primary Key (e.g., id, cod, uuid); default is 'id'.",
9
9
  "x-prompt": "What is the name of the default Primary Key (e.g., id, cod, uuid)?",
10
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"
11
17
  }
12
18
  },
13
19
  "required": ["pk"]
@@ -1,4 +1,4 @@
1
- import { FormGroupType } from 'src/app/shared/state/entity.model';
1
+ import { FormGroupType } from '@shared-state/entity.model';
2
2
 
3
3
  export interface Add<%= classify(name) %> {
4
4
  }
@@ -4,7 +4,7 @@ import {
4
4
  Add<%= classify(name) %>,
5
5
  <%= classify(name) %>Dto,
6
6
  Update<%= classify(name) %>
7
- } from '<%= grouped ? "../models/<%= dasherize(name) %>.model" : "./<%= dasherize(name) %>.model"';
7
+ } from '<%= grouped ? "../models/" + dasherize(name) + ".model" : "./" + dasherize(name) + ".model" %>';
8
8
 
9
9
  @Injectable({
10
10
  providedIn: 'root'
@@ -9,17 +9,17 @@ import {
9
9
  withEntities
10
10
  } from '@ngrx/signals/entities';
11
11
  import { rxMethod } from '@ngrx/signals/rxjs-interop';
12
- import { catchError, of, pipe, switchMap, tap } from 'rxjs';
12
+ import { catchError, EMPTY, pipe, switchMap, tap } from 'rxjs';
13
13
 
14
- import { RequestConfig } from 'src/app/shared/state/entity.model';
15
- import { withPagination } from 'src/app/shared/state/with-entity-pagination';
16
- import { withEntityStatus } from 'src/app/shared/state/with-entity-status';
17
- iimport {
14
+ import { RequestConfig } from '@shared-state/entity.model';
15
+ import { withPagination } from '@shared-state/with-entity-pagination';
16
+ import { withEntityStatus } from '@shared-state/with-entity-status';
17
+ import {
18
18
  Add<%= classify(name) %>,
19
19
  <%= classify(name) %>Dto,
20
20
  Update<%= classify(name) %>
21
- } from '<%= grouped ? "./models/<%= dasherize(name) %>.model" : "./<%= dasherize(name) %>.model"';
22
- import { <%= classify(name) %>Service } from '<%= grouped ? "./services/./<%= dasherize(name) %>.service" : "./<%= dasherize(name) %>.service"';
21
+ } from '<%= grouped ? "./models/" + dasherize(name) + ".model" : "./" + dasherize(name) + ".model" %>';
22
+ import { <%= classify(name) %>Service } from '<%= grouped ? "./services/" + dasherize(name) + ".service" : "./" + dasherize(name) + ".service" %>';;
23
23
 
24
24
  const config = entityConfig({
25
25
  entity: type<<%= classify(name) %>Dto>(),
@@ -43,16 +43,16 @@ export const <%= classify(name) %>Store = signalStore(
43
43
  tap(() => {
44
44
  patchState(store, (state) => ({ status: { ...state.status, addLoading: true } }));
45
45
  }),
46
- switchMap(({ onError, onSuccess, payload: { request } }) => {
47
- return <%= camelize(name) %>Service.add<%= classify(name) %>$(request).pipe(
46
+ switchMap(({ onError, onSuccess, payload }) => {
47
+ return <%= camelize(name) %>Service.add<%= classify(name) %>$(payload).pipe(
48
48
  tap((<%= pk %>) => {
49
- const new<%= classify(name) %>: <%= classify(name) %>Dto = { ...request, <%= pk %>};
49
+ const new<%= classify(name) %>: <%= classify(name) %>Dto = { ...payload, <%= pk %>};
50
50
  patchState(store, addEntity(new<%= classify(name) %>, config), (state) => ({
51
51
  ...state,
52
52
  status: { ...state.status, addError: null, addLoading: false }
53
53
  }));
54
54
  if (onSuccess) {
55
- onSuccess(newHorario);
55
+ onSuccess(new<%= classify(name) %>);
56
56
  }
57
57
  }),
58
58
  catchError(() => {
@@ -148,21 +148,21 @@ export const <%= classify(name) %>Store = signalStore(
148
148
  status: {
149
149
  ...state.status,
150
150
  _updateLoading: true,
151
- idsUpdating: [...(state.status.idsUpdating || []), payload.cod]
151
+ idsUpdating: [...(state.status.idsUpdating || []), payload.<%= pk %>]
152
152
  }
153
153
  }));
154
154
  }),
155
155
  switchMap(({ onError, onSuccess, payload }) => {
156
- return <%= camelize(name) %>Service.update<%= classify(name) %>$(entity).pipe(
156
+ return <%= camelize(name) %>Service.update<%= classify(name) %>$(payload).pipe(
157
157
  tap((response) => {
158
158
  if (response) {
159
159
  const idsUpdating = store.status.idsUpdating() || [];
160
- patchState(store, updateEntity({ changes: payload, id: payload.cod }, config), (state) => ({
160
+ patchState(store, updateEntity({ changes: payload, id: payload.<%= pk %> }, config), (state) => ({
161
161
  status: {
162
162
  ...state.status,
163
163
  _updateLoading: false,
164
164
  error: null,
165
- idsUpdating: idsUpdating.filter((idUpdating) => idUpdating !== payload.cod)
165
+ idsUpdating: idsUpdating.filter((idUpdating) => idUpdating !== payload.<%= pk %>)
166
166
  }
167
167
  }));
168
168
  if (onSuccess) {
@@ -179,7 +179,7 @@ export const <%= classify(name) %>Store = signalStore(
179
179
  ...state.status,
180
180
  _updateLoading: false,
181
181
  error: new Error('Error al actualizar horario-acceso'),
182
- idsUpdating: idsUpdating.filter((idUpdating) => idUpdating !== payload.cod)
182
+ idsUpdating: idsUpdating.filter((idUpdating) => idUpdating !== payload.<%= pk %>)
183
183
  }
184
184
  }));
185
185
  if (onError) {
@@ -37,29 +37,21 @@ const pluralizeEn = (name) => {
37
37
  }
38
38
  return name + "s";
39
39
  };
40
- function mergeFilesSmart(urlPath, destPath, options) {
40
+ function mergeFilesSmart(urlPath, destPath, options, tree) {
41
41
  return (0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.url)(urlPath), [
42
42
  (0, schematics_1.applyTemplates)(Object.assign(Object.assign({}, core_1.strings), options)),
43
43
  (0, schematics_1.move)(destPath),
44
44
  (0, schematics_1.forEach)((fileEntry) => {
45
- // Si el archivo ya existe en el árbol
46
- if (treeRef.exists(fileEntry.path)) {
47
- const existingContent = treeRef.read(fileEntry.path).toString();
48
- const newContent = fileEntry.content.toString();
49
- // Solo escribimos si el contenido nuevo no está ya incluido (basado en una cadena clave o firma)
50
- // Puedes ajustar esta condición según lo que necesites verificar
51
- if (existingContent.includes(newContent.trim())) {
52
- return null; // Descarta el archivo del proceso de merge (no hace nada)
45
+ if (tree.exists(fileEntry.path)) {
46
+ const existingContent = tree.read(fileEntry.path).toString();
47
+ if (existingContent.includes(fileEntry.content.toString().trim())) {
48
+ return null;
53
49
  }
54
- // Si el archivo existe pero queremos añadir contenido al final (opcional)
55
- // treeRef.overwrite(fileEntry.path, existingContent + '\n' + newContent);
56
- return null;
57
50
  }
58
51
  return fileEntry;
59
52
  }),
60
53
  ]));
61
54
  }
62
- let treeRef;
63
55
  function signalStore(options) {
64
56
  return (tree) => __awaiter(this, void 0, void 0, function* () {
65
57
  var _a;
@@ -68,16 +60,26 @@ function signalStore(options) {
68
60
  if (globalConfig && globalConfig.pk && !options.pk) {
69
61
  options.pk = globalConfig.pk;
70
62
  }
71
- if (!options.path) {
72
- options.path = process.cwd();
63
+ // En tu función signalStore
64
+ // 1. Obtener la ruta absoluta del sistema donde se ejecuta el comando
65
+ const fullPath = process.cwd();
66
+ // 2. Buscar la posición de 'src' para limpiar la ruta
67
+ const srcIndex = fullPath.lastIndexOf("src");
68
+ let relativePath = "";
69
+ if (srcIndex !== -1) {
70
+ // Extraemos de 'src' en adelante (ej: src/app/features/billing)
71
+ relativePath = fullPath.substring(srcIndex);
73
72
  }
74
- // Si la carpeta final no se llama 'state', agregarla
75
- let movePath = (0, core_1.normalize)(options.path);
76
- const pathParts = movePath.split(/[\\/]/).filter(Boolean);
77
- if (pathParts[pathParts.length - 1] !== "state") {
73
+ else {
74
+ // Si no encuentra 'src' (estás en la raíz), usamos el path por defecto
75
+ relativePath = (0, core_1.join)((0, core_1.normalize)("src"), "app");
76
+ }
77
+ // 3. Normalizar y asegurar que termine en 'state'
78
+ let movePath = (0, core_1.normalize)(relativePath);
79
+ if (!movePath.endsWith("state")) {
78
80
  movePath = (0, core_1.join)(movePath, "state");
79
81
  }
80
- treeRef = tree;
82
+ options.path = movePath;
81
83
  const indexPath = (0, core_1.join)(movePath, "index.ts");
82
84
  const nameDash = core_1.strings.dasherize(options.name);
83
85
  const entityName = core_1.strings.classify(options.name);
@@ -124,7 +126,7 @@ function signalStore(options) {
124
126
  return pluralizeEn(word);
125
127
  }
126
128
  }, pk: options.pk || "id" })),
127
- (0, schematics_1.move)("store"),
129
+ (0, schematics_1.move)(namePath),
128
130
  ])));
129
131
  // services
130
132
  rules.push((0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.url)("./files/state/services"), [
@@ -151,7 +153,7 @@ function signalStore(options) {
151
153
  (0, schematics_1.move)((0, core_1.join)(namePath, options.grouped ? "models" : "")),
152
154
  ])));
153
155
  // common entity
154
- rules.push(mergeFilesSmart("./files/entity", "src/app/shared/state", options));
156
+ rules.push(mergeFilesSmart("./files/entity", "src/app/shared/state", options, tree));
155
157
  return (0, schematics_1.chain)(rules);
156
158
  });
157
159
  }