@colyseus/schema 3.0.0-alpha.38 → 3.0.0-alpha.39
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/build/cjs/index.js +73 -20
- package/build/cjs/index.js.map +1 -1
- package/build/esm/index.mjs +73 -21
- package/build/esm/index.mjs.map +1 -1
- package/build/umd/index.js +73 -20
- package/lib/Metadata.d.ts +2 -1
- package/lib/Metadata.js +14 -14
- package/lib/Metadata.js.map +1 -1
- package/lib/Reflection.d.ts +4 -3
- package/lib/Reflection.js +13 -3
- package/lib/Reflection.js.map +1 -1
- package/lib/Schema.d.ts +2 -2
- package/lib/Schema.js.map +1 -1
- package/lib/annotations.d.ts +29 -12
- package/lib/annotations.js +33 -0
- package/lib/annotations.js.map +1 -1
- package/lib/codegen/parser.js +83 -0
- package/lib/codegen/parser.js.map +1 -1
- package/lib/codegen/types.js +3 -0
- package/lib/codegen/types.js.map +1 -1
- package/lib/decoder/DecodeOperation.js +4 -0
- package/lib/decoder/DecodeOperation.js.map +1 -1
- package/lib/decoder/strategy/StateCallbacks.js.map +1 -1
- package/lib/encoder/EncodeOperation.js +2 -2
- package/lib/encoder/EncodeOperation.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +2 -1
- package/lib/index.js.map +1 -1
- package/lib/types/HelperTypes.d.ts +34 -2
- package/lib/types/HelperTypes.js.map +1 -1
- package/lib/types/TypeContext.js +9 -1
- package/lib/types/TypeContext.js.map +1 -1
- package/package.json +1 -1
- package/src/Metadata.ts +16 -17
- package/src/Reflection.ts +13 -5
- package/src/Schema.ts +2 -3
- package/src/annotations.ts +65 -15
- package/src/codegen/parser.ts +107 -0
- package/src/codegen/types.ts +1 -0
- package/src/decoder/DecodeOperation.ts +4 -0
- package/src/decoder/strategy/StateCallbacks.ts +1 -1
- package/src/encoder/EncodeOperation.ts +4 -2
- package/src/index.ts +1 -1
- package/src/types/HelperTypes.ts +54 -2
- package/src/types/TypeContext.ts +11 -1
package/src/Reflection.ts
CHANGED
|
@@ -24,19 +24,27 @@ export class ReflectionType extends Schema {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
export class Reflection extends Schema {
|
|
27
|
-
@type([
|
|
27
|
+
@type([ReflectionType]) types: ArraySchema<ReflectionType> = new ArraySchema<ReflectionType>();
|
|
28
|
+
@type("number") rootType: number;
|
|
28
29
|
|
|
29
30
|
/**
|
|
30
31
|
* Encodes the TypeContext of an Encoder into a buffer.
|
|
31
32
|
*
|
|
32
|
-
* @param
|
|
33
|
+
* @param encoder Encoder instance
|
|
33
34
|
* @param it
|
|
34
35
|
* @returns
|
|
35
36
|
*/
|
|
36
|
-
static encode(
|
|
37
|
+
static encode(encoder: Encoder, it: Iterator = { offset: 0 }) {
|
|
38
|
+
const context = encoder.context;
|
|
39
|
+
|
|
37
40
|
const reflection = new Reflection();
|
|
38
41
|
const reflectionEncoder = new Encoder(reflection);
|
|
39
42
|
|
|
43
|
+
// rootType is usually the first schema passed to the Encoder
|
|
44
|
+
// (unless it inherits from another schema)
|
|
45
|
+
const rootType = context.schemas.get(encoder.state.constructor);
|
|
46
|
+
if (rootType > 0) { reflection.rootType = rootType; }
|
|
47
|
+
|
|
40
48
|
const buildType = (currentType: ReflectionType, metadata: Metadata) => {
|
|
41
49
|
for (const fieldIndex in metadata) {
|
|
42
50
|
const index = Number(fieldIndex);
|
|
@@ -157,7 +165,7 @@ export class Reflection extends Schema {
|
|
|
157
165
|
Metadata.addField(metadata, fieldIndex, field.name, refType);
|
|
158
166
|
|
|
159
167
|
} else {
|
|
160
|
-
Metadata.addField(metadata, fieldIndex, field.name, { [fieldType]: refType }
|
|
168
|
+
Metadata.addField(metadata, fieldIndex, field.name, { [fieldType]: refType });
|
|
161
169
|
}
|
|
162
170
|
|
|
163
171
|
} else {
|
|
@@ -191,7 +199,7 @@ export class Reflection extends Schema {
|
|
|
191
199
|
});
|
|
192
200
|
});
|
|
193
201
|
|
|
194
|
-
const state: T = new (typeContext.get(0) as unknown as any)();
|
|
202
|
+
const state: T = new (typeContext.get(reflection.rootType || 0) as unknown as any)();
|
|
195
203
|
|
|
196
204
|
return new Decoder<T>(state, typeContext);
|
|
197
205
|
}
|
package/src/Schema.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { OPERATION } from './encoding/spec';
|
|
2
|
-
import { DEFAULT_VIEW_TAG, DefinitionType } from "./annotations";
|
|
2
|
+
import { DEFAULT_VIEW_TAG, type DefinitionType } from "./annotations";
|
|
3
3
|
|
|
4
4
|
import { NonFunctionPropNames, ToJSON } from './types/HelperTypes';
|
|
5
5
|
|
|
@@ -15,7 +15,7 @@ import { getIndent } from './utils';
|
|
|
15
15
|
/**
|
|
16
16
|
* Schema encoder / decoder
|
|
17
17
|
*/
|
|
18
|
-
export
|
|
18
|
+
export class Schema {
|
|
19
19
|
static [$encoder] = encodeSchemaOperation;
|
|
20
20
|
static [$decoder] = decodeSchemaOperation;
|
|
21
21
|
|
|
@@ -147,7 +147,6 @@ export abstract class Schema {
|
|
|
147
147
|
|
|
148
148
|
toJSON () {
|
|
149
149
|
const obj: unknown = {};
|
|
150
|
-
|
|
151
150
|
const metadata = this.constructor[Symbol.metadata];
|
|
152
151
|
for (const index in metadata) {
|
|
153
152
|
const field = metadata[index];
|
package/src/annotations.ts
CHANGED
|
@@ -9,12 +9,11 @@ import { OPERATION } from "./encoding/spec";
|
|
|
9
9
|
import { TypeContext } from "./types/TypeContext";
|
|
10
10
|
import { assertInstanceType, assertType } from "./encoding/assert";
|
|
11
11
|
import type { Ref } from "./encoder/ChangeTree";
|
|
12
|
+
import type { DefinedSchemaType, InferValueType } from "./types/HelperTypes";
|
|
13
|
+
import type { CollectionSchema } from "./types/custom/CollectionSchema";
|
|
14
|
+
import type { SetSchema } from "./types/custom/SetSchema";
|
|
12
15
|
|
|
13
|
-
|
|
14
|
-
* Data types
|
|
15
|
-
*/
|
|
16
|
-
export type PrimitiveType =
|
|
17
|
-
"string" |
|
|
16
|
+
export type RawPrimitiveType = "string" |
|
|
18
17
|
"number" |
|
|
19
18
|
"boolean" |
|
|
20
19
|
"int8" |
|
|
@@ -26,16 +25,18 @@ export type PrimitiveType =
|
|
|
26
25
|
"int64" |
|
|
27
26
|
"uint64" |
|
|
28
27
|
"float32" |
|
|
29
|
-
"float64"
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
"float64";
|
|
29
|
+
|
|
30
|
+
export type PrimitiveType = RawPrimitiveType | typeof Schema | object;
|
|
32
31
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
|
36
|
-
| {
|
|
37
|
-
| {
|
|
38
|
-
| {
|
|
32
|
+
// TODO: infer "default" value type correctly.
|
|
33
|
+
export type DefinitionType<T extends PrimitiveType = PrimitiveType> = T
|
|
34
|
+
| T[]
|
|
35
|
+
| { type: T, default?: InferValueType<T>, view?: boolean | number }
|
|
36
|
+
| { array: T, default?: ArraySchema<InferValueType<T>>, view?: boolean | number }
|
|
37
|
+
| { map: T, default?: MapSchema<InferValueType<T>>, view?: boolean | number }
|
|
38
|
+
| { collection: T, default?: CollectionSchema<InferValueType<T>>, view?: boolean | number }
|
|
39
|
+
| { set: T, default?: SetSchema<InferValueType<T>>, view?: boolean | number };
|
|
39
40
|
|
|
40
41
|
export type Definition = { [field: string]: DefinitionType };
|
|
41
42
|
|
|
@@ -479,7 +480,7 @@ export function deprecated(throws: boolean = true): PropertyDecorator {
|
|
|
479
480
|
|
|
480
481
|
export function defineTypes(
|
|
481
482
|
target: typeof Schema,
|
|
482
|
-
fields:
|
|
483
|
+
fields: Definition,
|
|
483
484
|
options?: TypeOptions
|
|
484
485
|
) {
|
|
485
486
|
for (let field in fields) {
|
|
@@ -487,3 +488,52 @@ export function defineTypes(
|
|
|
487
488
|
}
|
|
488
489
|
return target;
|
|
489
490
|
}
|
|
491
|
+
|
|
492
|
+
export interface SchemaWithExtends<T extends Definition, P extends typeof Schema> extends DefinedSchemaType<T, P> {
|
|
493
|
+
extends: <T2 extends Definition>(
|
|
494
|
+
fields: T2,
|
|
495
|
+
name?: string
|
|
496
|
+
) => SchemaWithExtends<T & T2, typeof this>;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
export function schema<T extends Definition, P extends typeof Schema = typeof Schema>(
|
|
500
|
+
fields: T,
|
|
501
|
+
name?: string,
|
|
502
|
+
inherits: P = Schema as P
|
|
503
|
+
): SchemaWithExtends<T, P> {
|
|
504
|
+
const defaultValues: any = {};
|
|
505
|
+
const viewTagFields: any = {};
|
|
506
|
+
|
|
507
|
+
for (let fieldName in fields) {
|
|
508
|
+
const field = fields[fieldName] as DefinitionType;
|
|
509
|
+
if (typeof (field) === "object") {
|
|
510
|
+
if (field['default'] !== undefined) {
|
|
511
|
+
defaultValues[fieldName] = field['default'];
|
|
512
|
+
}
|
|
513
|
+
if (field['view'] !== undefined) {
|
|
514
|
+
viewTagFields[fieldName] = (typeof (field['view']) === "boolean")
|
|
515
|
+
? DEFAULT_VIEW_TAG
|
|
516
|
+
: field['view'];
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
const klass = Metadata.setFields(class extends inherits {
|
|
522
|
+
constructor (...args: any[]) {
|
|
523
|
+
args[0] = Object.assign({}, defaultValues, args[0]);
|
|
524
|
+
super(...args);
|
|
525
|
+
}
|
|
526
|
+
}, fields) as SchemaWithExtends<T, P>;
|
|
527
|
+
|
|
528
|
+
for (let fieldName in viewTagFields) {
|
|
529
|
+
view(viewTagFields[fieldName])(klass.prototype, fieldName);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
if (name) {
|
|
533
|
+
Object.defineProperty(klass, "name", { value: name });
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
klass.extends = (fields, name) => schema(fields, name, klass);
|
|
537
|
+
|
|
538
|
+
return klass;
|
|
539
|
+
}
|
package/src/codegen/parser.ts
CHANGED
|
@@ -148,6 +148,49 @@ function inspectNode(node: ts.Node, context: Context, decoratorName: string) {
|
|
|
148
148
|
defineProperty(property, typeArgument);
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
+
} else if (
|
|
152
|
+
node.getText() === "setFields" &&
|
|
153
|
+
(
|
|
154
|
+
node.parent.kind === ts.SyntaxKind.CallExpression ||
|
|
155
|
+
node.parent.kind === ts.SyntaxKind.PropertyAccessExpression
|
|
156
|
+
)
|
|
157
|
+
) {
|
|
158
|
+
/**
|
|
159
|
+
* Metadata.setFields(klassName, { ... })
|
|
160
|
+
*/
|
|
161
|
+
const callExpression = (node.parent.kind === ts.SyntaxKind.PropertyAccessExpression)
|
|
162
|
+
? node.parent.parent as ts.CallExpression
|
|
163
|
+
: node.parent as ts.CallExpression;
|
|
164
|
+
|
|
165
|
+
if (callExpression.kind !== ts.SyntaxKind.CallExpression) {
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const classNameNode = callExpression.arguments[0];
|
|
170
|
+
const className = ts.isClassExpression(classNameNode)
|
|
171
|
+
? classNameNode.name?.escapedText.toString()
|
|
172
|
+
: classNameNode.getText();
|
|
173
|
+
|
|
174
|
+
// skip if no className is provided
|
|
175
|
+
if (!className) { break; }
|
|
176
|
+
|
|
177
|
+
if (currentStructure.name !== className) {
|
|
178
|
+
currentStructure = new Class();
|
|
179
|
+
}
|
|
180
|
+
context.addStructure(currentStructure);
|
|
181
|
+
(currentStructure as Class).extends = "Schema"; // force extends to Schema
|
|
182
|
+
currentStructure.name = className;
|
|
183
|
+
|
|
184
|
+
const types = callExpression.arguments[1] as any;
|
|
185
|
+
for (let i = 0; i < types.properties.length; i++) {
|
|
186
|
+
const prop = types.properties[i];
|
|
187
|
+
|
|
188
|
+
const property = currentProperty || new Property();
|
|
189
|
+
property.name = prop.name.escapedText;
|
|
190
|
+
|
|
191
|
+
currentStructure.addProperty(property);
|
|
192
|
+
defineProperty(property, prop.initializer);
|
|
193
|
+
}
|
|
151
194
|
|
|
152
195
|
} else if (
|
|
153
196
|
node.getText() === "defineTypes" &&
|
|
@@ -192,6 +235,70 @@ function inspectNode(node: ts.Node, context: Context, decoratorName: string) {
|
|
|
192
235
|
|
|
193
236
|
break;
|
|
194
237
|
|
|
238
|
+
case ts.SyntaxKind.CallExpression:
|
|
239
|
+
/**
|
|
240
|
+
* Defining schema via `schema.schema({ ... })`
|
|
241
|
+
* - schema.schema({})
|
|
242
|
+
* - schema({})
|
|
243
|
+
* - ClassName.extends({})
|
|
244
|
+
*/
|
|
245
|
+
if (
|
|
246
|
+
(
|
|
247
|
+
(
|
|
248
|
+
(node as ts.CallExpression).expression?.getText() === "schema.schema" ||
|
|
249
|
+
(node as ts.CallExpression).expression?.getText() === "schema"
|
|
250
|
+
) ||
|
|
251
|
+
(
|
|
252
|
+
(node as ts.CallExpression).expression?.getText().indexOf(".extends") !== -1
|
|
253
|
+
)
|
|
254
|
+
) &&
|
|
255
|
+
(node as ts.CallExpression).arguments[0].kind === ts.SyntaxKind.ObjectLiteralExpression
|
|
256
|
+
) {
|
|
257
|
+
const callExpression = node as ts.CallExpression;
|
|
258
|
+
|
|
259
|
+
let className = callExpression.arguments[1]?.getText();
|
|
260
|
+
|
|
261
|
+
if (!className && callExpression.parent.kind === ts.SyntaxKind.VariableDeclaration) {
|
|
262
|
+
className = (callExpression.parent as ts.VariableDeclaration).name?.getText();
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// skip if no className is provided
|
|
266
|
+
if (!className) { break; }
|
|
267
|
+
|
|
268
|
+
if (currentStructure.name !== className) {
|
|
269
|
+
currentStructure = new Class();
|
|
270
|
+
context.addStructure(currentStructure);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
if ((node as ts.CallExpression).expression?.getText().indexOf(".extends") !== -1) {
|
|
274
|
+
// if it's using `.extends({})`
|
|
275
|
+
const extendsClass = (node as any).expression?.expression?.escapedText;
|
|
276
|
+
|
|
277
|
+
// skip if no extendsClass is provided
|
|
278
|
+
if (!extendsClass) { break; }
|
|
279
|
+
(currentStructure as Class).extends = extendsClass;
|
|
280
|
+
|
|
281
|
+
} else {
|
|
282
|
+
// if it's using `schema({})`
|
|
283
|
+
(currentStructure as Class).extends = "Schema"; // force extends to Schema
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
currentStructure.name = className;
|
|
287
|
+
|
|
288
|
+
const types = callExpression.arguments[0] as any;
|
|
289
|
+
for (let i = 0; i < types.properties.length; i++) {
|
|
290
|
+
const prop = types.properties[i];
|
|
291
|
+
|
|
292
|
+
const property = currentProperty || new Property();
|
|
293
|
+
property.name = prop.name.escapedText;
|
|
294
|
+
|
|
295
|
+
currentStructure.addProperty(property);
|
|
296
|
+
defineProperty(property, prop.initializer);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
break;
|
|
301
|
+
|
|
195
302
|
case ts.SyntaxKind.EnumMember:
|
|
196
303
|
if (currentStructure instanceof Enum) {
|
|
197
304
|
const initializer = (node as any).initializer?.text;
|
package/src/codegen/types.ts
CHANGED
|
@@ -327,6 +327,10 @@ export const decodeArray: DecodeOperation = function (
|
|
|
327
327
|
(ref as ArraySchema).clear();
|
|
328
328
|
return;
|
|
329
329
|
|
|
330
|
+
} else if (operation === OPERATION.REVERSE) {
|
|
331
|
+
(ref as ArraySchema).reverse();
|
|
332
|
+
return;
|
|
333
|
+
|
|
330
334
|
} else if (operation === OPERATION.DELETE_BY_REFID) {
|
|
331
335
|
// TODO: refactor here, try to follow same flow as below
|
|
332
336
|
const refId = decode.number(bytes, it);
|
|
@@ -4,8 +4,8 @@ import { Ref } from "../../encoder/ChangeTree";
|
|
|
4
4
|
import { Decoder } from "../Decoder";
|
|
5
5
|
import { DataChange } from "../DecodeOperation";
|
|
6
6
|
import { OPERATION } from "../../encoding/spec";
|
|
7
|
-
import { DefinitionType } from "../../annotations";
|
|
8
7
|
import { Schema } from "../../Schema";
|
|
8
|
+
import type { DefinitionType } from "../../annotations";
|
|
9
9
|
import type { CollectionSchema } from "../../types/custom/CollectionSchema";
|
|
10
10
|
|
|
11
11
|
//
|
|
@@ -79,7 +79,6 @@ export const encodeSchemaOperation: EncodeOperation = function (
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
const ref = changeTree.ref;
|
|
82
|
-
// const metadata: Metadata = ref.constructor[Symbol.metadata];
|
|
83
82
|
const field = metadata[index];
|
|
84
83
|
|
|
85
84
|
// TODO: inline this function call small performance gain
|
|
@@ -200,7 +199,10 @@ export const encodeArray: EncodeOperation = function (
|
|
|
200
199
|
bytes[it.offset++] = operation & 255;
|
|
201
200
|
|
|
202
201
|
// custom operations
|
|
203
|
-
if (
|
|
202
|
+
if (
|
|
203
|
+
operation === OPERATION.CLEAR ||
|
|
204
|
+
operation === OPERATION.REVERSE
|
|
205
|
+
) {
|
|
204
206
|
return;
|
|
205
207
|
}
|
|
206
208
|
|
package/src/index.ts
CHANGED
|
@@ -41,7 +41,7 @@ export {
|
|
|
41
41
|
|
|
42
42
|
// Annotations, Metadata and TypeContext
|
|
43
43
|
export { Metadata } from "./Metadata";
|
|
44
|
-
export { type, deprecated, defineTypes, view, } from "./annotations";
|
|
44
|
+
export { type, deprecated, defineTypes, view, schema, type SchemaWithExtends, } from "./annotations";
|
|
45
45
|
export { TypeContext } from "./types/TypeContext";
|
|
46
46
|
|
|
47
47
|
// Annotation types
|
package/src/types/HelperTypes.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import type { Definition, DefinitionType, PrimitiveType, RawPrimitiveType } from "../annotations";
|
|
2
|
+
import type { Schema } from "../Schema";
|
|
3
|
+
import type { ArraySchema } from "./custom/ArraySchema";
|
|
4
|
+
import type { CollectionSchema } from "./custom/CollectionSchema";
|
|
5
|
+
import type { MapSchema } from "./custom/MapSchema";
|
|
6
|
+
import type { SetSchema } from "./custom/SetSchema";
|
|
7
|
+
|
|
8
|
+
export type Constructor<T = {}> = new (...args: any[]) => T;
|
|
3
9
|
|
|
4
10
|
export interface Collection<K = any, V = any, IT = V> {
|
|
5
11
|
[Symbol.iterator](): IterableIterator<IT>;
|
|
@@ -7,6 +13,52 @@ export interface Collection<K = any, V = any, IT = V> {
|
|
|
7
13
|
entries(): IterableIterator<[K, V]>;
|
|
8
14
|
}
|
|
9
15
|
|
|
16
|
+
export type InferValueType<T extends DefinitionType> =
|
|
17
|
+
T extends "string" ? string
|
|
18
|
+
: T extends "number" ? number
|
|
19
|
+
: T extends "int8" ? number
|
|
20
|
+
: T extends "uint8" ? number
|
|
21
|
+
: T extends "int16" ? number
|
|
22
|
+
: T extends "uint16" ? number
|
|
23
|
+
: T extends "int32" ? number
|
|
24
|
+
: T extends "uint32" ? number
|
|
25
|
+
: T extends "int64" ? number
|
|
26
|
+
: T extends "uint64" ? number
|
|
27
|
+
: T extends "float32" ? number
|
|
28
|
+
: T extends "float64" ? number
|
|
29
|
+
: T extends "boolean" ? boolean
|
|
30
|
+
|
|
31
|
+
: T extends { type: infer ChildType extends Constructor } ? InstanceType<ChildType>
|
|
32
|
+
: T extends { type: infer ChildType extends PrimitiveType } ? ChildType
|
|
33
|
+
|
|
34
|
+
: T extends Array<infer ChildType extends Constructor> ? InstanceType<ChildType>[]
|
|
35
|
+
: T extends Array<infer ChildType extends RawPrimitiveType> ? ChildType[]
|
|
36
|
+
|
|
37
|
+
: T extends { array: infer ChildType extends Constructor } ? InstanceType<ChildType>[]
|
|
38
|
+
: T extends { array: infer ChildType extends PrimitiveType } ? ChildType[]
|
|
39
|
+
|
|
40
|
+
: T extends { map: infer ChildType extends Constructor } ? MapSchema<InstanceType<ChildType>>
|
|
41
|
+
: T extends { map: infer ChildType extends PrimitiveType } ? MapSchema<ChildType>
|
|
42
|
+
|
|
43
|
+
: T extends { set: infer ChildType extends Constructor } ? SetSchema<InstanceType<ChildType>>
|
|
44
|
+
: T extends { set: infer ChildType extends PrimitiveType } ? SetSchema<ChildType>
|
|
45
|
+
|
|
46
|
+
: T extends { collection: infer ChildType extends Constructor } ? CollectionSchema<InstanceType<ChildType>>
|
|
47
|
+
: T extends { collection: infer ChildType extends PrimitiveType } ? CollectionSchema<ChildType>
|
|
48
|
+
|
|
49
|
+
: T extends Constructor ? InstanceType<T>
|
|
50
|
+
: T extends PrimitiveType ? T
|
|
51
|
+
|
|
52
|
+
: never;
|
|
53
|
+
|
|
54
|
+
export type InferSchemaInstanceType<T extends Definition> = {
|
|
55
|
+
[K in keyof T]: InferValueType<T[K]>
|
|
56
|
+
} & Schema;
|
|
57
|
+
|
|
58
|
+
export type DefinedSchemaType<T extends Definition, P extends typeof Schema> = {
|
|
59
|
+
new (): InferSchemaInstanceType<T> & InstanceType<P>;
|
|
60
|
+
} & typeof Schema;
|
|
61
|
+
|
|
10
62
|
export type NonFunctionProps<T> = Omit<T, {
|
|
11
63
|
[K in keyof T]: T[K] extends Function ? K : never;
|
|
12
64
|
}[keyof T]>;
|
package/src/types/TypeContext.ts
CHANGED
|
@@ -53,7 +53,7 @@ export class TypeContext {
|
|
|
53
53
|
// Workaround to allow using an empty Schema (with no `@type()` fields)
|
|
54
54
|
//
|
|
55
55
|
if (schema[Symbol.metadata] === undefined) {
|
|
56
|
-
Metadata.
|
|
56
|
+
Metadata.initialize(schema);
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
this.schemas.set(schema, typeid);
|
|
@@ -74,6 +74,16 @@ export class TypeContext {
|
|
|
74
74
|
this.discoverTypes(child, parentIndex, parentFieldViewTag);
|
|
75
75
|
});
|
|
76
76
|
|
|
77
|
+
// add parent classes
|
|
78
|
+
let parent: any = klass;
|
|
79
|
+
while (
|
|
80
|
+
(parent = Object.getPrototypeOf(parent)) &&
|
|
81
|
+
parent !== Schema && // stop at root (Schema)
|
|
82
|
+
parent !== Function.prototype // stop at root (non-Schema)
|
|
83
|
+
) {
|
|
84
|
+
this.discoverTypes(parent);
|
|
85
|
+
}
|
|
86
|
+
|
|
77
87
|
const metadata: Metadata = (klass[Symbol.metadata] ??= {});
|
|
78
88
|
|
|
79
89
|
// if any schema/field has filters, mark "context" as having filters.
|