@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.
Files changed (37) hide show
  1. package/dist/index.cjs +1205 -967
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +134 -312
  4. package/dist/index.d.ts +134 -312
  5. package/dist/index.js +1207 -964
  6. package/dist/index.js.map +1 -1
  7. package/package.json +6 -6
  8. package/src/app-extension.ts +33 -24
  9. package/src/app-utility-proxy.ts +33 -27
  10. package/src/descriptor.ts +29 -199
  11. package/src/generator/generator.ts +102 -145
  12. package/src/generator/index.ts +0 -1
  13. package/src/generator/locale-resources-generator.ts +67 -42
  14. package/src/gs1/character-set-proxy.ts +5 -5
  15. package/src/gs1/check-proxy.ts +35 -42
  16. package/src/gs1/gtin-creator-proxy.ts +58 -0
  17. package/src/gs1/gtin-descriptor.ts +29 -0
  18. package/src/gs1/gtin-validator-proxy.ts +161 -0
  19. package/src/gs1/identifier-creator-proxy.ts +227 -0
  20. package/src/gs1/identifier-validator-proxy.ts +87 -0
  21. package/src/gs1/index.ts +5 -1
  22. package/src/gs1/non-gtin-creator-proxy.ts +119 -0
  23. package/src/gs1/non-gtin-validator-proxy.ts +119 -0
  24. package/src/gs1/prefix-definition-descriptor.ts +18 -0
  25. package/src/gs1/prefix-manager-proxy.ts +42 -0
  26. package/src/index.ts +1 -0
  27. package/src/lib-proxy.ts +22 -19
  28. package/src/proxy.ts +509 -0
  29. package/src/utility/character-set-descriptor.ts +5 -5
  30. package/src/utility/character-set-proxy.ts +39 -55
  31. package/src/utility/reg-exp-proxy.ts +11 -15
  32. package/src/utility/string-descriptor.ts +2 -2
  33. package/src/utility/transformer-descriptor.ts +3 -3
  34. package/src/utility/transformer-proxy.ts +16 -26
  35. package/tsconfig-src.json +1 -4
  36. package/src/generator/descriptor.ts +0 -122
  37. 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.26-beta",
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.26-beta"
31
+ "@aidc-toolkit/dev": "1.0.28-beta"
32
32
  },
33
33
  "dependencies": {
34
- "@aidc-toolkit/core": "1.0.26-beta",
35
- "@aidc-toolkit/gs1": "1.0.26-beta",
36
- "@aidc-toolkit/utility": "1.0.26-beta",
37
- "i18next": "^25.7.1"
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
  }
@@ -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
- private readonly _version: string;
24
+ readonly #version: string;
22
25
 
23
26
  /**
24
27
  * Maximum sequence count supported by application.
25
28
  */
26
- private readonly _maximumSequenceCount: number;
29
+ readonly #maximumSequenceCount: number;
27
30
 
28
31
  /**
29
32
  * If true, errors are reported through the throw/catch mechanism.
30
33
  */
31
- private readonly _throwError: ThrowError;
34
+ readonly #throwError: ThrowError;
32
35
 
33
36
  /**
34
37
  * Maximum width supported by application.
35
38
  */
36
- private _maximumWidth?: number;
39
+ #maximumWidth?: number;
37
40
 
38
41
  /**
39
42
  * Maximum height supported by application.
40
43
  */
41
- private _maximumHeight?: number;
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
- protected constructor(version: string, maximumSequenceCount: number, throwError: ThrowError) {
56
- this._version = version;
57
- this._maximumSequenceCount = maximumSequenceCount;
58
- this._throwError = throwError;
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._version;
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._throwError;
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._maximumWidth ??= await this.getMaximumWidth();
88
+ this.#maximumWidth ??= await this.getMaximumWidth();
86
89
 
87
- return this._maximumWidth;
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._maximumHeight ??= await this.getMaximumHeight();
108
+ this.#maximumHeight ??= await this.getMaximumHeight();
106
109
 
107
- return this._maximumHeight;
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._maximumSequenceCount) {
155
+ if (absoluteSequenceCount > this.#maximumSequenceCount) {
153
156
  throw new RangeError(i18nextAppExtension.t("AppExtension.sequenceCountMustBeLessThanOrEqualTo", {
154
157
  sequenceCount: absoluteSequenceCount,
155
- maximumSequenceCount: this._maximumSequenceCount
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
  *
@@ -1,7 +1,8 @@
1
1
  import { isNullish, type NonNullishable, type Nullishable } from "@aidc-toolkit/core";
2
- import { type ParameterDescriptor, ProxyClass, ProxyMethod, ProxyParameter, Types } from "./descriptor.js";
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: ParameterDescriptor = {
22
+ const spillMaximumWidthParameterDescriptor: ExtendsParameterDescriptor = {
22
23
  extendsDescriptor: spillMaximumParameterDescriptor,
23
24
  sortOrder: 0,
24
25
  name: "spillMaximumWidth"
25
26
  };
26
27
 
27
- const spillMaximumHeightParameterDescriptor: ParameterDescriptor = {
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
- @ProxyClass()
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
- @ProxyMethod({
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
- private async defaultMaximums(maximumDimensions: MaximumDimensions, invocationContext: Nullishable<TInvocationContext>): Promise<NonNullishable<MaximumDimensions>> {
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
- @ProxyMethod({
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.defaultMaximums({
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 = Math.pow(10, Math.floor(Math.log10(spillWidth)));
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
- @ProxyMethod({
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.defaultMaximums({
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 = Math.pow(10, Math.floor(Math.log10(spillHeight)));
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
- * Base parameter descriptor; all attributes required.
62
+ * Parameter descriptor.
68
63
  */
69
- export interface BaseParameterDescriptor extends TypeDescriptor {
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; extends a parameter descriptor and overrides select attributes.
72
+ * Extends parameter descriptor.
78
73
  */
79
- export interface ExtendsParameterDescriptor extends Partial<BaseParameterDescriptor> {
74
+ export interface ExtendsParameterDescriptor extends Partial<ParameterDescriptor> {
80
75
  /**
81
- * Base parameter descriptor that this one extends.
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 base parameter descriptor if applicable.
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
- * Method descriptors.
145
+ * Class name in optional namespace.
164
146
  */
165
- readonly methodDescriptors: readonly MethodDescriptor[];
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
- * Proxy method decorator.
205
- *
206
- * @param methodDescriptor
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
- * Get class descriptors map.
322
- *
323
- * @returns
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
  }