@colyseus/schema 3.0.53 → 3.0.54
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 +48 -25
- package/build/cjs/index.js.map +1 -1
- package/build/esm/index.mjs +48 -25
- package/build/esm/index.mjs.map +1 -1
- package/build/umd/index.js +48 -25
- package/lib/Metadata.js +36 -12
- package/lib/Metadata.js.map +1 -1
- package/lib/annotations.js +7 -6
- package/lib/annotations.js.map +1 -1
- package/lib/types/HelperTypes.d.ts +25 -11
- package/lib/types/HelperTypes.js.map +1 -1
- package/lib/types/TypeContext.js +1 -9
- package/lib/types/TypeContext.js.map +1 -1
- package/lib/types/registry.d.ts +3 -0
- package/lib/types/registry.js +4 -3
- package/lib/types/registry.js.map +1 -1
- package/package.json +1 -1
- package/src/Metadata.ts +41 -13
- package/src/annotations.ts +10 -7
- package/src/types/HelperTypes.ts +15 -6
- package/src/types/TypeContext.ts +1 -11
- package/src/types/registry.ts +2 -1
package/build/cjs/index.js
CHANGED
|
@@ -685,15 +685,7 @@ class TypeContext {
|
|
|
685
685
|
if (typeof (fieldType) === "string") {
|
|
686
686
|
continue;
|
|
687
687
|
}
|
|
688
|
-
if (
|
|
689
|
-
const type = fieldType[0];
|
|
690
|
-
// skip primitive types
|
|
691
|
-
if (type === "string") {
|
|
692
|
-
continue;
|
|
693
|
-
}
|
|
694
|
-
this.discoverTypes(type, klass, index, parentHasViewTag || fieldHasViewTag);
|
|
695
|
-
}
|
|
696
|
-
else if (typeof (fieldType) === "function") {
|
|
688
|
+
if (typeof (fieldType) === "function") {
|
|
697
689
|
this.discoverTypes(fieldType, klass, index, parentHasViewTag || fieldHasViewTag);
|
|
698
690
|
}
|
|
699
691
|
else {
|
|
@@ -743,11 +735,43 @@ class TypeContext {
|
|
|
743
735
|
}
|
|
744
736
|
|
|
745
737
|
function getNormalizedType(type) {
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
738
|
+
if (Array.isArray(type)) {
|
|
739
|
+
return { array: getNormalizedType(type[0]) };
|
|
740
|
+
}
|
|
741
|
+
else if (typeof (type['type']) !== "undefined") {
|
|
742
|
+
return type['type'];
|
|
743
|
+
}
|
|
744
|
+
else if (isTSEnum(type)) {
|
|
745
|
+
// Detect TS Enum type (either string or number)
|
|
746
|
+
return Object.keys(type).every(key => typeof type[key] === "string")
|
|
747
|
+
? "string"
|
|
748
|
+
: "number";
|
|
749
|
+
}
|
|
750
|
+
else if (typeof type === "object" && type !== null) {
|
|
751
|
+
// Handle collection types
|
|
752
|
+
const collectionType = Object.keys(type).find(k => registeredTypes[k] !== undefined);
|
|
753
|
+
if (collectionType) {
|
|
754
|
+
type[collectionType] = getNormalizedType(type[collectionType]);
|
|
755
|
+
return type;
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
return type;
|
|
759
|
+
}
|
|
760
|
+
function isTSEnum(_enum) {
|
|
761
|
+
if (typeof _enum === 'function' && _enum[Symbol.metadata]) {
|
|
762
|
+
return false;
|
|
763
|
+
}
|
|
764
|
+
const keys = Object.keys(_enum);
|
|
765
|
+
const numericFields = keys.filter(k => /\d+/.test(k));
|
|
766
|
+
// Check for number enum (has numeric keys and reverse mapping)
|
|
767
|
+
if (numericFields.length > 0 && numericFields.length === (keys.length / 2) && _enum[_enum[numericFields[0]]] == numericFields[0]) {
|
|
768
|
+
return true;
|
|
769
|
+
}
|
|
770
|
+
// Check for string enum (all values are strings and keys match values)
|
|
771
|
+
if (keys.length > 0 && keys.every(key => typeof _enum[key] === 'string' && _enum[key] === key)) {
|
|
772
|
+
return true;
|
|
773
|
+
}
|
|
774
|
+
return false;
|
|
751
775
|
}
|
|
752
776
|
const Metadata = {
|
|
753
777
|
addField(metadata, index, name, type, descriptor) {
|
|
@@ -862,14 +886,12 @@ const Metadata = {
|
|
|
862
886
|
?? -1; // no fields defined
|
|
863
887
|
fieldIndex++;
|
|
864
888
|
for (const field in fields) {
|
|
865
|
-
const type = fields[field];
|
|
889
|
+
const type = getNormalizedType(fields[field]);
|
|
866
890
|
// FIXME: this code is duplicated from @type() annotation
|
|
867
|
-
const complexTypeKlass = (
|
|
868
|
-
? getType("array")
|
|
869
|
-
: (typeof (Object.keys(type)[0]) === "string") && getType(Object.keys(type)[0]);
|
|
891
|
+
const complexTypeKlass = typeof (Object.keys(type)[0]) === "string" && getType(Object.keys(type)[0]);
|
|
870
892
|
const childType = (complexTypeKlass)
|
|
871
893
|
? Object.values(type)[0]
|
|
872
|
-
:
|
|
894
|
+
: type;
|
|
873
895
|
Metadata.addField(metadata, fieldIndex, field, type, getPropertyDescriptor(`_${field}`, fieldIndex, childType, complexTypeKlass));
|
|
874
896
|
fieldIndex++;
|
|
875
897
|
}
|
|
@@ -3331,6 +3353,8 @@ function type(type, options) {
|
|
|
3331
3353
|
if (!type) {
|
|
3332
3354
|
throw new Error(`${constructor.name}: @type() reference provided for "${field}" is undefined. Make sure you don't have any circular dependencies.`);
|
|
3333
3355
|
}
|
|
3356
|
+
// Normalize type (enum/collection/etc)
|
|
3357
|
+
type = getNormalizedType(type);
|
|
3334
3358
|
// for inheritance support
|
|
3335
3359
|
TypeContext.register(constructor);
|
|
3336
3360
|
const parentClass = Object.getPrototypeOf(constructor);
|
|
@@ -3375,9 +3399,7 @@ function type(type, options) {
|
|
|
3375
3399
|
});
|
|
3376
3400
|
}
|
|
3377
3401
|
else {
|
|
3378
|
-
const complexTypeKlass = (
|
|
3379
|
-
? getType("array")
|
|
3380
|
-
: (typeof (Object.keys(type)[0]) === "string") && getType(Object.keys(type)[0]);
|
|
3402
|
+
const complexTypeKlass = typeof (Object.keys(type)[0]) === "string" && getType(Object.keys(type)[0]);
|
|
3381
3403
|
const childType = (complexTypeKlass)
|
|
3382
3404
|
? Object.values(type)[0]
|
|
3383
3405
|
: type;
|
|
@@ -3504,9 +3526,10 @@ function schema(fieldsAndMethods, name, inherits = Schema) {
|
|
|
3504
3526
|
? DEFAULT_VIEW_TAG
|
|
3505
3527
|
: value['view'];
|
|
3506
3528
|
}
|
|
3507
|
-
fields[fieldName] = value;
|
|
3529
|
+
fields[fieldName] = getNormalizedType(value);
|
|
3508
3530
|
// If no explicit default provided, handle automatic instantiation for collection types
|
|
3509
3531
|
if (!Object.prototype.hasOwnProperty.call(value, 'default')) {
|
|
3532
|
+
// TODO: remove Array.isArray() check. Use ['array'] !== undefined only.
|
|
3510
3533
|
if (Array.isArray(value) || value['array'] !== undefined) {
|
|
3511
3534
|
// Collection: Array → new ArraySchema()
|
|
3512
3535
|
defaultValues[fieldName] = new ArraySchema();
|
|
@@ -3536,14 +3559,14 @@ function schema(fieldsAndMethods, name, inherits = Schema) {
|
|
|
3536
3559
|
if (Schema.is(value)) {
|
|
3537
3560
|
// Direct Schema type: Type → new Type()
|
|
3538
3561
|
defaultValues[fieldName] = new value();
|
|
3539
|
-
fields[fieldName] = value;
|
|
3562
|
+
fields[fieldName] = getNormalizedType(value);
|
|
3540
3563
|
}
|
|
3541
3564
|
else {
|
|
3542
3565
|
methods[fieldName] = value;
|
|
3543
3566
|
}
|
|
3544
3567
|
}
|
|
3545
3568
|
else {
|
|
3546
|
-
fields[fieldName] = value;
|
|
3569
|
+
fields[fieldName] = getNormalizedType(value);
|
|
3547
3570
|
}
|
|
3548
3571
|
}
|
|
3549
3572
|
const getDefaultValues = () => {
|