@ihk-gfi/lux-components-update 19.6.0 → 21.1.0
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/README.md +5 -27
- package/collection.json +20 -0
- package/package.json +4 -4
- package/src/migrate-i18n-keys/index.js +55 -0
- package/src/migrate-i18n-keys/schema.json +23 -0
- package/src/migrate-xlf/index.js +125 -0
- package/src/migrate-xlf/schema.json +28 -0
- package/src/updates/21.0.0/files/scripts/move-files.js +14 -0
- package/src/updates/21.0.0/files/transloco/base/transloco-loader.ts +16 -0
- package/src/updates/21.0.0/files/transloco/base/transloco-root.config.ts +21 -0
- package/src/updates/21.0.0/files/transloco/i18n/de.json +3 -0
- package/src/updates/21.0.0/files/transloco/i18n/en.json +3 -0
- package/src/updates/21.0.0/files/transloco/testing/transloco-test.provider.ts +51 -0
- package/src/updates/21.0.0/index.js +207 -0
- package/src/updates/21.0.0/schema.json +23 -0
- package/src/updates/21.1.0/index.js +19 -0
- package/src/updates/21.1.0/schema.json +23 -0
- package/src/utility/dependencies.js +16 -56
- package/src/utility/typescript.js +13 -5
- package/src/utility/util.js +1 -1
- package/src/utility/validation.js +2 -8
package/README.md
CHANGED
|
@@ -1,39 +1,17 @@
|
|
|
1
1
|
# LUX-Components-Update
|
|
2
2
|
|
|
3
|
-
Dieses Projekt enthält alle Updateskripte (umgesetzt mit Angular Schematics) für die LUX-Components.
|
|
3
|
+
Dieses Projekt enthält alle Updateskripte (umgesetzt mit Angular Schematics) für die [LUX-Components](https://www.npmjs.com/package/@ihk-gfi/lux-components).
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
- `update-19.x.x` (aktualisiert das Projekt auf die Version 19.x.x)
|
|
8
|
-
- `add-lux-components` (fügt die LUX-Components zu einem Angular-Projekt hinzu)
|
|
9
|
-
|
|
10
|
-
## Voraussetzungen
|
|
11
|
-
|
|
12
|
-
Stellen Sie zunächst sicher, dass Sie die Angular-Schematics-Cli installiert haben:
|
|
5
|
+
## Installation
|
|
13
6
|
|
|
14
7
|
```bash
|
|
15
|
-
npm install
|
|
8
|
+
npm install @ihk-gfi/lux-components-update
|
|
16
9
|
```
|
|
17
10
|
|
|
18
11
|
## LUX-Components im Projekt aktualisieren
|
|
19
12
|
|
|
20
|
-
Um ein Updateskript zu starten, kann
|
|
21
|
-
|
|
22
|
-
```bash
|
|
23
|
-
ng generate @ihk-gfi/lux-components-update:update-19.x.x
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
Falls erst einmal ein Testdurchlauf ohne persistente Änderungen gewünscht ist,
|
|
27
|
-
ist es möglich den Aufruf mit dem Flag "--dry-run" zu versehen:
|
|
28
|
-
|
|
29
|
-
```bash
|
|
30
|
-
ng generate @ihk-gfi/lux-components-update:update-19.x.x --dry-run
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
## LUX-Components im Projekt einrichten
|
|
34
|
-
|
|
35
|
-
Wenn man die LUX-Components in seinem Projekt einrichten möchte, kann der folgende Befehl verwendet werden:
|
|
13
|
+
Um ein Updateskript zu starten, kann folgender Befehl verwendet werden:
|
|
36
14
|
|
|
37
15
|
```bash
|
|
38
|
-
ng generate @ihk-gfi/lux-components-update:
|
|
16
|
+
ng generate @ihk-gfi/lux-components-update:update-x.x.x
|
|
39
17
|
```
|
package/collection.json
CHANGED
|
@@ -6,6 +6,16 @@
|
|
|
6
6
|
"factory": "./src/update-standalone-imports/index#updateStandAloneImports",
|
|
7
7
|
"schema": "./src/update-standalone-imports/schema.json"
|
|
8
8
|
},
|
|
9
|
+
"update-21.1.0": {
|
|
10
|
+
"description": "Aktualisiert das LUX-Componentsprojekt auf die Version 21.1.0",
|
|
11
|
+
"factory": "./src/updates/21.1.0/index#update210100",
|
|
12
|
+
"schema": "./src/updates/21.1.0/schema.json"
|
|
13
|
+
},
|
|
14
|
+
"update-21.0.0": {
|
|
15
|
+
"description": "Aktualisiert das LUX-Componentsprojekt auf die Version 21.0.0",
|
|
16
|
+
"factory": "./src/updates/21.0.0/index#update210000",
|
|
17
|
+
"schema": "./src/updates/21.0.0/schema.json"
|
|
18
|
+
},
|
|
9
19
|
"update-19.6.0": {
|
|
10
20
|
"description": "Aktualisiert das LUX-Componentsprojekt auf die Version 19.6.0",
|
|
11
21
|
"factory": "./src/updates/19.6.0/index#update190600",
|
|
@@ -50,6 +60,16 @@
|
|
|
50
60
|
"description": "Aktualisiert die englischen Übersetzungen im Projekt",
|
|
51
61
|
"factory": "./src/update-en-messages/index#updateEnMessages",
|
|
52
62
|
"schema": "./src/update-en-messages/schema.json"
|
|
63
|
+
},
|
|
64
|
+
"migrate-xlf": {
|
|
65
|
+
"description": "Migriert die XLF Übersetzungsdateien in das neue Format",
|
|
66
|
+
"factory": "./src/migrate-xlf/index#migrateXlf",
|
|
67
|
+
"schema": "./src/migrate-xlf/schema.json"
|
|
68
|
+
},
|
|
69
|
+
"migrate-i18n-keys": {
|
|
70
|
+
"description": "Migriert die I18N-Tags in den HTML-Dateien",
|
|
71
|
+
"factory": "./src/migrate-i18n-keys/index#migrateI18nKeys",
|
|
72
|
+
"schema": "./src/migrate-i18n-keys/schema.json"
|
|
53
73
|
}
|
|
54
74
|
}
|
|
55
75
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ihk-gfi/lux-components-update",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "21.1.0",
|
|
4
4
|
"description": "Schematics für die Aktualisierung von LUX-Applikationen",
|
|
5
5
|
"private": false,
|
|
6
6
|
"publishConfig": {
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
"scripts": {
|
|
10
10
|
"build": "npm run clean && tsc -p tsconfig.json",
|
|
11
11
|
"clean": "del-cli --force ../../dist/updater/",
|
|
12
|
-
"pack-copy-base-files": "
|
|
13
|
-
"pack-copy-template-dirs": "
|
|
12
|
+
"pack-copy-base-files": "node ./scripts/copy-base-files.js",
|
|
13
|
+
"pack-copy-template-dirs": "node ./scripts/copy-template-dirs.js",
|
|
14
14
|
"pack": "npm run build && npm run pack-copy-base-files && npm run pack-copy-template-dirs",
|
|
15
15
|
"security": "npm audit --registry=https://registry.npmjs.org --audit-level high",
|
|
16
16
|
"smoketest": "npm run test && npm run pack",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"chalk": "^4.1.2",
|
|
36
36
|
"cheerio": "1.0.0-rc.12",
|
|
37
37
|
"htmlparser2": "^9.1.0",
|
|
38
|
-
"jsdom": "^
|
|
38
|
+
"jsdom": "^28.0.0",
|
|
39
39
|
"jsonc-parser": "^3.2.1",
|
|
40
40
|
"semver": "^7.6.0"
|
|
41
41
|
},
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.migrateI18nKeys = migrateI18nKeys;
|
|
4
|
+
const schematics_1 = require("@angular-devkit/schematics");
|
|
5
|
+
const files_1 = require("../utility/files");
|
|
6
|
+
const logging_1 = require("../utility/logging");
|
|
7
|
+
const util_1 = require("../utility/util");
|
|
8
|
+
function migrateI18nKeys(options) {
|
|
9
|
+
return (0, schematics_1.chain)([
|
|
10
|
+
(0, util_1.messageInfoRule)(`Die I18N-Tags in den HTML-Dateien werden migriert...`),
|
|
11
|
+
migrateI18nKeysIntern(options),
|
|
12
|
+
(0, util_1.messageInfoRule)(`Die I18N-Tags in den HTML-Dateien wurden migriert.`)
|
|
13
|
+
]);
|
|
14
|
+
}
|
|
15
|
+
function migrateI18nKeysIntern(options) {
|
|
16
|
+
return (tree, _context) => {
|
|
17
|
+
(0, files_1.iterateFilesAndModifyContent)(tree, options.path, (filePath, content) => {
|
|
18
|
+
let result = transformContent(content);
|
|
19
|
+
if (result.changed) {
|
|
20
|
+
(0, logging_1.logInfo)(filePath + ' wurde angepasst.');
|
|
21
|
+
tree.overwrite(filePath, result.content);
|
|
22
|
+
}
|
|
23
|
+
}, '.html');
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function transformContent(content) {
|
|
27
|
+
let changed = false;
|
|
28
|
+
// Attribute-level replacements (cases 1 & 2): i18n-attr
|
|
29
|
+
// Regex explanation:
|
|
30
|
+
// (\s) leading whitespace
|
|
31
|
+
// (?:([\w:-]+)="[^"]*"\s+i18n-\2|i18n-([\w:-]+))="@@?([^"]+)"
|
|
32
|
+
// Group 2 or 3 = attribute name; group 4 = key
|
|
33
|
+
const attrRegex = /(\s)(?:([\w:-]+)="[^"]*"\s+i18n-\2|i18n-([\w:-]+))="@@?([^"]+)"/g;
|
|
34
|
+
content = content.replace(attrRegex, (m, ws, attrWithValue, attrOnly, key) => {
|
|
35
|
+
const attrName = attrWithValue || attrOnly;
|
|
36
|
+
changed = true;
|
|
37
|
+
return `${ws}${attrName}="{{ '${key}' | transloco }}"`;
|
|
38
|
+
});
|
|
39
|
+
// Element-level i18n replacement (case 3): <tag ... i18n="@@key">ExistingText</tag>
|
|
40
|
+
// Caution: Avoid replacing if already contains transloco pipe.
|
|
41
|
+
const elemRegex = /(<[a-zA-Z][^>]*?)\s+i18n="@@?([^"]+)"([^>]*>)([\s\S]*?<\/[a-zA-Z][^>]*?>)/g;
|
|
42
|
+
content = content.replace(elemRegex, (m, startTagStart, key, startTagEnd, innerAndClose) => {
|
|
43
|
+
// If inner already includes transloco pipe for this key, skip.
|
|
44
|
+
if (innerAndClose.includes(`'${key}' | transloco`)) {
|
|
45
|
+
return m; // idempotent
|
|
46
|
+
}
|
|
47
|
+
changed = true;
|
|
48
|
+
// Remove any existing inner text between start and closing tag
|
|
49
|
+
// Extract closing tag separately to keep structure.
|
|
50
|
+
const closingTagMatch = innerAndClose.match(/<\/[a-zA-Z][^>]*?>$/);
|
|
51
|
+
const closingTag = closingTagMatch ? closingTagMatch[0] : '';
|
|
52
|
+
return `${startTagStart}${startTagEnd}{{ '${key}' | transloco }}${closingTag}`;
|
|
53
|
+
});
|
|
54
|
+
return { content, changed };
|
|
55
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/schema",
|
|
3
|
+
"$id": "migrateI18nKeysSchema",
|
|
4
|
+
"title": "Migriert die I18N-Tags in den HTML-Dateien.",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"description": "Migriert die I18N-Tags in den HTML-Dateien in das neue Format.",
|
|
7
|
+
"properties": {
|
|
8
|
+
"project": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"description": "Der Projektname",
|
|
11
|
+
"$default": {
|
|
12
|
+
"$source": "projectName"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"verbose": {
|
|
16
|
+
"type": "boolean",
|
|
17
|
+
"description": "Generiert mehr Logausgaben",
|
|
18
|
+
"default": false
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"required": [],
|
|
22
|
+
"additionalProperties": false
|
|
23
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.migrateXlf = migrateXlf;
|
|
4
|
+
const schematics_1 = require("@angular-devkit/schematics");
|
|
5
|
+
const logging_1 = require("../utility/logging");
|
|
6
|
+
const util_1 = require("../utility/util");
|
|
7
|
+
function migrateXlf(options) {
|
|
8
|
+
return (0, schematics_1.chain)([
|
|
9
|
+
(0, util_1.messageInfoRule)(`Die XLF-Dateien werden migriert...`),
|
|
10
|
+
migrateXlfIntern(options, 'de'),
|
|
11
|
+
migrateXlfIntern(options, 'en'),
|
|
12
|
+
(0, util_1.messageInfoRule)(`Die XLF-Dateien wurden migriert.`)
|
|
13
|
+
]);
|
|
14
|
+
}
|
|
15
|
+
function migrateXlfIntern(options, lang) {
|
|
16
|
+
return (tree, _context) => {
|
|
17
|
+
const xlfFilePath = (options.path ?? '') + `/src/locale/messages${lang === 'de' ? '' : '.en'}.xlf`;
|
|
18
|
+
const jsonFilePath = (options.path ?? '') + `/src/locale/${lang}.json`;
|
|
19
|
+
if (!tree.exists(xlfFilePath)) {
|
|
20
|
+
(0, logging_1.logInfo)(`Die Datei '${xlfFilePath}' wurde nicht gefunden. Die Migration wird übersprungen.`);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const xlfContent = tree.read(xlfFilePath)?.toString() ?? '';
|
|
24
|
+
let jsonContent = '';
|
|
25
|
+
const transUnits = [];
|
|
26
|
+
const tuRegex = /<trans-unit([^>]*)>([\s\S]*?)<\/trans-unit>/g;
|
|
27
|
+
let match;
|
|
28
|
+
while ((match = tuRegex.exec(xlfContent)) !== null) {
|
|
29
|
+
const attrs = match[1];
|
|
30
|
+
const body = match[2];
|
|
31
|
+
const idMatch = /id="([^"]+)"/.exec(attrs);
|
|
32
|
+
if (!idMatch)
|
|
33
|
+
continue;
|
|
34
|
+
const id = idMatch[1].trim();
|
|
35
|
+
if (id.startsWith('luxc.'))
|
|
36
|
+
continue;
|
|
37
|
+
const sourceMatch = /<source>([\s\S]*?)<\/source>/.exec(body);
|
|
38
|
+
if (!sourceMatch)
|
|
39
|
+
continue;
|
|
40
|
+
const targetMatch = /<target[^>]*>([\s\S]*?)<\/target>/.exec(body);
|
|
41
|
+
const source = normalizeMessage(sourceMatch[1]);
|
|
42
|
+
const target = targetMatch ? normalizeMessage(targetMatch[1]) : undefined;
|
|
43
|
+
transUnits.push({ id, source, target });
|
|
44
|
+
}
|
|
45
|
+
const namespaces = {};
|
|
46
|
+
for (const tu of transUnits) {
|
|
47
|
+
const { ns, key } = resolveNamespaceAndKey(options, tu.id);
|
|
48
|
+
namespaces[ns] = namespaces[ns] || {};
|
|
49
|
+
const useTarget = lang && lang.toLowerCase() === 'en';
|
|
50
|
+
const value = useTarget ? tu.target || tu.source : tu.source;
|
|
51
|
+
if (useTarget && !tu.target) {
|
|
52
|
+
(0, logging_1.logWarn)(`[MISSING TARGET] ${tu.id} -> falling back to <source>`);
|
|
53
|
+
}
|
|
54
|
+
namespaces[ns][key] = value;
|
|
55
|
+
}
|
|
56
|
+
let sortedNamespaces;
|
|
57
|
+
if (!options.namespace) {
|
|
58
|
+
const flat = namespaces._flat || {};
|
|
59
|
+
const sortedFlat = Object.keys(flat)
|
|
60
|
+
.sort()
|
|
61
|
+
.reduce((acc, k) => {
|
|
62
|
+
acc[k] = flat[k];
|
|
63
|
+
return acc;
|
|
64
|
+
}, {});
|
|
65
|
+
jsonContent = JSON.stringify(sortedFlat, null, 2) + '\n';
|
|
66
|
+
sortedNamespaces = ['(flat)'];
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
sortedNamespaces = Object.keys(namespaces).sort();
|
|
70
|
+
const aggregate = {};
|
|
71
|
+
for (const ns of sortedNamespaces) {
|
|
72
|
+
const obj = namespaces[ns];
|
|
73
|
+
const sortedKeys = Object.keys(obj)
|
|
74
|
+
.sort()
|
|
75
|
+
.reduce((acc, k) => {
|
|
76
|
+
acc[k] = obj[k];
|
|
77
|
+
return acc;
|
|
78
|
+
}, {});
|
|
79
|
+
aggregate[ns] = sortedKeys;
|
|
80
|
+
}
|
|
81
|
+
jsonContent = JSON.stringify(aggregate, null, 2) + '\n';
|
|
82
|
+
}
|
|
83
|
+
if (!tree.exists(jsonFilePath)) {
|
|
84
|
+
tree.create(jsonFilePath, jsonContent);
|
|
85
|
+
(0, logging_1.logInfo)(`Die Datei '${jsonFilePath}' wurde erstellt.`);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
tree.overwrite(jsonFilePath, jsonContent);
|
|
89
|
+
(0, logging_1.logInfo)(`Die Datei '${jsonFilePath}' wurde aktualisiert.`);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function normalizeMessage(text) {
|
|
94
|
+
let t = text
|
|
95
|
+
.replace(/\r?\n/g, ' ')
|
|
96
|
+
.replace(/\s+/g, ' ')
|
|
97
|
+
.replace(/"/g, '"')
|
|
98
|
+
.replace(/'/g, "'")
|
|
99
|
+
.replace(/>/g, '>')
|
|
100
|
+
.replace(/</g, '<')
|
|
101
|
+
.replace(/&/g, '&')
|
|
102
|
+
.trim();
|
|
103
|
+
t = t.replace(/<x [^>]*equiv-text="([^"]+)"[^>]*\/>/g, (_m, p1) => {
|
|
104
|
+
let val = p1;
|
|
105
|
+
const interpolation = /\{\{\s*([^}]+?)\s*\}\}/.exec(val);
|
|
106
|
+
if (interpolation) {
|
|
107
|
+
return `{{${interpolation[1].trim()}}}`;
|
|
108
|
+
}
|
|
109
|
+
const cleaned = val.replace(/[^a-zA-Z0-9_]+/g, '_').replace(/^_+|_+$/g, '');
|
|
110
|
+
return `{{${cleaned || 'value'}}}`;
|
|
111
|
+
});
|
|
112
|
+
return t;
|
|
113
|
+
}
|
|
114
|
+
function resolveNamespaceAndKey(options, id) {
|
|
115
|
+
let work = id;
|
|
116
|
+
if (!options.namespace) {
|
|
117
|
+
return { ns: '_flat', key: work };
|
|
118
|
+
}
|
|
119
|
+
const segments = work.split('.');
|
|
120
|
+
let ns = segments[0];
|
|
121
|
+
let rest = segments.slice(1).join('.');
|
|
122
|
+
if (!rest)
|
|
123
|
+
rest = '_';
|
|
124
|
+
return { ns, key: rest };
|
|
125
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/schema",
|
|
3
|
+
"$id": "migrateXlfSchema",
|
|
4
|
+
"title": "Migriert die XLF Übersetzungsdateien in das neue Format.",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"description": "Migriert die XLF Übersetzungsdateien in das neue Format.",
|
|
7
|
+
"properties": {
|
|
8
|
+
"project": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"description": "Der Projektname",
|
|
11
|
+
"$default": {
|
|
12
|
+
"$source": "projectName"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"namespace": {
|
|
16
|
+
"type": "boolean",
|
|
17
|
+
"description": "Deaktiviert die Namensräume in den generierten Dateien.",
|
|
18
|
+
"default": true
|
|
19
|
+
},
|
|
20
|
+
"verbose": {
|
|
21
|
+
"type": "boolean",
|
|
22
|
+
"description": "Generiert mehr Logausgaben",
|
|
23
|
+
"default": false
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"required": [],
|
|
27
|
+
"additionalProperties": false
|
|
28
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const fse = require('fs-extra');
|
|
2
|
+
|
|
3
|
+
console.log('> Script "move-files.js" started...');
|
|
4
|
+
|
|
5
|
+
if (fse.pathExistsSync('dist/browser')) {
|
|
6
|
+
console.log('> Move files...');
|
|
7
|
+
fse.copySync('dist/browser', 'dist/', { overwrite: true });
|
|
8
|
+
fse.removeSync('dist/browser');
|
|
9
|
+
console.log('> Success!');
|
|
10
|
+
} else {
|
|
11
|
+
console.log('> No folder "browser" found. Nothing is to do.');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
console.log('> Script "move-de-files.js" finished.');
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { HttpClient } from '@angular/common/http';
|
|
2
|
+
import { inject, Injectable } from '@angular/core';
|
|
3
|
+
import { Translation, TranslocoLoader } from '@jsverse/transloco';
|
|
4
|
+
import { forkJoin, map } from 'rxjs';
|
|
5
|
+
|
|
6
|
+
@Injectable({ providedIn: 'root' })
|
|
7
|
+
export class TranslocoHttpLoader implements TranslocoLoader {
|
|
8
|
+
private http = inject(HttpClient);
|
|
9
|
+
|
|
10
|
+
getTranslation(lang: string) {
|
|
11
|
+
const luxc$ = this.http.get<Translation>(`/assets/i18n/luxc-${lang}.json`);
|
|
12
|
+
const app$ = this.http.get<Translation>(`/assets/i18n/${lang}.json`);
|
|
13
|
+
|
|
14
|
+
return forkJoin([luxc$, app$]).pipe(map(([luxc, app]) => ({ ...luxc, ...app })));
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { isDevMode } from '@angular/core';
|
|
2
|
+
import { provideTransloco } from '@jsverse/transloco';
|
|
3
|
+
import { TranslocoHttpLoader } from './transloco-loader';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Shared Transloco root provider so the configuration stays in one place.
|
|
7
|
+
*/
|
|
8
|
+
export function provideLuxTranslocoRoot() {
|
|
9
|
+
return provideTransloco({
|
|
10
|
+
config: {
|
|
11
|
+
availableLangs: [
|
|
12
|
+
{ id: 'de', label: 'Deutsch' },
|
|
13
|
+
{ id: 'en', label: 'English' }
|
|
14
|
+
],
|
|
15
|
+
defaultLang: 'de',
|
|
16
|
+
reRenderOnLangChange: true,
|
|
17
|
+
prodMode: !isDevMode()
|
|
18
|
+
},
|
|
19
|
+
loader: TranslocoHttpLoader
|
|
20
|
+
});
|
|
21
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { inject, makeEnvironmentProviders, provideAppInitializer } from '@angular/core';
|
|
2
|
+
import { provideTransloco, TranslocoLoader, TranslocoService } from '@jsverse/transloco';
|
|
3
|
+
import { of } from 'rxjs';
|
|
4
|
+
// Hinweis: setzt "resolveJsonModule" in tsconfig voraus (in Angular Projekten standardmäßig aktiv)
|
|
5
|
+
// Falls nicht aktiv, bitte in tsconfig.lib.json ergänzen.
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
7
|
+
// @ts-ignore - Typen aus JSON
|
|
8
|
+
import deBase from '../locale/de.json';
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
10
|
+
// @ts-ignore
|
|
11
|
+
import enBase from '../locale/en.json';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Test-Provider für Transloco.
|
|
15
|
+
* Lädt standardmäßig die echten Übersetzungen (de/en) und merged optionale Overrides.
|
|
16
|
+
* Optional können einzelne Keys für spezifische Tests überschrieben werden:
|
|
17
|
+
* provideLuxTranslocoTesting({ de: { 'some.key': 'Neuer Wert' } })
|
|
18
|
+
*/
|
|
19
|
+
export function provideLuxTranslocoTesting(customLangs: Record<string, any> = {}) {
|
|
20
|
+
class TestingLoader implements TranslocoLoader {
|
|
21
|
+
getTranslation(lang: string) {
|
|
22
|
+
// Synchronous: real base translations + optional test overrides
|
|
23
|
+
const base = lang === 'de' ? (deBase as any) : lang === 'en' ? (enBase as any) : {};
|
|
24
|
+
const merged = { ...base, ...(customLangs[lang] || {}) };
|
|
25
|
+
return of(merged);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return makeEnvironmentProviders([
|
|
30
|
+
provideTransloco({
|
|
31
|
+
config: {
|
|
32
|
+
availableLangs: [
|
|
33
|
+
{ id: 'de', label: 'Deutsch' },
|
|
34
|
+
{ id: 'en', label: 'English' }
|
|
35
|
+
],
|
|
36
|
+
defaultLang: 'de',
|
|
37
|
+
reRenderOnLangChange: true,
|
|
38
|
+
prodMode: true
|
|
39
|
+
},
|
|
40
|
+
loader: TestingLoader
|
|
41
|
+
}),
|
|
42
|
+
provideAppInitializer(() => {
|
|
43
|
+
const t = inject(TranslocoService);
|
|
44
|
+
t.setActiveLang('de');
|
|
45
|
+
t.setTranslation(deBase as any, 'de', { merge: true });
|
|
46
|
+
t.setTranslation(enBase as any, 'en', { merge: true });
|
|
47
|
+
if (customLangs['de']) t.setTranslation(customLangs['de'], 'de', { merge: true });
|
|
48
|
+
if (customLangs['en']) t.setTranslation(customLangs['en'], 'en', { merge: true });
|
|
49
|
+
})
|
|
50
|
+
]);
|
|
51
|
+
}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.addOrUpdate = exports.updateNodeMinVersion = exports.updateMinVersion = exports.updateMajorVersion = void 0;
|
|
4
|
+
exports.update210000 = update210000;
|
|
5
|
+
exports.updateProject = updateProject;
|
|
6
|
+
exports.updatePackageJson = updatePackageJson;
|
|
7
|
+
exports.migrateToTransloco = migrateToTransloco;
|
|
8
|
+
exports.updatePackageJsonTransloco = updatePackageJsonTransloco;
|
|
9
|
+
exports.updateStylesScss = updateStylesScss;
|
|
10
|
+
exports.updateAngularJson = updateAngularJson;
|
|
11
|
+
exports.updateKarmaConfJs = updateKarmaConfJs;
|
|
12
|
+
exports.updateAngularJsonTransloco = updateAngularJsonTransloco;
|
|
13
|
+
const schematics_1 = require("@angular-devkit/schematics");
|
|
14
|
+
const chalk = require("chalk");
|
|
15
|
+
const update_dependencies_1 = require("../../update-dependencies");
|
|
16
|
+
const dependencies_1 = require("../../utility/dependencies");
|
|
17
|
+
const files_1 = require("../../utility/files");
|
|
18
|
+
const json_1 = require("../../utility/json");
|
|
19
|
+
const logging_1 = require("../../utility/logging");
|
|
20
|
+
const replace_item_1 = require("../../utility/replace-item");
|
|
21
|
+
const typescript_1 = require("../../utility/typescript");
|
|
22
|
+
const util_1 = require("../../utility/util");
|
|
23
|
+
const validation_1 = require("../../utility/validation");
|
|
24
|
+
exports.updateMajorVersion = '21';
|
|
25
|
+
exports.updateMinVersion = '19.6.0';
|
|
26
|
+
exports.updateNodeMinVersion = '20.0.0';
|
|
27
|
+
exports.addOrUpdate = false;
|
|
28
|
+
function update210000(options) {
|
|
29
|
+
return (_tree, _context) => {
|
|
30
|
+
return (0, schematics_1.chain)([check(options), (0, util_1.applyRuleIf)(exports.updateMinVersion, updateProject(options)), (0, util_1.finish)(false, `${chalk.greenBright('Fertig!')}`)]);
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function updateProject(options) {
|
|
34
|
+
return (_tree, _context) => {
|
|
35
|
+
return (0, schematics_1.chain)([
|
|
36
|
+
(0, util_1.messageInfoRule)(`LUX-Components ${exports.updateMajorVersion} werden aktualisiert...`),
|
|
37
|
+
updatePackageJson(options),
|
|
38
|
+
migrateToTransloco(options),
|
|
39
|
+
updateAngularJson(options),
|
|
40
|
+
updateKarmaConfJs(options),
|
|
41
|
+
updateStylesScss(options),
|
|
42
|
+
(0, util_1.messageSuccessRule)(`LUX-Components ${exports.updateMajorVersion} wurden aktualisiert.`)
|
|
43
|
+
]);
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function check(_options) {
|
|
47
|
+
return (tree, _context) => {
|
|
48
|
+
(0, logging_1.logInfoWithDescriptor)(`Vorbedingungen werden geprüft...`);
|
|
49
|
+
(0, validation_1.validateNodeVersion)(_context, exports.updateNodeMinVersion);
|
|
50
|
+
(0, validation_1.validateLuxComponentsVersion)(tree, `${exports.updateMinVersion} || ^${exports.updateMajorVersion}.0.0`);
|
|
51
|
+
(0, logging_1.logSuccess)(`Vorbedingungen wurden geprüft.`);
|
|
52
|
+
return tree;
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function updatePackageJson(_options) {
|
|
56
|
+
return (0, schematics_1.chain)([
|
|
57
|
+
(0, util_1.messageInfoRule)(`Abhängigkeiten in der Datei "package.json" werden aktualisiert...`),
|
|
58
|
+
(0, dependencies_1.updateDep)('@ihk-gfi/lux-components', '21.0.0', exports.addOrUpdate),
|
|
59
|
+
(0, dependencies_1.updateDep)('@ihk-gfi/lux-components-theme', '21.0.0', exports.addOrUpdate),
|
|
60
|
+
(0, dependencies_1.updateDep)('@ihk-gfi/lux-components-icons-and-fonts', '1.10.0', exports.addOrUpdate),
|
|
61
|
+
(0, update_dependencies_1.deleteDep)('@angular-devkit/build-angular'),
|
|
62
|
+
(0, util_1.messageSuccessRule)(`Abhängigkeiten in der Datei "package.json" wurden aktualisiert.`)
|
|
63
|
+
]);
|
|
64
|
+
}
|
|
65
|
+
function migrateToTransloco(options) {
|
|
66
|
+
return (0, schematics_1.chain)([
|
|
67
|
+
(0, util_1.messageInfoRule)(`I18n wird auf Transloco umgestellt...`),
|
|
68
|
+
(0, dependencies_1.updateDep)('@jsverse/transloco', '^8.0.2', exports.addOrUpdate),
|
|
69
|
+
(0, update_dependencies_1.deleteDep)('@angular/localize'),
|
|
70
|
+
updatePackageJsonTransloco(options),
|
|
71
|
+
updateAngularJsonTransloco(options),
|
|
72
|
+
updateMainTsAndTestTs(options),
|
|
73
|
+
updateCompilerOptions(options),
|
|
74
|
+
addTranslocoProvider(options),
|
|
75
|
+
(0, util_1.messageSuccessRule)(`I18n wurde auf Transloco umgestellt.`)
|
|
76
|
+
]);
|
|
77
|
+
}
|
|
78
|
+
function updatePackageJsonTransloco(options) {
|
|
79
|
+
const packageJson = (options.path ?? '') + '/package.json';
|
|
80
|
+
return (0, schematics_1.chain)([
|
|
81
|
+
(0, util_1.messageInfoRule)(`"package.json" wird aktualisiert...`),
|
|
82
|
+
(0, json_1.deleteJsonValue)(packageJson, ['scripts', 'xi18n']),
|
|
83
|
+
(0, json_1.deleteJsonValue)(packageJson, ['scripts', 'start-en']),
|
|
84
|
+
(0, files_1.replaceRule)(options, `--localize wird entfernt...`, `--localize wurde entfernt.`, packageJson, new replace_item_1.ReplaceItem(' --localize', '', true)),
|
|
85
|
+
(0, files_1.deleteFile)(options.path ?? '', 'move-de-files.js'),
|
|
86
|
+
(0, files_1.moveFilesToDirectory)(options, 'files/scripts', '/scripts'),
|
|
87
|
+
(0, files_1.moveFilesToDirectory)(options, 'files/transloco/base', '/src/app'),
|
|
88
|
+
(0, files_1.moveFilesToDirectory)(options, 'files/transloco/i18n', '/src/locale'),
|
|
89
|
+
(0, files_1.moveFilesToDirectory)(options, 'files/transloco/testing', '/src/testing'),
|
|
90
|
+
(0, files_1.replaceRule)(options, `move-de-files wird umbenannt in move-files...`, `move-de-files wurde umbenannt in move-files.`, packageJson, new replace_item_1.ReplaceItem('move-de-files', 'move-files', true), new replace_item_1.ReplaceItem('node move-files.js', 'node scripts/move-files.js', true)),
|
|
91
|
+
(0, util_1.messageSuccessRule)(`"package.json" wurde aktualisiert.`)
|
|
92
|
+
]);
|
|
93
|
+
}
|
|
94
|
+
function addTranslocoProvider(options) {
|
|
95
|
+
return (tree, _context) => {
|
|
96
|
+
const appConfigTs = (options.path ?? '') + '/src/app/app.config.ts';
|
|
97
|
+
const appModuleTs = (options.path ?? '') + '/src/app/app.module.ts';
|
|
98
|
+
const tsFile = tree.exists(appConfigTs) ? appConfigTs : appModuleTs;
|
|
99
|
+
if (!tree.exists(tsFile)) {
|
|
100
|
+
(0, logging_1.logError)(`Weder "app.config.ts" noch "app.module.ts" wurde im Pfad "${options.path}/src/app/" gefunden.`);
|
|
101
|
+
(0, logging_1.logError)(`Der Transloco-Provider konnte nicht hinzugefügt werden.`);
|
|
102
|
+
return tree;
|
|
103
|
+
}
|
|
104
|
+
(0, typescript_1.addImport)(tree, tsFile, '@angular/core', 'inject');
|
|
105
|
+
(0, typescript_1.addImport)(tree, tsFile, '@angular/core', 'provideAppInitializer');
|
|
106
|
+
(0, typescript_1.addImport)(tree, tsFile, './transloco-root.config', 'provideLuxTranslocoRoot');
|
|
107
|
+
(0, typescript_1.addImport)(tree, tsFile, 'ngx-cookie-service', 'CookieService');
|
|
108
|
+
(0, typescript_1.addImport)(tree, tsFile, '@jsverse/transloco', 'LangDefinition');
|
|
109
|
+
(0, typescript_1.addImport)(tree, tsFile, '@jsverse/transloco', 'TranslocoService');
|
|
110
|
+
(0, typescript_1.addImport)(tree, tsFile, 'rxjs', 'firstValueFrom');
|
|
111
|
+
(0, typescript_1.addComponentProvider)(tree, tsFile, `provideAppInitializer(() => {
|
|
112
|
+
// Dependencies per inject() to avoid deprecated APP_INITIALIZER pattern.
|
|
113
|
+
const t = inject(TranslocoService);
|
|
114
|
+
const cookieService = inject(CookieService);
|
|
115
|
+
|
|
116
|
+
// Sprache aus CookieService auslesen (gleiches Cookie wie LuxLangSelectAcComponent)
|
|
117
|
+
const cookieLang = cookieService.get('X-GFI-LANGUAGE');
|
|
118
|
+
const available = t.getAvailableLangs().map((l) => (l as LangDefinition).id);
|
|
119
|
+
const chosen = cookieLang && available.includes(cookieLang) ? cookieLang : 'de';
|
|
120
|
+
|
|
121
|
+
// Sprache setzen bevor Komponenten erstellt werden.
|
|
122
|
+
t.setActiveLang(chosen);
|
|
123
|
+
// Sicherstellen, dass Ressourcen geladen sind bevor Bootstrap finalisiert.
|
|
124
|
+
return firstValueFrom(t.load(chosen));
|
|
125
|
+
})`);
|
|
126
|
+
(0, typescript_1.addComponentProvider)(tree, tsFile, `CookieService`);
|
|
127
|
+
(0, typescript_1.addComponentProvider)(tree, tsFile, `provideLuxTranslocoRoot()`);
|
|
128
|
+
return tree;
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
function updateStylesScss(options) {
|
|
132
|
+
const filePath = (options.path ?? '') + '/src/styles.scss';
|
|
133
|
+
return (0, schematics_1.chain)([
|
|
134
|
+
(0, files_1.replaceRule)(options, `"styles.scss" wird aktualisiert...`, `"styles.scss" wurde aktualisiert.`, filePath, new replace_item_1.ReplaceItem('@ihk-gfi/lux-components-theme/src/base/luxfonts', '@ihk-gfi/lux-components-theme/src/base-templates/common/luxfonts', true))
|
|
135
|
+
]);
|
|
136
|
+
}
|
|
137
|
+
function updateAngularJson(options) {
|
|
138
|
+
const filePath = (options.path ?? '') + '/angular.json';
|
|
139
|
+
return (0, schematics_1.chain)([
|
|
140
|
+
(0, files_1.replaceRule)(options, `"angular.json" wird aktualisiert...`, `"angular.json" wurde aktualisiert.`, filePath, new replace_item_1.ReplaceItem('@angular-devkit/build-angular', '@angular/build', true))
|
|
141
|
+
]);
|
|
142
|
+
}
|
|
143
|
+
function updateKarmaConfJs(options) {
|
|
144
|
+
const filePath = (options.path ?? '') + '/karma.conf.js';
|
|
145
|
+
return (0, schematics_1.chain)([
|
|
146
|
+
(0, files_1.replaceRule)(options, `"karma.conf.js" wird aktualisiert...`, `"karma.conf.js" wurde aktualisiert.`, filePath, new replace_item_1.ReplaceItem('require(\'@angular-devkit/build-angular/plugins/karma\')', '', true), new replace_item_1.ReplaceItem('require("@angular-devkit/build-angular/plugins/karma")', '', true), new replace_item_1.ReplaceItem('require(\'@angular-devkit/build-angular/plugins/karma\'),', '', true), new replace_item_1.ReplaceItem('require("@angular-devkit/build-angular/plugins/karma"),', '', true))
|
|
147
|
+
]);
|
|
148
|
+
}
|
|
149
|
+
function updateAngularJsonTransloco(options) {
|
|
150
|
+
const angularJson = (options.path ?? '') + '/angular.json';
|
|
151
|
+
const i18nComponents = {
|
|
152
|
+
glob: '*.json',
|
|
153
|
+
input: 'node_modules/@ihk-gfi/lux-components/locale',
|
|
154
|
+
output: './assets/i18n'
|
|
155
|
+
};
|
|
156
|
+
const i18nApp = {
|
|
157
|
+
glob: '*.json',
|
|
158
|
+
input: 'src/locale',
|
|
159
|
+
output: './assets/i18n'
|
|
160
|
+
};
|
|
161
|
+
const angularInitFn = (node) => (0, json_1.findStringInArray)(node, '@angular/localize/init');
|
|
162
|
+
return (0, schematics_1.chain)([
|
|
163
|
+
(0, util_1.messageInfoRule)(`"angular.json" wird aktualisiert...`),
|
|
164
|
+
(0, json_1.deleteJsonValue)(angularJson, ['projects', options.project, 'i18n']),
|
|
165
|
+
(0, json_1.updateJsonArray)(angularJson, ['projects', options.project, 'architect', 'build', 'options', 'assets'], i18nComponents),
|
|
166
|
+
(0, json_1.updateJsonArray)(angularJson, ['projects', options.project, 'architect', 'build', 'options', 'assets'], i18nApp),
|
|
167
|
+
(0, json_1.updateJsonArray)(angularJson, ['projects', options.project, 'architect', 'test', 'options', 'assets'], i18nComponents),
|
|
168
|
+
(0, json_1.updateJsonArray)(angularJson, ['projects', options.project, 'architect', 'test', 'options', 'assets'], i18nApp),
|
|
169
|
+
(0, json_1.deleteJsonArray)(angularJson, ['projects', options.project, 'architect', 'build', 'options', 'polyfills'], angularInitFn),
|
|
170
|
+
(0, json_1.deleteJsonArray)(angularJson, ['projects', options.project, 'architect', 'test', 'options', 'polyfills'], angularInitFn),
|
|
171
|
+
(0, json_1.deleteJsonValue)(angularJson, ['projects', options.project, 'architect', 'build', 'options', 'localize']),
|
|
172
|
+
(0, json_1.deleteJsonValue)(angularJson, ['projects', options.project, 'architect', 'build', 'options', 'i18nMissingTranslation']),
|
|
173
|
+
(0, json_1.deleteJsonValue)(angularJson, ['projects', options.project, 'architect', 'build', 'configurations', 'en']),
|
|
174
|
+
(0, json_1.deleteJsonValue)(angularJson, ['projects', options.project, 'architect', 'extract-i18n']),
|
|
175
|
+
(0, util_1.messageSuccessRule)(`"angular.json" wurde aktualisiert.`)
|
|
176
|
+
]);
|
|
177
|
+
}
|
|
178
|
+
function updateMainTsAndTestTs(options) {
|
|
179
|
+
return (tree, _context) => {
|
|
180
|
+
(0, files_1.iterateFilesAndModifyContent)(tree, options.path, (filePath, content) => {
|
|
181
|
+
let result = content;
|
|
182
|
+
result = (0, util_1.replaceAll)(result, `/// <reference types="@angular/localize" />`, ``);
|
|
183
|
+
if (content !== result) {
|
|
184
|
+
(0, logging_1.logInfo)(filePath + ' wurde angepasst.');
|
|
185
|
+
tree.overwrite(filePath, result);
|
|
186
|
+
}
|
|
187
|
+
}, 'main.ts', 'test.ts');
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
function updateCompilerOptions(options) {
|
|
191
|
+
return (tree, _context) => {
|
|
192
|
+
const paths = ['/tsconfig.json', '/tsconfig.spec.json', '/tsconfig.app.json'];
|
|
193
|
+
const prePath = options.path ?? '';
|
|
194
|
+
const rules = [];
|
|
195
|
+
for (const filePath of paths) {
|
|
196
|
+
const path1 = prePath + filePath;
|
|
197
|
+
if (tree.exists(path1)) {
|
|
198
|
+
rules.push((0, json_1.deleteJsonArray)(path1, ['compilerOptions', 'types'], (node) => (0, json_1.findStringInArray)(node, '@angular/localize')));
|
|
199
|
+
}
|
|
200
|
+
const path2 = prePath + `/src` + filePath;
|
|
201
|
+
if (tree.exists(path2)) {
|
|
202
|
+
rules.push((0, json_1.deleteJsonArray)(path2, ['compilerOptions', 'types'], (node) => (0, json_1.findStringInArray)(node, '@angular/localize')));
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return (0, schematics_1.chain)(rules);
|
|
206
|
+
};
|
|
207
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/schema",
|
|
3
|
+
"$id": "luxUpdateSchema",
|
|
4
|
+
"title": "Aktualisiert das LUX-Componentsprojekt",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"description": "Aktualisiert das LUX-Componentsprojekt",
|
|
7
|
+
"properties": {
|
|
8
|
+
"project": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"description": "Der Projektname",
|
|
11
|
+
"$default": {
|
|
12
|
+
"$source": "projectName"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"verbose": {
|
|
16
|
+
"type": "boolean",
|
|
17
|
+
"description": "Generiert mehr Logausgaben",
|
|
18
|
+
"default": false
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"required": [],
|
|
22
|
+
"additionalProperties": false
|
|
23
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.update210100 = update210100;
|
|
4
|
+
const schematics_1 = require("@angular-devkit/schematics");
|
|
5
|
+
const chalk = require("chalk");
|
|
6
|
+
const index_1 = require("../../update-dependencies/index");
|
|
7
|
+
const util_1 = require("../../utility/util");
|
|
8
|
+
function update210100(_options, runNpmInstall = true) {
|
|
9
|
+
return (_tree, _context) => {
|
|
10
|
+
return (0, schematics_1.chain)([
|
|
11
|
+
(0, util_1.messageInfoRule)(`Die LUX-Components werden auf die Version 21.1.0 aktualisiert...`),
|
|
12
|
+
(0, util_1.messageInfoRule)(`Die Datei "package.json" wird angepasst...`),
|
|
13
|
+
(0, index_1.updateDep)('@ihk-gfi/lux-components', '21.1.0', false),
|
|
14
|
+
(0, index_1.updateDep)('@ihk-gfi/lux-components-theme', '21.1.0', false),
|
|
15
|
+
(0, util_1.messageSuccessRule)(`Die LUX-Components wurden auf die Version 21.1.0 aktualisiert.`),
|
|
16
|
+
(0, util_1.finish)(runNpmInstall, `${chalk.yellowBright('Fertig!')}`)
|
|
17
|
+
]);
|
|
18
|
+
};
|
|
19
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/schema",
|
|
3
|
+
"$id": "luxupdate210100Schema",
|
|
4
|
+
"title": "Aktualisiert das LUX-Componentsprojekt",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"description": "Aktualisiert das LUX-Componentsprojekt",
|
|
7
|
+
"properties": {
|
|
8
|
+
"project": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"description": "Der Projektname",
|
|
11
|
+
"$default": {
|
|
12
|
+
"$source": "projectName"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"verbose": {
|
|
16
|
+
"type": "boolean",
|
|
17
|
+
"description": "Generiert mehr Logausgaben",
|
|
18
|
+
"default": false
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"required": [],
|
|
22
|
+
"additionalProperties": false
|
|
23
|
+
}
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.NodeDependencyType = void 0;
|
|
4
|
-
exports.
|
|
5
|
-
exports.
|
|
6
|
-
exports.
|
|
7
|
-
exports.
|
|
8
|
-
exports.
|
|
9
|
-
exports.
|
|
10
|
-
const chalk = require("chalk");
|
|
4
|
+
exports.hasDep = hasDep;
|
|
5
|
+
exports.getDep = getDep;
|
|
6
|
+
exports.updateDep = updateDep;
|
|
7
|
+
exports.deleteDep = deleteDep;
|
|
8
|
+
exports.updateDevDep = updateDevDep;
|
|
9
|
+
exports.deleteDevDep = deleteDevDep;
|
|
11
10
|
const jsonc_parser_1 = require("jsonc-parser");
|
|
12
|
-
const files_1 = require("./files");
|
|
13
11
|
const json_1 = require("./json");
|
|
14
12
|
const logging_1 = require("./logging");
|
|
15
13
|
var NodeDependencyType;
|
|
@@ -24,7 +22,7 @@ var NodeDependencyType;
|
|
|
24
22
|
* @param tree
|
|
25
23
|
* @param name
|
|
26
24
|
*/
|
|
27
|
-
function
|
|
25
|
+
function hasDep(tree, name) {
|
|
28
26
|
const packageJsonNode = (0, json_1.readJson)(tree, '/package.json');
|
|
29
27
|
let dependency = undefined;
|
|
30
28
|
[NodeDependencyType.Default, NodeDependencyType.Dev, NodeDependencyType.Optional, NodeDependencyType.Peer].forEach((depType) => {
|
|
@@ -44,7 +42,7 @@ function hasPackageJsonDependency(tree, name) {
|
|
|
44
42
|
* @param tree
|
|
45
43
|
* @param name
|
|
46
44
|
*/
|
|
47
|
-
function
|
|
45
|
+
function getDep(tree, name) {
|
|
48
46
|
const packageJsonNode = (0, json_1.readJson)(tree, '/package.json');
|
|
49
47
|
let dependency = null;
|
|
50
48
|
[NodeDependencyType.Default, NodeDependencyType.Dev, NodeDependencyType.Optional, NodeDependencyType.Peer].forEach((depType) => {
|
|
@@ -64,53 +62,15 @@ function getPackageJsonDependency(tree, name) {
|
|
|
64
62
|
throw (0, logging_1.formattedSchematicsException)(`Dependency ${name} nicht in der package.json gefunden.`);
|
|
65
63
|
}
|
|
66
64
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
* @param tree
|
|
70
|
-
* @param name
|
|
71
|
-
* @param verion
|
|
72
|
-
*/
|
|
73
|
-
function updateDependency(tree, name, version) {
|
|
74
|
-
updatePackageJsonDependency(tree, { type: NodeDependencyType.Default, name: name, version: version });
|
|
65
|
+
function updateDep(name, version, onlyUpdate) {
|
|
66
|
+
return (0, json_1.updateJsonValue)('/package.json', [NodeDependencyType.Default, name], version, onlyUpdate);
|
|
75
67
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
* @param tree
|
|
79
|
-
* @param name
|
|
80
|
-
* @param verion
|
|
81
|
-
*/
|
|
82
|
-
function updateDependencyDev(tree, name, version) {
|
|
83
|
-
updatePackageJsonDependency(tree, { type: NodeDependencyType.Dev, name: name, version: version });
|
|
68
|
+
function deleteDep(name) {
|
|
69
|
+
return (0, json_1.updateJsonValue)('/package.json', [NodeDependencyType.Default, name], void 0, true);
|
|
84
70
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
* @param tree
|
|
88
|
-
* @param dependency
|
|
89
|
-
*/
|
|
90
|
-
function updatePackageJsonDependency(tree, dependency) {
|
|
91
|
-
const packageJsonAsNode = (0, json_1.readJson)(tree, '/package.json');
|
|
92
|
-
let node = (0, jsonc_parser_1.findNodeAtLocation)(packageJsonAsNode, [dependency.type.toString(), dependency.name]);
|
|
93
|
-
if (node) {
|
|
94
|
-
if (node && node.value !== dependency.version) {
|
|
95
|
-
(0, logging_1.logInfo)(`Dependency ` + chalk.yellowBright(`${dependency.name}`) + ` ${node.value} wird ersetzt durch ${dependency.version}.`);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
(0, logging_1.logInfo)(`Dependency ` + chalk.yellowBright(`${dependency.name}`) + ` ${dependency.version} wird im Abschnitt ${dependency.type} hinzugefügt.`);
|
|
100
|
-
}
|
|
101
|
-
if (!node || node.value !== dependency.version) {
|
|
102
|
-
const packageJonsAsString = (0, json_1.readJsonAsString)(tree, '/package.json');
|
|
103
|
-
const edits = (0, jsonc_parser_1.modify)(packageJonsAsString, [dependency.type.toString(), dependency.name], dependency.version, {
|
|
104
|
-
formattingOptions: json_1.jsonFormattingOptions
|
|
105
|
-
});
|
|
106
|
-
if (edits) {
|
|
107
|
-
tree.overwrite('/package.json', (0, jsonc_parser_1.applyEdits)(packageJonsAsString, edits));
|
|
108
|
-
}
|
|
109
|
-
}
|
|
71
|
+
function updateDevDep(name, version, onlyUpdate) {
|
|
72
|
+
return (0, json_1.updateJsonValue)('/package.json', [NodeDependencyType.Dev, name], version, onlyUpdate);
|
|
110
73
|
}
|
|
111
|
-
function
|
|
112
|
-
|
|
113
|
-
if (changed) {
|
|
114
|
-
(0, logging_1.logInfo)(`Dependency ` + chalk.yellowBright(`${dependency.name}`) + ` wurde aus dem Abschnitt ${dependency.type} gelöscht.`);
|
|
115
|
-
}
|
|
74
|
+
function deleteDevDep(name) {
|
|
75
|
+
return (0, json_1.updateJsonValue)('/package.json', [NodeDependencyType.Dev, name], void 0, true);
|
|
116
76
|
}
|
|
@@ -6,6 +6,8 @@ exports.removeInterface = removeInterface;
|
|
|
6
6
|
exports.addImport = addImport;
|
|
7
7
|
exports.removeImport = removeImport;
|
|
8
8
|
exports.addComponentImport = addComponentImport;
|
|
9
|
+
exports.addComponentProvider = addComponentProvider;
|
|
10
|
+
exports.addComponent = addComponent;
|
|
9
11
|
exports.removeComponentImport = removeComponentImport;
|
|
10
12
|
exports.removeComponentProvider = removeComponentProvider;
|
|
11
13
|
exports.getSiblings = getSiblings;
|
|
@@ -304,11 +306,17 @@ function removeImport(tree, filePath, packageName, importName, logMessage = true
|
|
|
304
306
|
}
|
|
305
307
|
}
|
|
306
308
|
function addComponentImport(tree, filePath, importName, logMessage = true) {
|
|
309
|
+
addComponent(tree, filePath, "imports", importName, logMessage);
|
|
310
|
+
}
|
|
311
|
+
function addComponentProvider(tree, filePath, importName, logMessage = true) {
|
|
312
|
+
addComponent(tree, filePath, "providers", importName, logMessage);
|
|
313
|
+
}
|
|
314
|
+
function addComponent(tree, filePath, property, importName, logMessage = true) {
|
|
307
315
|
const content = tree.read(filePath).toString();
|
|
308
316
|
const fileName = filePath.substring(filePath.lastIndexOf('/') + 1, filePath.length);
|
|
309
317
|
const sourceFile = ts.createSourceFile(`${fileName}`, content, ts.ScriptTarget.Latest, true);
|
|
310
318
|
const nodes = getSourceNodes(sourceFile);
|
|
311
|
-
const importIdentifierNode = nodes.find((n) => n.kind === ts.SyntaxKind.Identifier && n.getText() ===
|
|
319
|
+
const importIdentifierNode = nodes.find((n) => n.kind === ts.SyntaxKind.Identifier && n.getText() === property);
|
|
312
320
|
if (importIdentifierNode) {
|
|
313
321
|
const siblings = importIdentifierNode.parent.getChildren();
|
|
314
322
|
if (siblings) {
|
|
@@ -324,7 +332,7 @@ function addComponentImport(tree, filePath, importName, logMessage = true) {
|
|
|
324
332
|
updateRecorder.insertLeft(importChildren[0].pos, `${importName}, `);
|
|
325
333
|
tree.commitUpdate(updateRecorder);
|
|
326
334
|
if (logMessage) {
|
|
327
|
-
(0, logging_1.logInfo)(
|
|
335
|
+
(0, logging_1.logInfo)(`${property} ${importName} hinzugefügt.`);
|
|
328
336
|
}
|
|
329
337
|
}
|
|
330
338
|
}
|
|
@@ -333,7 +341,7 @@ function addComponentImport(tree, filePath, importName, logMessage = true) {
|
|
|
333
341
|
updateRecorder.insertLeft(importNode.end, `${importName}`);
|
|
334
342
|
tree.commitUpdate(updateRecorder);
|
|
335
343
|
if (logMessage) {
|
|
336
|
-
(0, logging_1.logInfo)(
|
|
344
|
+
(0, logging_1.logInfo)(`${property} ${importName} hinzugefügt.`);
|
|
337
345
|
}
|
|
338
346
|
}
|
|
339
347
|
}
|
|
@@ -346,10 +354,10 @@ function addComponentImport(tree, filePath, importName, logMessage = true) {
|
|
|
346
354
|
if (selectIdentifierNode) {
|
|
347
355
|
const lastNode = selectIdentifierNode.parent.getChildren()[selectIdentifierNode.parent.getChildren().length - 1];
|
|
348
356
|
const updateRecorder = tree.beginUpdate(filePath);
|
|
349
|
-
updateRecorder.insertLeft(lastNode.end, `,\n
|
|
357
|
+
updateRecorder.insertLeft(lastNode.end, `,\n ${property}: [${importName}]`);
|
|
350
358
|
tree.commitUpdate(updateRecorder);
|
|
351
359
|
if (logMessage) {
|
|
352
|
-
(0, logging_1.logInfo)(
|
|
360
|
+
(0, logging_1.logInfo)(`${property} ${importName} hinzugefügt.`);
|
|
353
361
|
}
|
|
354
362
|
}
|
|
355
363
|
}
|
package/src/utility/util.js
CHANGED
|
@@ -116,7 +116,7 @@ function applyRuleIfFileNotExists(rule, path) {
|
|
|
116
116
|
}
|
|
117
117
|
function applyRuleIf(minVersion, rule) {
|
|
118
118
|
return (tree, _context) => {
|
|
119
|
-
let version = (0, dependencies_1.
|
|
119
|
+
let version = (0, dependencies_1.getDep)(tree, '@ihk-gfi/lux-components').version;
|
|
120
120
|
if (semver.satisfies(minVersion, version)) {
|
|
121
121
|
return rule;
|
|
122
122
|
}
|
|
@@ -16,14 +16,8 @@ function validateNodeVersion(_context, minimumVersion) {
|
|
|
16
16
|
}
|
|
17
17
|
(0, logging_1.logInfo)(`Nodeversion ${process.versions.node} -> ok`);
|
|
18
18
|
}
|
|
19
|
-
/**
|
|
20
|
-
* Prüft die Angular Version der aufrufenden Applikation und wirft eine SchematicsException, wenn
|
|
21
|
-
* die Version nicht der erforderlichen entspricht.
|
|
22
|
-
* @param tree
|
|
23
|
-
* @param angularVersion
|
|
24
|
-
*/
|
|
25
19
|
function validateAngularVersion(tree, angularVersion) {
|
|
26
|
-
const currentVersion = (0, dependencies_1.
|
|
20
|
+
const currentVersion = (0, dependencies_1.getDep)(tree, '@angular/common').version.replace(/([\^~])/g, '');
|
|
27
21
|
if (!semver.satisfies(currentVersion, angularVersion)) {
|
|
28
22
|
(0, logging_1.logInfo)(`Angularversion ${currentVersion} -> ${chalk.redBright('fail')}`);
|
|
29
23
|
throw (0, logging_1.formattedSchematicsException)(`Sie nutzen die Angular Version ${currentVersion}.`, `Dieser Generator benötigt allerdings eine ${angularVersion}.`, `Bitte nutzen Sie eine neuere Schematic für Ihr Update.`);
|
|
@@ -31,7 +25,7 @@ function validateAngularVersion(tree, angularVersion) {
|
|
|
31
25
|
(0, logging_1.logInfo)(`Angularversion ${currentVersion} -> ok`);
|
|
32
26
|
}
|
|
33
27
|
function validateLuxComponentsVersion(tree, versionRange) {
|
|
34
|
-
const version = (0, dependencies_1.
|
|
28
|
+
const version = (0, dependencies_1.getDep)(tree, '@ihk-gfi/lux-components').version.replace(/([\^~])/g, '');
|
|
35
29
|
if (!semver.satisfies(version, versionRange)) {
|
|
36
30
|
(0, logging_1.logInfo)(`LUX-Componentsversion ${version} -> ${chalk.redBright('fail')}`);
|
|
37
31
|
throw (0, logging_1.formattedSchematicsException)(`Die LUX-Componentsversion ${version} wird nicht unterstützt. ` + `Dieser Updater unterstützt die Versionen ${versionRange}.`);
|