objectmodel 4.3.1 → 4.4.1
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/dist/object-model.cjs +380 -387
- package/dist/object-model.js +380 -387
- package/dist/object-model.js.map +1 -1
- package/dist/object-model.min.js +2 -2
- package/dist/object-model.min.js.map +1 -1
- package/index.html +4 -4
- package/package.json +70 -64
- package/src/array-model.d.ts +16 -0
- package/src/array-model.js +68 -68
- package/src/devtool-formatter.js +198 -198
- package/src/function-model.d.ts +24 -0
- package/src/function-model.js +58 -65
- package/src/index.js +4 -4
- package/src/map-model.d.ts +18 -0
- package/src/map-model.js +48 -48
- package/src/object-model.d.ts +74 -0
- package/src/set-model.d.ts +16 -0
- package/src/set-model.js +41 -41
- package/test/array-model.test-d.ts +24 -0
- package/test/basic-model.test-d.ts +30 -0
- package/test/function-model.spec.cjs +161 -162
- package/test/function-model.test-d.ts +18 -0
- package/test/map-model.test-d.ts +21 -0
- package/test/object-model.spec.cjs +1345 -1346
- package/test/object-model.test-d.ts +53 -0
- package/test/set-model.test-d.ts +17 -0
- package/types/definitions.d.ts +43 -0
- package/types/helpers.d.ts +4 -0
- package/types/index.d.ts +6 -128
- package/.travis.yml +0 -3
package/dist/object-model.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// ObjectModel v4.
|
|
1
|
+
// ObjectModel v4.4.1 - http://objectmodel.js.org
|
|
2
2
|
// MIT License - Sylvain Pollet-Villard
|
|
3
3
|
const
|
|
4
4
|
ObjectProto = Object.prototype,
|
|
@@ -561,400 +561,393 @@ const initListModel = (base, constructor, def, init, clone, mutators, otherTraps
|
|
|
561
561
|
}, otherTraps))
|
|
562
562
|
};
|
|
563
563
|
|
|
564
|
-
function ArrayModel(initialDefinition) {
|
|
565
|
-
const model = initListModel(
|
|
566
|
-
Array,
|
|
567
|
-
ArrayModel,
|
|
568
|
-
initialDefinition,
|
|
569
|
-
a => Array.isArray(a) ? a.map(arg => cast(arg, model.definition)) : a,
|
|
570
|
-
a => [...a],
|
|
571
|
-
{
|
|
572
|
-
"copyWithin": [],
|
|
573
|
-
"fill": [0, 0],
|
|
574
|
-
"pop": [],
|
|
575
|
-
"push": [0],
|
|
576
|
-
"reverse": [],
|
|
577
|
-
"shift": [],
|
|
578
|
-
"sort": [],
|
|
579
|
-
"splice": [2],
|
|
580
|
-
"unshift": [0]
|
|
581
|
-
},
|
|
582
|
-
{
|
|
583
|
-
set(arr, key, val) {
|
|
584
|
-
return controlMutation(model, arr, key, val, (a, v) => a[key] = v, true)
|
|
585
|
-
},
|
|
586
|
-
|
|
587
|
-
deleteProperty(arr, key) {
|
|
588
|
-
return controlMutation(model, arr, key, undefined, a => delete a[key])
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
);
|
|
592
|
-
|
|
593
|
-
return model
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
extend(ArrayModel, Model, {
|
|
597
|
-
toString(stack) {
|
|
598
|
-
return "Array of " + formatDefinition(this.definition, stack)
|
|
599
|
-
},
|
|
600
|
-
|
|
601
|
-
[_check](arr, path, errors, stack) {
|
|
602
|
-
if (Array.isArray(arr))
|
|
603
|
-
(arr[_original] || arr).forEach((a, i) => checkDefinition(a, this.definition, `${path || "Array"}[${i}]`, errors, stack));
|
|
604
|
-
else stackError(errors, this, arr, path);
|
|
605
|
-
|
|
606
|
-
checkAssertions(arr, this, path, errors);
|
|
607
|
-
},
|
|
608
|
-
|
|
609
|
-
extend(...newParts) {
|
|
610
|
-
return extendModel(new ArrayModel(extendDefinition(this.definition, newParts)), this)
|
|
611
|
-
}
|
|
612
|
-
});
|
|
613
|
-
|
|
614
|
-
const controlMutation = (model, array, key, value, applyMutation, canBeExtended) => {
|
|
615
|
-
const path = `Array[${key}]`;
|
|
616
|
-
const isInDef = (+key >= 0 && (canBeExtended || key in array));
|
|
617
|
-
if (isInDef) value = checkDefinition(value, model.definition, path, model.errors, [], true);
|
|
618
|
-
|
|
619
|
-
const testArray = [...array];
|
|
620
|
-
applyMutation(testArray);
|
|
621
|
-
checkAssertions(testArray, model, path);
|
|
622
|
-
const isSuccess = !unstackErrors(model);
|
|
623
|
-
if (isSuccess) applyMutation(array, value);
|
|
624
|
-
return isSuccess
|
|
564
|
+
function ArrayModel(initialDefinition) {
|
|
565
|
+
const model = initListModel(
|
|
566
|
+
Array,
|
|
567
|
+
ArrayModel,
|
|
568
|
+
initialDefinition,
|
|
569
|
+
a => Array.isArray(a) ? a.map(arg => cast(arg, model.definition)) : a,
|
|
570
|
+
a => [...a],
|
|
571
|
+
{
|
|
572
|
+
"copyWithin": [],
|
|
573
|
+
"fill": [0, 0],
|
|
574
|
+
"pop": [],
|
|
575
|
+
"push": [0],
|
|
576
|
+
"reverse": [],
|
|
577
|
+
"shift": [],
|
|
578
|
+
"sort": [],
|
|
579
|
+
"splice": [2],
|
|
580
|
+
"unshift": [0]
|
|
581
|
+
},
|
|
582
|
+
{
|
|
583
|
+
set(arr, key, val) {
|
|
584
|
+
return controlMutation(model, arr, key, val, (a, v) => a[key] = v, true)
|
|
585
|
+
},
|
|
586
|
+
|
|
587
|
+
deleteProperty(arr, key) {
|
|
588
|
+
return controlMutation(model, arr, key, undefined, a => delete a[key])
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
);
|
|
592
|
+
|
|
593
|
+
return model
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
extend(ArrayModel, Model, {
|
|
597
|
+
toString(stack) {
|
|
598
|
+
return "Array of " + formatDefinition(this.definition, stack)
|
|
599
|
+
},
|
|
600
|
+
|
|
601
|
+
[_check](arr, path, errors, stack) {
|
|
602
|
+
if (Array.isArray(arr))
|
|
603
|
+
(arr[_original] || arr).forEach((a, i) => checkDefinition(a, this.definition, `${path || "Array"}[${i}]`, errors, stack));
|
|
604
|
+
else stackError(errors, this, arr, path);
|
|
605
|
+
|
|
606
|
+
checkAssertions(arr, this, path, errors);
|
|
607
|
+
},
|
|
608
|
+
|
|
609
|
+
extend(...newParts) {
|
|
610
|
+
return extendModel(new ArrayModel(extendDefinition(this.definition, newParts)), this)
|
|
611
|
+
}
|
|
612
|
+
});
|
|
613
|
+
|
|
614
|
+
const controlMutation = (model, array, key, value, applyMutation, canBeExtended) => {
|
|
615
|
+
const path = `Array[${key}]`;
|
|
616
|
+
const isInDef = (+key >= 0 && (canBeExtended || key in array));
|
|
617
|
+
if (isInDef) value = checkDefinition(value, model.definition, path, model.errors, [], true);
|
|
618
|
+
|
|
619
|
+
const testArray = [...array];
|
|
620
|
+
applyMutation(testArray);
|
|
621
|
+
checkAssertions(testArray, model, path);
|
|
622
|
+
const isSuccess = !unstackErrors(model);
|
|
623
|
+
if (isSuccess) applyMutation(array, value);
|
|
624
|
+
return isSuccess
|
|
625
625
|
};
|
|
626
626
|
|
|
627
|
-
function SetModel(initialDefinition) {
|
|
628
|
-
const model = initListModel(
|
|
629
|
-
Set,
|
|
630
|
-
SetModel,
|
|
631
|
-
initialDefinition,
|
|
632
|
-
it => isIterable(it) ? new Set([...it].map(val => cast(val, model.definition))) : it,
|
|
633
|
-
set => new Set(set),
|
|
634
|
-
{
|
|
635
|
-
"add": [0, 0],
|
|
636
|
-
"delete": [],
|
|
637
|
-
"clear": []
|
|
638
|
-
}
|
|
639
|
-
);
|
|
640
|
-
|
|
641
|
-
return model
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
extend(SetModel, Model, {
|
|
645
|
-
toString(stack) {
|
|
646
|
-
return "Set of " + formatDefinition(this.definition, stack)
|
|
647
|
-
},
|
|
648
|
-
|
|
649
|
-
[_check](set, path, errors, stack) {
|
|
650
|
-
if (is(Set, set)) {
|
|
651
|
-
for (let item of set.values()) {
|
|
652
|
-
checkDefinition(item, this.definition, `${path || "Set"} value`, errors, stack);
|
|
653
|
-
}
|
|
654
|
-
} else stackError(errors, this, set, path);
|
|
655
|
-
checkAssertions(set, this, path, errors);
|
|
656
|
-
},
|
|
657
|
-
|
|
658
|
-
extend(...newParts) {
|
|
659
|
-
return extendModel(new SetModel(extendDefinition(this.definition, newParts)), this)
|
|
660
|
-
}
|
|
627
|
+
function SetModel(initialDefinition) {
|
|
628
|
+
const model = initListModel(
|
|
629
|
+
Set,
|
|
630
|
+
SetModel,
|
|
631
|
+
initialDefinition,
|
|
632
|
+
it => isIterable(it) ? new Set([...it].map(val => cast(val, model.definition))) : it,
|
|
633
|
+
set => new Set(set),
|
|
634
|
+
{
|
|
635
|
+
"add": [0, 0],
|
|
636
|
+
"delete": [],
|
|
637
|
+
"clear": []
|
|
638
|
+
}
|
|
639
|
+
);
|
|
640
|
+
|
|
641
|
+
return model
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
extend(SetModel, Model, {
|
|
645
|
+
toString(stack) {
|
|
646
|
+
return "Set of " + formatDefinition(this.definition, stack)
|
|
647
|
+
},
|
|
648
|
+
|
|
649
|
+
[_check](set, path, errors, stack) {
|
|
650
|
+
if (is(Set, set)) {
|
|
651
|
+
for (let item of set.values()) {
|
|
652
|
+
checkDefinition(item, this.definition, `${path || "Set"} value`, errors, stack);
|
|
653
|
+
}
|
|
654
|
+
} else stackError(errors, this, set, path);
|
|
655
|
+
checkAssertions(set, this, path, errors);
|
|
656
|
+
},
|
|
657
|
+
|
|
658
|
+
extend(...newParts) {
|
|
659
|
+
return extendModel(new SetModel(extendDefinition(this.definition, newParts)), this)
|
|
660
|
+
}
|
|
661
661
|
});
|
|
662
662
|
|
|
663
|
-
function MapModel(initialKeyDefinition, initialValueDefinition) {
|
|
664
|
-
const getDef = i => i === 0 ? model.definition.key : model.definition.value;
|
|
665
|
-
const model = initListModel(
|
|
666
|
-
Map,
|
|
667
|
-
MapModel,
|
|
668
|
-
{ key: initialKeyDefinition, value: initialValueDefinition },
|
|
669
|
-
it => isIterable(it) ? new Map([...it].map(pair => pair.map((x, i) => cast(x, getDef(i))))) : it,
|
|
670
|
-
map => new Map(map),
|
|
671
|
-
{
|
|
672
|
-
"set": [0, 1, getDef],
|
|
673
|
-
"delete": [],
|
|
674
|
-
"clear": []
|
|
675
|
-
}
|
|
676
|
-
);
|
|
677
|
-
|
|
678
|
-
return model
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
extend(MapModel, Model, {
|
|
682
|
-
toString(stack) {
|
|
683
|
-
return `Map of ${formatDefinition(this.definition.key, stack)} : ${formatDefinition(this.definition.value, stack)}`
|
|
684
|
-
},
|
|
685
|
-
|
|
686
|
-
[_check](map, path, errors, stack) {
|
|
687
|
-
if (is(Map, map)) {
|
|
688
|
-
path = path || "Map";
|
|
689
|
-
for (let [key, value] of map) {
|
|
690
|
-
checkDefinition(key, this.definition.key, `${path} key`, errors, stack);
|
|
691
|
-
checkDefinition(value, this.definition.value, `${path}[${format$1(key)}]`, errors, stack);
|
|
692
|
-
}
|
|
693
|
-
} else stackError(errors, this, map, path);
|
|
694
|
-
|
|
695
|
-
checkAssertions(map, this, path, errors);
|
|
696
|
-
},
|
|
697
|
-
|
|
698
|
-
extend(keyParts, valueParts) {
|
|
699
|
-
return extendModel(new MapModel(
|
|
700
|
-
extendDefinition(this.definition.key, keyParts),
|
|
701
|
-
extendDefinition(this.definition.value, valueParts)
|
|
702
|
-
), this)
|
|
703
|
-
}
|
|
663
|
+
function MapModel(initialKeyDefinition, initialValueDefinition) {
|
|
664
|
+
const getDef = i => i === 0 ? model.definition.key : model.definition.value;
|
|
665
|
+
const model = initListModel(
|
|
666
|
+
Map,
|
|
667
|
+
MapModel,
|
|
668
|
+
{ key: initialKeyDefinition, value: initialValueDefinition },
|
|
669
|
+
it => isIterable(it) ? new Map([...it].map(pair => pair.map((x, i) => cast(x, getDef(i))))) : it,
|
|
670
|
+
map => new Map(map),
|
|
671
|
+
{
|
|
672
|
+
"set": [0, 1, getDef],
|
|
673
|
+
"delete": [],
|
|
674
|
+
"clear": []
|
|
675
|
+
}
|
|
676
|
+
);
|
|
677
|
+
|
|
678
|
+
return model
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
extend(MapModel, Model, {
|
|
682
|
+
toString(stack) {
|
|
683
|
+
return `Map of ${formatDefinition(this.definition.key, stack)} : ${formatDefinition(this.definition.value, stack)}`
|
|
684
|
+
},
|
|
685
|
+
|
|
686
|
+
[_check](map, path, errors, stack) {
|
|
687
|
+
if (is(Map, map)) {
|
|
688
|
+
path = path || "Map";
|
|
689
|
+
for (let [key, value] of map) {
|
|
690
|
+
checkDefinition(key, this.definition.key, `${path} key`, errors, stack);
|
|
691
|
+
checkDefinition(value, this.definition.value, `${path}[${format$1(key)}]`, errors, stack);
|
|
692
|
+
}
|
|
693
|
+
} else stackError(errors, this, map, path);
|
|
694
|
+
|
|
695
|
+
checkAssertions(map, this, path, errors);
|
|
696
|
+
},
|
|
697
|
+
|
|
698
|
+
extend(keyParts, valueParts) {
|
|
699
|
+
return extendModel(new MapModel(
|
|
700
|
+
extendDefinition(this.definition.key, keyParts),
|
|
701
|
+
extendDefinition(this.definition.value, valueParts)
|
|
702
|
+
), this)
|
|
703
|
+
}
|
|
704
704
|
});
|
|
705
705
|
|
|
706
|
-
function FunctionModel(...argsDef) {
|
|
707
|
-
return initModel({ arguments: argsDef }, FunctionModel, Function, null, model => ({
|
|
708
|
-
getPrototypeOf: () => model.prototype,
|
|
709
|
-
|
|
710
|
-
get(fn, key) {
|
|
711
|
-
return key === _original ? fn : fn[key]
|
|
712
|
-
},
|
|
713
|
-
|
|
714
|
-
apply(fn, ctx, args) {
|
|
715
|
-
const def = model.definition;
|
|
716
|
-
const remainingArgDef = def.arguments.find(argDef => is(Any.remaining, argDef));
|
|
717
|
-
const nbArgsToCheck = remainingArgDef ? Math.max(args.length, def.arguments.length - 1) : def.arguments.length;
|
|
718
|
-
|
|
719
|
-
for (let i = 0; i < nbArgsToCheck; i++) {
|
|
720
|
-
const argDef = remainingArgDef && i >= def.arguments.length - 1 ? remainingArgDef.definition : def.arguments[i];
|
|
721
|
-
args[i] = checkDefinition(args[i], argDef, `arguments[${i}]`, model.errors, [], true);
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
checkAssertions(args, model, "arguments");
|
|
725
|
-
|
|
726
|
-
let result;
|
|
727
|
-
if (!model.errors.length) {
|
|
728
|
-
result = Reflect.apply(fn, ctx, args);
|
|
729
|
-
if ("return" in def)
|
|
730
|
-
result = checkDefinition(result, def.return, "return value", model.errors, [], true);
|
|
731
|
-
}
|
|
732
|
-
unstackErrors(model);
|
|
733
|
-
return result
|
|
734
|
-
}
|
|
735
|
-
}))
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
extend(FunctionModel, Model, {
|
|
739
|
-
toString(stack = []) {
|
|
740
|
-
let out = `Function(${this.definition.arguments.map(
|
|
741
|
-
argDef => formatDefinition(argDef, [...stack])
|
|
742
|
-
).join(", ")})`;
|
|
743
|
-
|
|
744
|
-
if ("return" in this.definition) {
|
|
745
|
-
out += " => " + formatDefinition(this.definition.return, stack);
|
|
746
|
-
}
|
|
747
|
-
return out
|
|
748
|
-
},
|
|
749
|
-
|
|
750
|
-
return(def) {
|
|
751
|
-
this.definition.return = def;
|
|
752
|
-
return this
|
|
753
|
-
},
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
mixedReturns = extendDefinition(this.definition.return, newReturns);
|
|
759
|
-
return extendModel(new FunctionModel(...mixedArgs).return(mixedReturns), this)
|
|
760
|
-
},
|
|
761
|
-
|
|
762
|
-
[_check](f, path, errors) {
|
|
763
|
-
if (!isFunction(f)) stackError(errors, "Function", f, path);
|
|
764
|
-
}
|
|
706
|
+
function FunctionModel(...argsDef) {
|
|
707
|
+
return initModel({ arguments: argsDef }, FunctionModel, Function, null, model => ({
|
|
708
|
+
getPrototypeOf: () => model.prototype,
|
|
709
|
+
|
|
710
|
+
get(fn, key) {
|
|
711
|
+
return key === _original ? fn : fn[key]
|
|
712
|
+
},
|
|
713
|
+
|
|
714
|
+
apply(fn, ctx, args) {
|
|
715
|
+
const def = model.definition;
|
|
716
|
+
const remainingArgDef = def.arguments.find(argDef => is(Any.remaining, argDef));
|
|
717
|
+
const nbArgsToCheck = remainingArgDef ? Math.max(args.length, def.arguments.length - 1) : def.arguments.length;
|
|
718
|
+
|
|
719
|
+
for (let i = 0; i < nbArgsToCheck; i++) {
|
|
720
|
+
const argDef = remainingArgDef && i >= def.arguments.length - 1 ? remainingArgDef.definition : def.arguments[i];
|
|
721
|
+
args[i] = checkDefinition(args[i], argDef, `arguments[${i}]`, model.errors, [], true);
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
checkAssertions(args, model, "arguments");
|
|
725
|
+
|
|
726
|
+
let result;
|
|
727
|
+
if (!model.errors.length) {
|
|
728
|
+
result = Reflect.apply(fn, ctx, args);
|
|
729
|
+
if ("return" in def)
|
|
730
|
+
result = checkDefinition(result, def.return, "return value", model.errors, [], true);
|
|
731
|
+
}
|
|
732
|
+
unstackErrors(model);
|
|
733
|
+
return result
|
|
734
|
+
}
|
|
735
|
+
}))
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
extend(FunctionModel, Model, {
|
|
739
|
+
toString(stack = []) {
|
|
740
|
+
let out = `Function(${this.definition.arguments.map(
|
|
741
|
+
argDef => formatDefinition(argDef, [...stack])
|
|
742
|
+
).join(", ")})`;
|
|
743
|
+
|
|
744
|
+
if ("return" in this.definition) {
|
|
745
|
+
out += " => " + formatDefinition(this.definition.return, stack);
|
|
746
|
+
}
|
|
747
|
+
return out
|
|
748
|
+
},
|
|
749
|
+
|
|
750
|
+
return(def) {
|
|
751
|
+
this.definition.return = def;
|
|
752
|
+
return this
|
|
753
|
+
},
|
|
754
|
+
|
|
755
|
+
[_check](f, path, errors) {
|
|
756
|
+
if (!isFunction(f)) stackError(errors, "Function", f, path);
|
|
757
|
+
}
|
|
765
758
|
});
|
|
766
759
|
|
|
767
|
-
const styles = {
|
|
768
|
-
list: "list-style-type: none; padding: 0; margin: 0;",
|
|
769
|
-
listItem: "padding: 0 0 0 1em;",
|
|
770
|
-
model: "color: #3e999f;",
|
|
771
|
-
instance: "color: #718c00; font-style: italic",
|
|
772
|
-
function: "color: #4271AE",
|
|
773
|
-
string: "color: #C41A16",
|
|
774
|
-
number: "color: #1C00CF",
|
|
775
|
-
boolean: "color: #AA0D91",
|
|
776
|
-
property: "color: #8959a8",
|
|
777
|
-
private: "color: #C19ED8",
|
|
778
|
-
constant: "color: #8959a8; font-weight: bold",
|
|
779
|
-
privateConstant: "color: #C19ED8; font-weight: bold",
|
|
780
|
-
null: "color: #8e908c",
|
|
781
|
-
undeclared: "color: #C0C0C0;",
|
|
782
|
-
proto: "color: #B871BD; font-style: italic"
|
|
783
|
-
};
|
|
784
|
-
|
|
785
|
-
const getModel = (instance) => {
|
|
786
|
-
if (instance === undefined || instance === null)
|
|
787
|
-
return null
|
|
788
|
-
|
|
789
|
-
const proto = getProto(instance);
|
|
790
|
-
if (!proto || !proto.constructor || !is(Model, proto.constructor))
|
|
791
|
-
return null
|
|
792
|
-
|
|
793
|
-
return proto.constructor
|
|
794
|
-
};
|
|
795
|
-
|
|
796
|
-
const span = (style, ...children) => ["span", { style }, ...children];
|
|
797
|
-
|
|
798
|
-
const format = (x, config = {}) => {
|
|
799
|
-
if (x === null || x === undefined)
|
|
800
|
-
return span(styles.null, "" + x);
|
|
801
|
-
|
|
802
|
-
if (typeof x === "boolean")
|
|
803
|
-
return span(styles.boolean, x);
|
|
804
|
-
|
|
805
|
-
if (typeof x === "number")
|
|
806
|
-
return span(styles.number, x);
|
|
807
|
-
|
|
808
|
-
if (typeof x === "string")
|
|
809
|
-
return span(styles.string, `"${x}"`);
|
|
810
|
-
|
|
811
|
-
if (Array.isArray(x) && config.isModelDefinition) {
|
|
812
|
-
return span("", ...x.flatMap(part => [format(part, config), " or "]).slice(0, -1))
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
if (isPlainObject(x))
|
|
816
|
-
return formatObject(x, getModel(x), config)
|
|
817
|
-
|
|
818
|
-
if (isFunction(x) && !is(Model, x) && config.isModelDefinition)
|
|
819
|
-
return span(styles.function, x.name || x.toString());
|
|
820
|
-
|
|
821
|
-
return ["object", { object: x, config }]
|
|
822
|
-
};
|
|
823
|
-
|
|
824
|
-
const formatObject = (o, model, config) => span("",
|
|
825
|
-
"{",
|
|
826
|
-
["ol", { style: styles.list }, ...Object.keys(o).map(prop =>
|
|
827
|
-
["li", { style: styles.listItem }, span(styles.property, prop), ": ", format(o[prop], config)])
|
|
828
|
-
],
|
|
829
|
-
"}"
|
|
830
|
-
);
|
|
831
|
-
|
|
832
|
-
const formatModel = model => {
|
|
833
|
-
const
|
|
834
|
-
cfg = { isModelDefinition: true },
|
|
835
|
-
def = model.definition,
|
|
836
|
-
formatList = (list, map) => list.flatMap(e => [map(e), ", "]).slice(0, -1);
|
|
837
|
-
let parts = [];
|
|
838
|
-
|
|
839
|
-
if (is(BasicModel, model)) parts = [format(def, cfg)];
|
|
840
|
-
if (is(ArrayModel, model)) parts = ["Array of ", format(def, cfg)];
|
|
841
|
-
if (is(SetModel, model)) parts = ["Set of ", format(def, cfg)];
|
|
842
|
-
if (is(MapModel, model)) parts = ["Map of ", format(def.key, cfg), " : ", format(def.value, cfg)];
|
|
843
|
-
if (is(FunctionModel, model)) {
|
|
844
|
-
parts = ["Function(", ...formatList(def.arguments, arg => format(arg, cfg)), ")"];
|
|
845
|
-
if ("return" in def) parts.push(" => ", format(def.return, cfg));
|
|
846
|
-
}
|
|
847
|
-
|
|
848
|
-
if (model.assertions.length > 0) {
|
|
849
|
-
parts.push("\n(assertions: ", ...formatList(model.assertions, f => ["object", { object: f }]), ")");
|
|
850
|
-
}
|
|
851
|
-
|
|
852
|
-
return span(styles.model, ...parts)
|
|
853
|
-
};
|
|
854
|
-
|
|
855
|
-
const ModelFormatter = {
|
|
856
|
-
header(x, config = {}) {
|
|
857
|
-
if (x === Any)
|
|
858
|
-
return span(styles.model, "Any")
|
|
859
|
-
|
|
860
|
-
if (is(Any.remaining, x))
|
|
861
|
-
return span(styles.model, "...", format(x.definition, { isModelDefinition: true }))
|
|
862
|
-
|
|
863
|
-
if (is(ObjectModel, x))
|
|
864
|
-
return span(styles.model, x.name)
|
|
865
|
-
|
|
866
|
-
if (is(Model, x)) {
|
|
867
|
-
return formatModel(x)
|
|
868
|
-
}
|
|
869
|
-
|
|
870
|
-
if (config.isModelDefinition && isPlainObject(x))
|
|
871
|
-
return format(x, config)
|
|
872
|
-
|
|
873
|
-
return null;
|
|
874
|
-
},
|
|
875
|
-
hasBody(x) {
|
|
876
|
-
return is(ObjectModel, x)
|
|
877
|
-
},
|
|
878
|
-
body(model) {
|
|
879
|
-
return span("",
|
|
880
|
-
"{",
|
|
881
|
-
["ol", { style: styles.list }, ...Object.keys(model.definition).map(prop => {
|
|
882
|
-
const isPrivate = model.conventionForPrivate(prop);
|
|
883
|
-
const isConstant = model.conventionForConstant(prop);
|
|
884
|
-
const hasDefault = model.default && has(model.default, prop);
|
|
885
|
-
let style = styles.property;
|
|
886
|
-
|
|
887
|
-
if (isPrivate) {
|
|
888
|
-
style = isConstant ? styles.privateConstant : styles.private;
|
|
889
|
-
} else if (isConstant) {
|
|
890
|
-
style = styles.constant;
|
|
891
|
-
}
|
|
892
|
-
|
|
893
|
-
return ["li", { style: styles.listItem },
|
|
894
|
-
span(style, prop), ": ", format(model.definition[prop], { isModelDefinition: true }),
|
|
895
|
-
hasDefault ? span(styles.proto, " = ", format(model.default[prop])) : ""
|
|
896
|
-
]
|
|
897
|
-
})],
|
|
898
|
-
"}"
|
|
899
|
-
)
|
|
900
|
-
}
|
|
901
|
-
};
|
|
902
|
-
|
|
903
|
-
const ModelInstanceFormatter = {
|
|
904
|
-
header(x, config = {}) {
|
|
905
|
-
if (config.isInstanceProperty && isPlainObject(x)) {
|
|
906
|
-
return format(x, config)
|
|
907
|
-
}
|
|
908
|
-
|
|
909
|
-
const model = getModel(x);
|
|
910
|
-
if (is(Model, model)) {
|
|
911
|
-
const parts = is(ObjectModel, model) ? [model.name] : [["object", { object: x[_original] }], ` (${model.name})`];
|
|
912
|
-
return span(styles.instance, ...parts)
|
|
913
|
-
}
|
|
914
|
-
|
|
915
|
-
return null;
|
|
916
|
-
},
|
|
917
|
-
hasBody(x) {
|
|
918
|
-
return x && is(ObjectModel, getModel(x))
|
|
919
|
-
},
|
|
920
|
-
body(x) {
|
|
921
|
-
const model = getModel(x);
|
|
922
|
-
const o = x[_original] || x;
|
|
923
|
-
return span("",
|
|
924
|
-
"{",
|
|
925
|
-
[
|
|
926
|
-
"ol",
|
|
927
|
-
{ style: styles.list },
|
|
928
|
-
...Object.keys(o).map(prop => {
|
|
929
|
-
const isPrivate = model.conventionForPrivate(prop);
|
|
930
|
-
const isConstant = model.conventionForConstant(prop);
|
|
931
|
-
const isDeclared = prop in model.definition;
|
|
932
|
-
let style = styles.property;
|
|
933
|
-
|
|
934
|
-
if (!isDeclared) {
|
|
935
|
-
style = styles.undeclared;
|
|
936
|
-
} else if (isPrivate) {
|
|
937
|
-
style = isConstant ? styles.privateConstant : styles.private;
|
|
938
|
-
} else if (isConstant) {
|
|
939
|
-
style = styles.constant;
|
|
940
|
-
}
|
|
941
|
-
|
|
942
|
-
return ["li", { style: styles.listItem },
|
|
943
|
-
span(style, prop), ": ", format(o[prop], { isInstanceProperty: true })
|
|
944
|
-
]
|
|
945
|
-
}),
|
|
946
|
-
["li", { style: styles.listItem },
|
|
947
|
-
span(styles.proto, "__proto__", ": ", ["object", { object: getProto(x) }])
|
|
948
|
-
]
|
|
949
|
-
],
|
|
950
|
-
"}"
|
|
951
|
-
)
|
|
952
|
-
}
|
|
953
|
-
};
|
|
954
|
-
|
|
955
|
-
if (typeof window !== "undefined") {
|
|
956
|
-
window.devtoolsFormatters = (window.devtoolsFormatters || [])
|
|
957
|
-
.concat(ModelFormatter, ModelInstanceFormatter);
|
|
760
|
+
const styles = {
|
|
761
|
+
list: "list-style-type: none; padding: 0; margin: 0;",
|
|
762
|
+
listItem: "padding: 0 0 0 1em;",
|
|
763
|
+
model: "color: #3e999f;",
|
|
764
|
+
instance: "color: #718c00; font-style: italic",
|
|
765
|
+
function: "color: #4271AE",
|
|
766
|
+
string: "color: #C41A16",
|
|
767
|
+
number: "color: #1C00CF",
|
|
768
|
+
boolean: "color: #AA0D91",
|
|
769
|
+
property: "color: #8959a8",
|
|
770
|
+
private: "color: #C19ED8",
|
|
771
|
+
constant: "color: #8959a8; font-weight: bold",
|
|
772
|
+
privateConstant: "color: #C19ED8; font-weight: bold",
|
|
773
|
+
null: "color: #8e908c",
|
|
774
|
+
undeclared: "color: #C0C0C0;",
|
|
775
|
+
proto: "color: #B871BD; font-style: italic"
|
|
776
|
+
};
|
|
777
|
+
|
|
778
|
+
const getModel = (instance) => {
|
|
779
|
+
if (instance === undefined || instance === null)
|
|
780
|
+
return null
|
|
781
|
+
|
|
782
|
+
const proto = getProto(instance);
|
|
783
|
+
if (!proto || !proto.constructor || !is(Model, proto.constructor))
|
|
784
|
+
return null
|
|
785
|
+
|
|
786
|
+
return proto.constructor
|
|
787
|
+
};
|
|
788
|
+
|
|
789
|
+
const span = (style, ...children) => ["span", { style }, ...children];
|
|
790
|
+
|
|
791
|
+
const format = (x, config = {}) => {
|
|
792
|
+
if (x === null || x === undefined)
|
|
793
|
+
return span(styles.null, "" + x);
|
|
794
|
+
|
|
795
|
+
if (typeof x === "boolean")
|
|
796
|
+
return span(styles.boolean, x);
|
|
797
|
+
|
|
798
|
+
if (typeof x === "number")
|
|
799
|
+
return span(styles.number, x);
|
|
800
|
+
|
|
801
|
+
if (typeof x === "string")
|
|
802
|
+
return span(styles.string, `"${x}"`);
|
|
803
|
+
|
|
804
|
+
if (Array.isArray(x) && config.isModelDefinition) {
|
|
805
|
+
return span("", ...x.flatMap(part => [format(part, config), " or "]).slice(0, -1))
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
if (isPlainObject(x))
|
|
809
|
+
return formatObject(x, getModel(x), config)
|
|
810
|
+
|
|
811
|
+
if (isFunction(x) && !is(Model, x) && config.isModelDefinition)
|
|
812
|
+
return span(styles.function, x.name || x.toString());
|
|
813
|
+
|
|
814
|
+
return ["object", { object: x, config }]
|
|
815
|
+
};
|
|
816
|
+
|
|
817
|
+
const formatObject = (o, model, config) => span("",
|
|
818
|
+
"{",
|
|
819
|
+
["ol", { style: styles.list }, ...Object.keys(o).map(prop =>
|
|
820
|
+
["li", { style: styles.listItem }, span(styles.property, prop), ": ", format(o[prop], config)])
|
|
821
|
+
],
|
|
822
|
+
"}"
|
|
823
|
+
);
|
|
824
|
+
|
|
825
|
+
const formatModel = model => {
|
|
826
|
+
const
|
|
827
|
+
cfg = { isModelDefinition: true },
|
|
828
|
+
def = model.definition,
|
|
829
|
+
formatList = (list, map) => list.flatMap(e => [map(e), ", "]).slice(0, -1);
|
|
830
|
+
let parts = [];
|
|
831
|
+
|
|
832
|
+
if (is(BasicModel, model)) parts = [format(def, cfg)];
|
|
833
|
+
if (is(ArrayModel, model)) parts = ["Array of ", format(def, cfg)];
|
|
834
|
+
if (is(SetModel, model)) parts = ["Set of ", format(def, cfg)];
|
|
835
|
+
if (is(MapModel, model)) parts = ["Map of ", format(def.key, cfg), " : ", format(def.value, cfg)];
|
|
836
|
+
if (is(FunctionModel, model)) {
|
|
837
|
+
parts = ["Function(", ...formatList(def.arguments, arg => format(arg, cfg)), ")"];
|
|
838
|
+
if ("return" in def) parts.push(" => ", format(def.return, cfg));
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
if (model.assertions.length > 0) {
|
|
842
|
+
parts.push("\n(assertions: ", ...formatList(model.assertions, f => ["object", { object: f }]), ")");
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
return span(styles.model, ...parts)
|
|
846
|
+
};
|
|
847
|
+
|
|
848
|
+
const ModelFormatter = {
|
|
849
|
+
header(x, config = {}) {
|
|
850
|
+
if (x === Any)
|
|
851
|
+
return span(styles.model, "Any")
|
|
852
|
+
|
|
853
|
+
if (is(Any.remaining, x))
|
|
854
|
+
return span(styles.model, "...", format(x.definition, { isModelDefinition: true }))
|
|
855
|
+
|
|
856
|
+
if (is(ObjectModel, x))
|
|
857
|
+
return span(styles.model, x.name)
|
|
858
|
+
|
|
859
|
+
if (is(Model, x)) {
|
|
860
|
+
return formatModel(x)
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
if (config.isModelDefinition && isPlainObject(x))
|
|
864
|
+
return format(x, config)
|
|
865
|
+
|
|
866
|
+
return null;
|
|
867
|
+
},
|
|
868
|
+
hasBody(x) {
|
|
869
|
+
return is(ObjectModel, x)
|
|
870
|
+
},
|
|
871
|
+
body(model) {
|
|
872
|
+
return span("",
|
|
873
|
+
"{",
|
|
874
|
+
["ol", { style: styles.list }, ...Object.keys(model.definition).map(prop => {
|
|
875
|
+
const isPrivate = model.conventionForPrivate(prop);
|
|
876
|
+
const isConstant = model.conventionForConstant(prop);
|
|
877
|
+
const hasDefault = model.default && has(model.default, prop);
|
|
878
|
+
let style = styles.property;
|
|
879
|
+
|
|
880
|
+
if (isPrivate) {
|
|
881
|
+
style = isConstant ? styles.privateConstant : styles.private;
|
|
882
|
+
} else if (isConstant) {
|
|
883
|
+
style = styles.constant;
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
return ["li", { style: styles.listItem },
|
|
887
|
+
span(style, prop), ": ", format(model.definition[prop], { isModelDefinition: true }),
|
|
888
|
+
hasDefault ? span(styles.proto, " = ", format(model.default[prop])) : ""
|
|
889
|
+
]
|
|
890
|
+
})],
|
|
891
|
+
"}"
|
|
892
|
+
)
|
|
893
|
+
}
|
|
894
|
+
};
|
|
895
|
+
|
|
896
|
+
const ModelInstanceFormatter = {
|
|
897
|
+
header(x, config = {}) {
|
|
898
|
+
if (config.isInstanceProperty && isPlainObject(x)) {
|
|
899
|
+
return format(x, config)
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
const model = getModel(x);
|
|
903
|
+
if (is(Model, model)) {
|
|
904
|
+
const parts = is(ObjectModel, model) ? [model.name] : [["object", { object: x[_original] }], ` (${model.name})`];
|
|
905
|
+
return span(styles.instance, ...parts)
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
return null;
|
|
909
|
+
},
|
|
910
|
+
hasBody(x) {
|
|
911
|
+
return x && is(ObjectModel, getModel(x))
|
|
912
|
+
},
|
|
913
|
+
body(x) {
|
|
914
|
+
const model = getModel(x);
|
|
915
|
+
const o = x[_original] || x;
|
|
916
|
+
return span("",
|
|
917
|
+
"{",
|
|
918
|
+
[
|
|
919
|
+
"ol",
|
|
920
|
+
{ style: styles.list },
|
|
921
|
+
...Object.keys(o).map(prop => {
|
|
922
|
+
const isPrivate = model.conventionForPrivate(prop);
|
|
923
|
+
const isConstant = model.conventionForConstant(prop);
|
|
924
|
+
const isDeclared = prop in model.definition;
|
|
925
|
+
let style = styles.property;
|
|
926
|
+
|
|
927
|
+
if (!isDeclared) {
|
|
928
|
+
style = styles.undeclared;
|
|
929
|
+
} else if (isPrivate) {
|
|
930
|
+
style = isConstant ? styles.privateConstant : styles.private;
|
|
931
|
+
} else if (isConstant) {
|
|
932
|
+
style = styles.constant;
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
return ["li", { style: styles.listItem },
|
|
936
|
+
span(style, prop), ": ", format(o[prop], { isInstanceProperty: true })
|
|
937
|
+
]
|
|
938
|
+
}),
|
|
939
|
+
["li", { style: styles.listItem },
|
|
940
|
+
span(styles.proto, "__proto__", ": ", ["object", { object: getProto(x) }])
|
|
941
|
+
]
|
|
942
|
+
],
|
|
943
|
+
"}"
|
|
944
|
+
)
|
|
945
|
+
}
|
|
946
|
+
};
|
|
947
|
+
|
|
948
|
+
if (typeof window !== "undefined") {
|
|
949
|
+
window.devtoolsFormatters = (window.devtoolsFormatters || [])
|
|
950
|
+
.concat(ModelFormatter, ModelInstanceFormatter);
|
|
958
951
|
}
|
|
959
952
|
|
|
960
953
|
;
|