@barcidev/ngx-autogen 0.1.4 → 0.1.6
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 +2 -1
- package/src/ng-add/index.js +42 -13
- package/src/ng-add/schema.d.ts +1 -0
- package/src/ng-add/schema.json +6 -0
- package/src/ngrx/store/files/state/models/__name@dasherize__.model.ts.template +1 -1
- package/src/ngrx/store/files/state/services/__name@dasherize__.service.ts.template +1 -1
- package/src/ngrx/store/files/state/store/__name@dasherize__.store.ts.template +16 -16
- package/src/ngrx/store/index.js +24 -22
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@barcidev/ngx-autogen",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
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",
|
package/src/ng-add/index.js
CHANGED
|
@@ -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
|
-
|
|
22
|
-
|
|
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
|
-
|
|
37
|
+
updateTsConfig(tree);
|
|
45
38
|
_context.addTask(new tasks_1.NodePackageInstallTask());
|
|
46
39
|
return tree;
|
|
47
40
|
};
|
|
@@ -63,15 +56,51 @@ function updateAngularJson(tree, options) {
|
|
|
63
56
|
if (!workspace.cli)
|
|
64
57
|
workspace.cli = {};
|
|
65
58
|
const collections = workspace.cli.schematicCollections || [];
|
|
66
|
-
if (!collections.includes("ngx-autogen")) {
|
|
67
|
-
collections.push("ngx-autogen");
|
|
59
|
+
if (!collections.includes("@barcidev/ngx-autogen")) {
|
|
60
|
+
collections.push("@barcidev/ngx-autogen");
|
|
68
61
|
workspace.cli.schematicCollections = collections;
|
|
69
62
|
}
|
|
70
63
|
if (!workspace.schematics)
|
|
71
64
|
workspace.schematics = {};
|
|
72
|
-
workspace.schematics["ngx-autogen:all"] = {
|
|
65
|
+
workspace.schematics["@barcidev/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
|
package/src/ng-add/schema.d.ts
CHANGED
package/src/ng-add/schema.json
CHANGED
|
@@ -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"]
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
Add<%= classify(name) %>,
|
|
5
5
|
<%= classify(name) %>Dto,
|
|
6
6
|
Update<%= classify(name) %>
|
|
7
|
-
} from '<%= grouped ? "../models
|
|
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,
|
|
12
|
+
import { catchError, EMPTY, pipe, switchMap, tap } from 'rxjs';
|
|
13
13
|
|
|
14
|
-
import { RequestConfig } from '
|
|
15
|
-
import { withPagination } from '
|
|
16
|
-
import { withEntityStatus } from '
|
|
17
|
-
|
|
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
|
|
22
|
-
import { <%= classify(name) %>Service } from '<%= grouped ? "./services
|
|
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
|
|
47
|
-
return <%= camelize(name) %>Service.add<%= classify(name) %>$(
|
|
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 = { ...
|
|
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(
|
|
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
|
|
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) %>$(
|
|
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
|
|
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
|
|
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
|
|
182
|
+
idsUpdating: idsUpdating.filter((idUpdating) => idUpdating !== payload.<%= pk %>)
|
|
183
183
|
}
|
|
184
184
|
}));
|
|
185
185
|
if (onError) {
|
package/src/ngrx/store/index.js
CHANGED
|
@@ -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
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
-
|
|
72
|
-
|
|
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
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
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
|
-
|
|
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)(
|
|
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
|
}
|