@aidc-toolkit/app-extension 1.0.26-beta → 1.0.27-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 +127 -114
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +123 -139
- package/dist/index.d.ts +123 -139
- package/dist/index.js +128 -115
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
- package/src/app-extension.ts +28 -19
- package/src/app-utility-proxy.ts +15 -3
- package/src/descriptor.ts +61 -1
- package/src/generator/descriptor.ts +5 -2
- package/src/generator/generator.ts +22 -19
- package/src/generator/locale-resources-generator.ts +29 -29
- package/src/gs1/identifier-proxy.ts +37 -36
- package/src/lib-proxy.ts +21 -18
- package/src/utility/character-set-proxy.ts +8 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aidc-toolkit/app-extension",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.27-beta",
|
|
4
4
|
"description": "Application extension framework for AIDC Toolkit",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -28,12 +28,12 @@
|
|
|
28
28
|
"build:doc": "npm run build:dev"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@aidc-toolkit/dev": "1.0.
|
|
31
|
+
"@aidc-toolkit/dev": "1.0.27-beta"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@aidc-toolkit/core": "1.0.
|
|
35
|
-
"@aidc-toolkit/gs1": "1.0.
|
|
36
|
-
"@aidc-toolkit/utility": "1.0.
|
|
37
|
-
"i18next": "^25.7.
|
|
34
|
+
"@aidc-toolkit/core": "1.0.27-beta",
|
|
35
|
+
"@aidc-toolkit/gs1": "1.0.27-beta",
|
|
36
|
+
"@aidc-toolkit/utility": "1.0.27-beta",
|
|
37
|
+
"i18next": "^25.7.2"
|
|
38
38
|
}
|
|
39
39
|
}
|
package/src/app-extension.ts
CHANGED
|
@@ -5,40 +5,43 @@ import type { ErrorExtends, ResultError, SheetAddress, SheetRange } from "./type
|
|
|
5
5
|
/**
|
|
6
6
|
* Application extension.
|
|
7
7
|
*
|
|
8
|
-
* @template TBigInt
|
|
9
|
-
* Type to which big integer is mapped.
|
|
10
|
-
*
|
|
11
8
|
* @template ThrowError
|
|
12
9
|
* If true, errors are reported through the throw/catch mechanism.
|
|
13
10
|
*
|
|
14
11
|
* @template TError
|
|
15
12
|
* Error type.
|
|
13
|
+
*
|
|
14
|
+
* @template TInvocationContext
|
|
15
|
+
* Application-specific invocation context type.
|
|
16
|
+
*
|
|
17
|
+
* @template TBigInt
|
|
18
|
+
* Type to which big integer is mapped.
|
|
16
19
|
*/
|
|
17
20
|
export abstract class AppExtension<ThrowError extends boolean, TError extends ErrorExtends<ThrowError>, TInvocationContext, TBigInt> {
|
|
18
21
|
/**
|
|
19
22
|
* Application version.
|
|
20
23
|
*/
|
|
21
|
-
|
|
24
|
+
readonly #version: string;
|
|
22
25
|
|
|
23
26
|
/**
|
|
24
27
|
* Maximum sequence count supported by application.
|
|
25
28
|
*/
|
|
26
|
-
|
|
29
|
+
readonly #maximumSequenceCount: number;
|
|
27
30
|
|
|
28
31
|
/**
|
|
29
32
|
* If true, errors are reported through the throw/catch mechanism.
|
|
30
33
|
*/
|
|
31
|
-
|
|
34
|
+
readonly #throwError: ThrowError;
|
|
32
35
|
|
|
33
36
|
/**
|
|
34
37
|
* Maximum width supported by application.
|
|
35
38
|
*/
|
|
36
|
-
|
|
39
|
+
#maximumWidth?: number;
|
|
37
40
|
|
|
38
41
|
/**
|
|
39
42
|
* Maximum height supported by application.
|
|
40
43
|
*/
|
|
41
|
-
|
|
44
|
+
#maximumHeight?: number;
|
|
42
45
|
|
|
43
46
|
/**
|
|
44
47
|
* Constructor.
|
|
@@ -53,9 +56,9 @@ export abstract class AppExtension<ThrowError extends boolean, TError extends Er
|
|
|
53
56
|
* If true, errors are reported through the throw/catch mechanism.
|
|
54
57
|
*/
|
|
55
58
|
protected constructor(version: string, maximumSequenceCount: number, throwError: ThrowError) {
|
|
56
|
-
this
|
|
57
|
-
this
|
|
58
|
-
this
|
|
59
|
+
this.#version = version;
|
|
60
|
+
this.#maximumSequenceCount = maximumSequenceCount;
|
|
61
|
+
this.#throwError = throwError;
|
|
59
62
|
}
|
|
60
63
|
|
|
61
64
|
/**
|
|
@@ -65,14 +68,14 @@ export abstract class AppExtension<ThrowError extends boolean, TError extends Er
|
|
|
65
68
|
* Version.
|
|
66
69
|
*/
|
|
67
70
|
get version(): string {
|
|
68
|
-
return this
|
|
71
|
+
return this.#version;
|
|
69
72
|
}
|
|
70
73
|
|
|
71
74
|
/**
|
|
72
75
|
* Determine if errors are reported through the throw/catch mechanism.
|
|
73
76
|
*/
|
|
74
77
|
get throwError(): ThrowError {
|
|
75
|
-
return this
|
|
78
|
+
return this.#throwError;
|
|
76
79
|
}
|
|
77
80
|
|
|
78
81
|
/**
|
|
@@ -82,9 +85,9 @@ export abstract class AppExtension<ThrowError extends boolean, TError extends Er
|
|
|
82
85
|
* Maximum width supported by the application.
|
|
83
86
|
*/
|
|
84
87
|
async maximumWidth(): Promise<number> {
|
|
85
|
-
this
|
|
88
|
+
this.#maximumWidth ??= await this.getMaximumWidth();
|
|
86
89
|
|
|
87
|
-
return this
|
|
90
|
+
return this.#maximumWidth;
|
|
88
91
|
}
|
|
89
92
|
|
|
90
93
|
/**
|
|
@@ -102,9 +105,9 @@ export abstract class AppExtension<ThrowError extends boolean, TError extends Er
|
|
|
102
105
|
* Maximum height supported by the application.
|
|
103
106
|
*/
|
|
104
107
|
async maximumHeight(): Promise<number> {
|
|
105
|
-
this
|
|
108
|
+
this.#maximumHeight ??= await this.getMaximumHeight();
|
|
106
109
|
|
|
107
|
-
return this
|
|
110
|
+
return this.#maximumHeight;
|
|
108
111
|
}
|
|
109
112
|
|
|
110
113
|
/**
|
|
@@ -149,10 +152,10 @@ export abstract class AppExtension<ThrowError extends boolean, TError extends Er
|
|
|
149
152
|
validateSequenceCount(sequenceCount: number): void {
|
|
150
153
|
const absoluteSequenceCount = Math.abs(sequenceCount);
|
|
151
154
|
|
|
152
|
-
if (absoluteSequenceCount > this
|
|
155
|
+
if (absoluteSequenceCount > this.#maximumSequenceCount) {
|
|
153
156
|
throw new RangeError(i18nextAppExtension.t("AppExtension.sequenceCountMustBeLessThanOrEqualTo", {
|
|
154
157
|
sequenceCount: absoluteSequenceCount,
|
|
155
|
-
maximumSequenceCount: this
|
|
158
|
+
maximumSequenceCount: this.#maximumSequenceCount
|
|
156
159
|
}));
|
|
157
160
|
}
|
|
158
161
|
}
|
|
@@ -188,6 +191,9 @@ export abstract class AppExtension<ThrowError extends boolean, TError extends Er
|
|
|
188
191
|
/**
|
|
189
192
|
* Bind a synchronous method and wrap it in a try/catch for comprehensive error handling.
|
|
190
193
|
*
|
|
194
|
+
* @template TMethod
|
|
195
|
+
* Method type.
|
|
196
|
+
*
|
|
191
197
|
* @param thisArg
|
|
192
198
|
* The value to be passed as the `this` parameter to the method.
|
|
193
199
|
*
|
|
@@ -215,6 +221,9 @@ export abstract class AppExtension<ThrowError extends boolean, TError extends Er
|
|
|
215
221
|
/**
|
|
216
222
|
* Bind an asynchronous method and wrap it in a try/catch for comprehensive error handling.
|
|
217
223
|
*
|
|
224
|
+
* @template TMethod
|
|
225
|
+
* Method type.
|
|
226
|
+
*
|
|
218
227
|
* @param thisArg
|
|
219
228
|
* The value to be passed as the `this` parameter to the method.
|
|
220
229
|
*
|
package/src/app-utility-proxy.ts
CHANGED
|
@@ -47,6 +47,18 @@ interface MaximumDimensions {
|
|
|
47
47
|
|
|
48
48
|
/**
|
|
49
49
|
* Application utilities.
|
|
50
|
+
*
|
|
51
|
+
*@template ThrowError
|
|
52
|
+
* If true, errors are reported through the throw/catch mechanism.
|
|
53
|
+
*
|
|
54
|
+
* @template TError
|
|
55
|
+
* Error type.
|
|
56
|
+
*
|
|
57
|
+
* @template TInvocationContext
|
|
58
|
+
* Application-specific invocation context type.
|
|
59
|
+
*
|
|
60
|
+
* @template TBigInt
|
|
61
|
+
* Type to which big integer is mapped.
|
|
50
62
|
*/
|
|
51
63
|
@ProxyClass()
|
|
52
64
|
export class AppUtilityProxy<ThrowError extends boolean, TError extends ErrorExtends<ThrowError>, TInvocationContext, TBigInt> extends LibProxy<ThrowError, TError, TInvocationContext, TBigInt> {
|
|
@@ -76,7 +88,7 @@ export class AppUtilityProxy<ThrowError extends boolean, TError extends ErrorExt
|
|
|
76
88
|
* @returns
|
|
77
89
|
* Array of maximum width and maximum height.
|
|
78
90
|
*/
|
|
79
|
-
|
|
91
|
+
async #defaultMaximums(maximumDimensions: MaximumDimensions, invocationContext: Nullishable<TInvocationContext>): Promise<NonNullishable<MaximumDimensions>> {
|
|
80
92
|
if (isNullish(invocationContext)) {
|
|
81
93
|
// Application error; no localization necessary.
|
|
82
94
|
throw new Error("Invocation context not provided by application");
|
|
@@ -140,7 +152,7 @@ export class AppUtilityProxy<ThrowError extends boolean, TError extends ErrorExt
|
|
|
140
152
|
throw new RangeError(i18nextAppExtension.t("Proxy.vSpillMustBeHorizontalArray"));
|
|
141
153
|
}
|
|
142
154
|
|
|
143
|
-
const maximumDimensions = await this
|
|
155
|
+
const maximumDimensions = await this.#defaultMaximums({
|
|
144
156
|
width: maximumWidth,
|
|
145
157
|
height: maximumHeight
|
|
146
158
|
}, invocationContext);
|
|
@@ -222,7 +234,7 @@ export class AppUtilityProxy<ThrowError extends boolean, TError extends ErrorExt
|
|
|
222
234
|
}
|
|
223
235
|
}
|
|
224
236
|
|
|
225
|
-
const maximumDimensions = await this
|
|
237
|
+
const maximumDimensions = await this.#defaultMaximums({
|
|
226
238
|
width: maximumWidth,
|
|
227
239
|
height: maximumHeight
|
|
228
240
|
}, invocationContext);
|
package/src/descriptor.ts
CHANGED
|
@@ -167,8 +167,23 @@ export interface ClassDescriptor extends Descriptor {
|
|
|
167
167
|
|
|
168
168
|
/**
|
|
169
169
|
* Proxy class type with fixed constructor.
|
|
170
|
+
*
|
|
171
|
+
* @template ThrowError
|
|
172
|
+
* If true, errors are reported through the throw/catch mechanism.
|
|
173
|
+
*
|
|
174
|
+
* @template TError
|
|
175
|
+
* Error type.
|
|
176
|
+
*
|
|
177
|
+
* @template TInvocationContext
|
|
178
|
+
* Application-specific invocation context type.
|
|
179
|
+
*
|
|
180
|
+
* @template TBigInt
|
|
181
|
+
* Type to which big integer is mapped.
|
|
182
|
+
*
|
|
183
|
+
* @template T
|
|
184
|
+
* Proxy type.
|
|
170
185
|
*/
|
|
171
|
-
type ProxyClassType<ThrowError extends boolean, TError extends ErrorExtends<ThrowError>, TInvocationContext, TBigInt, T extends LibProxy<ThrowError, TError, TInvocationContext, TBigInt>> = (new(appExtension: AppExtension<ThrowError, TError, TInvocationContext, TBigInt>) => T) & typeof LibProxy;
|
|
186
|
+
type ProxyClassType<ThrowError extends boolean, TError extends ErrorExtends<ThrowError>, TInvocationContext, TBigInt, T extends LibProxy<ThrowError, TError, TInvocationContext, TBigInt>> = (new (appExtension: AppExtension<ThrowError, TError, TInvocationContext, TBigInt>) => T) & typeof LibProxy;
|
|
172
187
|
|
|
173
188
|
/**
|
|
174
189
|
* Pending parameter descriptors, consumed and reset when method is described.
|
|
@@ -188,6 +203,21 @@ const classDescriptorsMap = new Map<string, ClassDescriptor>();
|
|
|
188
203
|
/**
|
|
189
204
|
* Proxy parameter decorator.
|
|
190
205
|
*
|
|
206
|
+
* @template ThrowError
|
|
207
|
+
* If true, errors are reported through the throw/catch mechanism.
|
|
208
|
+
*
|
|
209
|
+
* @template TError
|
|
210
|
+
* Error type.
|
|
211
|
+
*
|
|
212
|
+
* @template TInvocationContext
|
|
213
|
+
* Application-specific invocation context type.
|
|
214
|
+
*
|
|
215
|
+
* @template TBigInt
|
|
216
|
+
* Type to which big integer is mapped.
|
|
217
|
+
*
|
|
218
|
+
* @template T
|
|
219
|
+
* Proxy type.
|
|
220
|
+
*
|
|
191
221
|
* @param parameterDescriptor
|
|
192
222
|
* Parameter descriptor.
|
|
193
223
|
*
|
|
@@ -203,6 +233,21 @@ export function ProxyParameter<ThrowError extends boolean, TError extends ErrorE
|
|
|
203
233
|
/**
|
|
204
234
|
* Proxy method decorator.
|
|
205
235
|
*
|
|
236
|
+
* @template ThrowError
|
|
237
|
+
* If true, errors are reported through the throw/catch mechanism.
|
|
238
|
+
*
|
|
239
|
+
* @template TError
|
|
240
|
+
* Error type.
|
|
241
|
+
*
|
|
242
|
+
* @template TInvocationContext
|
|
243
|
+
* Application-specific invocation context type.
|
|
244
|
+
*
|
|
245
|
+
* @template TBigInt
|
|
246
|
+
* Type to which big integer is mapped.
|
|
247
|
+
*
|
|
248
|
+
* @template T
|
|
249
|
+
* Proxy type.
|
|
250
|
+
*
|
|
206
251
|
* @param methodDescriptor
|
|
207
252
|
* Method descriptor.
|
|
208
253
|
*
|
|
@@ -258,6 +303,21 @@ export function ProxyMethod<ThrowError extends boolean, TError extends ErrorExte
|
|
|
258
303
|
/**
|
|
259
304
|
* Proxy class decorator.
|
|
260
305
|
*
|
|
306
|
+
* @template ThrowError
|
|
307
|
+
* If true, errors are reported through the throw/catch mechanism.
|
|
308
|
+
*
|
|
309
|
+
* @template TError
|
|
310
|
+
* Error type.
|
|
311
|
+
*
|
|
312
|
+
* @template TInvocationContext
|
|
313
|
+
* Application-specific invocation context type.
|
|
314
|
+
*
|
|
315
|
+
* @template TBigInt
|
|
316
|
+
* Type to which big integer is mapped.
|
|
317
|
+
*
|
|
318
|
+
* @template T
|
|
319
|
+
* Proxy type.
|
|
320
|
+
*
|
|
261
321
|
* @param classDescriptor
|
|
262
322
|
* Class descriptor.
|
|
263
323
|
*
|
|
@@ -33,12 +33,15 @@ export interface ParameterLocalization extends Localization {
|
|
|
33
33
|
|
|
34
34
|
/**
|
|
35
35
|
* Localization descriptor.
|
|
36
|
+
*
|
|
37
|
+
* @param TLocalization
|
|
38
|
+
* Localization type.
|
|
36
39
|
*/
|
|
37
|
-
export interface LocalizationDescriptor<
|
|
40
|
+
export interface LocalizationDescriptor<TLocalization extends Localization> {
|
|
38
41
|
/**
|
|
39
42
|
* Localizations map by locale.
|
|
40
43
|
*/
|
|
41
|
-
readonly localizationsMap: ReadonlyMap<string,
|
|
44
|
+
readonly localizationsMap: ReadonlyMap<string, TLocalization>;
|
|
42
45
|
}
|
|
43
46
|
|
|
44
47
|
/**
|
|
@@ -31,32 +31,32 @@ export abstract class Generator {
|
|
|
31
31
|
/**
|
|
32
32
|
* Documentation base URL.
|
|
33
33
|
*/
|
|
34
|
-
|
|
34
|
+
static readonly #DOCUMENTATION_BASE_URL = "https://aidc-toolkit.com/";
|
|
35
35
|
|
|
36
36
|
/**
|
|
37
37
|
* Documentation path, optionally preceded by locale.
|
|
38
38
|
*/
|
|
39
|
-
|
|
39
|
+
static readonly #DOCUMENTATION_PATH = "app-extension/";
|
|
40
40
|
|
|
41
41
|
/**
|
|
42
42
|
* Locales.
|
|
43
43
|
*/
|
|
44
|
-
|
|
44
|
+
readonly #locales: readonly string[];
|
|
45
45
|
|
|
46
46
|
/**
|
|
47
47
|
* Default locale.
|
|
48
48
|
*/
|
|
49
|
-
|
|
49
|
+
readonly #defaultLocale: string;
|
|
50
50
|
|
|
51
51
|
/**
|
|
52
52
|
* Map of function localizations maps by namespace function name.
|
|
53
53
|
*/
|
|
54
|
-
|
|
54
|
+
readonly #functionLocalizationsMapsMap = new Map<string, ReadonlyMap<string, FunctionLocalization>>();
|
|
55
55
|
|
|
56
56
|
/**
|
|
57
57
|
* Map of parameter localizations maps by namespace function parameter name.
|
|
58
58
|
*/
|
|
59
|
-
|
|
59
|
+
readonly #parameterLocalizationsMapsMap = new Map<string, ReadonlyMap<string, ParameterLocalization>>();
|
|
60
60
|
|
|
61
61
|
/**
|
|
62
62
|
*
|
|
@@ -69,22 +69,22 @@ export abstract class Generator {
|
|
|
69
69
|
* Include localizations if true.
|
|
70
70
|
*/
|
|
71
71
|
constructor(includeLocalizations = true) {
|
|
72
|
-
this
|
|
73
|
-
this
|
|
72
|
+
this.#locales = includeLocalizations ? Object.keys(appExtensionResources) : [];
|
|
73
|
+
this.#defaultLocale = this.#locales[0] ?? "";
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
/**
|
|
77
77
|
* Get the locales.
|
|
78
78
|
*/
|
|
79
79
|
protected get locales(): readonly string[] {
|
|
80
|
-
return this
|
|
80
|
+
return this.#locales;
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
/**
|
|
84
84
|
* Get the default locale.
|
|
85
85
|
*/
|
|
86
86
|
protected get defaultLocale(): string {
|
|
87
|
-
return this
|
|
87
|
+
return this.#defaultLocale;
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
/**
|
|
@@ -100,7 +100,7 @@ export abstract class Generator {
|
|
|
100
100
|
* Function localization.
|
|
101
101
|
*/
|
|
102
102
|
protected getFunctionLocalization(namespaceFunctionName: string, locale: string): FunctionLocalization {
|
|
103
|
-
const functionLocalization = this.
|
|
103
|
+
const functionLocalization = this.#functionLocalizationsMapsMap.get(namespaceFunctionName)?.get(locale);
|
|
104
104
|
|
|
105
105
|
if (functionLocalization === undefined) {
|
|
106
106
|
throw new Error(`${locale} localization for function ${namespaceFunctionName} not found`);
|
|
@@ -125,7 +125,7 @@ export abstract class Generator {
|
|
|
125
125
|
* Function localization.
|
|
126
126
|
*/
|
|
127
127
|
protected getParameterLocalization(namespaceFunctionName: string, parameterName: string, locale: string): ParameterLocalization {
|
|
128
|
-
const parameterLocalization = this.
|
|
128
|
+
const parameterLocalization = this.#parameterLocalizationsMapsMap.get(`${namespaceFunctionName}.${parameterName}`)?.get(locale);
|
|
129
129
|
|
|
130
130
|
if (parameterLocalization === undefined) {
|
|
131
131
|
throw new Error(`${locale} localization for function ${namespaceFunctionName} parameter ${parameterName} not found`);
|
|
@@ -166,6 +166,9 @@ export abstract class Generator {
|
|
|
166
166
|
/**
|
|
167
167
|
* Generate localizations map.
|
|
168
168
|
*
|
|
169
|
+
* @template TLocalization
|
|
170
|
+
* Localization type.
|
|
171
|
+
*
|
|
169
172
|
* @param localizedKeyPrefix
|
|
170
173
|
* Localized key prefix.
|
|
171
174
|
*
|
|
@@ -175,8 +178,8 @@ export abstract class Generator {
|
|
|
175
178
|
* @returns
|
|
176
179
|
* Localization map.
|
|
177
180
|
*/
|
|
178
|
-
|
|
179
|
-
return new Map(this.
|
|
181
|
+
#generateLocalizationsMap<TLocalization extends Localization>(localizedKeyPrefix: string, localizationCallback: (locale: string, localization: Localization) => TLocalization): ReadonlyMap<string, TLocalization> {
|
|
182
|
+
return new Map(this.#locales.map((locale) => {
|
|
180
183
|
const lngOption = {
|
|
181
184
|
lng: locale
|
|
182
185
|
};
|
|
@@ -264,12 +267,12 @@ export abstract class Generator {
|
|
|
264
267
|
|
|
265
268
|
const namespaceFunctionName = `${namespacePrefix}${functionName}`;
|
|
266
269
|
|
|
267
|
-
const functionLocalizationsMap = this
|
|
270
|
+
const functionLocalizationsMap = this.#generateLocalizationsMap<FunctionLocalization>(`Functions.${namespaceFunctionName}.`, (locale, localization) => ({
|
|
268
271
|
...localization,
|
|
269
|
-
documentationURL: `${Generator
|
|
272
|
+
documentationURL: `${Generator.#DOCUMENTATION_BASE_URL}${locale === this.defaultLocale ? "" : `${locale}/`}${Generator.#DOCUMENTATION_PATH}${namespace === undefined ? "" : `${namespace}/`}${localization.name}.html`
|
|
270
273
|
}));
|
|
271
274
|
|
|
272
|
-
this.
|
|
275
|
+
this.#functionLocalizationsMapsMap.set(namespaceFunctionName, functionLocalizationsMap);
|
|
273
276
|
|
|
274
277
|
this.createProxyFunction({
|
|
275
278
|
...proxyObjectDescriptor,
|
|
@@ -281,9 +284,9 @@ export abstract class Generator {
|
|
|
281
284
|
|
|
282
285
|
const parameterName = expandedParameterDescriptor.name;
|
|
283
286
|
|
|
284
|
-
const parameterLocalizationsMap = this
|
|
287
|
+
const parameterLocalizationsMap = this.#generateLocalizationsMap(`Parameters.${parameterName}.`, (_locale, localization) => localization);
|
|
285
288
|
|
|
286
|
-
this.
|
|
289
|
+
this.#parameterLocalizationsMapsMap.set(`${namespaceFunctionName}.${parameterName}`, parameterLocalizationsMap);
|
|
287
290
|
|
|
288
291
|
return {
|
|
289
292
|
namespace,
|
|
@@ -47,34 +47,34 @@ class LocaleResourcesGenerator extends Generator {
|
|
|
47
47
|
/**
|
|
48
48
|
* Locale resources import path.
|
|
49
49
|
*/
|
|
50
|
-
|
|
50
|
+
static readonly #IMPORT_PATH = "../app-extension/src/locale";
|
|
51
51
|
|
|
52
52
|
/**
|
|
53
53
|
* Logger.
|
|
54
54
|
*/
|
|
55
|
-
|
|
55
|
+
readonly #logger = getLogger();
|
|
56
56
|
|
|
57
57
|
/**
|
|
58
58
|
* Parameters sequencer.
|
|
59
59
|
*/
|
|
60
|
-
|
|
60
|
+
readonly #parametersSequencer: ParametersSequencer = {};
|
|
61
61
|
|
|
62
62
|
/**
|
|
63
63
|
* Parameters locale resources.
|
|
64
64
|
*/
|
|
65
|
-
|
|
65
|
+
readonly #parametersLocaleResources: LocaleResources = {};
|
|
66
66
|
|
|
67
67
|
/**
|
|
68
68
|
* Functions locale resources.
|
|
69
69
|
*/
|
|
70
|
-
|
|
70
|
+
readonly #functionsLocaleResources: LocaleResources = {};
|
|
71
71
|
|
|
72
72
|
/**
|
|
73
73
|
* Locale resources.
|
|
74
74
|
*/
|
|
75
|
-
|
|
76
|
-
Parameters: this
|
|
77
|
-
Functions: this
|
|
75
|
+
readonly #LocaleResources: LocaleResources = {
|
|
76
|
+
Parameters: this.#parametersLocaleResources,
|
|
77
|
+
Functions: this.#functionsLocaleResources
|
|
78
78
|
};
|
|
79
79
|
|
|
80
80
|
/**
|
|
@@ -108,26 +108,26 @@ class LocaleResourcesGenerator extends Generator {
|
|
|
108
108
|
* @returns
|
|
109
109
|
* Parameters sequencer entry.
|
|
110
110
|
*/
|
|
111
|
-
|
|
111
|
+
#saveParameterSequence(parameterDescriptor: ParameterDescriptor, isUsed: boolean): ParametersSequencerEntry {
|
|
112
112
|
let parametersSequencerEntry: ParametersSequencerEntry;
|
|
113
113
|
|
|
114
114
|
if (!("extendsDescriptor" in parameterDescriptor)) {
|
|
115
115
|
const parameterName = parameterDescriptor.name;
|
|
116
116
|
|
|
117
117
|
// Create entry if it doesn't exist, otherwise pick up where last call left off.
|
|
118
|
-
if (!(parameterName in this
|
|
118
|
+
if (!(parameterName in this.#parametersSequencer)) {
|
|
119
119
|
parametersSequencerEntry = {
|
|
120
120
|
parametersSequencerOrNull: null,
|
|
121
121
|
parameterDescriptor,
|
|
122
122
|
isUsed
|
|
123
123
|
};
|
|
124
124
|
|
|
125
|
-
this
|
|
125
|
+
this.#parametersSequencer[parameterName] = parametersSequencerEntry;
|
|
126
126
|
} else {
|
|
127
|
-
parametersSequencerEntry = this
|
|
127
|
+
parametersSequencerEntry = this.#parametersSequencer[parameterName];
|
|
128
128
|
}
|
|
129
129
|
} else {
|
|
130
|
-
const baseParametersSequencerEntry = this
|
|
130
|
+
const baseParametersSequencerEntry = this.#saveParameterSequence(parameterDescriptor.extendsDescriptor, false);
|
|
131
131
|
|
|
132
132
|
const expandedParameterDescriptor = expandParameterDescriptor(parameterDescriptor);
|
|
133
133
|
const parameterName = expandedParameterDescriptor.name;
|
|
@@ -168,10 +168,10 @@ class LocaleResourcesGenerator extends Generator {
|
|
|
168
168
|
|
|
169
169
|
// Add any parameters that are not already known.
|
|
170
170
|
for (const parameterDescriptor of methodDescriptor.parameterDescriptors) {
|
|
171
|
-
this
|
|
171
|
+
this.#saveParameterSequence(parameterDescriptor, true);
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
-
let functionsLocaleResources = this
|
|
174
|
+
let functionsLocaleResources = this.#functionsLocaleResources;
|
|
175
175
|
|
|
176
176
|
if (namespace !== undefined) {
|
|
177
177
|
if (!(namespace in functionsLocaleResources)) {
|
|
@@ -219,7 +219,7 @@ class LocaleResourcesGenerator extends Generator {
|
|
|
219
219
|
* @returns
|
|
220
220
|
* Merged locale resources.
|
|
221
221
|
*/
|
|
222
|
-
|
|
222
|
+
#merge(logChanges: boolean, parentKey: string, sourceLocaleResources: LocaleResources, destinationLocaleResources: LocaleResources, addMissing: boolean): LocaleResources {
|
|
223
223
|
// Some entries at the top are not part of the generator output.
|
|
224
224
|
const deleteMissing = parentKey.length !== 0;
|
|
225
225
|
|
|
@@ -231,7 +231,7 @@ class LocaleResourcesGenerator extends Generator {
|
|
|
231
231
|
if (!deleteMissing) {
|
|
232
232
|
newDestinationLocaleResources[key] = destinationValue;
|
|
233
233
|
} else if (logChanges) {
|
|
234
|
-
this.
|
|
234
|
+
this.#logger.info(`Deleting ${parentKey}${key}...`);
|
|
235
235
|
}
|
|
236
236
|
}
|
|
237
237
|
}
|
|
@@ -240,7 +240,7 @@ class LocaleResourcesGenerator extends Generator {
|
|
|
240
240
|
if (!(key in destinationLocaleResources)) {
|
|
241
241
|
if (addMissing) {
|
|
242
242
|
if (logChanges) {
|
|
243
|
-
this.
|
|
243
|
+
this.#logger.info(`Adding ${parentKey}${key}...`);
|
|
244
244
|
}
|
|
245
245
|
|
|
246
246
|
newDestinationLocaleResources[key] = sourceValue;
|
|
@@ -249,7 +249,7 @@ class LocaleResourcesGenerator extends Generator {
|
|
|
249
249
|
const destinationValue = destinationLocaleResources[key];
|
|
250
250
|
|
|
251
251
|
if (typeof sourceValue === "object" && typeof destinationValue === "object") {
|
|
252
|
-
newDestinationLocaleResources[key] = this
|
|
252
|
+
newDestinationLocaleResources[key] = this.#merge(logChanges, `${parentKey}${key}.`, sourceValue, destinationValue, addMissing);
|
|
253
253
|
} else if (typeof sourceValue === "string" && typeof destinationValue === "string") {
|
|
254
254
|
newDestinationLocaleResources[key] = destinationValue;
|
|
255
255
|
} else {
|
|
@@ -267,7 +267,7 @@ class LocaleResourcesGenerator extends Generator {
|
|
|
267
267
|
* @param parametersSequencer
|
|
268
268
|
* Parameters sequencer.
|
|
269
269
|
*/
|
|
270
|
-
|
|
270
|
+
#buildParametersLocaleResources(parametersSequencer: ParametersSequencer): void {
|
|
271
271
|
const entries = Object.entries(parametersSequencer);
|
|
272
272
|
|
|
273
273
|
// Sort the entries as defined by the descriptors.
|
|
@@ -299,14 +299,14 @@ class LocaleResourcesGenerator extends Generator {
|
|
|
299
299
|
|
|
300
300
|
for (const [parameterName, parametersSequencerEntry] of entries) {
|
|
301
301
|
if (parametersSequencerEntry.isUsed) {
|
|
302
|
-
this
|
|
302
|
+
this.#parametersLocaleResources[parameterName] = {
|
|
303
303
|
name: parameterName,
|
|
304
304
|
description: "*** LOCALIZATION REQUIRED ***"
|
|
305
305
|
};
|
|
306
306
|
}
|
|
307
307
|
|
|
308
308
|
if (parametersSequencerEntry.parametersSequencerOrNull !== null) {
|
|
309
|
-
this
|
|
309
|
+
this.#buildParametersLocaleResources(parametersSequencerEntry.parametersSequencerOrNull);
|
|
310
310
|
}
|
|
311
311
|
}
|
|
312
312
|
}
|
|
@@ -326,10 +326,10 @@ class LocaleResourcesGenerator extends Generator {
|
|
|
326
326
|
* @returns
|
|
327
327
|
* Output string.
|
|
328
328
|
*/
|
|
329
|
-
|
|
329
|
+
static #buildOutput(prefix: string, value: LocaleResources | string, indentLevel: number): string {
|
|
330
330
|
return `${" ".repeat(indentLevel)}${prefix} ${typeof value === "object" ?
|
|
331
331
|
`{\n${
|
|
332
|
-
Object.entries(value).map(entry => LocaleResourcesGenerator
|
|
332
|
+
Object.entries(value).map(entry => LocaleResourcesGenerator.#buildOutput(`${entry[0]}:`, entry[1], indentLevel + 1)).join(",\n")
|
|
333
333
|
}\n${" ".repeat(indentLevel)}}` :
|
|
334
334
|
// JSON.stringify() will apply quotes as appropriate.
|
|
335
335
|
JSON.stringify(value)
|
|
@@ -341,18 +341,18 @@ class LocaleResourcesGenerator extends Generator {
|
|
|
341
341
|
*/
|
|
342
342
|
protected async finalize(success: boolean): Promise<void> {
|
|
343
343
|
if (success) {
|
|
344
|
-
this
|
|
344
|
+
this.#buildParametersLocaleResources(this.#parametersSequencer);
|
|
345
345
|
|
|
346
|
-
await Promise.all(fs.readdirSync(LocaleResourcesGenerator
|
|
346
|
+
await Promise.all(fs.readdirSync(LocaleResourcesGenerator.#IMPORT_PATH, {
|
|
347
347
|
withFileTypes: true
|
|
348
348
|
}).filter(entry => entry.isDirectory()).map(async (entry) => {
|
|
349
|
-
const localeResourcesSource = path.resolve(LocaleResourcesGenerator
|
|
349
|
+
const localeResourcesSource = path.resolve(LocaleResourcesGenerator.#IMPORT_PATH, entry.name, "locale-resources.ts");
|
|
350
350
|
|
|
351
351
|
await import(localeResourcesSource).then((module) => {
|
|
352
352
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Module format is known.
|
|
353
|
-
const localeResources = this
|
|
353
|
+
const localeResources = this.#merge(entry.name === "en", "", this.#LocaleResources, (module as LocaleResourcesModule).default, !entry.name.includes("-"));
|
|
354
354
|
|
|
355
|
-
fs.writeFileSync(localeResourcesSource, `${LocaleResourcesGenerator
|
|
355
|
+
fs.writeFileSync(localeResourcesSource, `${LocaleResourcesGenerator.#buildOutput("export default", localeResources, 0)};\n`);
|
|
356
356
|
});
|
|
357
357
|
}));
|
|
358
358
|
}
|