@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
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.28-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.28-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.28-beta",
|
|
35
|
+
"@aidc-toolkit/gs1": "1.0.28-beta",
|
|
36
|
+
"@aidc-toolkit/utility": "1.0.28-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.
|
|
@@ -52,10 +55,10 @@ export abstract class AppExtension<ThrowError extends boolean, TError extends Er
|
|
|
52
55
|
* @param throwError
|
|
53
56
|
* If true, errors are reported through the throw/catch mechanism.
|
|
54
57
|
*/
|
|
55
|
-
|
|
56
|
-
this
|
|
57
|
-
this
|
|
58
|
-
this
|
|
58
|
+
constructor(version: string, maximumSequenceCount: number, throwError: ThrowError) {
|
|
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
|
/**
|
|
@@ -93,7 +96,7 @@ export abstract class AppExtension<ThrowError extends boolean, TError extends Er
|
|
|
93
96
|
* @returns
|
|
94
97
|
* Maximum width supported by the application.
|
|
95
98
|
*/
|
|
96
|
-
protected abstract getMaximumWidth(): Promise<number>;
|
|
99
|
+
protected abstract getMaximumWidth(): number | Promise<number>;
|
|
97
100
|
|
|
98
101
|
/**
|
|
99
102
|
* Get the maximum height supported by the application.
|
|
@@ -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
|
/**
|
|
@@ -113,7 +116,7 @@ export abstract class AppExtension<ThrowError extends boolean, TError extends Er
|
|
|
113
116
|
* @returns
|
|
114
117
|
* Maximum height supported by the application.
|
|
115
118
|
*/
|
|
116
|
-
protected abstract getMaximumHeight(): Promise<number>;
|
|
119
|
+
protected abstract getMaximumHeight(): number | Promise<number>;
|
|
117
120
|
|
|
118
121
|
/**
|
|
119
122
|
* Get the sheet address from an invocation context.
|
|
@@ -124,7 +127,7 @@ export abstract class AppExtension<ThrowError extends boolean, TError extends Er
|
|
|
124
127
|
* @returns
|
|
125
128
|
* Sheet address.
|
|
126
129
|
*/
|
|
127
|
-
abstract getSheetAddress(invocationContext: TInvocationContext): Promise<SheetAddress>;
|
|
130
|
+
abstract getSheetAddress(invocationContext: TInvocationContext): SheetAddress | Promise<SheetAddress>;
|
|
128
131
|
|
|
129
132
|
/**
|
|
130
133
|
* Get a parameter range from an invocation context.
|
|
@@ -138,7 +141,7 @@ export abstract class AppExtension<ThrowError extends boolean, TError extends Er
|
|
|
138
141
|
* @returns
|
|
139
142
|
* Sheet range or null if parameter is not a range.
|
|
140
143
|
*/
|
|
141
|
-
abstract getParameterSheetRange(invocationContext: TInvocationContext, parameterNumber: number): Promise<SheetRange | null>;
|
|
144
|
+
abstract getParameterSheetRange(invocationContext: TInvocationContext, parameterNumber: number): SheetRange | null | Promise<SheetRange | null>;
|
|
142
145
|
|
|
143
146
|
/**
|
|
144
147
|
* Validate a sequence count against the maximum supported by application.
|
|
@@ -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
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { isNullish, type NonNullishable, type Nullishable } from "@aidc-toolkit/core";
|
|
2
|
-
import { type
|
|
2
|
+
import { type ExtendsParameterDescriptor, type ParameterDescriptor, Types } from "./descriptor.js";
|
|
3
3
|
import { LibProxy } from "./lib-proxy.js";
|
|
4
4
|
import { i18nextAppExtension } from "./locale/i18n.js";
|
|
5
|
+
import { proxy } from "./proxy.js";
|
|
5
6
|
import type { ErrorExtends, Matrix } from "./type.js";
|
|
6
7
|
|
|
7
8
|
const spillMatrix: ParameterDescriptor = {
|
|
@@ -18,13 +19,13 @@ const spillMaximumParameterDescriptor: ParameterDescriptor = {
|
|
|
18
19
|
isRequired: false
|
|
19
20
|
};
|
|
20
21
|
|
|
21
|
-
const spillMaximumWidthParameterDescriptor:
|
|
22
|
+
const spillMaximumWidthParameterDescriptor: ExtendsParameterDescriptor = {
|
|
22
23
|
extendsDescriptor: spillMaximumParameterDescriptor,
|
|
23
24
|
sortOrder: 0,
|
|
24
25
|
name: "spillMaximumWidth"
|
|
25
26
|
};
|
|
26
27
|
|
|
27
|
-
const spillMaximumHeightParameterDescriptor:
|
|
28
|
+
const spillMaximumHeightParameterDescriptor: ExtendsParameterDescriptor = {
|
|
28
29
|
extendsDescriptor: spillMaximumParameterDescriptor,
|
|
29
30
|
sortOrder: 1,
|
|
30
31
|
name: "spillMaximumHeight"
|
|
@@ -47,8 +48,20 @@ interface MaximumDimensions {
|
|
|
47
48
|
|
|
48
49
|
/**
|
|
49
50
|
* Application utilities.
|
|
51
|
+
*
|
|
52
|
+
*@template ThrowError
|
|
53
|
+
* If true, errors are reported through the throw/catch mechanism.
|
|
54
|
+
*
|
|
55
|
+
* @template TError
|
|
56
|
+
* Error type.
|
|
57
|
+
*
|
|
58
|
+
* @template TInvocationContext
|
|
59
|
+
* Application-specific invocation context type.
|
|
60
|
+
*
|
|
61
|
+
* @template TBigInt
|
|
62
|
+
* Type to which big integer is mapped.
|
|
50
63
|
*/
|
|
51
|
-
@
|
|
64
|
+
@proxy.describeClass(false)
|
|
52
65
|
export class AppUtilityProxy<ThrowError extends boolean, TError extends ErrorExtends<ThrowError>, TInvocationContext, TBigInt> extends LibProxy<ThrowError, TError, TInvocationContext, TBigInt> {
|
|
53
66
|
/**
|
|
54
67
|
* Get the version.
|
|
@@ -56,9 +69,10 @@ export class AppUtilityProxy<ThrowError extends boolean, TError extends ErrorExt
|
|
|
56
69
|
* @returns
|
|
57
70
|
* Version.
|
|
58
71
|
*/
|
|
59
|
-
@
|
|
72
|
+
@proxy.describeMethod({
|
|
60
73
|
type: Types.String,
|
|
61
|
-
isMatrix: false
|
|
74
|
+
isMatrix: false,
|
|
75
|
+
parameterDescriptors: []
|
|
62
76
|
})
|
|
63
77
|
version(): string {
|
|
64
78
|
return this.appExtension.version;
|
|
@@ -76,7 +90,7 @@ export class AppUtilityProxy<ThrowError extends boolean, TError extends ErrorExt
|
|
|
76
90
|
* @returns
|
|
77
91
|
* Array of maximum width and maximum height.
|
|
78
92
|
*/
|
|
79
|
-
|
|
93
|
+
async #defaultMaximums(maximumDimensions: MaximumDimensions, invocationContext: Nullishable<TInvocationContext>): Promise<NonNullishable<MaximumDimensions>> {
|
|
80
94
|
if (isNullish(invocationContext)) {
|
|
81
95
|
// Application error; no localization necessary.
|
|
82
96
|
throw new Error("Invocation context not provided by application");
|
|
@@ -123,24 +137,20 @@ export class AppUtilityProxy<ThrowError extends boolean, TError extends ErrorExt
|
|
|
123
137
|
* @returns
|
|
124
138
|
* Matrix spilled within maximum width and maximum height.
|
|
125
139
|
*/
|
|
126
|
-
@
|
|
140
|
+
@proxy.describeMethod({
|
|
127
141
|
requiresContext: true,
|
|
128
142
|
type: Types.Any,
|
|
129
|
-
isMatrix: true
|
|
143
|
+
isMatrix: true,
|
|
144
|
+
parameterDescriptors: [spillMatrix, spillMaximumWidthParameterDescriptor, spillMaximumHeightParameterDescriptor]
|
|
130
145
|
})
|
|
131
|
-
async vSpill(
|
|
132
|
-
@ProxyParameter(spillMatrix) hMatrixValues: Matrix<unknown>,
|
|
133
|
-
@ProxyParameter(spillMaximumWidthParameterDescriptor) maximumWidth: Nullishable<number>,
|
|
134
|
-
@ProxyParameter(spillMaximumHeightParameterDescriptor) maximumHeight: Nullishable<number>,
|
|
135
|
-
invocationContext: Nullishable<TInvocationContext>
|
|
136
|
-
): Promise<Matrix<unknown>> {
|
|
146
|
+
async vSpill(hMatrixValues: Matrix<unknown>, maximumWidth: Nullishable<number>, maximumHeight: Nullishable<number>, invocationContext: Nullishable<TInvocationContext>): Promise<Matrix<unknown>> {
|
|
137
147
|
let result: Matrix<unknown>;
|
|
138
148
|
|
|
139
149
|
if (hMatrixValues.length !== 1) {
|
|
140
150
|
throw new RangeError(i18nextAppExtension.t("Proxy.vSpillMustBeHorizontalArray"));
|
|
141
151
|
}
|
|
142
152
|
|
|
143
|
-
const maximumDimensions = await this
|
|
153
|
+
const maximumDimensions = await this.#defaultMaximums({
|
|
144
154
|
width: maximumWidth,
|
|
145
155
|
height: maximumHeight
|
|
146
156
|
}, invocationContext);
|
|
@@ -157,7 +167,7 @@ export class AppUtilityProxy<ThrowError extends boolean, TError extends ErrorExt
|
|
|
157
167
|
// Array that has a length of a power of 10 is treated specially.
|
|
158
168
|
if (Number.isInteger(Math.log10(hLength))) {
|
|
159
169
|
// Try spill width that is a power of 10.
|
|
160
|
-
const spillWidth10 =
|
|
170
|
+
const spillWidth10 = 10 ** Math.floor(Math.log10(spillWidth));
|
|
161
171
|
|
|
162
172
|
// Keep default if not enough space for power of 10 matrix.
|
|
163
173
|
if (hLength / spillWidth10 <= maximumDimensions.height) {
|
|
@@ -202,17 +212,13 @@ export class AppUtilityProxy<ThrowError extends boolean, TError extends ErrorExt
|
|
|
202
212
|
* @returns
|
|
203
213
|
* Matrix spilled within maximum height and maximum width.
|
|
204
214
|
*/
|
|
205
|
-
@
|
|
215
|
+
@proxy.describeMethod({
|
|
206
216
|
requiresContext: true,
|
|
207
217
|
type: Types.Any,
|
|
208
|
-
isMatrix: true
|
|
218
|
+
isMatrix: true,
|
|
219
|
+
parameterDescriptors: [spillMatrix, spillMaximumHeightParameterDescriptor, spillMaximumWidthParameterDescriptor]
|
|
209
220
|
})
|
|
210
|
-
async hSpill(
|
|
211
|
-
@ProxyParameter(spillMatrix) vMatrixValues: Matrix<unknown>,
|
|
212
|
-
@ProxyParameter(spillMaximumHeightParameterDescriptor) maximumHeight: Nullishable<number>,
|
|
213
|
-
@ProxyParameter(spillMaximumWidthParameterDescriptor) maximumWidth: Nullishable<number>,
|
|
214
|
-
invocationContext: Nullishable<TInvocationContext>
|
|
215
|
-
): Promise<Matrix<unknown>> {
|
|
221
|
+
async hSpill(vMatrixValues: Matrix<unknown>, maximumHeight: Nullishable<number>, maximumWidth: Nullishable<number>, invocationContext: Nullishable<TInvocationContext>): Promise<Matrix<unknown>> {
|
|
216
222
|
let result: Matrix<unknown>;
|
|
217
223
|
|
|
218
224
|
for (const hArrayValues of vMatrixValues) {
|
|
@@ -222,7 +228,7 @@ export class AppUtilityProxy<ThrowError extends boolean, TError extends ErrorExt
|
|
|
222
228
|
}
|
|
223
229
|
}
|
|
224
230
|
|
|
225
|
-
const maximumDimensions = await this
|
|
231
|
+
const maximumDimensions = await this.#defaultMaximums({
|
|
226
232
|
width: maximumWidth,
|
|
227
233
|
height: maximumHeight
|
|
228
234
|
}, invocationContext);
|
|
@@ -238,7 +244,7 @@ export class AppUtilityProxy<ThrowError extends boolean, TError extends ErrorExt
|
|
|
238
244
|
// Array that has a length of a power of 10 is treated specially.
|
|
239
245
|
if (Number.isInteger(Math.log10(vLength))) {
|
|
240
246
|
// Try spill height that is a power of 10.
|
|
241
|
-
const spillHeight10 =
|
|
247
|
+
const spillHeight10 = 10 ** Math.floor(Math.log10(spillHeight));
|
|
242
248
|
|
|
243
249
|
// Keep default if not enough space for power of 10 matrix.
|
|
244
250
|
if (vLength / spillHeight10 <= maximumDimensions.width) {
|
package/src/descriptor.ts
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
import type { TypedFunction } from "@aidc-toolkit/core";
|
|
2
|
-
import type { AppExtension } from "./app-extension.js";
|
|
3
|
-
import { LibProxy } from "./lib-proxy.js";
|
|
4
|
-
import type { ErrorExtends } from "./type.js";
|
|
5
|
-
|
|
6
1
|
/**
|
|
7
2
|
* Core descriptor.
|
|
8
3
|
*/
|
|
@@ -64,9 +59,9 @@ interface TypeDescriptor extends Descriptor {
|
|
|
64
59
|
}
|
|
65
60
|
|
|
66
61
|
/**
|
|
67
|
-
*
|
|
62
|
+
* Parameter descriptor.
|
|
68
63
|
*/
|
|
69
|
-
export interface
|
|
64
|
+
export interface ParameterDescriptor extends TypeDescriptor {
|
|
70
65
|
/**
|
|
71
66
|
* True if required.
|
|
72
67
|
*/
|
|
@@ -74,43 +69,20 @@ export interface BaseParameterDescriptor extends TypeDescriptor {
|
|
|
74
69
|
}
|
|
75
70
|
|
|
76
71
|
/**
|
|
77
|
-
* Extends parameter descriptor
|
|
72
|
+
* Extends parameter descriptor.
|
|
78
73
|
*/
|
|
79
|
-
export interface ExtendsParameterDescriptor extends Partial<
|
|
74
|
+
export interface ExtendsParameterDescriptor extends Partial<ParameterDescriptor> {
|
|
80
75
|
/**
|
|
81
|
-
*
|
|
76
|
+
* Parameter descriptor that this one extends.
|
|
82
77
|
*/
|
|
83
|
-
readonly extendsDescriptor: ParameterDescriptor;
|
|
78
|
+
readonly extendsDescriptor: ParameterDescriptor | ExtendsParameterDescriptor;
|
|
84
79
|
|
|
85
80
|
/**
|
|
86
|
-
* Sort order within
|
|
81
|
+
* Sort order within extended parameter descriptor.
|
|
87
82
|
*/
|
|
88
83
|
readonly sortOrder?: number;
|
|
89
84
|
}
|
|
90
85
|
|
|
91
|
-
/**
|
|
92
|
-
* Parameter descriptor, either base or extends.
|
|
93
|
-
*/
|
|
94
|
-
export type ParameterDescriptor = BaseParameterDescriptor | ExtendsParameterDescriptor;
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Expand a parameter descriptor to its full form with all required attributes.
|
|
98
|
-
*
|
|
99
|
-
* @param parameterDescriptor
|
|
100
|
-
* Parameter descriptor.
|
|
101
|
-
*
|
|
102
|
-
* @returns
|
|
103
|
-
* Parameter descriptor in its full form.
|
|
104
|
-
*/
|
|
105
|
-
export function expandParameterDescriptor(parameterDescriptor: ParameterDescriptor): BaseParameterDescriptor {
|
|
106
|
-
return !("extendsDescriptor" in parameterDescriptor) ?
|
|
107
|
-
parameterDescriptor :
|
|
108
|
-
{
|
|
109
|
-
...expandParameterDescriptor(parameterDescriptor.extendsDescriptor),
|
|
110
|
-
...parameterDescriptor
|
|
111
|
-
};
|
|
112
|
-
}
|
|
113
|
-
|
|
114
86
|
/**
|
|
115
87
|
* Method descriptor.
|
|
116
88
|
*/
|
|
@@ -135,6 +107,16 @@ export interface MethodDescriptor extends TypeDescriptor {
|
|
|
135
107
|
* Parameter descriptors.
|
|
136
108
|
*/
|
|
137
109
|
readonly parameterDescriptors: readonly ParameterDescriptor[];
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Function name with optional infix.
|
|
113
|
+
*/
|
|
114
|
+
readonly functionName: string;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Function name in optional namespace with optional infix.
|
|
118
|
+
*/
|
|
119
|
+
readonly namespaceFunctionName: string;
|
|
138
120
|
}
|
|
139
121
|
|
|
140
122
|
/**
|
|
@@ -144,12 +126,12 @@ export interface ClassDescriptor extends Descriptor {
|
|
|
144
126
|
/**
|
|
145
127
|
* Class namespace. If not provided, class is at the top level.
|
|
146
128
|
*/
|
|
147
|
-
readonly namespace?: string;
|
|
129
|
+
readonly namespace?: string | undefined;
|
|
148
130
|
|
|
149
131
|
/**
|
|
150
132
|
* Method infix. If undefined, method name is generated verbatim.
|
|
151
133
|
*/
|
|
152
|
-
readonly methodInfix?: string;
|
|
134
|
+
readonly methodInfix?: string | undefined;
|
|
153
135
|
|
|
154
136
|
/**
|
|
155
137
|
* Replace parameter descriptors for class hierarchies where enumeration parameter descriptors can change.
|
|
@@ -160,169 +142,17 @@ export interface ClassDescriptor extends Descriptor {
|
|
|
160
142
|
}>;
|
|
161
143
|
|
|
162
144
|
/**
|
|
163
|
-
*
|
|
145
|
+
* Class name in optional namespace.
|
|
164
146
|
*/
|
|
165
|
-
readonly
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Proxy class type with fixed constructor.
|
|
170
|
-
*/
|
|
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;
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Pending parameter descriptors, consumed and reset when method is described.
|
|
175
|
-
*/
|
|
176
|
-
let pendingParameterDescriptors: ParameterDescriptor[] = [];
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Class method descriptors map, keyed on declaration class name and method name.
|
|
180
|
-
*/
|
|
181
|
-
const classMethodsDescriptorsMap = new Map<string, MethodDescriptor[]>();
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Class descriptors map, keyed on declaration class name.
|
|
185
|
-
*/
|
|
186
|
-
const classDescriptorsMap = new Map<string, ClassDescriptor>();
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Proxy parameter decorator.
|
|
190
|
-
*
|
|
191
|
-
* @param parameterDescriptor
|
|
192
|
-
* Parameter descriptor.
|
|
193
|
-
*
|
|
194
|
-
* @returns
|
|
195
|
-
* Function defining metadata for the parameter.
|
|
196
|
-
*/
|
|
197
|
-
export function ProxyParameter<ThrowError extends boolean, TError extends ErrorExtends<ThrowError>, TInvocationContext, TBigInt, T extends LibProxy<ThrowError, TError, TInvocationContext, TBigInt>>(parameterDescriptor: ParameterDescriptor): ((target: T, propertyKey: string, parameterIndex: number) => void) {
|
|
198
|
-
return (_target: T, _propertyKey: string, parameterIndex: number) => {
|
|
199
|
-
pendingParameterDescriptors[parameterIndex] = parameterDescriptor;
|
|
200
|
-
};
|
|
201
|
-
}
|
|
147
|
+
readonly namespaceClassName: string;
|
|
202
148
|
|
|
203
|
-
/**
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
* Method descriptor.
|
|
208
|
-
*
|
|
209
|
-
* @returns
|
|
210
|
-
* Function defining metadata for the method.
|
|
211
|
-
*/
|
|
212
|
-
export function ProxyMethod<ThrowError extends boolean, TError extends ErrorExtends<ThrowError>, TInvocationContext, TBigInt, T extends LibProxy<ThrowError, TError, TInvocationContext, TBigInt>>(methodDescriptor: Omit<MethodDescriptor, "name" | "parameterDescriptors">): ((target: T, propertyKey: string, propertyDescriptor: PropertyDescriptor) => void) {
|
|
213
|
-
return (target: T, propertyKey: string, propertyDescriptor: PropertyDescriptor) => {
|
|
214
|
-
const declarationClassName = target.constructor.name;
|
|
215
|
-
|
|
216
|
-
// Validate that method descriptor is applied to a function.
|
|
217
|
-
if (typeof propertyDescriptor.value !== "function") {
|
|
218
|
-
throw new Error(`${declarationClassName}.${propertyKey} is not a method`);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Known to be a method.
|
|
222
|
-
const parameterCount = (propertyDescriptor.value as TypedFunction<(...args: unknown[]) => unknown>).length - (!(methodDescriptor.requiresContext ?? false) ? 0 : 1);
|
|
223
|
-
|
|
224
|
-
let anyOptional = false;
|
|
225
|
-
|
|
226
|
-
// Validate that all parameters have descriptors.
|
|
227
|
-
for (let index = 0; index < parameterCount; index++) {
|
|
228
|
-
const parameterDescriptor = expandParameterDescriptor(pendingParameterDescriptors[index]);
|
|
229
|
-
|
|
230
|
-
if (typeof parameterDescriptor === "undefined") {
|
|
231
|
-
throw new Error(`Missing parameter descriptor at index ${index} of ${declarationClassName}.${propertyKey}`);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
if (!parameterDescriptor.isRequired) {
|
|
235
|
-
anyOptional = true;
|
|
236
|
-
} else if (anyOptional) {
|
|
237
|
-
throw new Error(`Parameter descriptor ${parameterDescriptor.name} at index ${index} of ${declarationClassName}.${propertyKey} is required but prior parameter descriptor ${pendingParameterDescriptors[index - 1].name} is optional`);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
let methodDescriptors = classMethodsDescriptorsMap.get(declarationClassName);
|
|
242
|
-
if (methodDescriptors === undefined) {
|
|
243
|
-
methodDescriptors = [];
|
|
244
|
-
classMethodsDescriptorsMap.set(declarationClassName, methodDescriptors);
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
// Method descriptors array is constructed in reverse order so that final result is in the correct order.
|
|
248
|
-
methodDescriptors.push({
|
|
249
|
-
name: propertyKey,
|
|
250
|
-
...methodDescriptor,
|
|
251
|
-
parameterDescriptors: pendingParameterDescriptors
|
|
252
|
-
});
|
|
253
|
-
|
|
254
|
-
pendingParameterDescriptors = [];
|
|
255
|
-
};
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
/**
|
|
259
|
-
* Proxy class decorator.
|
|
260
|
-
*
|
|
261
|
-
* @param classDescriptor
|
|
262
|
-
* Class descriptor.
|
|
263
|
-
*
|
|
264
|
-
* @returns
|
|
265
|
-
* Function defining metadata for the class.
|
|
266
|
-
*/
|
|
267
|
-
export function ProxyClass<ThrowError extends boolean, TError extends ErrorExtends<ThrowError>, TInvocationContext, TBigInt, T extends LibProxy<ThrowError, TError, TInvocationContext, TBigInt>>(classDescriptor: Omit<ClassDescriptor, "name" | "methodDescriptors"> = {}): ((classType: ProxyClassType<ThrowError, TError, TInvocationContext, TBigInt, T>) => void) {
|
|
268
|
-
return (classType: ProxyClassType<ThrowError, TError, TInvocationContext, TBigInt, T>) => {
|
|
269
|
-
const methodDescriptorsMap = new Map<string, MethodDescriptor>();
|
|
270
|
-
|
|
271
|
-
/**
|
|
272
|
-
* Build method descriptors map from every class in hierarchy until LibProxy class is reached.
|
|
273
|
-
*
|
|
274
|
-
* @param classType
|
|
275
|
-
* Class type.
|
|
276
|
-
*/
|
|
277
|
-
function buildMethodDescriptorsMap(classType: typeof LibProxy): void {
|
|
278
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- Class hierarchy is known.
|
|
279
|
-
const baseClassType = Object.getPrototypeOf(classType) as typeof LibProxy;
|
|
280
|
-
|
|
281
|
-
// Start with class furthest up the hierarchy.
|
|
282
|
-
if (baseClassType !== LibProxy) {
|
|
283
|
-
buildMethodDescriptorsMap(baseClassType);
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
const classMethodDescriptors = classMethodsDescriptorsMap.get(classType.name);
|
|
287
|
-
|
|
288
|
-
if (classMethodDescriptors !== undefined) {
|
|
289
|
-
for (const classMethodDescriptor of classMethodDescriptors) {
|
|
290
|
-
// If any class overrides a base class method, it will appear in the same position as the base class method.
|
|
291
|
-
methodDescriptorsMap.set(classMethodDescriptor.name, classMethodDescriptor);
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
buildMethodDescriptorsMap(classType);
|
|
297
|
-
|
|
298
|
-
let methodDescriptors: MethodDescriptor[];
|
|
299
|
-
|
|
300
|
-
if (classDescriptor.replaceParameterDescriptors !== undefined) {
|
|
301
|
-
const replacementParameterDescriptorsMap = new Map(classDescriptor.replaceParameterDescriptors.map(replaceParameterDescriptor => [replaceParameterDescriptor.name, replaceParameterDescriptor.replacement]));
|
|
302
|
-
|
|
303
|
-
// Method descriptors for class have to be built as copies due to possible mutation of parameter descriptors.
|
|
304
|
-
methodDescriptors = Array.from(methodDescriptorsMap.values()).map(methodDescriptor => ({
|
|
305
|
-
...methodDescriptor,
|
|
306
|
-
parameterDescriptors: methodDescriptor.parameterDescriptors.map(parameterDescriptor => replacementParameterDescriptorsMap.get(expandParameterDescriptor(parameterDescriptor).name) ?? parameterDescriptor)
|
|
307
|
-
}));
|
|
308
|
-
} else {
|
|
309
|
-
methodDescriptors = Array.from(methodDescriptorsMap.values());
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
classDescriptorsMap.set(classType.name, {
|
|
313
|
-
name: classType.name,
|
|
314
|
-
...classDescriptor,
|
|
315
|
-
methodDescriptors
|
|
316
|
-
});
|
|
317
|
-
};
|
|
318
|
-
}
|
|
149
|
+
/**
|
|
150
|
+
* Object name.
|
|
151
|
+
*/
|
|
152
|
+
readonly objectName: string;
|
|
319
153
|
|
|
320
|
-
/**
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
* Class descriptors map.
|
|
325
|
-
*/
|
|
326
|
-
export function getClassDescriptorsMap(): ReadonlyMap<string, ClassDescriptor> {
|
|
327
|
-
return classDescriptorsMap;
|
|
154
|
+
/**
|
|
155
|
+
* Method descriptors.
|
|
156
|
+
*/
|
|
157
|
+
readonly methodDescriptors: readonly MethodDescriptor[];
|
|
328
158
|
}
|