@bikky/replication 1.0.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/Constants/Errors.d.ts +27 -0
- package/Constants/Errors.js +75 -0
- package/Constants/Logging.d.ts +17 -0
- package/Constants/Logging.js +97 -0
- package/Constants/ReplicableRegistry.d.ts +37 -0
- package/Constants/ReplicableRegistry.js +234 -0
- package/Constants/SerialisationTypes.d.ts +82 -0
- package/Constants/SerialisationTypes.js +160 -0
- package/Constants/SourceMaps.d.ts +10 -0
- package/Constants/SourceMaps.js +12 -0
- package/Constants/TraversalStep.d.ts +5 -0
- package/Constants/TraversalStep.js +2 -0
- package/Constants/Versions.d.ts +15 -0
- package/Constants/Versions.js +63 -0
- package/Expressions/Compiler/BuiltinGrammar.d.ts +234 -0
- package/Expressions/Compiler/BuiltinGrammar.js +446 -0
- package/Expressions/Compiler/ExpressionGrammar.d.ts +89 -0
- package/Expressions/Compiler/ExpressionGrammar.js +70 -0
- package/Expressions/Compiler/Parser.d.ts +56 -0
- package/Expressions/Compiler/Parser.js +314 -0
- package/Expressions/Compiler/Tokenizer.d.ts +52 -0
- package/Expressions/Compiler/Tokenizer.js +222 -0
- package/Expressions/Compiler/__tests__/Replicable.Expressions.Parser.test.d.ts +1 -0
- package/Expressions/Compiler/__tests__/Replicable.Expressions.Parser.test.js +516 -0
- package/Expressions/Compiler/__tests__/Replicable.Expressions.Tokenizer.test.d.ts +1 -0
- package/Expressions/Compiler/__tests__/Replicable.Expressions.Tokenizer.test.js +68 -0
- package/Expressions/CreateEvaluator.d.ts +4 -0
- package/Expressions/CreateEvaluator.js +85 -0
- package/Expressions/EvaluatorChain.d.ts +19 -0
- package/Expressions/EvaluatorChain.js +137 -0
- package/Expressions/EvaluatorSteps.d.ts +19 -0
- package/Expressions/EvaluatorSteps.js +12 -0
- package/Expressions/EvaluatorString.d.ts +21 -0
- package/Expressions/EvaluatorString.js +26 -0
- package/Expressions/Expression.d.ts +36 -0
- package/Expressions/Expression.js +147 -0
- package/Expressions/Traverser.d.ts +28 -0
- package/Expressions/Traverser.js +348 -0
- package/Expressions/TypeRegistry/Accessors.d.ts +26 -0
- package/Expressions/TypeRegistry/Accessors.js +58 -0
- package/Expressions/TypeRegistry/ChainCollections.d.ts +51 -0
- package/Expressions/TypeRegistry/ChainCollections.js +134 -0
- package/Expressions/TypeRegistry/ChainTypes.d.ts +23 -0
- package/Expressions/TypeRegistry/ChainTypes.js +46 -0
- package/Expressions/TypeRegistry/CustomAPI.d.ts +36 -0
- package/Expressions/TypeRegistry/CustomAPI.js +181 -0
- package/Expressions/TypeRegistry/Primitive.d.ts +19 -0
- package/Expressions/TypeRegistry/Primitive.js +47 -0
- package/Expressions/TypeRegistry/Registry.d.ts +27 -0
- package/Expressions/TypeRegistry/Registry.js +270 -0
- package/Expressions/TypeRegistry/ReplAPI.d.ts +41 -0
- package/Expressions/TypeRegistry/ReplAPI.js +220 -0
- package/Expressions/TypeRegistry/Scope.d.ts +24 -0
- package/Expressions/TypeRegistry/Scope.js +44 -0
- package/Expressions/TypeRegistry/Types.d.ts +23 -0
- package/Expressions/TypeRegistry/Types.js +1 -0
- package/Expressions/TypeRegistry/__tests__/Replicable.Expressions.Accessors.test.d.ts +1 -0
- package/Expressions/TypeRegistry/__tests__/Replicable.Expressions.Accessors.test.js +31 -0
- package/Expressions/__tests__/ExpressionExamples.d.ts +28 -0
- package/Expressions/__tests__/ExpressionExamples.js +50 -0
- package/Expressions/__tests__/Replicable.Expressions.Expressions.test.d.ts +1 -0
- package/Expressions/__tests__/Replicable.Expressions.Expressions.test.js +166 -0
- package/IDPool.d.ts +18 -0
- package/IDPool.data.d.ts +17 -0
- package/IDPool.js +139 -0
- package/License.txt +1 -0
- package/Main.d.ts +13 -0
- package/Main.js +13 -0
- package/Networking.d.ts +60 -0
- package/Networking.js +626 -0
- package/Replicatable.d.ts +66 -0
- package/Replicatable.js +123 -0
- package/Tracking/Buffable.d.ts +68 -0
- package/Tracking/Buffable.js +194 -0
- package/Tracking/Class.d.ts +97 -0
- package/Tracking/Class.js +221 -0
- package/Tracking/Functions.d.ts +14 -0
- package/Tracking/Functions.js +27 -0
- package/Tracking/GlobalGroup.d.ts +5 -0
- package/Tracking/GlobalGroup.js +39 -0
- package/Tracking/Property.d.ts +95 -0
- package/Tracking/Property.js +125 -0
- package/Tracking/Types.d.ts +33 -0
- package/Tracking/Types.js +1 -0
- package/Tracking/__tests__/Replicable.Tracking.Decorator.test.d.ts +1 -0
- package/Tracking/__tests__/Replicable.Tracking.Decorator.test.js +151 -0
- package/Tracking/__tests__/Replicable.Tracking.Deserialisation.test.d.ts +1 -0
- package/Tracking/__tests__/Replicable.Tracking.Deserialisation.test.js +253 -0
- package/Tracking/__tests__/Replicable.Tracking.MixinSchemaGeneration.test.d.ts +1 -0
- package/Tracking/__tests__/Replicable.Tracking.MixinSchemaGeneration.test.js +135 -0
- package/Tracking/__tests__/Replicable.Tracking.Struct.test.d.ts +1 -0
- package/Tracking/__tests__/Replicable.Tracking.Struct.test.js +66 -0
- package/Tracking/__tests__/Replicable.Tracking.Type.test.d.ts +1 -0
- package/Tracking/__tests__/Replicable.Tracking.Type.test.js +67 -0
- package/Transformers/Configurer.d.ts +39 -0
- package/Transformers/Configurer.js +415 -0
- package/Transformers/Constructor.d.ts +12 -0
- package/Transformers/Constructor.js +44 -0
- package/Transformers/Definitions.d.ts +102 -0
- package/Transformers/Definitions.js +626 -0
- package/Transformers/Loader.d.ts +45 -0
- package/Transformers/Loader.js +350 -0
- package/Transformers/Progress.d.ts +32 -0
- package/Transformers/Progress.js +429 -0
- package/Transformers/Reference.d.ts +37 -0
- package/Transformers/Reference.js +212 -0
- package/Transformers/SchemaGenerator.d.ts +102 -0
- package/Transformers/SchemaGenerator.js +564 -0
- package/Transformers/Serialiser.d.ts +31 -0
- package/Transformers/Serialiser.js +366 -0
- package/Transformers/Utils.d.ts +33 -0
- package/Transformers/Utils.js +287 -0
- package/Transformers/__tests__/Examples.d.ts +168 -0
- package/Transformers/__tests__/Examples.js +263 -0
- package/Transformers/__tests__/Replicable.Transformers.Definitions.test.d.ts +1 -0
- package/Transformers/__tests__/Replicable.Transformers.Definitions.test.js +457 -0
- package/Transformers/__tests__/Replicable.Transformers.Loader.test.d.ts +1 -0
- package/Transformers/__tests__/Replicable.Transformers.Loader.test.js +339 -0
- package/Transformers/__tests__/Replicable.Transformers.Progress.test.d.ts +1 -0
- package/Transformers/__tests__/Replicable.Transformers.Progress.test.js +256 -0
- package/Transformers/__tests__/Replicable.Transformers.Reference.test.d.ts +1 -0
- package/Transformers/__tests__/Replicable.Transformers.Reference.test.js +167 -0
- package/Transformers/__tests__/Replicable.Transformers.SchemaGenerator.test.d.ts +1 -0
- package/Transformers/__tests__/Replicable.Transformers.SchemaGenerator.test.js +400 -0
- package/Transformers/__tests__/Replicable.Transformers.SchemaGeneratorOutput.test.d.ts +1 -0
- package/Transformers/__tests__/Replicable.Transformers.SchemaGeneratorOutput.test.js +441 -0
- package/Transformers/__tests__/Replicable.Transformers.Serialiser.test.d.ts +1 -0
- package/Transformers/__tests__/Replicable.Transformers.Serialiser.test.js +320 -0
- package/Transformers/__tests__/Replicable.Transformers.Utils.test.d.ts +1 -0
- package/Transformers/__tests__/Replicable.Transformers.Utils.test.js +534 -0
- package/__tests__/Replicable.Expressions.test.d.ts +1 -0
- package/__tests__/Replicable.Expressions.test.js +166 -0
- package/__tests__/Replicable.IDPool.test.d.ts +1 -0
- package/__tests__/Replicable.IDPool.test.js +11 -0
- package/__tests__/Replicable.ReplicableRegistry.test.d.ts +1 -0
- package/__tests__/Replicable.ReplicableRegistry.test.js +154 -0
- package/__tests__/Replicable.Serialisation.test.d.ts +1 -0
- package/__tests__/Replicable.Serialisation.test.js +283 -0
- package/package.json +14 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1,626 @@
|
|
|
1
|
+
import { Expression } from "../Expressions/Expression.js";
|
|
2
|
+
import { ReplicableRegistry } from "../Constants/ReplicableRegistry.js";
|
|
3
|
+
import { DataSymbol, describeObject, isPrimitiveType, isPrimitiveValue, PropertyTypes, TypeSymbol, ValueIsPrimitiveType } from "../Constants/SerialisationTypes.js";
|
|
4
|
+
import { ErrorStack } from "../Constants/Errors.js";
|
|
5
|
+
import { Utils } from "./Utils.js";
|
|
6
|
+
import { Pointer } from "./Reference.js";
|
|
7
|
+
import { MinVersion } from "../Constants/Versions.js";
|
|
8
|
+
import { ReplicableClass } from "../Tracking/Class.js";
|
|
9
|
+
import { __ReplTypeHelperFunctions } from "../Expressions/TypeRegistry/ReplAPI.js";
|
|
10
|
+
export var Definitions;
|
|
11
|
+
(function (Definitions) {
|
|
12
|
+
var isExpressionKind = Expression.isExpressionKind;
|
|
13
|
+
function ProducePropertyError(errorStack, errorContext, expected, got) {
|
|
14
|
+
let expectedString;
|
|
15
|
+
if (typeof expected === "string") {
|
|
16
|
+
expectedString = expected;
|
|
17
|
+
}
|
|
18
|
+
else if ("load" in expected) {
|
|
19
|
+
expectedString = Utils.PrintUtils.CategoryVisualModifierAid(expected.load.possibleModifiers);
|
|
20
|
+
let multi = expected.load.types.length > 1;
|
|
21
|
+
let types = (expected.load.types)
|
|
22
|
+
.flatMap((e) => {
|
|
23
|
+
var _a;
|
|
24
|
+
let vals = e.types;
|
|
25
|
+
if (typeof vals === "string") {
|
|
26
|
+
vals = (_a = [ReplicableRegistry.__GetReplicableForDataName(vals)]) !== null && _a !== void 0 ? _a : vals;
|
|
27
|
+
if (typeof vals === "string") {
|
|
28
|
+
return vals;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return vals.map((currentVal) => {
|
|
32
|
+
let stringName = Utils.PrintUtils.ReplPrimOrRawToName(currentVal);
|
|
33
|
+
if (stringName.includes("|"))
|
|
34
|
+
multi = true;
|
|
35
|
+
return stringName;
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
if (multi) {
|
|
39
|
+
expectedString = expectedString.replace("1", "(" + types.join(" | ") + ")");
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
expectedString = expectedString.replace("1", types.join(" | "));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
expectedString = Utils.PrintUtils.ConfigVisualModifierAid(expected);
|
|
47
|
+
let types = expected.outputTypes.flatMap((e) => typeof e === "string" ? ReplicableRegistry.__GetReplicableForDataName(e) : e);
|
|
48
|
+
if (types.length > 1) {
|
|
49
|
+
expectedString = expectedString.replace("1", "(" + types.map((e) => Utils.PrintUtils.ReplPrimOrRawToName(e)).join(" | ") + ")");
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
expectedString = expectedString.replace("1", Utils.PrintUtils.ReplPrimOrRawToName(types[0]));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
let gotString = "value" in got ? Utils.PrintUtils.ValVisualAidBestGuess(got.value) : got.aid;
|
|
56
|
+
errorStack.add("REP_TD001", `${errorContext} expects ${expectedString} but got a ${gotString}.`);
|
|
57
|
+
}
|
|
58
|
+
function ProducePropertyExpressionError(errorStack, errorContext, expected, got) {
|
|
59
|
+
let expectedString = typeof expected === "string" ? expected : Utils.PrintUtils.ConfigVisualModifierAid(expected);
|
|
60
|
+
if (typeof expected !== "string") {
|
|
61
|
+
let expectedTypes = expected.outputTypes.flatMap((e) => typeof e === "string" ? ReplicableRegistry.__GetReplicableForDataName(e) : e);
|
|
62
|
+
if (expectedTypes.length == 1) {
|
|
63
|
+
expectedString = expectedString.replace("1", Utils.PrintUtils.ReplPrimOrRawToName(expectedTypes[0]));
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
expectedString = expectedString.replace("1", "(" + expectedTypes.map((e) => Utils.PrintUtils.ReplPrimOrRawToName(e)).join(" | ")) + ")";
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
let gotString = Utils.PrintUtils.ConfigVisualModifierAid(got.config);
|
|
70
|
+
let gotTypes = got.config.outputTypes.flatMap((e) => typeof e === "string" ? ReplicableRegistry.__GetReplicableForDataName(e) : e);
|
|
71
|
+
if (gotTypes.length == 1) {
|
|
72
|
+
gotString = gotString.replace("1", Utils.PrintUtils.ReplPrimOrRawToName(gotTypes[0]));
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
gotString = gotString.replace("1", "(" + gotTypes.map((e) => Utils.PrintUtils.ReplPrimOrRawToName(e)).join(" | ")) + ")";
|
|
76
|
+
}
|
|
77
|
+
errorStack.add("REP_TD002", `${errorContext} expects ${expectedString} but Expression produces ${gotString}. Expression is ${got.rawText}.`);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Determines if the expression results matches the modifiers for the given property definition.
|
|
81
|
+
* Modifiers include array, map, dictionary and optional.
|
|
82
|
+
* @param errorContext The context to add to the error message, should be ClassName.PropertyName.
|
|
83
|
+
* @param def The property definition to check against.
|
|
84
|
+
* @param val The value to check.
|
|
85
|
+
* @param errorStack The error stack to add errors to.
|
|
86
|
+
*/
|
|
87
|
+
function DoExprOutputsMatchPropertyModifier(errorContext, def, val, errorStack) {
|
|
88
|
+
if (val instanceof Expression)
|
|
89
|
+
val = val.expression;
|
|
90
|
+
let defStyle = Utils.PrintUtils.ConfigVisualModifierAid(def);
|
|
91
|
+
let valStyle = Utils.PrintUtils.ConfigVisualModifierAid(val.config);
|
|
92
|
+
if (defStyle !== valStyle) {
|
|
93
|
+
ProducePropertyExpressionError(errorStack, errorContext, def, val);
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
Definitions.DoExprOutputsMatchPropertyModifier = DoExprOutputsMatchPropertyModifier;
|
|
99
|
+
/**
|
|
100
|
+
* Determines if the expression results match the types for the given property definition, ignores modifiers
|
|
101
|
+
* like array, map and dictionary.
|
|
102
|
+
* @param errorContext The context to add to the error message, should be ClassName.PropertyName.
|
|
103
|
+
* @param def The property definition to check against.
|
|
104
|
+
* @param propVal The value to check.
|
|
105
|
+
* @param errorStack The error stack to add errors to.
|
|
106
|
+
* @constructor
|
|
107
|
+
*/
|
|
108
|
+
function DoExprOutputsMatchPropertyType(errorContext, def, propVal, errorStack) {
|
|
109
|
+
if (propVal instanceof Expression)
|
|
110
|
+
propVal = propVal.expression;
|
|
111
|
+
let outputTypes = def.outputTypes.flatMap((e) => typeof e === "string" ? ReplicableRegistry.GetTypesForName(e) : e);
|
|
112
|
+
outputTypes = outputTypes.map((e) => e instanceof ReplicableClass ? e.classConstructor : e);
|
|
113
|
+
if (!propVal.outputTypes.every((t) => outputTypes.some((e) => e == t))) {
|
|
114
|
+
ProducePropertyExpressionError(errorStack, errorContext, def, propVal);
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
Definitions.DoExprOutputsMatchPropertyType = DoExprOutputsMatchPropertyType;
|
|
120
|
+
/**
|
|
121
|
+
* Determines if value matches the modifiers for the given property definition.
|
|
122
|
+
* Modifiers include array, map, dictionary and optional.
|
|
123
|
+
* Also checks map index requirements.
|
|
124
|
+
* @param def The property definition to check against.
|
|
125
|
+
* @param val The value to check. DOES NOT SUPPORT EXPRESSIONS.
|
|
126
|
+
* @param errorStack The error stack to add errors to.
|
|
127
|
+
*/
|
|
128
|
+
function DoesValMatchPropertyModifier(def, val) {
|
|
129
|
+
let modifiers = PropertyTypes.ModOnly(def.modifiers);
|
|
130
|
+
let succeeded = true;
|
|
131
|
+
switch (modifiers) {
|
|
132
|
+
case PropertyTypes.Solo: {
|
|
133
|
+
// Everything matches!
|
|
134
|
+
// Can't do a strict check on this because some classes might have special conditions for
|
|
135
|
+
// what is a valid value, including arrays and objects without "Class" in them.
|
|
136
|
+
succeeded = true;
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
case PropertyTypes.Array: {
|
|
140
|
+
succeeded = Array.isArray(val);
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
case PropertyTypes.Array2: {
|
|
144
|
+
succeeded = Array.isArray(val) && val.every((e) => Array.isArray(e));
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
case PropertyTypes.Map:
|
|
148
|
+
if (val instanceof Map) {
|
|
149
|
+
succeeded = true;
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
//Fall through
|
|
153
|
+
case PropertyTypes.Dictionary: {
|
|
154
|
+
succeeded = typeof val === "object" && val.__proto__ === Object.prototype;
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return succeeded;
|
|
159
|
+
}
|
|
160
|
+
Definitions.DoesValMatchPropertyModifier = DoesValMatchPropertyModifier;
|
|
161
|
+
/**
|
|
162
|
+
* ASSUMES INPUTS ARE CORRECT - DOES NOT CHECK FOR ERRORS.
|
|
163
|
+
* Get all of the assigned property values, so that they can individually be checked against the type requirements
|
|
164
|
+
* of the definiton. Turns single values, double arrays, maps and dicts all into a single flat array of values.
|
|
165
|
+
* @param def The property definition to get the values for.
|
|
166
|
+
* @param val The value to get the values from.
|
|
167
|
+
*/
|
|
168
|
+
function GetPropValuesFromData(def, val) {
|
|
169
|
+
let result = [];
|
|
170
|
+
let type;
|
|
171
|
+
if (PropertyTypes.isType(def.load.possibleModifiers, PropertyTypes.Array2) && Array.isArray(val) && (val.length == 0 || Array.isArray(val[0]))) {
|
|
172
|
+
type = PropertyTypes.Array2;
|
|
173
|
+
result = val.flat(2);
|
|
174
|
+
}
|
|
175
|
+
else if (PropertyTypes.isType(def.load.possibleModifiers, PropertyTypes.Array) && Array.isArray(val)) {
|
|
176
|
+
type = PropertyTypes.Array;
|
|
177
|
+
result = [...val];
|
|
178
|
+
}
|
|
179
|
+
else if (PropertyTypes.isType(def.load.possibleModifiers, PropertyTypes.Map) && val instanceof Map) {
|
|
180
|
+
type = PropertyTypes.Map;
|
|
181
|
+
result = [...val.values()];
|
|
182
|
+
}
|
|
183
|
+
else if (PropertyTypes.isTypeOr(def.load.possibleModifiers, PropertyTypes.Dictionary, PropertyTypes.Map) && typeof val === "object" && val.__proto__ === Object.prototype) {
|
|
184
|
+
type = PropertyTypes.Dictionary | PropertyTypes.Map;
|
|
185
|
+
result = Object.values(val);
|
|
186
|
+
}
|
|
187
|
+
else if (PropertyTypes.isType(def.load.possibleModifiers, PropertyTypes.Solo)) {
|
|
188
|
+
type = PropertyTypes.Solo;
|
|
189
|
+
result = [val];
|
|
190
|
+
}
|
|
191
|
+
if (type === undefined) {
|
|
192
|
+
throw new Error(`Property ${def.load.name} has no valid type for the value ${describeObject(val)}.`);
|
|
193
|
+
}
|
|
194
|
+
return [result.map((e) => e instanceof Pointer ? e.val : e), type];
|
|
195
|
+
}
|
|
196
|
+
Definitions.GetPropValuesFromData = GetPropValuesFromData;
|
|
197
|
+
/**
|
|
198
|
+
* ASSUMES INPUTS ARE CORRECT - DOES NOT CHECK FOR ERRORS.
|
|
199
|
+
* Runs a function on every value, setting the value to the results of the function.
|
|
200
|
+
* @param def The property definition to get the values for.
|
|
201
|
+
* @param val The value to get the values from.
|
|
202
|
+
* @param cb The function to run on every value.
|
|
203
|
+
*/
|
|
204
|
+
function MapEveryPropValue(def, val, cb) {
|
|
205
|
+
if (PropertyTypes.isType(def.load.possibleModifiers, PropertyTypes.Array2) && Array.isArray(val) && (val.length == 0 || Array.isArray(val[0]))) {
|
|
206
|
+
for (let i = 0; i < val.length; i++) {
|
|
207
|
+
for (let j = 0; j < val[i].length; j++) {
|
|
208
|
+
val[i][j] = cb(val[i][j]);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
else if (PropertyTypes.isType(def.load.possibleModifiers, PropertyTypes.Array) && Array.isArray(val)) {
|
|
213
|
+
for (let i = 0; i < val.length; i++) {
|
|
214
|
+
val[i] = cb(val[i]);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
else if (PropertyTypes.isType(def.load.possibleModifiers, PropertyTypes.Map) && val instanceof Map) {
|
|
218
|
+
for (let k of val.keys()) {
|
|
219
|
+
let v = val.get(k);
|
|
220
|
+
val.set(k, cb(v));
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
else if (PropertyTypes.isTypeOr(def.load.possibleModifiers, PropertyTypes.Dictionary, PropertyTypes.Map) && typeof val === "object" && val.__proto__ === Object.prototype) {
|
|
224
|
+
for (let v in val) {
|
|
225
|
+
val[v] = cb(val[v]);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
else if (PropertyTypes.isType(def.load.possibleModifiers, PropertyTypes.Solo)) {
|
|
229
|
+
val = cb(val);
|
|
230
|
+
}
|
|
231
|
+
return val;
|
|
232
|
+
}
|
|
233
|
+
Definitions.MapEveryPropValue = MapEveryPropValue;
|
|
234
|
+
/**
|
|
235
|
+
* Check if the given value is assignable to the given class.
|
|
236
|
+
* @param type The type to check against.
|
|
237
|
+
* @param val The value to check.
|
|
238
|
+
* @param errorStack The error stack to add errors to.
|
|
239
|
+
* @param skipCustomOverride allows us to skip the class specific "DataIsType" function and use the default checks
|
|
240
|
+
* instead. This should mostly be used by the class itself when checking its own properties.
|
|
241
|
+
*/
|
|
242
|
+
function DoesDataClassMatchRepl(version, type, val, errorStack, skipCustomOverride = false) {
|
|
243
|
+
if (!skipCustomOverride && "DataIsType" in type.classConstructor) {
|
|
244
|
+
return type.classConstructor.DataIsType(version, val, errorStack) ? type : null;
|
|
245
|
+
}
|
|
246
|
+
if (isPrimitiveValue(val)) {
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
if (val[TypeSymbol]) {
|
|
250
|
+
if ((val[TypeSymbol] === type || type.isChildTypeOfThisType(val[TypeSymbol]))) {
|
|
251
|
+
return val[TypeSymbol];
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
errorStack.add("REP_TD003", `Data is of type ${val[TypeSymbol].opts.dataTypeName} which is not assignable to ${type.opts.dataTypeName}.`);
|
|
255
|
+
return null;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
if (!("Class" in val)) {
|
|
259
|
+
errorStack.add("REP_TD004", `Data is missing a "Class" property.`);
|
|
260
|
+
return null;
|
|
261
|
+
}
|
|
262
|
+
let specificType = ReplicableRegistry.GetTypeForDataName(val.Class);
|
|
263
|
+
//If value thinks it's of type Class, but type Class doesn't exist, that's an error.
|
|
264
|
+
if (!specificType) {
|
|
265
|
+
errorStack.add("REP_TD005", `Data claims to be of type ${val.Class} but no such type exists.`);
|
|
266
|
+
return null;
|
|
267
|
+
}
|
|
268
|
+
//If value thinks it's of type Class, but Class isn't assignable to type, then miss-match.
|
|
269
|
+
if (type !== specificType && !type.isChildTypeOfThisType(specificType)) {
|
|
270
|
+
let aliases = ReplicableRegistry.__GetReplicablesFor(type.classConstructor);
|
|
271
|
+
if (aliases) {
|
|
272
|
+
let valids = aliases.filter((e) => e === specificType || (e instanceof ReplicableClass && e.isChildTypeOfThisType(specificType)));
|
|
273
|
+
if (valids.length > 0) {
|
|
274
|
+
//TODO: Handle Primitive returns?
|
|
275
|
+
return valids[0];
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
errorStack.add("REP_TD006", `Data claims to be of type ${specificType.opts.dataTypeName} which is not assignable to ${type.opts.dataTypeName}.`);
|
|
279
|
+
return null;
|
|
280
|
+
}
|
|
281
|
+
return specificType;
|
|
282
|
+
}
|
|
283
|
+
Definitions.DoesDataClassMatchRepl = DoesDataClassMatchRepl;
|
|
284
|
+
/**
|
|
285
|
+
* Check if the given expression matches the property definition.
|
|
286
|
+
* @param errorContext The context to add to the error message, should be ClassName.PropertyName.
|
|
287
|
+
* @param conf The expression configuration to check against.
|
|
288
|
+
* @param propVal The value to check.
|
|
289
|
+
* @param errorStack The error stack to add errors to.
|
|
290
|
+
* @param instanceOnly If true, will check the expression to match a single value of the property,
|
|
291
|
+
* rather than an array or a map.
|
|
292
|
+
*/
|
|
293
|
+
function DoesExpressionMatchProperty(errorContext, conf, propVal, errorStack, instanceOnly = false) {
|
|
294
|
+
if (!conf) {
|
|
295
|
+
errorStack.add("REP_TD007", `${errorContext} does not allow for expressions.`);
|
|
296
|
+
return false;
|
|
297
|
+
}
|
|
298
|
+
if (instanceOnly) {
|
|
299
|
+
conf = Object.assign(Object.assign({}, conf), { outputArray: 0, outputDict: false, outputMap: false });
|
|
300
|
+
}
|
|
301
|
+
if (!DoExprOutputsMatchPropertyModifier(errorContext, conf, propVal, errorStack)) {
|
|
302
|
+
return false;
|
|
303
|
+
}
|
|
304
|
+
return DoExprOutputsMatchPropertyType(errorContext, conf, propVal, errorStack);
|
|
305
|
+
}
|
|
306
|
+
Definitions.DoesExpressionMatchProperty = DoesExpressionMatchProperty;
|
|
307
|
+
/**
|
|
308
|
+
* Check if the given data is loadable for this ReplicableClass.
|
|
309
|
+
* @param type The type to check against.
|
|
310
|
+
* @param val The data to check.
|
|
311
|
+
* @param source The source file that the data comes from.
|
|
312
|
+
* @param errorStack The error stack to add errors to.
|
|
313
|
+
* @param skipCustomOverride If true, will skip the class' "DataIsType" function and use the default checks instead.
|
|
314
|
+
*/
|
|
315
|
+
function IsLoadableDataForRepl(type, val, version, errorStack, skipCustomOverride = false) {
|
|
316
|
+
if (typeof val === "object" && val !== null) {
|
|
317
|
+
if (val[DataSymbol] && val[DataSymbol] instanceof ReplicableClass) {
|
|
318
|
+
let result = type.isChildTypeOfThisType(val[DataSymbol]);
|
|
319
|
+
if (!result) {
|
|
320
|
+
errorStack.add("REP_TD008", `Data is of type ${val[DataSymbol].opts.dataTypeName} which is not assignable to ${type.opts.dataTypeName}.`);
|
|
321
|
+
}
|
|
322
|
+
return result;
|
|
323
|
+
}
|
|
324
|
+
if (val[TypeSymbol]) {
|
|
325
|
+
let result = type.isChildTypeOfThisType(val[TypeSymbol]);
|
|
326
|
+
if (!result) {
|
|
327
|
+
errorStack.add("REP_TD009", `Data is of type ${val[TypeSymbol].opts.dataTypeName} which is not assignable to ${type.opts.dataTypeName}.`);
|
|
328
|
+
}
|
|
329
|
+
return result;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
let subStack = new ErrorStack(errorStack.source);
|
|
333
|
+
if (isPrimitiveValue(val)) {
|
|
334
|
+
if (skipCustomOverride) {
|
|
335
|
+
errorStack.add("REP_TD010", `Data is a primitive value (${describeObject(val)}), and is not a valid value for ${type.opts.dataTypeName}.`);
|
|
336
|
+
return false;
|
|
337
|
+
}
|
|
338
|
+
if ("DataIsType" in type.classConstructor) {
|
|
339
|
+
return type.classConstructor.DataIsType(version, val, errorStack);
|
|
340
|
+
}
|
|
341
|
+
errorStack.add("REP_TD011", `Data is a primitive value (${describeObject(val)}), and is not a valid value for ${type.opts.dataTypeName}.`);
|
|
342
|
+
return false;
|
|
343
|
+
}
|
|
344
|
+
if ("DataIsType" in type.classConstructor && !skipCustomOverride) {
|
|
345
|
+
if (typeof val === "object" && val.__proto__ == Object.prototype) {
|
|
346
|
+
val[DataSymbol] = type;
|
|
347
|
+
}
|
|
348
|
+
return type.classConstructor.DataIsType(version, val, errorStack);
|
|
349
|
+
}
|
|
350
|
+
let repl = DoesDataClassMatchRepl(version, type, val, subStack, skipCustomOverride);
|
|
351
|
+
if (!repl) {
|
|
352
|
+
errorStack.appendAndIndent(subStack);
|
|
353
|
+
errorStack.add("REP_TD012", `Error parsing data. Data ${type.getIDAsString(val, true)} is not assignable to class ${type.opts.typescriptTypeName}, see above errors for details.`);
|
|
354
|
+
return false;
|
|
355
|
+
}
|
|
356
|
+
let classStack = new ErrorStack(errorStack.source);
|
|
357
|
+
let optionalClassErrors = new ErrorStack(errorStack.source);
|
|
358
|
+
let props = type.finalised_properties.get(type.opts.version);
|
|
359
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
360
|
+
iterateProperties: for (let name of type.finalised_propertyNames) {
|
|
361
|
+
let propInfo = props[name];
|
|
362
|
+
if ("removed" in propInfo || "doesntExist" in propInfo) {
|
|
363
|
+
continue;
|
|
364
|
+
}
|
|
365
|
+
if (!propInfo.load.present || propInfo.load.skipLoad) {
|
|
366
|
+
continue;
|
|
367
|
+
}
|
|
368
|
+
if (propInfo.load.present == "optional" && typeof val[propInfo.load.name] === "undefined") {
|
|
369
|
+
continue;
|
|
370
|
+
}
|
|
371
|
+
//If the needed variable is not present...
|
|
372
|
+
if (!(propInfo.load.name in val)) {
|
|
373
|
+
classStack.add("REP_TD013", `${type.opts.typescriptTypeName}.${propInfo.load.name} is missing and is not optional.`);
|
|
374
|
+
continue;
|
|
375
|
+
}
|
|
376
|
+
let propVal = val[propInfo.load.name];
|
|
377
|
+
//There should be no expression strings as InitialiseData preps them all as EvaluationChains or
|
|
378
|
+
// EvaluationStrings.
|
|
379
|
+
if (Expression.isExpressionString(propVal)) {
|
|
380
|
+
if (!propInfo.expressionForProperty) {
|
|
381
|
+
classStack.add("REP_TD014", `${type.opts.typescriptTypeName}.${propInfo.load.name} does not allow for expressions.`);
|
|
382
|
+
continue;
|
|
383
|
+
}
|
|
384
|
+
else {
|
|
385
|
+
throw new Error(`Data should be initialised before being verified, ${type.getIDAsString(val)} has not been initialised.`);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
//Evaluate expressions to see if they're correct, if they are then skip everything after.
|
|
389
|
+
if (isExpressionKind(propVal)) {
|
|
390
|
+
DoesExpressionMatchProperty(`${repl.opts.dataTypeName}.${propInfo.load.name}`, propInfo.expressionForProperty[version], propVal, classStack);
|
|
391
|
+
continue;
|
|
392
|
+
}
|
|
393
|
+
//Only keep values that match the modifiers we have. So if we have a dict or map we don't care about
|
|
394
|
+
// matching the values of an array.
|
|
395
|
+
let validTypes = propInfo.load.types.filter((e) => DoesValMatchPropertyModifier(e, propVal));
|
|
396
|
+
if (validTypes.length == 0) {
|
|
397
|
+
let subStack = new ErrorStack(errorStack.source);
|
|
398
|
+
ProducePropertyError(subStack, `${type.opts.dataTypeName}.${propInfo.load.name}`, propInfo, { value: propVal });
|
|
399
|
+
classStack.appendWithoutIndent(subStack);
|
|
400
|
+
continue;
|
|
401
|
+
}
|
|
402
|
+
let [values, modifier] = GetPropValuesFromData(propInfo, propVal);
|
|
403
|
+
let propErrorStack = new ErrorStack(errorStack.source);
|
|
404
|
+
let valid = false;
|
|
405
|
+
//Most of the time this loop will only execute once.
|
|
406
|
+
//Must match one of the type groups.
|
|
407
|
+
iterateTypeGroup: for (let propTypeGroup of propInfo.load.types) {
|
|
408
|
+
if (!PropertyTypes.isType(propTypeGroup.modifiers, modifier)) {
|
|
409
|
+
continue;
|
|
410
|
+
}
|
|
411
|
+
//If using a string definition, assume correct data since we can't actually verify it.
|
|
412
|
+
if (typeof propTypeGroup.types === "string") {
|
|
413
|
+
break;
|
|
414
|
+
}
|
|
415
|
+
let subValid = true;
|
|
416
|
+
let primitives = propTypeGroup.types.filter((e) => isPrimitiveType(e));
|
|
417
|
+
let overrides = propTypeGroup.types.filter((e) => !isPrimitiveType(e) && ("DataIsType" in e.classConstructor));
|
|
418
|
+
let repls = propTypeGroup.types.filter((e) => !isPrimitiveType(e) && !("DataIsType" in e.classConstructor));
|
|
419
|
+
//Each value must match one of the types.
|
|
420
|
+
checkValues: for (let value of values) {
|
|
421
|
+
//There should be no expression strings as InitialiseData preps them all as EvaluationChains or
|
|
422
|
+
// EvaluationStrings.
|
|
423
|
+
if (Expression.isExpressionString(value)) {
|
|
424
|
+
if (!propInfo.expressionForValue) {
|
|
425
|
+
propErrorStack.add("REP_TD015", `${type.opts.dataTypeName}.${propInfo.load.name} does not allow for expressions.`);
|
|
426
|
+
subValid = false;
|
|
427
|
+
//This value is invalid, report it and check the next one.
|
|
428
|
+
continue checkValues;
|
|
429
|
+
}
|
|
430
|
+
else {
|
|
431
|
+
throw new Error(`Data should be initialised before being verified, ${type.getIDAsString(val)} has not been initialised.`);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
//If this value matches one of the special class overrides for the valid types, then it's valid.
|
|
435
|
+
//Otherwise we continue as normal.
|
|
436
|
+
for (let def of overrides) {
|
|
437
|
+
if (def.classConstructor.DataIsType(version, value, propErrorStack)) {
|
|
438
|
+
//This value is valid, now check the next one.
|
|
439
|
+
continue checkValues;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
if (isPrimitiveValue(value)) {
|
|
443
|
+
if (!primitives.some((e) => ValueIsPrimitiveType(e, value))) {
|
|
444
|
+
ProducePropertyError(propErrorStack, `${type.opts.typescriptTypeName}.${propInfo.load.name}`, propInfo, { value });
|
|
445
|
+
subValid = false;
|
|
446
|
+
}
|
|
447
|
+
//This value has been validated, report the results and check the next one.
|
|
448
|
+
continue checkValues;
|
|
449
|
+
}
|
|
450
|
+
if (isExpressionKind(value)) {
|
|
451
|
+
if (!propInfo.expressionForValue) {
|
|
452
|
+
propErrorStack.add("REP_TD017", `${type.opts.dataTypeName}.${propInfo.load.name} does not allow for expressions.`);
|
|
453
|
+
subValid = false;
|
|
454
|
+
//This value is invalid, report it and check the next one.
|
|
455
|
+
continue checkValues;
|
|
456
|
+
}
|
|
457
|
+
let errStr = `${repl.opts.dataTypeName}.${propInfo.load.name}'s individual values`;
|
|
458
|
+
if (!DoesExpressionMatchProperty(errStr, propInfo.expressionForValue[version], value, propErrorStack, true)) {
|
|
459
|
+
subValid = false;
|
|
460
|
+
}
|
|
461
|
+
//This value has been validated, report the results and check the next one.
|
|
462
|
+
continue checkValues;
|
|
463
|
+
}
|
|
464
|
+
if (value[TypeSymbol]) {
|
|
465
|
+
if (!repls.some((e) => e instanceof ReplicableClass && e.isChildTypeOfThisType(value[TypeSymbol]))) {
|
|
466
|
+
subValid = false;
|
|
467
|
+
propErrorStack.add("REP_TD018", `Data is of type ${value[TypeSymbol].opts.dataTypeName} which is not assignable to ${type.opts.dataTypeName}.${propInfo.load.name}.`);
|
|
468
|
+
}
|
|
469
|
+
//This value is invalid, report it and check the next one.
|
|
470
|
+
continue checkValues;
|
|
471
|
+
}
|
|
472
|
+
let subErrorStack = new ErrorStack(errorStack.source);
|
|
473
|
+
if (!repls.some((e) => IsLoadableDataForRepl(e, value, version, subErrorStack))) {
|
|
474
|
+
propErrorStack.appendAndIndent(subErrorStack);
|
|
475
|
+
// let subInfo = {...propInfo, type: propInfo.type.map((e) => {return { type: e.type }})};
|
|
476
|
+
ProducePropertyError(propErrorStack, `${type.opts.typescriptTypeName}.${propInfo.load.name}`, propInfo, { value: propVal });
|
|
477
|
+
subValid = false;
|
|
478
|
+
//This value has been validated, report the results and check the next one.
|
|
479
|
+
continue checkValues;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
if (subValid) {
|
|
483
|
+
valid = true;
|
|
484
|
+
break;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
//Only add the various errors to the stack if one of the values doesn't match any valid types.
|
|
488
|
+
if (!valid) {
|
|
489
|
+
classStack.appendWithoutIndent(propErrorStack);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
if (optionalClassErrors.hasErrors()) {
|
|
493
|
+
errorStack.appendAndIndent(optionalClassErrors);
|
|
494
|
+
}
|
|
495
|
+
if (classStack.hasErrors()) {
|
|
496
|
+
errorStack.appendAndIndent(classStack);
|
|
497
|
+
errorStack.add("REP_TD019", `Failed to parse ${type.getIDAsString(val, true)} for class ${type.opts.typescriptTypeName}, see above errors for details.`);
|
|
498
|
+
return false;
|
|
499
|
+
}
|
|
500
|
+
if (errorStack.hasErrors()) {
|
|
501
|
+
errorStack.add("REP_TD020", `Warnings present when parsing ${type.getIDAsString(val, true)} for class ${type.opts.typescriptTypeName}, see above warnings for details.`);
|
|
502
|
+
}
|
|
503
|
+
val[DataSymbol] = type;
|
|
504
|
+
return true;
|
|
505
|
+
}
|
|
506
|
+
Definitions.IsLoadableDataForRepl = IsLoadableDataForRepl;
|
|
507
|
+
/**
|
|
508
|
+
* Check if the given value is loadable for the given type.
|
|
509
|
+
* @param type The repl class or primitive type to check against.
|
|
510
|
+
* @param val The value to check.
|
|
511
|
+
* @param version The version to check against.
|
|
512
|
+
* @param errorStack The error stack to add errors to.
|
|
513
|
+
* @param skipCustomOverride If true, will skip the class' "DataIsType" function and use the default checks instead.
|
|
514
|
+
*/
|
|
515
|
+
function IsLoadableDataForType(type, val, version, errorStack, skipCustomOverride = false) {
|
|
516
|
+
if (isPrimitiveType(type)) {
|
|
517
|
+
let result = ValueIsPrimitiveType(type, val);
|
|
518
|
+
if (!result) {
|
|
519
|
+
errorStack.add("REP_TD021", `Tried to assign ${describeObject(val)} to ${describeObject(type)}.`);
|
|
520
|
+
}
|
|
521
|
+
return result;
|
|
522
|
+
}
|
|
523
|
+
if (!(type instanceof ReplicableClass)) {
|
|
524
|
+
let types = ReplicableRegistry.__GetReplOrPrimFor(type);
|
|
525
|
+
if (!types) {
|
|
526
|
+
throw new Error(`Type ${describeObject(type)} is not a valid type.`);
|
|
527
|
+
}
|
|
528
|
+
let stack = new ErrorStack(errorStack.source);
|
|
529
|
+
for (let type of types) {
|
|
530
|
+
if (isPrimitiveType(type)) {
|
|
531
|
+
if (ValueIsPrimitiveType(type, val)) {
|
|
532
|
+
return true;
|
|
533
|
+
}
|
|
534
|
+
stack.add("REP_TD022", `Tried to assign ${describeObject(val)} to ${describeObject(type)}.`);
|
|
535
|
+
continue;
|
|
536
|
+
}
|
|
537
|
+
if (IsLoadableDataForRepl(type, val, version, stack, skipCustomOverride)) {
|
|
538
|
+
return true;
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
errorStack.appendWithoutIndent(stack);
|
|
542
|
+
if (typeof val === "object" && "Class" in val) {
|
|
543
|
+
}
|
|
544
|
+
return false;
|
|
545
|
+
}
|
|
546
|
+
return IsLoadableDataForRepl(type, val, version, errorStack, skipCustomOverride);
|
|
547
|
+
}
|
|
548
|
+
Definitions.IsLoadableDataForType = IsLoadableDataForType;
|
|
549
|
+
/**
|
|
550
|
+
* Setup and cache parsed expressions so that they don't have to be re-parsed every time an object is created with
|
|
551
|
+
* type data.
|
|
552
|
+
* Perform property migration for removed properties.
|
|
553
|
+
* @param rawType The type to setup expressions for.
|
|
554
|
+
* @param data
|
|
555
|
+
* @param source
|
|
556
|
+
*/
|
|
557
|
+
function PrePrepareData(rawType, data, source, expressionStartOverride) {
|
|
558
|
+
let types = rawType instanceof ReplicableClass ? [rawType] : ReplicableRegistry.__GetReplicablesFor(rawType);
|
|
559
|
+
if (!types) {
|
|
560
|
+
throw new Error(`Type ${describeObject(rawType)} is not a valid type.`);
|
|
561
|
+
}
|
|
562
|
+
//Hard-coded to one for now.
|
|
563
|
+
let type = types[0];
|
|
564
|
+
if (isPrimitiveType(type)) {
|
|
565
|
+
return data;
|
|
566
|
+
}
|
|
567
|
+
let version = MinVersion(source.Version, type.opts.version);
|
|
568
|
+
let props = type.finalised_properties.get(version);
|
|
569
|
+
for (let tsProp of type.finalised_propertyNames) {
|
|
570
|
+
let propInfo = props[tsProp];
|
|
571
|
+
if ("doesntExist" in propInfo || "removed" in propInfo) {
|
|
572
|
+
continue;
|
|
573
|
+
}
|
|
574
|
+
if (!propInfo.load.present || propInfo.load.skipLoad) {
|
|
575
|
+
continue;
|
|
576
|
+
}
|
|
577
|
+
if (propInfo.load.present == "optional" && typeof data[propInfo.load.name] === "undefined") {
|
|
578
|
+
continue;
|
|
579
|
+
}
|
|
580
|
+
let dataName = propInfo.load.name;
|
|
581
|
+
if (Expression.isExpressionString(data[dataName])) {
|
|
582
|
+
//If no config then the property doesn't allow expressions.
|
|
583
|
+
if (!propInfo.expressionForProperty)
|
|
584
|
+
continue;
|
|
585
|
+
if (expressionStartOverride) {
|
|
586
|
+
data[dataName] = Expression.Parse(data[dataName], source.SourceFile, Object.assign(Object.assign({}, propInfo.expressionForProperty[version]), { startType: expressionStartOverride }));
|
|
587
|
+
}
|
|
588
|
+
else {
|
|
589
|
+
data[dataName] = Expression.Parse(data[dataName], source.SourceFile, propInfo.expressionForProperty[version]);
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
else if (typeof data[dataName] === "object") {
|
|
593
|
+
data[dataName] = MapEveryPropValue(propInfo, data[dataName], (val) => {
|
|
594
|
+
if (Expression.isExpressionString(val)) {
|
|
595
|
+
//If no config then the property doesn't allow expressions.
|
|
596
|
+
if (!propInfo.expressionForValue)
|
|
597
|
+
return val;
|
|
598
|
+
return Expression.Parse(val, source.SourceFile, propInfo.expressionForValue[version]);
|
|
599
|
+
}
|
|
600
|
+
if (isPrimitiveValue(val) || !("Class" in val)) {
|
|
601
|
+
//Not an object that can have expressions.
|
|
602
|
+
return val;
|
|
603
|
+
}
|
|
604
|
+
let specificType = ReplicableRegistry.GetTypeForDataName(val.Class);
|
|
605
|
+
if (!specificType || isPrimitiveType(specificType)) {
|
|
606
|
+
return val;
|
|
607
|
+
}
|
|
608
|
+
for (let group of propInfo.load.types) {
|
|
609
|
+
if (typeof group.types === "string") {
|
|
610
|
+
continue;
|
|
611
|
+
}
|
|
612
|
+
for (let type of group.types) {
|
|
613
|
+
if (type instanceof ReplicableClass && type.isChildTypeOfThisType(specificType)) {
|
|
614
|
+
return PrePrepareData(type, val, source, expressionStartOverride);
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
return val;
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
return data;
|
|
623
|
+
}
|
|
624
|
+
Definitions.PrePrepareData = PrePrepareData;
|
|
625
|
+
})(Definitions || (Definitions = {}));
|
|
626
|
+
__ReplTypeHelperFunctions.SetIsLoadableDataForType(Definitions.IsLoadableDataForType);
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Primitive, PropertyTypes } from "../Constants/SerialisationTypes.js";
|
|
2
|
+
import { Expression } from "../Expressions/Expression.js";
|
|
3
|
+
import { ReplicableClass } from "../Tracking/Class.js";
|
|
4
|
+
import { SourceMap } from "../Constants/SourceMaps.js";
|
|
5
|
+
import { ErrorStack } from "../Constants/Errors.js";
|
|
6
|
+
import { PropertyConfiguration, PropertyLoadingTypeInfo } from "../Tracking/Property.js";
|
|
7
|
+
export declare namespace Loader {
|
|
8
|
+
interface ObjectData {
|
|
9
|
+
root: any;
|
|
10
|
+
source: SourceMap;
|
|
11
|
+
rootRepl: ReplicableClass;
|
|
12
|
+
}
|
|
13
|
+
interface PropertyData {
|
|
14
|
+
name: string;
|
|
15
|
+
dataName: string;
|
|
16
|
+
conf: PropertyConfiguration;
|
|
17
|
+
}
|
|
18
|
+
function LoadSingleValueAsType(propErrors: ErrorStack, obj: ObjectData, prop: PropertyData, propInfo: PropertyLoadingTypeInfo, propType: ReplicableClass | Primitive, val: any): any;
|
|
19
|
+
function PerValueCallback(value: any, idxName: any, triggeredMod: PropertyTypes, propErrors: ErrorStack, obj: ObjectData, prop: PropertyData): [val: any, idx: any];
|
|
20
|
+
/**
|
|
21
|
+
* ASSUMES INPUTS ARE CORRECT - DOES NOT CHECK FOR ERRORS.
|
|
22
|
+
* Get all of the assigned property values, so that they can individually be checked against the type requirements
|
|
23
|
+
* of the definiton. Turns single values, double arrays, maps and dicts all into a single flat array of values.
|
|
24
|
+
* @param def The property definition to get the values for.
|
|
25
|
+
* @param val The value to get the values from.
|
|
26
|
+
*/
|
|
27
|
+
function LoadPropValuesFromData(val: any, propErrors: ErrorStack, obj: ObjectData, prop: PropertyData): any;
|
|
28
|
+
/**
|
|
29
|
+
*
|
|
30
|
+
* @param type The type that the property is defined for.
|
|
31
|
+
* @param source The location that the property's definition was defined at.
|
|
32
|
+
* @param name The name of the property that will be instantiated, used for looking up property info.
|
|
33
|
+
* @param val The data value that will be used to instantiate the property
|
|
34
|
+
* @param target The 'this' object that will house the property
|
|
35
|
+
*/
|
|
36
|
+
function CalcPropInitialValue(obj: ObjectData, name: string, val: any, target: any): any;
|
|
37
|
+
function SetPropertyToExpression(target: any, property: string, expression: Expression): void;
|
|
38
|
+
function IsPropertyExpression(target: any, property: string): boolean;
|
|
39
|
+
function ClearPropertyExpression(target: any, property: string): void;
|
|
40
|
+
function GetExprText(target: any, property: string): any;
|
|
41
|
+
function InitFromData(type: ReplicableClass, source: SourceMap, target: any, data: any): any;
|
|
42
|
+
function MarkInitialised(object: any): void;
|
|
43
|
+
function HasObjectBeenInitialised(obj: any): any;
|
|
44
|
+
function GetExpression(obj: any, propName: string): Expression | undefined;
|
|
45
|
+
}
|