@barcidev/ngx-autogen 0.1.6 → 0.1.8
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 +5 -5
- package/src/collection.json +5 -0
- package/src/common/file-actions.d.ts +9 -0
- package/src/common/file-actions.js +56 -0
- package/src/common/pluralize.d.ts +2 -0
- package/src/common/pluralize.js +30 -0
- package/src/ng-add/index.js +2 -2
- package/src/ngrx/store/files/state/services/__name@dasherize__.service.ts.template +2 -2
- package/src/ngrx/store/files/state/store/__name@dasherize__.store.ts.template +3 -2
- package/src/ngrx/store/index.js +10 -47
- package/src/transloco/files/component/__name@dasherize__.i18n.ts.template +18 -0
- package/src/transloco/files/i18n/global.i18n.ts.template +19 -0
- package/src/transloco/files/i18n/transloco-loader.ts.template +10 -0
- package/src/transloco/files/i18n/transloco-wrapper.ts.template +12 -0
- package/src/transloco/files/i18n/transloco.model.ts.template +34 -0
- package/src/transloco/index.d.ts +3 -0
- package/src/transloco/index.js +113 -0
- package/src/transloco/schema.json +23 -0
- package/src/transloco/scheme.d.ts +6 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@barcidev/ngx-autogen",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"description": "A collection of Angular schematics for essential functionalities.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -47,13 +47,13 @@
|
|
|
47
47
|
"node": ">=16.0.0"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@angular-devkit/core": "^
|
|
51
|
-
"@angular-devkit/schematics": "^
|
|
52
|
-
"@schematics/angular": "^21.0
|
|
50
|
+
"@angular-devkit/core": "^21.2.0",
|
|
51
|
+
"@angular-devkit/schematics": "^21.2.0",
|
|
52
|
+
"@schematics/angular": "^21.2.0",
|
|
53
53
|
"typescript": "~5.9.2"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
-
"@angular-devkit/schematics-cli": "^21.
|
|
56
|
+
"@angular-devkit/schematics-cli": "^21.2.0",
|
|
57
57
|
"@types/jasmine": "~5.1.0",
|
|
58
58
|
"@types/node": "^20.17.19",
|
|
59
59
|
"copyfiles": "^2.4.1",
|
package/src/collection.json
CHANGED
|
@@ -10,6 +10,11 @@
|
|
|
10
10
|
"description": "Adds NgRx Store to the Angular application with signal support.",
|
|
11
11
|
"factory": "./ngrx/store/index#signalStore",
|
|
12
12
|
"schema": "./ngrx/store/schema.json"
|
|
13
|
+
},
|
|
14
|
+
"app-i18n": {
|
|
15
|
+
"description": "Adds Transloco to the Angular application.",
|
|
16
|
+
"factory": "./transloco/index#transloco",
|
|
17
|
+
"schema": "./transloco/schema.json"
|
|
13
18
|
}
|
|
14
19
|
}
|
|
15
20
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Rule, Tree } from "@angular-devkit/schematics";
|
|
2
|
+
export declare const mergeFilesSmart: (urlPath: string, destPath: string, options: any, tree: Tree) => Rule;
|
|
3
|
+
/**
|
|
4
|
+
* Añade un provider a un componente Standalone y gestiona sus imports.
|
|
5
|
+
*/
|
|
6
|
+
export declare function addProviderToStandaloneComponent(componentPath: string, providerName: string, imports: {
|
|
7
|
+
symbol: string;
|
|
8
|
+
path: string;
|
|
9
|
+
}[]): Rule;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.mergeFilesSmart = void 0;
|
|
4
|
+
exports.addProviderToStandaloneComponent = addProviderToStandaloneComponent;
|
|
5
|
+
const schematics_1 = require("@angular-devkit/schematics");
|
|
6
|
+
const change_1 = require("@schematics/angular/utility/change");
|
|
7
|
+
const ts = require("typescript");
|
|
8
|
+
const schematics_2 = require("@angular-devkit/schematics");
|
|
9
|
+
const ast_utils_1 = require("@schematics/angular/utility/ast-utils");
|
|
10
|
+
const mergeFilesSmart = (urlPath, destPath, options, tree) => {
|
|
11
|
+
return (0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.url)(urlPath), [
|
|
12
|
+
(0, schematics_1.applyTemplates)(Object.assign(Object.assign({}, schematics_1.strings), options)),
|
|
13
|
+
(0, schematics_1.move)(destPath),
|
|
14
|
+
(0, schematics_1.forEach)((fileEntry) => {
|
|
15
|
+
if (tree.exists(fileEntry.path)) {
|
|
16
|
+
const existingContent = tree.read(fileEntry.path).toString();
|
|
17
|
+
if (existingContent.includes(fileEntry.content.toString().trim())) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return fileEntry;
|
|
22
|
+
}),
|
|
23
|
+
]));
|
|
24
|
+
};
|
|
25
|
+
exports.mergeFilesSmart = mergeFilesSmart;
|
|
26
|
+
/**
|
|
27
|
+
* Añade un provider a un componente Standalone y gestiona sus imports.
|
|
28
|
+
*/
|
|
29
|
+
function addProviderToStandaloneComponent(componentPath, providerName, imports) {
|
|
30
|
+
return (tree) => {
|
|
31
|
+
const text = tree.read(componentPath);
|
|
32
|
+
if (!text) {
|
|
33
|
+
throw new schematics_2.SchematicsException(`No se encontró el archivo: ${componentPath}`);
|
|
34
|
+
}
|
|
35
|
+
const sourceText = text.toString("utf-8");
|
|
36
|
+
const source = ts.createSourceFile(componentPath, sourceText, ts.ScriptTarget.Latest, true);
|
|
37
|
+
const recorder = tree.beginUpdate(componentPath);
|
|
38
|
+
// 1. Añadir el provider al array de metadata
|
|
39
|
+
const providerChanges = (0, ast_utils_1.addSymbolToNgModuleMetadata)(source, componentPath, "providers", providerName, null);
|
|
40
|
+
providerChanges.forEach((change) => {
|
|
41
|
+
if (change instanceof change_1.InsertChange) {
|
|
42
|
+
recorder.insertLeft(change.pos, change.toAdd);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
// 2. Añadir todos los imports necesarios
|
|
46
|
+
imports.forEach((item) => {
|
|
47
|
+
const importChange = (0, ast_utils_1.insertImport)(source, componentPath, item.symbol, item.path);
|
|
48
|
+
if (importChange instanceof change_1.InsertChange) {
|
|
49
|
+
recorder.insertLeft(importChange.pos, importChange.toAdd);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
tree.commitUpdate(recorder);
|
|
53
|
+
return tree;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=file-actions.js.map
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.pluralizeEn = exports.pluralizeEs = void 0;
|
|
4
|
+
const pluralizeEs = (name) => {
|
|
5
|
+
if (!name)
|
|
6
|
+
return name;
|
|
7
|
+
const lastChar = name.slice(-1).toLowerCase();
|
|
8
|
+
const vowels = ["a", "e", "i", "o", "u"];
|
|
9
|
+
if (vowels.includes(lastChar))
|
|
10
|
+
return name + "s";
|
|
11
|
+
if (lastChar === "z")
|
|
12
|
+
return name.slice(0, -1) + "ces";
|
|
13
|
+
return name + "es";
|
|
14
|
+
};
|
|
15
|
+
exports.pluralizeEs = pluralizeEs;
|
|
16
|
+
const pluralizeEn = (name) => {
|
|
17
|
+
if (!name)
|
|
18
|
+
return name;
|
|
19
|
+
const lastChar = name.slice(-1).toLowerCase();
|
|
20
|
+
const vowels = ["a", "e", "i", "o", "u"];
|
|
21
|
+
if (lastChar === "y" && !vowels.includes(name.slice(-2, -1).toLowerCase())) {
|
|
22
|
+
return name.slice(0, -1) + "ies";
|
|
23
|
+
}
|
|
24
|
+
if (["s", "x", "z", "ch", "sh"].some((end) => name.toLowerCase().endsWith(end))) {
|
|
25
|
+
return name + "es";
|
|
26
|
+
}
|
|
27
|
+
return name + "s";
|
|
28
|
+
};
|
|
29
|
+
exports.pluralizeEn = pluralizeEn;
|
|
30
|
+
//# sourceMappingURL=pluralize.js.map
|
package/src/ng-add/index.js
CHANGED
|
@@ -18,12 +18,12 @@ function ngAdd(options) {
|
|
|
18
18
|
}
|
|
19
19
|
const mainVersion = parseInt(angularCoreVer.replace(/[^\d.]/g, "").split(".")[0], 10);
|
|
20
20
|
if (mainVersion < 20) {
|
|
21
|
-
_context.logger.error(`❌ Error: ngx-
|
|
21
|
+
_context.logger.error(`❌ Error: @barcidev/ngx-autogen requires Angular v20 or higher. Detected: v${mainVersion}`);
|
|
22
22
|
return tree; // Stop execution
|
|
23
23
|
}
|
|
24
24
|
const ngrxVersion = `^${mainVersion}.0.0`;
|
|
25
25
|
_context.logger.info(`📦 Configuring dependencies for Angular v${mainVersion}...`);
|
|
26
|
-
const packageName = "ngx-autogen";
|
|
26
|
+
const packageName = "@barcidev/ngx-autogen";
|
|
27
27
|
packageJson.dependencies = Object.assign(Object.assign({}, packageJson.dependencies), { "@ngrx/signals": ngrxVersion });
|
|
28
28
|
if (packageJson.dependencies[packageName]) {
|
|
29
29
|
const currentVer = packageJson.dependencies[packageName];
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
})
|
|
12
12
|
export class <%= classify(name) %>Service {
|
|
13
13
|
|
|
14
|
-
add<%= classify(name) %>$(
|
|
14
|
+
add<%= classify(name) %>$(payload: Add<%= classify(name) %>): Observable<number> {
|
|
15
15
|
return of(0);
|
|
16
16
|
}
|
|
17
17
|
|
|
@@ -23,7 +23,7 @@ export class <%= classify(name) %>Service {
|
|
|
23
23
|
return of([]);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
update<%= classify(name) %>$(
|
|
26
|
+
update<%= classify(name) %>$(payload: Update<%= classify(name) %>): Observable<boolean> {
|
|
27
27
|
return of(true);
|
|
28
28
|
}
|
|
29
29
|
}
|
|
@@ -27,6 +27,7 @@ const config = entityConfig({
|
|
|
27
27
|
});
|
|
28
28
|
|
|
29
29
|
export const <%= classify(name) %>Store = signalStore(
|
|
30
|
+
{ providedIn: 'root' },
|
|
30
31
|
withEntities(config),
|
|
31
32
|
withEntityStatus(),
|
|
32
33
|
withPagination(),
|
|
@@ -83,7 +84,7 @@ export const <%= classify(name) %>Store = signalStore(
|
|
|
83
84
|
}),
|
|
84
85
|
catchError(() => {
|
|
85
86
|
patchState(store, (state) => ({
|
|
86
|
-
status: { ...state.status, error: new Error('Error al cargar
|
|
87
|
+
status: { ...state.status, error: new Error('Error al cargar'), loading: false }
|
|
87
88
|
}));
|
|
88
89
|
return EMPTY;
|
|
89
90
|
})
|
|
@@ -178,7 +179,7 @@ export const <%= classify(name) %>Store = signalStore(
|
|
|
178
179
|
status: {
|
|
179
180
|
...state.status,
|
|
180
181
|
_updateLoading: false,
|
|
181
|
-
error: new Error('Error al actualizar
|
|
182
|
+
error: new Error('Error al actualizar'),
|
|
182
183
|
idsUpdating: idsUpdating.filter((idUpdating) => idUpdating !== payload.<%= pk %>)
|
|
183
184
|
}
|
|
184
185
|
}));
|
package/src/ngrx/store/index.js
CHANGED
|
@@ -13,50 +13,13 @@ exports.signalStore = signalStore;
|
|
|
13
13
|
const core_1 = require("@angular-devkit/core");
|
|
14
14
|
const schematics_1 = require("@angular-devkit/schematics");
|
|
15
15
|
const workspace_1 = require("@schematics/angular/utility/workspace");
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
return name;
|
|
19
|
-
const lastChar = name.slice(-1).toLowerCase();
|
|
20
|
-
const vowels = ["a", "e", "i", "o", "u"];
|
|
21
|
-
if (vowels.includes(lastChar))
|
|
22
|
-
return name + "s";
|
|
23
|
-
if (lastChar === "z")
|
|
24
|
-
return name.slice(0, -1) + "ces";
|
|
25
|
-
return name + "es";
|
|
26
|
-
};
|
|
27
|
-
const pluralizeEn = (name) => {
|
|
28
|
-
if (!name)
|
|
29
|
-
return name;
|
|
30
|
-
const lastChar = name.slice(-1).toLowerCase();
|
|
31
|
-
const vowels = ["a", "e", "i", "o", "u"];
|
|
32
|
-
if (lastChar === "y" && !vowels.includes(name.slice(-2, -1).toLowerCase())) {
|
|
33
|
-
return name.slice(0, -1) + "ies";
|
|
34
|
-
}
|
|
35
|
-
if (["s", "x", "z", "ch", "sh"].some((end) => name.toLowerCase().endsWith(end))) {
|
|
36
|
-
return name + "es";
|
|
37
|
-
}
|
|
38
|
-
return name + "s";
|
|
39
|
-
};
|
|
40
|
-
function mergeFilesSmart(urlPath, destPath, options, tree) {
|
|
41
|
-
return (0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.url)(urlPath), [
|
|
42
|
-
(0, schematics_1.applyTemplates)(Object.assign(Object.assign({}, core_1.strings), options)),
|
|
43
|
-
(0, schematics_1.move)(destPath),
|
|
44
|
-
(0, schematics_1.forEach)((fileEntry) => {
|
|
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;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
return fileEntry;
|
|
52
|
-
}),
|
|
53
|
-
]));
|
|
54
|
-
}
|
|
16
|
+
const file_actions_1 = require("../../common/file-actions");
|
|
17
|
+
const pluralize_1 = require("../../common/pluralize");
|
|
55
18
|
function signalStore(options) {
|
|
56
19
|
return (tree) => __awaiter(this, void 0, void 0, function* () {
|
|
57
20
|
var _a;
|
|
58
21
|
const workspace = yield (0, workspace_1.getWorkspace)(tree);
|
|
59
|
-
const globalConfig = (_a = workspace.extensions.schematics) === null || _a === void 0 ? void 0 : _a["ngx-autogen:all"];
|
|
22
|
+
const globalConfig = (_a = workspace.extensions.schematics) === null || _a === void 0 ? void 0 : _a["@barcidev/ngx-autogen:all"];
|
|
60
23
|
if (globalConfig && globalConfig.pk && !options.pk) {
|
|
61
24
|
options.pk = globalConfig.pk;
|
|
62
25
|
}
|
|
@@ -121,9 +84,9 @@ function signalStore(options) {
|
|
|
121
84
|
(0, schematics_1.applyTemplates)(Object.assign(Object.assign(Object.assign({}, core_1.strings), options), { pluralize: (word) => {
|
|
122
85
|
switch (options.lang) {
|
|
123
86
|
case "es":
|
|
124
|
-
return pluralizeEs(word);
|
|
87
|
+
return (0, pluralize_1.pluralizeEs)(word);
|
|
125
88
|
default:
|
|
126
|
-
return pluralizeEn(word);
|
|
89
|
+
return (0, pluralize_1.pluralizeEn)(word);
|
|
127
90
|
}
|
|
128
91
|
}, pk: options.pk || "id" })),
|
|
129
92
|
(0, schematics_1.move)(namePath),
|
|
@@ -133,9 +96,9 @@ function signalStore(options) {
|
|
|
133
96
|
(0, schematics_1.applyTemplates)(Object.assign(Object.assign(Object.assign({}, core_1.strings), options), { pluralize: (word) => {
|
|
134
97
|
switch (options.lang) {
|
|
135
98
|
case "es":
|
|
136
|
-
return pluralizeEs(word);
|
|
99
|
+
return (0, pluralize_1.pluralizeEs)(word);
|
|
137
100
|
default:
|
|
138
|
-
return pluralizeEn(word);
|
|
101
|
+
return (0, pluralize_1.pluralizeEn)(word);
|
|
139
102
|
}
|
|
140
103
|
}, pk: options.pk || "id" })),
|
|
141
104
|
(0, schematics_1.move)((0, core_1.join)(namePath, options.grouped ? "services" : "")),
|
|
@@ -145,15 +108,15 @@ function signalStore(options) {
|
|
|
145
108
|
(0, schematics_1.applyTemplates)(Object.assign(Object.assign(Object.assign({}, core_1.strings), options), { pluralize: (word) => {
|
|
146
109
|
switch (options.lang) {
|
|
147
110
|
case "es":
|
|
148
|
-
return pluralizeEs(word);
|
|
111
|
+
return (0, pluralize_1.pluralizeEs)(word);
|
|
149
112
|
default:
|
|
150
|
-
return pluralizeEn(word);
|
|
113
|
+
return (0, pluralize_1.pluralizeEn)(word);
|
|
151
114
|
}
|
|
152
115
|
}, pk: options.pk || "id" })),
|
|
153
116
|
(0, schematics_1.move)((0, core_1.join)(namePath, options.grouped ? "models" : "")),
|
|
154
117
|
])));
|
|
155
118
|
// common entity
|
|
156
|
-
rules.push(mergeFilesSmart("./files/entity", "src/app/shared/state", options, tree));
|
|
119
|
+
rules.push((0, file_actions_1.mergeFilesSmart)("./files/entity", "src/app/shared/state", options, tree));
|
|
157
120
|
return (0, schematics_1.chain)(rules);
|
|
158
121
|
});
|
|
159
122
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { TranslationScopeConfig } from 'app/i18n/transloco.model';
|
|
2
|
+
|
|
3
|
+
const esCO = {
|
|
4
|
+
title: 'Titulo'
|
|
5
|
+
};
|
|
6
|
+
const enUS = {
|
|
7
|
+
title: 'Title'
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const scope = '<%= name %>' as const;
|
|
11
|
+
|
|
12
|
+
export const <%= name %>I18n: TranslationScopeConfig<typeof esCO, typeof scope> = {
|
|
13
|
+
scope,
|
|
14
|
+
translations: {
|
|
15
|
+
'en-US': enUS,
|
|
16
|
+
'es-CO': esCO
|
|
17
|
+
}
|
|
18
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { TranslationScopeConfig } from "./transloco.model";
|
|
2
|
+
|
|
3
|
+
const esCO = {};
|
|
4
|
+
|
|
5
|
+
const enUS: typeof esCO = {};
|
|
6
|
+
|
|
7
|
+
const scope = "global" as const;
|
|
8
|
+
|
|
9
|
+
export const globalI18n: TranslationScopeConfig<typeof esCO, typeof scope> = {
|
|
10
|
+
scope,
|
|
11
|
+
translations: {
|
|
12
|
+
"en-US": enUS,
|
|
13
|
+
"es-CO": esCO,
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const appI18n = {
|
|
18
|
+
[scope]: globalI18n.translations["es-CO"],
|
|
19
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { HttpClient } from "@angular/common/http";
|
|
2
|
+
import { inject, Injectable } from "@angular/core";
|
|
3
|
+
import { Translation, TranslocoLoader } from "@jsverse/transloco";
|
|
4
|
+
|
|
5
|
+
@Injectable({ providedIn: "root" })
|
|
6
|
+
export class TranslocoHttpLoader implements TranslocoLoader {
|
|
7
|
+
private _http = inject(HttpClient);
|
|
8
|
+
|
|
9
|
+
getTranslation = (): Promise<Translation> => Promise.resolve({});
|
|
10
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { provideTranslocoScope } from '@jsverse/transloco';
|
|
2
|
+
|
|
3
|
+
import { TranslationScopeConfig } from './transloco.model';
|
|
4
|
+
|
|
5
|
+
export const provideTranslocoScopeWrapper = (config: TranslationScopeConfig) =>
|
|
6
|
+
provideTranslocoScope({
|
|
7
|
+
alias: config.alias,
|
|
8
|
+
loader: Object.fromEntries(
|
|
9
|
+
Object.entries(config.translations).map(([lang, translation]) => [lang, () => Promise.resolve(translation)])
|
|
10
|
+
),
|
|
11
|
+
scope: config.scope
|
|
12
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Translation } from "@jsverse/transloco";
|
|
2
|
+
|
|
3
|
+
import { appI18n } from "./global.i18n";
|
|
4
|
+
|
|
5
|
+
export type AppI18nType = typeof appI18n;
|
|
6
|
+
|
|
7
|
+
export type AppLanguageCode = "en-US" | "es-CO";
|
|
8
|
+
|
|
9
|
+
export type ConfigTranslation<T> = Record<AppLanguageCode, T>;
|
|
10
|
+
|
|
11
|
+
export type TranslationKeys = PathKeys<AppI18nType> | (string & {});
|
|
12
|
+
export type TranslationPagesKeys<K extends keyof AppI18nType> =
|
|
13
|
+
| PathKeys<AppI18nType[K]>
|
|
14
|
+
| (string & {});
|
|
15
|
+
|
|
16
|
+
export interface TranslationScopeConfig<T = Translation, U = string> {
|
|
17
|
+
alias?: string;
|
|
18
|
+
scope: U;
|
|
19
|
+
translations: ConfigTranslation<T>;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
type PathKeys<T> = T extends object
|
|
23
|
+
? {
|
|
24
|
+
[K in keyof T]: K extends number | string
|
|
25
|
+
?
|
|
26
|
+
| `${K}`
|
|
27
|
+
| (PathKeys<T[K]> extends infer P
|
|
28
|
+
? P extends number | string
|
|
29
|
+
? `${K}.${P}`
|
|
30
|
+
: never
|
|
31
|
+
: never)
|
|
32
|
+
: never;
|
|
33
|
+
}[keyof T]
|
|
34
|
+
: never;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.transloco = transloco;
|
|
13
|
+
const schematics_1 = require("@angular-devkit/schematics");
|
|
14
|
+
const tasks_1 = require("@angular-devkit/schematics/tasks");
|
|
15
|
+
const dependencies_1 = require("@schematics/angular/utility/dependencies");
|
|
16
|
+
const rules_1 = require("@schematics/angular/utility/standalone/rules");
|
|
17
|
+
const workspace_1 = require("@schematics/angular/utility/workspace");
|
|
18
|
+
const path_1 = require("path");
|
|
19
|
+
const file_actions_1 = require("../common/file-actions");
|
|
20
|
+
const pluralize_1 = require("../common/pluralize");
|
|
21
|
+
function transloco(options) {
|
|
22
|
+
return (tree, _context) => __awaiter(this, void 0, void 0, function* () {
|
|
23
|
+
var _a;
|
|
24
|
+
// 1. Configuración del Workspace y Proyecto
|
|
25
|
+
const workspace = yield (0, workspace_1.getWorkspace)(tree);
|
|
26
|
+
if (!options.project) {
|
|
27
|
+
options.project =
|
|
28
|
+
workspace.extensions.defaultProject ||
|
|
29
|
+
Array.from(workspace.projects.keys())[0];
|
|
30
|
+
}
|
|
31
|
+
const project = workspace.projects.get(options.project);
|
|
32
|
+
if (!project) {
|
|
33
|
+
throw new schematics_1.SchematicsException(`El proyecto "${options.project}" no existe.`);
|
|
34
|
+
}
|
|
35
|
+
// 2. Detección automática del componente en la ruta actual
|
|
36
|
+
const fullPath = process.cwd();
|
|
37
|
+
const relativeExecutionPath = fullPath
|
|
38
|
+
.replace(process.cwd(), "")
|
|
39
|
+
.replace(/\\/g, "/");
|
|
40
|
+
const directory = tree.getDir((0, path_1.normalize)(relativeExecutionPath));
|
|
41
|
+
const componentFile = directory.subfiles.find((file) => file.endsWith(".component.ts"));
|
|
42
|
+
if (!componentFile && !options.name) {
|
|
43
|
+
throw new schematics_1.SchematicsException("❌ No se encontró un archivo *.component.ts en este directorio.");
|
|
44
|
+
}
|
|
45
|
+
const componentFileName = componentFile
|
|
46
|
+
? componentFile.replace(".component.ts", "")
|
|
47
|
+
: options.name;
|
|
48
|
+
options.name = componentFileName;
|
|
49
|
+
// 3. Determinación de rutas para generación de archivos
|
|
50
|
+
const srcIndex = fullPath.lastIndexOf("src");
|
|
51
|
+
const relativePath = srcIndex !== -1
|
|
52
|
+
? fullPath.substring(srcIndex)
|
|
53
|
+
: (0, path_1.join)((0, path_1.normalize)("src"), "app");
|
|
54
|
+
options.path = (0, path_1.normalize)(relativePath);
|
|
55
|
+
const namePath = options.path; // Generamos archivos en la misma carpeta del componente detectado
|
|
56
|
+
const rules = [];
|
|
57
|
+
// 4. Verificación de instalación de Transloco (Idempotencia)
|
|
58
|
+
const appConfigPath = "src/app/app.config.ts";
|
|
59
|
+
const appConfigContent = ((_a = tree.read(appConfigPath)) === null || _a === void 0 ? void 0 : _a.toString()) || "";
|
|
60
|
+
const isTranslocoInstalled = appConfigContent.includes("provideTransloco");
|
|
61
|
+
if (!isTranslocoInstalled) {
|
|
62
|
+
_context.logger.info("📦 Transloco no detectado. Iniciando configuración global...");
|
|
63
|
+
// A. Añadir dependencia a package.json
|
|
64
|
+
rules.push((host) => {
|
|
65
|
+
(0, dependencies_1.addPackageJsonDependency)(host, {
|
|
66
|
+
type: dependencies_1.NodeDependencyType.Default,
|
|
67
|
+
name: "@jsverse/transloco",
|
|
68
|
+
version: "^7.0.0",
|
|
69
|
+
});
|
|
70
|
+
_context.addTask(new tasks_1.NodePackageInstallTask());
|
|
71
|
+
return host;
|
|
72
|
+
});
|
|
73
|
+
// B. Inyectar provider global en app.config.ts
|
|
74
|
+
rules.push((0, rules_1.addRootProvider)(options.project, ({ code, external }) => {
|
|
75
|
+
return code `
|
|
76
|
+
${external("provideTransloco", "@jsverse/transloco")}({
|
|
77
|
+
config: {
|
|
78
|
+
availableLangs: ['en', 'es'],
|
|
79
|
+
defaultLang: 'en',
|
|
80
|
+
prodMode: !${external("isDevMode", "@angular/core")}(),
|
|
81
|
+
reRenderOnLangChange: true
|
|
82
|
+
},
|
|
83
|
+
loader: ${external("TranslocoHttpLoader", "./i18n/transloco-loader")}
|
|
84
|
+
})
|
|
85
|
+
`;
|
|
86
|
+
}));
|
|
87
|
+
}
|
|
88
|
+
// 5. Generación de archivos i18n del componente
|
|
89
|
+
rules.push((0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.url)("./files/component"), [
|
|
90
|
+
(0, schematics_1.applyTemplates)(Object.assign(Object.assign(Object.assign({}, schematics_1.strings), options), { pluralize: (word) => options.lang === "es" ? (0, pluralize_1.pluralizeEs)(word) : (0, pluralize_1.pluralizeEn)(word) })),
|
|
91
|
+
(0, schematics_1.move)(namePath),
|
|
92
|
+
])));
|
|
93
|
+
// 6. Registro del Scope en el Componente Standalone
|
|
94
|
+
if (componentFile) {
|
|
95
|
+
const componentPath = (0, path_1.join)(namePath, componentFile);
|
|
96
|
+
const i18nConstantName = `${schematics_1.strings.camelize(options.name)}I18n`;
|
|
97
|
+
rules.push((0, file_actions_1.addProviderToStandaloneComponent)(componentPath, `provideTranslocoScopeWrapper(${i18nConstantName})`, [
|
|
98
|
+
{
|
|
99
|
+
symbol: `provideTranslocoScopeWrapper`,
|
|
100
|
+
path: `src/app/i18n/transloco-loader`, // Ajusta a tu path real de utilidades
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
symbol: i18nConstantName,
|
|
104
|
+
path: `./${schematics_1.strings.dasherize(options.name)}.i18n`,
|
|
105
|
+
},
|
|
106
|
+
]));
|
|
107
|
+
}
|
|
108
|
+
// 7. Sincronización de archivos i18n comunes
|
|
109
|
+
rules.push((0, file_actions_1.mergeFilesSmart)("./files/i18n", "src/app/i18n", options, tree));
|
|
110
|
+
return (0, schematics_1.chain)(rules);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/schema",
|
|
3
|
+
"$id": "TranslocoSchematic",
|
|
4
|
+
"title": "Transloco Schema",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"name": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"description": "Name of the component.",
|
|
10
|
+
"priority": 1
|
|
11
|
+
},
|
|
12
|
+
"path": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"description": "Destination path."
|
|
15
|
+
},
|
|
16
|
+
"lang": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"description": "Language for pluralization ('en' for English, 'es' for Spanish).",
|
|
19
|
+
"enum": ["en", "es"],
|
|
20
|
+
"default": "en"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|