@aidc-toolkit/app-extension 1.0.26-beta → 1.0.28-beta
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/dist/index.cjs +1205 -967
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +134 -312
- package/dist/index.d.ts +134 -312
- package/dist/index.js +1207 -964
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
- package/src/app-extension.ts +33 -24
- package/src/app-utility-proxy.ts +33 -27
- package/src/descriptor.ts +29 -199
- package/src/generator/generator.ts +102 -145
- package/src/generator/index.ts +0 -1
- package/src/generator/locale-resources-generator.ts +67 -42
- package/src/gs1/character-set-proxy.ts +5 -5
- package/src/gs1/check-proxy.ts +35 -42
- package/src/gs1/gtin-creator-proxy.ts +58 -0
- package/src/gs1/gtin-descriptor.ts +29 -0
- package/src/gs1/gtin-validator-proxy.ts +161 -0
- package/src/gs1/identifier-creator-proxy.ts +227 -0
- package/src/gs1/identifier-validator-proxy.ts +87 -0
- package/src/gs1/index.ts +5 -1
- package/src/gs1/non-gtin-creator-proxy.ts +119 -0
- package/src/gs1/non-gtin-validator-proxy.ts +119 -0
- package/src/gs1/prefix-definition-descriptor.ts +18 -0
- package/src/gs1/prefix-manager-proxy.ts +42 -0
- package/src/index.ts +1 -0
- package/src/lib-proxy.ts +22 -19
- package/src/proxy.ts +509 -0
- package/src/utility/character-set-descriptor.ts +5 -5
- package/src/utility/character-set-proxy.ts +39 -55
- package/src/utility/reg-exp-proxy.ts +11 -15
- package/src/utility/string-descriptor.ts +2 -2
- package/src/utility/transformer-descriptor.ts +3 -3
- package/src/utility/transformer-proxy.ts +16 -26
- package/tsconfig-src.json +1 -4
- package/src/generator/descriptor.ts +0 -122
- package/src/gs1/identifier-proxy.ts +0 -825
|
@@ -1,17 +1,11 @@
|
|
|
1
1
|
import { I18nEnvironments } from "@aidc-toolkit/core";
|
|
2
2
|
import type { ParseKeys } from "i18next";
|
|
3
3
|
import { AppUtilityProxy } from "../app-utility-proxy.js";
|
|
4
|
-
import {
|
|
4
|
+
import type { ClassDescriptor, MethodDescriptor } from "../descriptor.js";
|
|
5
5
|
import * as GS1 from "../gs1/index.js";
|
|
6
6
|
import { appExtensionResources, i18nAppExtensionInit, i18nextAppExtension } from "../locale/i18n.js";
|
|
7
|
+
import { proxy } from "../proxy.js";
|
|
7
8
|
import * as Utility from "../utility/index.js";
|
|
8
|
-
import type {
|
|
9
|
-
FunctionLocalization,
|
|
10
|
-
Localization,
|
|
11
|
-
ParameterLocalization,
|
|
12
|
-
ProxyFunctionDescriptor,
|
|
13
|
-
ProxyObjectDescriptor
|
|
14
|
-
} from "./descriptor.js";
|
|
15
9
|
|
|
16
10
|
/**
|
|
17
11
|
* Dummy method to force proxies to register their decorators.
|
|
@@ -23,6 +17,35 @@ function registerProxies(..._proxies: unknown[]): void {
|
|
|
23
17
|
}
|
|
24
18
|
|
|
25
19
|
registerProxies(AppUtilityProxy, Utility, GS1);
|
|
20
|
+
/**
|
|
21
|
+
* Localization.
|
|
22
|
+
*/
|
|
23
|
+
export interface Localization {
|
|
24
|
+
/**
|
|
25
|
+
* Name.
|
|
26
|
+
*/
|
|
27
|
+
name: string;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Description.
|
|
31
|
+
*/
|
|
32
|
+
description: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Function localization.
|
|
37
|
+
*/
|
|
38
|
+
export interface FunctionLocalization extends Localization {
|
|
39
|
+
/**
|
|
40
|
+
* Documentation URL.
|
|
41
|
+
*/
|
|
42
|
+
documentationURL: string;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Parameters map.
|
|
46
|
+
*/
|
|
47
|
+
parametersMap: Map<string, Localization>;
|
|
48
|
+
}
|
|
26
49
|
|
|
27
50
|
/**
|
|
28
51
|
* Abstract generator.
|
|
@@ -31,36 +54,27 @@ export abstract class Generator {
|
|
|
31
54
|
/**
|
|
32
55
|
* Documentation base URL.
|
|
33
56
|
*/
|
|
34
|
-
|
|
57
|
+
static readonly #DOCUMENTATION_BASE_URL = "https://aidc-toolkit.com/";
|
|
35
58
|
|
|
36
59
|
/**
|
|
37
60
|
* Documentation path, optionally preceded by locale.
|
|
38
61
|
*/
|
|
39
|
-
|
|
62
|
+
static readonly #DOCUMENTATION_PATH = "app-extension/";
|
|
40
63
|
|
|
41
64
|
/**
|
|
42
65
|
* Locales.
|
|
43
66
|
*/
|
|
44
|
-
|
|
67
|
+
readonly #locales: readonly string[];
|
|
45
68
|
|
|
46
69
|
/**
|
|
47
70
|
* Default locale.
|
|
48
71
|
*/
|
|
49
|
-
|
|
72
|
+
readonly #defaultLocale: string;
|
|
50
73
|
|
|
51
74
|
/**
|
|
52
75
|
* Map of function localizations maps by namespace function name.
|
|
53
76
|
*/
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Map of parameter localizations maps by namespace function parameter name.
|
|
58
|
-
*/
|
|
59
|
-
private readonly _parameterLocalizationsMapsMap = new Map<string, ReadonlyMap<string, ParameterLocalization>>();
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
*
|
|
63
|
-
*/
|
|
77
|
+
readonly #functionLocalizationsMapsMap = new Map<string, ReadonlyMap<string, FunctionLocalization>>();
|
|
64
78
|
|
|
65
79
|
/**
|
|
66
80
|
* Constructor.
|
|
@@ -69,38 +83,38 @@ export abstract class Generator {
|
|
|
69
83
|
* Include localizations if true.
|
|
70
84
|
*/
|
|
71
85
|
constructor(includeLocalizations = true) {
|
|
72
|
-
this
|
|
73
|
-
this
|
|
86
|
+
this.#locales = includeLocalizations ? Object.keys(appExtensionResources) : [];
|
|
87
|
+
this.#defaultLocale = this.#locales[0] ?? "";
|
|
74
88
|
}
|
|
75
89
|
|
|
76
90
|
/**
|
|
77
91
|
* Get the locales.
|
|
78
92
|
*/
|
|
79
93
|
protected get locales(): readonly string[] {
|
|
80
|
-
return this
|
|
94
|
+
return this.#locales;
|
|
81
95
|
}
|
|
82
96
|
|
|
83
97
|
/**
|
|
84
98
|
* Get the default locale.
|
|
85
99
|
*/
|
|
86
100
|
protected get defaultLocale(): string {
|
|
87
|
-
return this
|
|
101
|
+
return this.#defaultLocale;
|
|
88
102
|
}
|
|
89
103
|
|
|
90
104
|
/**
|
|
91
105
|
* Get function localization.
|
|
92
106
|
*
|
|
93
|
-
* @param namespaceFunctionName
|
|
94
|
-
* Namespace function name.
|
|
95
|
-
*
|
|
96
107
|
* @param locale
|
|
97
108
|
* Locale.
|
|
98
109
|
*
|
|
110
|
+
* @param namespaceFunctionName
|
|
111
|
+
* Namespace function name.
|
|
112
|
+
*
|
|
99
113
|
* @returns
|
|
100
114
|
* Function localization.
|
|
101
115
|
*/
|
|
102
|
-
protected getFunctionLocalization(
|
|
103
|
-
const functionLocalization = this.
|
|
116
|
+
protected getFunctionLocalization(locale: string, namespaceFunctionName: string): FunctionLocalization {
|
|
117
|
+
const functionLocalization = this.#functionLocalizationsMapsMap.get(namespaceFunctionName)?.get(locale);
|
|
104
118
|
|
|
105
119
|
if (functionLocalization === undefined) {
|
|
106
120
|
throw new Error(`${locale} localization for function ${namespaceFunctionName} not found`);
|
|
@@ -112,20 +126,20 @@ export abstract class Generator {
|
|
|
112
126
|
/**
|
|
113
127
|
* Get parameter localization.
|
|
114
128
|
*
|
|
129
|
+
* @param locale
|
|
130
|
+
* Locale.
|
|
131
|
+
*
|
|
115
132
|
* @param namespaceFunctionName
|
|
116
133
|
* Namespace function name.
|
|
117
134
|
*
|
|
118
135
|
* @param parameterName
|
|
119
136
|
* Parameter name.
|
|
120
137
|
*
|
|
121
|
-
* @param locale
|
|
122
|
-
* Locale.
|
|
123
|
-
*
|
|
124
138
|
* @returns
|
|
125
|
-
*
|
|
139
|
+
* Parameter localization.
|
|
126
140
|
*/
|
|
127
|
-
protected getParameterLocalization(
|
|
128
|
-
const parameterLocalization = this.
|
|
141
|
+
protected getParameterLocalization(locale: string, namespaceFunctionName: string, parameterName: string): Localization {
|
|
142
|
+
const parameterLocalization = this.getFunctionLocalization(locale, namespaceFunctionName).parametersMap.get(parameterName);
|
|
129
143
|
|
|
130
144
|
if (parameterLocalization === undefined) {
|
|
131
145
|
throw new Error(`${locale} localization for function ${namespaceFunctionName} parameter ${parameterName} not found`);
|
|
@@ -140,20 +154,26 @@ export abstract class Generator {
|
|
|
140
154
|
protected abstract initialize(): void;
|
|
141
155
|
|
|
142
156
|
/**
|
|
143
|
-
* Create a proxy object.
|
|
157
|
+
* Create a proxy object for a class.
|
|
144
158
|
*
|
|
145
|
-
* @param
|
|
146
|
-
*
|
|
159
|
+
* @param classDescriptor
|
|
160
|
+
* Class descriptor.
|
|
147
161
|
*/
|
|
148
|
-
protected abstract createProxyObject(
|
|
162
|
+
protected abstract createProxyObject(classDescriptor: ClassDescriptor): void;
|
|
149
163
|
|
|
150
164
|
/**
|
|
151
|
-
* Create a proxy function.
|
|
165
|
+
* Create a proxy function for a class and method.
|
|
152
166
|
*
|
|
153
|
-
* @param
|
|
154
|
-
*
|
|
167
|
+
* @param classDescriptor
|
|
168
|
+
* Class descriptor.
|
|
169
|
+
*
|
|
170
|
+
* @param methodDescriptor
|
|
171
|
+
* Method descriptor.
|
|
172
|
+
*
|
|
173
|
+
* @param functionLocalizationsMap
|
|
174
|
+
* Localizations map.
|
|
155
175
|
*/
|
|
156
|
-
protected abstract createProxyFunction(
|
|
176
|
+
protected abstract createProxyFunction(classDescriptor: ClassDescriptor, methodDescriptor: MethodDescriptor, functionLocalizationsMap: ReadonlyMap<string, FunctionLocalization>): void;
|
|
157
177
|
|
|
158
178
|
/**
|
|
159
179
|
* Finalize the generation of the output.
|
|
@@ -164,7 +184,13 @@ export abstract class Generator {
|
|
|
164
184
|
protected abstract finalize(success: boolean): void | Promise<void>;
|
|
165
185
|
|
|
166
186
|
/**
|
|
167
|
-
* Generate
|
|
187
|
+
* Generate a localization.
|
|
188
|
+
*
|
|
189
|
+
* @template TLocalization
|
|
190
|
+
* Localization type.
|
|
191
|
+
*
|
|
192
|
+
* @param locale
|
|
193
|
+
* Locale.
|
|
168
194
|
*
|
|
169
195
|
* @param localizedKeyPrefix
|
|
170
196
|
* Localized key prefix.
|
|
@@ -173,21 +199,19 @@ export abstract class Generator {
|
|
|
173
199
|
* Callback to finalize localization.
|
|
174
200
|
*
|
|
175
201
|
* @returns
|
|
176
|
-
* Localization
|
|
202
|
+
* Localization.
|
|
177
203
|
*/
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
})];
|
|
190
|
-
}));
|
|
204
|
+
#generateLocalization<TLocalization extends Localization>(locale: string, localizedKeyPrefix: string, localizationCallback: (locale: string, localization: Localization) => TLocalization): TLocalization {
|
|
205
|
+
const lngOption = {
|
|
206
|
+
lng: locale
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
return localizationCallback(locale, {
|
|
210
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Localized key exists.
|
|
211
|
+
name: i18nextAppExtension.t(`${localizedKeyPrefix}name` as ParseKeys, lngOption),
|
|
212
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Localized key exists.
|
|
213
|
+
description: i18nextAppExtension.t(`${localizedKeyPrefix}description` as ParseKeys, lngOption)
|
|
214
|
+
});
|
|
191
215
|
}
|
|
192
216
|
|
|
193
217
|
/**
|
|
@@ -205,95 +229,28 @@ export abstract class Generator {
|
|
|
205
229
|
this.initialize();
|
|
206
230
|
|
|
207
231
|
try {
|
|
208
|
-
for (const classDescriptor of
|
|
232
|
+
for (const [_namespaceClassName, classDescriptor] of proxy.classDescriptorsMap.entries()) {
|
|
209
233
|
const namespace = classDescriptor.namespace;
|
|
210
|
-
const namespacePrefix = namespace === undefined ? "" : `${namespace}.`;
|
|
211
|
-
const className = classDescriptor.name;
|
|
212
|
-
const methodInfix = classDescriptor.methodInfix;
|
|
213
|
-
|
|
214
|
-
// Namespace-qualified class name is used to construct object name.
|
|
215
|
-
const namespaceClassName = `${namespacePrefix}${className}`;
|
|
216
|
-
|
|
217
|
-
// First capture group is:
|
|
218
|
-
// - one or more uppercase letters followed by zero or more numbers; or
|
|
219
|
-
// - single uppercase letter followed by zero or more characters except uppercase letters or period.
|
|
220
|
-
// Second capture group is:
|
|
221
|
-
// - single uppercase letter followed by zero or more characters except period; or
|
|
222
|
-
// - zero characters (empty string).
|
|
223
|
-
// Third capture group, separated by optional period, is:
|
|
224
|
-
// - single uppercase letter followed by zero or more characters (remainder of string); or
|
|
225
|
-
// - zero characters (empty string).
|
|
226
|
-
const classNameMatch = /^([A-Z]+[0-9]*|[A-Z][^A-Z.]*)([A-Z][^.]*|)\.?([A-Z].*|)$/.exec(namespaceClassName);
|
|
227
|
-
|
|
228
|
-
if (classNameMatch === null) {
|
|
229
|
-
throw new Error(`${namespaceClassName} is not a valid namespace-qualified class name`);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
const proxyObjectDescriptor: ProxyObjectDescriptor = {
|
|
233
|
-
namespace,
|
|
234
|
-
className,
|
|
235
|
-
namespaceClassName,
|
|
236
|
-
classDescriptor,
|
|
237
|
-
objectName: `${classNameMatch[1].toLowerCase()}${classNameMatch[2]}${classNameMatch[3]}`
|
|
238
|
-
};
|
|
239
234
|
|
|
240
|
-
this.createProxyObject(
|
|
235
|
+
this.createProxyObject(classDescriptor);
|
|
241
236
|
|
|
242
237
|
for (const methodDescriptor of classDescriptor.methodDescriptors) {
|
|
243
|
-
const
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
// Other classes in the hierarchy and infix is in the middle of the string.
|
|
262
|
-
functionName = `${methodName.substring(0, insertIndex)}${methodInfix}${methodName.substring(insertIndex)}`;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
const namespaceFunctionName = `${namespacePrefix}${functionName}`;
|
|
266
|
-
|
|
267
|
-
const functionLocalizationsMap = this.generateLocalizationsMap<FunctionLocalization>(`Functions.${namespaceFunctionName}.`, (locale, localization) => ({
|
|
268
|
-
...localization,
|
|
269
|
-
documentationURL: `${Generator.DOCUMENTATION_BASE_URL}${locale === this.defaultLocale ? "" : `${locale}/`}${Generator.DOCUMENTATION_PATH}${namespace === undefined ? "" : `${namespace}/`}${localization.name}.html`
|
|
270
|
-
}));
|
|
271
|
-
|
|
272
|
-
this._functionLocalizationsMapsMap.set(namespaceFunctionName, functionLocalizationsMap);
|
|
273
|
-
|
|
274
|
-
this.createProxyFunction({
|
|
275
|
-
...proxyObjectDescriptor,
|
|
276
|
-
functionName,
|
|
277
|
-
namespaceFunctionName,
|
|
278
|
-
localizationsMap: functionLocalizationsMap,
|
|
279
|
-
proxyParameterDescriptors: methodDescriptor.parameterDescriptors.map((parameterDescriptor) => {
|
|
280
|
-
const expandedParameterDescriptor = expandParameterDescriptor(parameterDescriptor);
|
|
281
|
-
|
|
282
|
-
const parameterName = expandedParameterDescriptor.name;
|
|
283
|
-
|
|
284
|
-
const parameterLocalizationsMap = this.generateLocalizationsMap(`Parameters.${parameterName}.`, (_locale, localization) => localization);
|
|
285
|
-
|
|
286
|
-
this._parameterLocalizationsMapsMap.set(`${namespaceFunctionName}.${parameterName}`, parameterLocalizationsMap);
|
|
287
|
-
|
|
288
|
-
return {
|
|
289
|
-
namespace,
|
|
290
|
-
parameterName,
|
|
291
|
-
localizationsMap: parameterLocalizationsMap,
|
|
292
|
-
parameterDescriptor: expandedParameterDescriptor
|
|
293
|
-
};
|
|
294
|
-
}),
|
|
295
|
-
methodDescriptor
|
|
296
|
-
});
|
|
238
|
+
const namespaceFunctionName = methodDescriptor.namespaceFunctionName;
|
|
239
|
+
|
|
240
|
+
const functionLocalizationsMap = new Map(this.#locales.map(locale =>
|
|
241
|
+
[locale, this.#generateLocalization<FunctionLocalization>(locale, `Functions.${namespaceFunctionName}.`, (locale, localization) => ({
|
|
242
|
+
...localization,
|
|
243
|
+
documentationURL: `${Generator.#DOCUMENTATION_BASE_URL}${locale === this.defaultLocale ? "" : `${locale}/`}${Generator.#DOCUMENTATION_PATH}${namespace === undefined ? "" : `${namespace}/`}${localization.name}.html`,
|
|
244
|
+
parametersMap: new Map(methodDescriptor.parameterDescriptors.map(parameterDescriptor =>
|
|
245
|
+
// eslint-disable-next-line max-nested-callbacks -- Callback is empty.
|
|
246
|
+
[parameterDescriptor.name, this.#generateLocalization(locale, `Parameters.${parameterDescriptor.name}.`, (_locale, localization) => localization)]
|
|
247
|
+
))
|
|
248
|
+
}))]
|
|
249
|
+
));
|
|
250
|
+
|
|
251
|
+
this.#functionLocalizationsMapsMap.set(namespaceFunctionName, functionLocalizationsMap);
|
|
252
|
+
|
|
253
|
+
this.createProxyFunction(classDescriptor, methodDescriptor, functionLocalizationsMap);
|
|
297
254
|
}
|
|
298
255
|
}
|
|
299
256
|
|
package/src/generator/index.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { getLogger, type LocaleResources } from "@aidc-toolkit/core";
|
|
2
2
|
import * as fs from "node:fs";
|
|
3
3
|
import * as path from "node:path";
|
|
4
|
-
import
|
|
5
|
-
|
|
4
|
+
import type {
|
|
5
|
+
ClassDescriptor,
|
|
6
|
+
ExtendsParameterDescriptor,
|
|
7
|
+
MethodDescriptor,
|
|
8
|
+
ParameterDescriptor
|
|
9
|
+
} from "../descriptor.js";
|
|
6
10
|
import { Generator } from "./generator.js";
|
|
7
11
|
|
|
8
12
|
/**
|
|
@@ -17,7 +21,17 @@ interface ParametersSequencerEntry {
|
|
|
17
21
|
/**
|
|
18
22
|
* Parameter descriptor.
|
|
19
23
|
*/
|
|
20
|
-
parameterDescriptor: ParameterDescriptor;
|
|
24
|
+
parameterDescriptor: ParameterDescriptor | ExtendsParameterDescriptor;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Parameter name.
|
|
28
|
+
*/
|
|
29
|
+
parameterName: string;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Base parameter name.
|
|
33
|
+
*/
|
|
34
|
+
baseParameterName: string;
|
|
21
35
|
|
|
22
36
|
/**
|
|
23
37
|
* True if parameter is actually used and not just a base.
|
|
@@ -28,6 +42,7 @@ interface ParametersSequencerEntry {
|
|
|
28
42
|
/**
|
|
29
43
|
* Parameters sequencer for keeping similar (extended) parameters together.
|
|
30
44
|
*/
|
|
45
|
+
// TODO Replace with map.
|
|
31
46
|
type ParametersSequencer = Record<string, ParametersSequencerEntry>;
|
|
32
47
|
|
|
33
48
|
/**
|
|
@@ -47,34 +62,34 @@ class LocaleResourcesGenerator extends Generator {
|
|
|
47
62
|
/**
|
|
48
63
|
* Locale resources import path.
|
|
49
64
|
*/
|
|
50
|
-
|
|
65
|
+
static readonly #IMPORT_PATH = "../app-extension/src/locale";
|
|
51
66
|
|
|
52
67
|
/**
|
|
53
68
|
* Logger.
|
|
54
69
|
*/
|
|
55
|
-
|
|
70
|
+
readonly #logger = getLogger();
|
|
56
71
|
|
|
57
72
|
/**
|
|
58
73
|
* Parameters sequencer.
|
|
59
74
|
*/
|
|
60
|
-
|
|
75
|
+
readonly #parametersSequencer: ParametersSequencer = {};
|
|
61
76
|
|
|
62
77
|
/**
|
|
63
78
|
* Parameters locale resources.
|
|
64
79
|
*/
|
|
65
|
-
|
|
80
|
+
readonly #parametersLocaleResources: LocaleResources = {};
|
|
66
81
|
|
|
67
82
|
/**
|
|
68
83
|
* Functions locale resources.
|
|
69
84
|
*/
|
|
70
|
-
|
|
85
|
+
readonly #functionsLocaleResources: LocaleResources = {};
|
|
71
86
|
|
|
72
87
|
/**
|
|
73
88
|
* Locale resources.
|
|
74
89
|
*/
|
|
75
|
-
|
|
76
|
-
Parameters: this
|
|
77
|
-
Functions: this
|
|
90
|
+
readonly #LocaleResources: LocaleResources = {
|
|
91
|
+
Parameters: this.#parametersLocaleResources,
|
|
92
|
+
Functions: this.#functionsLocaleResources
|
|
78
93
|
};
|
|
79
94
|
|
|
80
95
|
/**
|
|
@@ -108,31 +123,41 @@ class LocaleResourcesGenerator extends Generator {
|
|
|
108
123
|
* @returns
|
|
109
124
|
* Parameters sequencer entry.
|
|
110
125
|
*/
|
|
111
|
-
|
|
126
|
+
#saveParameterSequence(parameterDescriptor: ParameterDescriptor | ExtendsParameterDescriptor, isUsed: boolean): ParametersSequencerEntry {
|
|
112
127
|
let parametersSequencerEntry: ParametersSequencerEntry;
|
|
113
128
|
|
|
114
129
|
if (!("extendsDescriptor" in parameterDescriptor)) {
|
|
115
130
|
const parameterName = parameterDescriptor.name;
|
|
116
131
|
|
|
117
132
|
// Create entry if it doesn't exist, otherwise pick up where last call left off.
|
|
118
|
-
if (!(parameterName in this
|
|
133
|
+
if (!(parameterName in this.#parametersSequencer)) {
|
|
119
134
|
parametersSequencerEntry = {
|
|
120
135
|
parametersSequencerOrNull: null,
|
|
121
136
|
parameterDescriptor,
|
|
137
|
+
parameterName,
|
|
138
|
+
baseParameterName: parameterName,
|
|
122
139
|
isUsed
|
|
123
140
|
};
|
|
124
141
|
|
|
125
|
-
this
|
|
142
|
+
this.#parametersSequencer[parameterName] = parametersSequencerEntry;
|
|
126
143
|
} else {
|
|
127
|
-
parametersSequencerEntry = this
|
|
144
|
+
parametersSequencerEntry = this.#parametersSequencer[parameterName];
|
|
128
145
|
}
|
|
129
146
|
} else {
|
|
130
|
-
const baseParametersSequencerEntry = this
|
|
147
|
+
const baseParametersSequencerEntry = this.#saveParameterSequence(parameterDescriptor.extendsDescriptor, false);
|
|
131
148
|
|
|
132
|
-
|
|
133
|
-
|
|
149
|
+
let parameterName: string;
|
|
150
|
+
let baseParameterName: string | null;
|
|
134
151
|
|
|
135
|
-
if (
|
|
152
|
+
if (parameterDescriptor.name !== undefined) {
|
|
153
|
+
parameterName = parameterDescriptor.name;
|
|
154
|
+
baseParameterName = baseParametersSequencerEntry.parameterName;
|
|
155
|
+
} else {
|
|
156
|
+
parameterName = baseParametersSequencerEntry.parameterName;
|
|
157
|
+
baseParameterName = baseParametersSequencerEntry.baseParameterName;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (parameterName !== baseParameterName) {
|
|
136
161
|
// Make sure that base parameters sequencer entry refers to a record type.
|
|
137
162
|
baseParametersSequencerEntry.parametersSequencerOrNull ??= {};
|
|
138
163
|
|
|
@@ -140,6 +165,8 @@ class LocaleResourcesGenerator extends Generator {
|
|
|
140
165
|
parametersSequencerEntry = {
|
|
141
166
|
parametersSequencerOrNull: null,
|
|
142
167
|
parameterDescriptor,
|
|
168
|
+
parameterName,
|
|
169
|
+
baseParameterName,
|
|
143
170
|
isUsed
|
|
144
171
|
};
|
|
145
172
|
|
|
@@ -159,19 +186,15 @@ class LocaleResourcesGenerator extends Generator {
|
|
|
159
186
|
/**
|
|
160
187
|
* @inheritDoc
|
|
161
188
|
*/
|
|
162
|
-
protected createProxyFunction(
|
|
163
|
-
const {
|
|
164
|
-
namespace,
|
|
165
|
-
functionName,
|
|
166
|
-
methodDescriptor
|
|
167
|
-
} = proxyFunctionDescriptor;
|
|
168
|
-
|
|
189
|
+
protected createProxyFunction(classDescriptor: ClassDescriptor, methodDescriptor: MethodDescriptor): void {
|
|
169
190
|
// Add any parameters that are not already known.
|
|
170
191
|
for (const parameterDescriptor of methodDescriptor.parameterDescriptors) {
|
|
171
|
-
this
|
|
192
|
+
this.#saveParameterSequence(parameterDescriptor, true);
|
|
172
193
|
}
|
|
173
194
|
|
|
174
|
-
let functionsLocaleResources = this
|
|
195
|
+
let functionsLocaleResources = this.#functionsLocaleResources;
|
|
196
|
+
|
|
197
|
+
const namespace = classDescriptor.namespace;
|
|
175
198
|
|
|
176
199
|
if (namespace !== undefined) {
|
|
177
200
|
if (!(namespace in functionsLocaleResources)) {
|
|
@@ -187,6 +210,8 @@ class LocaleResourcesGenerator extends Generator {
|
|
|
187
210
|
}
|
|
188
211
|
}
|
|
189
212
|
|
|
213
|
+
const functionName = methodDescriptor.functionName;
|
|
214
|
+
|
|
190
215
|
if (functionName in functionsLocaleResources) {
|
|
191
216
|
throw new Error(`Duplicate function ${functionName}`);
|
|
192
217
|
}
|
|
@@ -219,7 +244,7 @@ class LocaleResourcesGenerator extends Generator {
|
|
|
219
244
|
* @returns
|
|
220
245
|
* Merged locale resources.
|
|
221
246
|
*/
|
|
222
|
-
|
|
247
|
+
#merge(logChanges: boolean, parentKey: string, sourceLocaleResources: LocaleResources, destinationLocaleResources: LocaleResources, addMissing: boolean): LocaleResources {
|
|
223
248
|
// Some entries at the top are not part of the generator output.
|
|
224
249
|
const deleteMissing = parentKey.length !== 0;
|
|
225
250
|
|
|
@@ -231,7 +256,7 @@ class LocaleResourcesGenerator extends Generator {
|
|
|
231
256
|
if (!deleteMissing) {
|
|
232
257
|
newDestinationLocaleResources[key] = destinationValue;
|
|
233
258
|
} else if (logChanges) {
|
|
234
|
-
this.
|
|
259
|
+
this.#logger.info(`Deleting ${parentKey}${key}...`);
|
|
235
260
|
}
|
|
236
261
|
}
|
|
237
262
|
}
|
|
@@ -240,7 +265,7 @@ class LocaleResourcesGenerator extends Generator {
|
|
|
240
265
|
if (!(key in destinationLocaleResources)) {
|
|
241
266
|
if (addMissing) {
|
|
242
267
|
if (logChanges) {
|
|
243
|
-
this.
|
|
268
|
+
this.#logger.info(`Adding ${parentKey}${key}...`);
|
|
244
269
|
}
|
|
245
270
|
|
|
246
271
|
newDestinationLocaleResources[key] = sourceValue;
|
|
@@ -249,7 +274,7 @@ class LocaleResourcesGenerator extends Generator {
|
|
|
249
274
|
const destinationValue = destinationLocaleResources[key];
|
|
250
275
|
|
|
251
276
|
if (typeof sourceValue === "object" && typeof destinationValue === "object") {
|
|
252
|
-
newDestinationLocaleResources[key] = this
|
|
277
|
+
newDestinationLocaleResources[key] = this.#merge(logChanges, `${parentKey}${key}.`, sourceValue, destinationValue, addMissing);
|
|
253
278
|
} else if (typeof sourceValue === "string" && typeof destinationValue === "string") {
|
|
254
279
|
newDestinationLocaleResources[key] = destinationValue;
|
|
255
280
|
} else {
|
|
@@ -267,7 +292,7 @@ class LocaleResourcesGenerator extends Generator {
|
|
|
267
292
|
* @param parametersSequencer
|
|
268
293
|
* Parameters sequencer.
|
|
269
294
|
*/
|
|
270
|
-
|
|
295
|
+
#buildParametersLocaleResources(parametersSequencer: ParametersSequencer): void {
|
|
271
296
|
const entries = Object.entries(parametersSequencer);
|
|
272
297
|
|
|
273
298
|
// Sort the entries as defined by the descriptors.
|
|
@@ -299,14 +324,14 @@ class LocaleResourcesGenerator extends Generator {
|
|
|
299
324
|
|
|
300
325
|
for (const [parameterName, parametersSequencerEntry] of entries) {
|
|
301
326
|
if (parametersSequencerEntry.isUsed) {
|
|
302
|
-
this
|
|
327
|
+
this.#parametersLocaleResources[parameterName] = {
|
|
303
328
|
name: parameterName,
|
|
304
329
|
description: "*** LOCALIZATION REQUIRED ***"
|
|
305
330
|
};
|
|
306
331
|
}
|
|
307
332
|
|
|
308
333
|
if (parametersSequencerEntry.parametersSequencerOrNull !== null) {
|
|
309
|
-
this
|
|
334
|
+
this.#buildParametersLocaleResources(parametersSequencerEntry.parametersSequencerOrNull);
|
|
310
335
|
}
|
|
311
336
|
}
|
|
312
337
|
}
|
|
@@ -326,10 +351,10 @@ class LocaleResourcesGenerator extends Generator {
|
|
|
326
351
|
* @returns
|
|
327
352
|
* Output string.
|
|
328
353
|
*/
|
|
329
|
-
|
|
354
|
+
static #buildOutput(prefix: string, value: LocaleResources | string, indentLevel: number): string {
|
|
330
355
|
return `${" ".repeat(indentLevel)}${prefix} ${typeof value === "object" ?
|
|
331
356
|
`{\n${
|
|
332
|
-
Object.entries(value).map(entry => LocaleResourcesGenerator
|
|
357
|
+
Object.entries(value).map(entry => LocaleResourcesGenerator.#buildOutput(`${entry[0]}:`, entry[1], indentLevel + 1)).join(",\n")
|
|
333
358
|
}\n${" ".repeat(indentLevel)}}` :
|
|
334
359
|
// JSON.stringify() will apply quotes as appropriate.
|
|
335
360
|
JSON.stringify(value)
|
|
@@ -341,18 +366,18 @@ class LocaleResourcesGenerator extends Generator {
|
|
|
341
366
|
*/
|
|
342
367
|
protected async finalize(success: boolean): Promise<void> {
|
|
343
368
|
if (success) {
|
|
344
|
-
this
|
|
369
|
+
this.#buildParametersLocaleResources(this.#parametersSequencer);
|
|
345
370
|
|
|
346
|
-
await Promise.all(fs.readdirSync(LocaleResourcesGenerator
|
|
371
|
+
await Promise.all(fs.readdirSync(LocaleResourcesGenerator.#IMPORT_PATH, {
|
|
347
372
|
withFileTypes: true
|
|
348
373
|
}).filter(entry => entry.isDirectory()).map(async (entry) => {
|
|
349
|
-
const localeResourcesSource = path.resolve(LocaleResourcesGenerator
|
|
374
|
+
const localeResourcesSource = path.resolve(LocaleResourcesGenerator.#IMPORT_PATH, entry.name, "locale-resources.ts");
|
|
350
375
|
|
|
351
376
|
await import(localeResourcesSource).then((module) => {
|
|
352
377
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Module format is known.
|
|
353
|
-
const localeResources = this
|
|
378
|
+
const localeResources = this.#merge(entry.name === "en", "", this.#LocaleResources, (module as LocaleResourcesModule).default, !entry.name.includes("-"));
|
|
354
379
|
|
|
355
|
-
fs.writeFileSync(localeResourcesSource, `${LocaleResourcesGenerator
|
|
380
|
+
fs.writeFileSync(localeResourcesSource, `${LocaleResourcesGenerator.#buildOutput("export default", localeResources, 0)};\n`);
|
|
356
381
|
});
|
|
357
382
|
}));
|
|
358
383
|
}
|