@travetto/schema 8.0.0-alpha.19 → 8.0.0-alpha.20
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/package.json +3 -3
- package/src/bind-util.ts +14 -7
- package/src/service/types.ts +1 -1
- package/support/transformer/util.ts +18 -0
- package/support/transformer.schema.ts +36 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/schema",
|
|
3
|
-
"version": "8.0.0-alpha.
|
|
3
|
+
"version": "8.0.0-alpha.20",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Data type registry for runtime validation, reflection and binding.",
|
|
6
6
|
"keywords": [
|
|
@@ -28,10 +28,10 @@
|
|
|
28
28
|
"directory": "module/schema"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@travetto/registry": "^8.0.0-alpha.
|
|
31
|
+
"@travetto/registry": "^8.0.0-alpha.19"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
|
-
"@travetto/transformer": "^8.0.0-alpha.
|
|
34
|
+
"@travetto/transformer": "^8.0.0-alpha.13"
|
|
35
35
|
},
|
|
36
36
|
"peerDependenciesMeta": {
|
|
37
37
|
"@travetto/transformer": {
|
package/src/bind-util.ts
CHANGED
|
@@ -20,6 +20,16 @@ function isInstance<T>(value: unknown): value is T {
|
|
|
20
20
|
*/
|
|
21
21
|
export class BindUtil {
|
|
22
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Utility to make a property accessor enumerable at runtime
|
|
25
|
+
*/
|
|
26
|
+
static registerAccessor(instance: any, property: string): void {
|
|
27
|
+
Object.defineProperty(instance, property, {
|
|
28
|
+
...Object.getOwnPropertyDescriptor(Object.getPrototypeOf(instance), property),
|
|
29
|
+
enumerable: true
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
23
33
|
/**
|
|
24
34
|
* Coerce a value to match the field config type
|
|
25
35
|
* @param config The field config to coerce to
|
|
@@ -153,6 +163,10 @@ export class BindUtil {
|
|
|
153
163
|
const instance = classConstruct<T & { type?: string }>(resolvedCls);
|
|
154
164
|
|
|
155
165
|
for (const key of TypedObject.keys(instance)) { // Do not retain undefined fields
|
|
166
|
+
const descriptor = Object.getOwnPropertyDescriptor(instance, key);
|
|
167
|
+
if (descriptor?.get) {
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
156
170
|
if (instance[key] === undefined) {
|
|
157
171
|
delete instance[key];
|
|
158
172
|
}
|
|
@@ -244,13 +258,6 @@ export class BindUtil {
|
|
|
244
258
|
}
|
|
245
259
|
|
|
246
260
|
input[castKey<T>(schemaFieldName)] = castTo(value);
|
|
247
|
-
|
|
248
|
-
if (field.accessor) {
|
|
249
|
-
Object.defineProperty(input, schemaFieldName, {
|
|
250
|
-
...adapter.getAccessorDescriptor(schemaFieldName),
|
|
251
|
-
enumerable: true
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
261
|
}
|
|
255
262
|
}
|
|
256
263
|
}
|
package/src/service/types.ts
CHANGED
|
@@ -232,7 +232,7 @@ export interface SchemaFieldConfig extends SchemaInputConfig {
|
|
|
232
232
|
/**
|
|
233
233
|
* Is this field a getter or setter
|
|
234
234
|
*/
|
|
235
|
-
accessor?:
|
|
235
|
+
accessor?: boolean;
|
|
236
236
|
}
|
|
237
237
|
|
|
238
238
|
export type ViewFieldsConfig<T> = { with: Extract<(keyof T), string>[] } | { without: Extract<(keyof T), string>[] };
|
|
@@ -14,6 +14,7 @@ export class SchemaTransformUtil {
|
|
|
14
14
|
static INPUT_IMPORT = '@travetto/schema/src/decorator/input.ts';
|
|
15
15
|
static COMMON_IMPORT = '@travetto/schema/src/decorator/common.ts';
|
|
16
16
|
static TYPES_IMPORT = '@travetto/schema/src/types.ts';
|
|
17
|
+
static BIND_UTIL_IMPORT = '@travetto/schema/src/bind-util.ts';
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
20
|
* Produce concrete type given transformer type
|
|
@@ -365,4 +366,21 @@ class ${uniqueId} extends ${type.mappedClassName} {
|
|
|
365
366
|
const finalReturnType = SchemaTransformUtil.ensureType(state, innerReturnType ?? returnType, node);
|
|
366
367
|
return finalReturnType ? [state.fromLiteral({ returnType: finalReturnType })] : [];
|
|
367
368
|
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Helper to create inline defineProperty statement for accessors
|
|
372
|
+
*/
|
|
373
|
+
static createAccessorDefineProperty(state: TransformerState, accessorName: string): ts.Statement {
|
|
374
|
+
const bindUtilImport = state.importFile(this.BIND_UTIL_IMPORT);
|
|
375
|
+
return state.factory.createExpressionStatement(
|
|
376
|
+
state.factory.createCallExpression(
|
|
377
|
+
state.createAccess(bindUtilImport.identifier, 'BindUtil', 'registerAccessor'),
|
|
378
|
+
undefined,
|
|
379
|
+
[
|
|
380
|
+
state.factory.createThis(),
|
|
381
|
+
state.factory.createStringLiteral(accessorName)
|
|
382
|
+
]
|
|
383
|
+
)
|
|
384
|
+
);
|
|
385
|
+
}
|
|
368
386
|
}
|
|
@@ -6,6 +6,7 @@ const CONSTRUCTOR_PROPERTY = 'CONSTRUCTOR';
|
|
|
6
6
|
const InSchema = Symbol();
|
|
7
7
|
const IsOptIn = Symbol();
|
|
8
8
|
const AccessorsSymbol = Symbol();
|
|
9
|
+
const GettersSymbol = Symbol();
|
|
9
10
|
const AutoEnrollMethods = Symbol();
|
|
10
11
|
|
|
11
12
|
interface AutoState {
|
|
@@ -13,6 +14,7 @@ interface AutoState {
|
|
|
13
14
|
[IsOptIn]?: boolean;
|
|
14
15
|
[AutoEnrollMethods]?: Set<string>;
|
|
15
16
|
[AccessorsSymbol]?: Set<string>;
|
|
17
|
+
[GettersSymbol]?: Set<string>;
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
/**
|
|
@@ -64,6 +66,7 @@ export class SchemaTransformer {
|
|
|
64
66
|
*/
|
|
65
67
|
static startSchema(state: AutoState & TransformerState, node: ts.ClassDeclaration): ts.ClassDeclaration {
|
|
66
68
|
state[AccessorsSymbol] = new Set();
|
|
69
|
+
state[GettersSymbol] = new Set();
|
|
67
70
|
state[AutoEnrollMethods] = new Set();
|
|
68
71
|
state[InSchema] = true;
|
|
69
72
|
|
|
@@ -130,9 +133,40 @@ export class SchemaTransformer {
|
|
|
130
133
|
params = [...params, state.fromLiteral(attrs)];
|
|
131
134
|
}
|
|
132
135
|
|
|
136
|
+
let newMembers = node.members;
|
|
137
|
+
const accessors = state[GettersSymbol] ? [...state[GettersSymbol]] : [];
|
|
138
|
+
if (accessors.length > 0) {
|
|
139
|
+
node = DeclarationUtil.ensureConstructor(state.factory, node);
|
|
140
|
+
|
|
141
|
+
const accessorStatements = accessors.map(accessorName =>
|
|
142
|
+
SchemaTransformUtil.createAccessorDefineProperty(state, accessorName)
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
const consIndex = node.members.findIndex(member => ts.isConstructorDeclaration(member));
|
|
146
|
+
const consNode = node.members[consIndex] as ts.ConstructorDeclaration;
|
|
147
|
+
const insertIndex = DeclarationUtil.getConstructorInsertIndex(consNode);
|
|
148
|
+
const newStatements = [
|
|
149
|
+
...consNode.body?.statements.slice(0, insertIndex) ?? [],
|
|
150
|
+
...accessorStatements,
|
|
151
|
+
...consNode.body?.statements.slice(insertIndex) ?? []
|
|
152
|
+
];
|
|
153
|
+
const updatedCons = state.factory.updateConstructorDeclaration(
|
|
154
|
+
consNode,
|
|
155
|
+
consNode.modifiers,
|
|
156
|
+
consNode.parameters,
|
|
157
|
+
state.factory.createBlock(newStatements, true)
|
|
158
|
+
);
|
|
159
|
+
newMembers = ts.factory.createNodeArray([
|
|
160
|
+
...node.members.slice(0, consIndex),
|
|
161
|
+
updatedCons,
|
|
162
|
+
...node.members.slice(consIndex + 1)
|
|
163
|
+
]);
|
|
164
|
+
}
|
|
165
|
+
|
|
133
166
|
delete state[InSchema];
|
|
134
167
|
delete state[IsOptIn];
|
|
135
168
|
delete state[AccessorsSymbol];
|
|
169
|
+
delete state[GettersSymbol];
|
|
136
170
|
delete state[AutoEnrollMethods];
|
|
137
171
|
|
|
138
172
|
return state.factory.updateClassDeclaration(
|
|
@@ -143,7 +177,7 @@ export class SchemaTransformer {
|
|
|
143
177
|
node.name,
|
|
144
178
|
node.typeParameters,
|
|
145
179
|
node.heritageClauses,
|
|
146
|
-
|
|
180
|
+
newMembers
|
|
147
181
|
);
|
|
148
182
|
}
|
|
149
183
|
|
|
@@ -201,6 +235,7 @@ export class SchemaTransformer {
|
|
|
201
235
|
if (this.isInvisible(state, node) || DeclarationUtil.isStatic(node)) {
|
|
202
236
|
return node;
|
|
203
237
|
}
|
|
238
|
+
state[GettersSymbol]?.add(node.name.getText());
|
|
204
239
|
if (state[AccessorsSymbol]?.has(node.name.getText())) {
|
|
205
240
|
return node;
|
|
206
241
|
} else {
|