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