gingersnap 0.23.11 → 0.23.13
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/data/model/model.cjs +180 -138
- package/data/model/model.d.ts +64 -43
- package/data/model/model.mjs +180 -138
- package/data/model/property.cjs +32 -2
- package/data/model/property.d.ts +5 -1
- package/data/model/property.mjs +32 -3
- package/data/model.cjs +1 -0
- package/data/model.mjs +1 -1
- package/data/store/manager.cjs +3 -3
- package/data/store/manager.mjs +3 -3
- package/networking/EventSourceService.cjs +1 -1
- package/networking/EventSourceService.mjs +1 -1
- package/package.json +1 -1
package/data/model/model.mjs
CHANGED
|
@@ -52,14 +52,9 @@ class Optional {
|
|
|
52
52
|
* A Data de/serializer class that manages and validates data as JavaScript Objects
|
|
53
53
|
*/
|
|
54
54
|
class Model {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
* @param format data format
|
|
59
|
-
* @param options configurations for deserializing the data
|
|
60
|
-
* @returns new model or an array of models
|
|
61
|
-
*/
|
|
62
|
-
static fromBuffer(data, format = DataFormat.JSON, options) {
|
|
55
|
+
static fromBuffer(data, options) {
|
|
56
|
+
var _a;
|
|
57
|
+
const format = (_a = options === null || options === void 0 ? void 0 : options.format) !== null && _a !== void 0 ? _a : DataFormat.JSON;
|
|
63
58
|
switch (format) {
|
|
64
59
|
case DataFormat.MESSAGE_PACK: {
|
|
65
60
|
const decoder = decode;
|
|
@@ -68,27 +63,18 @@ class Model {
|
|
|
68
63
|
throw new ParsingError([], "expected an array of models");
|
|
69
64
|
if ((!(options === null || options === void 0 ? void 0 : options.array) && result instanceof Array) || Array.isArray(result))
|
|
70
65
|
throw new ParsingError([], "expected only one model");
|
|
71
|
-
|
|
72
|
-
return result.map((v) => this.fromJSON(v));
|
|
73
|
-
return this.fromJSON(result);
|
|
66
|
+
return this.fromJSON(result, { array: options === null || options === void 0 ? void 0 : options.array, maybeArray: options === null || options === void 0 ? void 0 : options.maybeArray });
|
|
74
67
|
}
|
|
75
68
|
case DataFormat.CSV: {
|
|
76
69
|
const text = data instanceof Uint8Array ? new TextDecoder().decode(data.buffer) : data.toString();
|
|
77
|
-
return this.fromString(text,
|
|
70
|
+
return this.fromString(text, options);
|
|
78
71
|
}
|
|
79
72
|
case DataFormat.XML:
|
|
80
73
|
case DataFormat.JSON:
|
|
81
|
-
return this.fromString(data instanceof Uint8Array ? new TextDecoder().decode(data) : data.toString(),
|
|
74
|
+
return this.fromString(data instanceof Uint8Array ? new TextDecoder().decode(data) : data.toString(), options);
|
|
82
75
|
}
|
|
83
76
|
}
|
|
84
|
-
|
|
85
|
-
* Downloads data from the given source and deserializes the data to one or more models
|
|
86
|
-
* @param source URL source to fetch the data
|
|
87
|
-
* @param format data format
|
|
88
|
-
* @param options configurations for deserializing and/or retrieving the data
|
|
89
|
-
* @returns one or more models
|
|
90
|
-
*/
|
|
91
|
-
static fromURL(source, format = DataFormat.JSON, options) {
|
|
77
|
+
static fromURL(source, options) {
|
|
92
78
|
return __awaiter(this, void 0, void 0, function* () {
|
|
93
79
|
const fetcher = fetch;
|
|
94
80
|
const resp = yield fetcher(source, {
|
|
@@ -98,48 +84,37 @@ class Model {
|
|
|
98
84
|
});
|
|
99
85
|
if (!resp.ok)
|
|
100
86
|
throw new NetworkError(resp.status);
|
|
101
|
-
return yield this.fromBlob(yield resp.blob(),
|
|
87
|
+
return yield this.fromBlob(yield resp.blob(), options);
|
|
102
88
|
});
|
|
103
89
|
}
|
|
104
|
-
|
|
105
|
-
* Deserializes one or more models from a Blob
|
|
106
|
-
* @param data blob data
|
|
107
|
-
* @param format data format
|
|
108
|
-
* @param options configurations for deserializing the data
|
|
109
|
-
* @returns one or more models
|
|
110
|
-
*/
|
|
111
|
-
static fromBlob(data, format = DataFormat.JSON, options) {
|
|
90
|
+
static fromBlob(data, options) {
|
|
112
91
|
return __awaiter(this, void 0, void 0, function* () {
|
|
113
|
-
return this.fromBuffer(new Uint8Array(yield data.arrayBuffer()),
|
|
92
|
+
return this.fromBuffer(new Uint8Array(yield data.arrayBuffer()), options);
|
|
114
93
|
});
|
|
115
94
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
* @remarks
|
|
120
|
-
* If the data format is a binary one, the provided string should be a hexadecimal string.
|
|
121
|
-
* @param data string data source
|
|
122
|
-
* @param format data format
|
|
123
|
-
* @param options
|
|
124
|
-
*/
|
|
125
|
-
static fromString(data, format = DataFormat.JSON, options) {
|
|
126
|
-
var _a, _b, _c, _d, _e, _f;
|
|
95
|
+
static fromString(data, options) {
|
|
96
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
97
|
+
const format = (_a = options === null || options === void 0 ? void 0 : options.format) !== null && _a !== void 0 ? _a : DataFormat.JSON;
|
|
127
98
|
switch (format) {
|
|
128
99
|
case DataFormat.JSON:
|
|
129
100
|
try {
|
|
130
101
|
data = JSON.parse(data);
|
|
131
102
|
}
|
|
132
103
|
catch (e) {
|
|
133
|
-
throw new ParsingError((
|
|
104
|
+
throw new ParsingError((_b = e === null || e === void 0 ? void 0 : e.message) !== null && _b !== void 0 ? _b : String(e));
|
|
134
105
|
}
|
|
135
|
-
return this.fromJSON(data);
|
|
106
|
+
return this.fromJSON(data, { maybeArray: options === null || options === void 0 ? void 0 : options.maybeArray, array: options === null || options === void 0 ? void 0 : options.array });
|
|
136
107
|
case DataFormat.XML:
|
|
137
|
-
return this.fromObject(this.__xmlParser__.xml2js(data),
|
|
108
|
+
return this.fromObject(this.__xmlParser__.xml2js(data), {
|
|
109
|
+
format,
|
|
110
|
+
maybeArray: options === null || options === void 0 ? void 0 : options.maybeArray,
|
|
111
|
+
array: options === null || options === void 0 ? void 0 : options.array,
|
|
112
|
+
});
|
|
138
113
|
case DataFormat.CSV: {
|
|
139
114
|
let result;
|
|
140
115
|
let text = data;
|
|
141
116
|
if (options === null || options === void 0 ? void 0 : options.headers)
|
|
142
|
-
text = options.headers.join((
|
|
117
|
+
text = options.headers.join((_c = options === null || options === void 0 ? void 0 : options.delimiter) !== null && _c !== void 0 ? _c : ",") + ((_d = options.newline) !== null && _d !== void 0 ? _d : "\n") + text;
|
|
143
118
|
try {
|
|
144
119
|
result = Papa.parse(text, {
|
|
145
120
|
header: true,
|
|
@@ -147,36 +122,34 @@ class Model {
|
|
|
147
122
|
});
|
|
148
123
|
}
|
|
149
124
|
catch (e) {
|
|
150
|
-
throw new ParsingError([], (
|
|
125
|
+
throw new ParsingError([], (_e = e === null || e === void 0 ? void 0 : e.message) !== null && _e !== void 0 ? _e : String(e));
|
|
151
126
|
}
|
|
152
127
|
if (!(options === null || options === void 0 ? void 0 : options.ignoreErrors) && result.errors.length > 0)
|
|
153
128
|
throw new ParsingError(result.errors);
|
|
154
129
|
if (!(options === null || options === void 0 ? void 0 : options.array) && result.data.length > 0)
|
|
155
130
|
throw new ParsingError([], "Too many records found");
|
|
156
|
-
if (options === null || options === void 0 ? void 0 : options.array)
|
|
157
|
-
return result.data
|
|
158
|
-
|
|
131
|
+
if ((options === null || options === void 0 ? void 0 : options.array) || (options === null || options === void 0 ? void 0 : options.maybeArray))
|
|
132
|
+
return this.fromObject(result.data, { array: true });
|
|
133
|
+
if (!(options === null || options === void 0 ? void 0 : options.maybeArray) || (options.maybeArray && result.data.length === 1))
|
|
134
|
+
return this.fromObject(result.data[0]);
|
|
135
|
+
break;
|
|
159
136
|
}
|
|
160
137
|
default:
|
|
161
|
-
return this.fromBuffer(new Uint8Array((
|
|
138
|
+
return this.fromBuffer(new Uint8Array((_g = (_f = data.match(/../g)) === null || _f === void 0 ? void 0 : _f.map((h) => parseInt(h, 16))) !== null && _g !== void 0 ? _g : []), options);
|
|
162
139
|
}
|
|
163
140
|
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
* @param data JSON Object
|
|
167
|
-
* @returns new model
|
|
168
|
-
*/
|
|
169
|
-
static fromJSON(data) {
|
|
170
|
-
return this.fromObject(data, DataFormat.JSON);
|
|
141
|
+
static fromJSON(data, options) {
|
|
142
|
+
return this.fromObject(data, options);
|
|
171
143
|
}
|
|
172
144
|
/**
|
|
173
145
|
* Converts the current model to a JSON object
|
|
174
146
|
*/
|
|
175
|
-
object(
|
|
147
|
+
object(options) {
|
|
176
148
|
var _a, _b;
|
|
149
|
+
const { removeMissingFields = false, keepOptionals = true } = options || {};
|
|
177
150
|
const serialize = (value) => {
|
|
178
151
|
if (value instanceof Model) {
|
|
179
|
-
return value.object(removeMissingFields);
|
|
152
|
+
return value.object({ removeMissingFields, keepOptionals });
|
|
180
153
|
}
|
|
181
154
|
else if (value instanceof Array || Array.isArray(value)) {
|
|
182
155
|
return value.map((v) => serialize(v));
|
|
@@ -196,6 +169,13 @@ class Model {
|
|
|
196
169
|
else if (value instanceof Function) {
|
|
197
170
|
return null;
|
|
198
171
|
}
|
|
172
|
+
else if (value instanceof Optional) {
|
|
173
|
+
if (keepOptionals)
|
|
174
|
+
return value;
|
|
175
|
+
if (value.isPresent())
|
|
176
|
+
return value.get();
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
199
179
|
return value;
|
|
200
180
|
};
|
|
201
181
|
return R.reduce((acc, [key, fieldProps]) => {
|
|
@@ -213,42 +193,42 @@ class Model {
|
|
|
213
193
|
/**
|
|
214
194
|
* Converts the current model to a JSON string
|
|
215
195
|
*/
|
|
216
|
-
json(
|
|
217
|
-
return JSON.stringify(this.object(
|
|
196
|
+
json(options) {
|
|
197
|
+
return JSON.stringify(this.object(options));
|
|
218
198
|
}
|
|
219
199
|
/**
|
|
220
200
|
* Converts the current model to an arraybuffer
|
|
221
201
|
*/
|
|
222
|
-
buffer(
|
|
223
|
-
return new TextEncoder().encode(this.json(
|
|
202
|
+
buffer(options) {
|
|
203
|
+
return new TextEncoder().encode(this.json(options));
|
|
224
204
|
}
|
|
225
205
|
/**
|
|
226
206
|
* Converts the current model to a blob
|
|
227
207
|
*/
|
|
228
|
-
blob(
|
|
229
|
-
return new Blob([this.buffer(
|
|
208
|
+
blob(options) {
|
|
209
|
+
return new Blob([this.buffer(options)]);
|
|
230
210
|
}
|
|
231
211
|
/**
|
|
232
212
|
* Converts the current model to an XML string
|
|
233
213
|
*/
|
|
234
|
-
xml(
|
|
235
|
-
return Model.__xmlParser__.js2xml(this.object(
|
|
214
|
+
xml(options) {
|
|
215
|
+
return Model.__xmlParser__.js2xml(this.object(options));
|
|
236
216
|
}
|
|
237
217
|
/**
|
|
238
218
|
* Converts the current model to message pack binary format
|
|
239
219
|
* @returns message pack binary
|
|
240
220
|
*/
|
|
241
|
-
messagePack(
|
|
242
|
-
return encode(this.object(
|
|
221
|
+
messagePack(options) {
|
|
222
|
+
return encode(this.object(options)).buffer;
|
|
243
223
|
}
|
|
244
224
|
/**
|
|
245
225
|
* Converts the current model to csv format
|
|
246
|
-
* @param
|
|
226
|
+
* @param options
|
|
247
227
|
* @param config CSV unparsing configuration
|
|
248
228
|
* @returns csv string
|
|
249
229
|
*/
|
|
250
|
-
csv(
|
|
251
|
-
return Papa.unparse([this.object(
|
|
230
|
+
csv(options, config) {
|
|
231
|
+
return Papa.unparse([this.object(options)], config);
|
|
252
232
|
}
|
|
253
233
|
clone() {
|
|
254
234
|
const newModel = new (Object.getPrototypeOf(this))();
|
|
@@ -259,10 +239,10 @@ class Model {
|
|
|
259
239
|
}
|
|
260
240
|
/**
|
|
261
241
|
* Retrieves the schema of the current model based on the selected format
|
|
262
|
-
* @param
|
|
242
|
+
* @param includeTitleAndDraft boolean whether the title and JSON schema draft version should be referenced in the schema
|
|
263
243
|
* @returns the schema for the current model
|
|
264
244
|
*/
|
|
265
|
-
static schema(
|
|
245
|
+
static schema(includeTitleAndDraft = true) {
|
|
266
246
|
const model = new this();
|
|
267
247
|
const props = this.buildPropTree(Object.getPrototypeOf(model));
|
|
268
248
|
const handleArrays = (v, entry) => {
|
|
@@ -354,24 +334,38 @@ class Model {
|
|
|
354
334
|
}
|
|
355
335
|
return entry;
|
|
356
336
|
}));
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
337
|
+
const fieldEntries = Array.from(props.fields.entries());
|
|
338
|
+
const optionals = Object.getOwnPropertyNames(this.prototype)
|
|
339
|
+
.filter((key) => key !== "constructor")
|
|
340
|
+
.map((key) => [key, model[key]])
|
|
341
|
+
.map(([key, modelValue]) => ({
|
|
342
|
+
modelValue,
|
|
343
|
+
fieldProps: fieldEntries.find(([k, v]) => { var _a; return k === key || ((_a = v.aliases) === null || _a === void 0 ? void 0 : _a.includes(key)); }),
|
|
344
|
+
}))
|
|
345
|
+
.filter(({ modelValue, fieldProps }) => { var _a, _b, _c; return modelValue !== undefined || ((_b = (_a = fieldProps[1].schema) === null || _a === void 0 ? void 0 : _a.options) === null || _b === void 0 ? void 0 : _b.optional) || ((_c = fieldProps[1].ignore) === null || _c === void 0 ? void 0 : _c.deserialize); })
|
|
346
|
+
.map(({ fieldProps }) => fieldProps[0]);
|
|
347
|
+
const required = fieldEntries.filter(([k]) => !optionals.includes(k)).map(([k]) => k);
|
|
348
|
+
const result = required.length
|
|
349
|
+
? {
|
|
361
350
|
type: "object",
|
|
362
351
|
properties: generateProperties(),
|
|
363
352
|
additionalProperties: false,
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
353
|
+
required,
|
|
354
|
+
}
|
|
355
|
+
: {
|
|
367
356
|
type: "object",
|
|
368
357
|
properties: generateProperties(),
|
|
369
358
|
additionalProperties: false,
|
|
370
359
|
};
|
|
360
|
+
if (includeTitleAndDraft) {
|
|
361
|
+
return Object.assign(Object.assign({}, result), { $schema: "https://json-schema.org/draft/2020-12/schema", title: this.name });
|
|
362
|
+
}
|
|
363
|
+
else {
|
|
364
|
+
return result;
|
|
371
365
|
}
|
|
372
366
|
}
|
|
373
367
|
toString() {
|
|
374
|
-
return this.json(true);
|
|
368
|
+
return this.json({ removeMissingFields: true, keepOptionals: false });
|
|
375
369
|
}
|
|
376
370
|
/**
|
|
377
371
|
* Constructs the model properties by traversing the inheritance tree of the current Model being instantiated
|
|
@@ -400,15 +394,17 @@ class Model {
|
|
|
400
394
|
}
|
|
401
395
|
return tree;
|
|
402
396
|
}
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
397
|
+
static fromObject(data, options) {
|
|
398
|
+
var _a;
|
|
399
|
+
const format = (_a = options === null || options === void 0 ? void 0 : options.format) !== null && _a !== void 0 ? _a : DataFormat.JSON;
|
|
400
|
+
if (Array.isArray(data)) {
|
|
401
|
+
if (!(options === null || options === void 0 ? void 0 : options.array) || !(options === null || options === void 0 ? void 0 : options.maybeArray))
|
|
402
|
+
throw new ParsingError([], "Invalid data provided. Must be an object");
|
|
403
|
+
else
|
|
404
|
+
return data.map((item) => this.fromObject(item, { format }));
|
|
405
|
+
}
|
|
406
|
+
else if (options === null || options === void 0 ? void 0 : options.array) {
|
|
407
|
+
throw new ParsingError([], "Invalid data provided. Must be an array of objects");
|
|
412
408
|
}
|
|
413
409
|
const processValue = (fieldProps, value) => {
|
|
414
410
|
var _a, _b;
|
|
@@ -420,7 +416,7 @@ class Model {
|
|
|
420
416
|
const model = new this();
|
|
421
417
|
const props = this.buildPropTree(Object.getPrototypeOf(model));
|
|
422
418
|
R.forEach(([key, fieldProps]) => {
|
|
423
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k
|
|
419
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
424
420
|
let value = data[key];
|
|
425
421
|
if (value === undefined || value === null) {
|
|
426
422
|
for (const alias of (_a = fieldProps.aliases) !== null && _a !== void 0 ? _a : []) {
|
|
@@ -441,12 +437,101 @@ class Model {
|
|
|
441
437
|
else if ((value === undefined || value === null) && !(model[key] === undefined || model[key] === null)) {
|
|
442
438
|
return;
|
|
443
439
|
}
|
|
440
|
+
const checkOtherTypes = (value, Type, fallback) => {
|
|
441
|
+
var _a, _b;
|
|
442
|
+
if ((Type === null || Type === void 0 ? void 0 : Type.name) === "String") {
|
|
443
|
+
return processValue(fieldProps, String(value));
|
|
444
|
+
}
|
|
445
|
+
else if ((Type === null || Type === void 0 ? void 0 : Type.name) === "Boolean") {
|
|
446
|
+
return processValue(fieldProps, Boolean(value));
|
|
447
|
+
}
|
|
448
|
+
else if ((Type === null || Type === void 0 ? void 0 : Type.name) === "Number") {
|
|
449
|
+
const v = Number(value);
|
|
450
|
+
if (isNaN(v))
|
|
451
|
+
throw new ParsingError([], `value for ${key} is not a valid number`);
|
|
452
|
+
return processValue(fieldProps, v);
|
|
453
|
+
}
|
|
454
|
+
else if ((Type === null || Type === void 0 ? void 0 : Type.name) === "Map") {
|
|
455
|
+
const valueType = typeof value;
|
|
456
|
+
switch (valueType) {
|
|
457
|
+
case "object": {
|
|
458
|
+
try {
|
|
459
|
+
return processValue(fieldProps, value instanceof Array || Array.isArray(value) ? new Map(value) : new Map(Object.entries(value)));
|
|
460
|
+
}
|
|
461
|
+
catch (e) {
|
|
462
|
+
throw new ParsingError([], (_a = e === null || e === void 0 ? void 0 : e.message) !== null && _a !== void 0 ? _a : String(e));
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
case "string":
|
|
466
|
+
try {
|
|
467
|
+
value = JSON.parse(value);
|
|
468
|
+
return processValue(fieldProps, value instanceof Array || Array.isArray(value) ? new Map(value) : new Map(Object.entries(value)));
|
|
469
|
+
}
|
|
470
|
+
catch (e) {
|
|
471
|
+
throw new ParsingError([], (_b = e === null || e === void 0 ? void 0 : e.message) !== null && _b !== void 0 ? _b : String(e));
|
|
472
|
+
}
|
|
473
|
+
default:
|
|
474
|
+
throw new ParsingError([value], `value for ${key} cannot be converted to a Map`);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
else if ((Type === null || Type === void 0 ? void 0 : Type.name) === "Set") {
|
|
478
|
+
if (value instanceof Array || Array.isArray(value)) {
|
|
479
|
+
return processValue(fieldProps, new Set(value));
|
|
480
|
+
}
|
|
481
|
+
else if (typeof value === "string") {
|
|
482
|
+
return processValue(fieldProps, new Set(JSON.parse(value)));
|
|
483
|
+
}
|
|
484
|
+
throw new ParsingError([value], `value for ${key} cannot be converted to a Set`);
|
|
485
|
+
}
|
|
486
|
+
else {
|
|
487
|
+
return fallback();
|
|
488
|
+
}
|
|
489
|
+
};
|
|
490
|
+
function processUnionField(value) {
|
|
491
|
+
let foundMatch = false;
|
|
492
|
+
let result;
|
|
493
|
+
for (const unionType of fieldProps.unionTypes) {
|
|
494
|
+
try {
|
|
495
|
+
result = checkOtherTypes(value, unionType, () => {
|
|
496
|
+
if (unionType.prototype instanceof Model) {
|
|
497
|
+
const parser = parse({
|
|
498
|
+
string: (v) => unionType.fromString(v, format),
|
|
499
|
+
object: (v) => unionType.fromObject(v, format),
|
|
500
|
+
default: () => {
|
|
501
|
+
throw new ParsingError([], `value for ${key} is expected to be an Array, instead received ${typeof value}`);
|
|
502
|
+
},
|
|
503
|
+
supportArray: true,
|
|
504
|
+
});
|
|
505
|
+
return processValue(fieldProps, parser(value));
|
|
506
|
+
}
|
|
507
|
+
throw new ParsingError([], `value for ${key} type is unsupported ${typeof value}`);
|
|
508
|
+
});
|
|
509
|
+
foundMatch = true;
|
|
510
|
+
break;
|
|
511
|
+
}
|
|
512
|
+
catch (e) { }
|
|
513
|
+
}
|
|
514
|
+
if (!foundMatch) {
|
|
515
|
+
throw new ParsingError([], `value for ${key} does not match any of the union types expected`);
|
|
516
|
+
}
|
|
517
|
+
return result;
|
|
518
|
+
}
|
|
444
519
|
if ((_e = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(model), key)) === null || _e === void 0 ? void 0 : _e.set) {
|
|
445
520
|
model[key] = processValue(fieldProps, value);
|
|
446
521
|
}
|
|
447
522
|
else if ((_f = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(model), key)) === null || _f === void 0 ? void 0 : _f.get) {
|
|
448
523
|
return;
|
|
449
524
|
}
|
|
525
|
+
else if (fieldProps.isUnion) {
|
|
526
|
+
if (!fieldProps.isArray) {
|
|
527
|
+
model[key] = processUnionField(value);
|
|
528
|
+
}
|
|
529
|
+
else if (fieldProps.isArray && Array.isArray(value)) {
|
|
530
|
+
model[key] = value.map((item) => processUnionField(item));
|
|
531
|
+
}
|
|
532
|
+
else
|
|
533
|
+
throw new ParsingError([], `value for ${key} is expected to be an array`);
|
|
534
|
+
}
|
|
450
535
|
else if (model[key] instanceof fieldProps.Type &&
|
|
451
536
|
typeof model[key] === "function" &&
|
|
452
537
|
fieldProps.Type instanceof Function) {
|
|
@@ -556,51 +641,8 @@ class Model {
|
|
|
556
641
|
}
|
|
557
642
|
}));
|
|
558
643
|
}
|
|
559
|
-
else if (((_k = fieldProps.Type) === null || _k === void 0 ? void 0 : _k.name) === "String") {
|
|
560
|
-
model[key] = processValue(fieldProps, String(value));
|
|
561
|
-
}
|
|
562
|
-
else if (((_l = fieldProps.Type) === null || _l === void 0 ? void 0 : _l.name) === "Boolean") {
|
|
563
|
-
model[key] = processValue(fieldProps, Boolean(value));
|
|
564
|
-
}
|
|
565
|
-
else if (((_m = fieldProps.Type) === null || _m === void 0 ? void 0 : _m.name) === "Number") {
|
|
566
|
-
model[key] = processValue(fieldProps, Number(value));
|
|
567
|
-
}
|
|
568
|
-
else if (((_o = fieldProps.Type) === null || _o === void 0 ? void 0 : _o.name) === "Map") {
|
|
569
|
-
const valueType = typeof value;
|
|
570
|
-
switch (valueType) {
|
|
571
|
-
case "object": {
|
|
572
|
-
try {
|
|
573
|
-
model[key] = processValue(fieldProps, value instanceof Array || Array.isArray(value) ? new Map(value) : new Map(Object.entries(value)));
|
|
574
|
-
}
|
|
575
|
-
catch (e) {
|
|
576
|
-
throw new ParsingError([], (_p = e === null || e === void 0 ? void 0 : e.message) !== null && _p !== void 0 ? _p : String(e));
|
|
577
|
-
}
|
|
578
|
-
break;
|
|
579
|
-
}
|
|
580
|
-
case "string":
|
|
581
|
-
try {
|
|
582
|
-
value = JSON.parse(value);
|
|
583
|
-
model[key] = processValue(fieldProps, value instanceof Array || Array.isArray(value) ? new Map(value) : new Map(Object.entries(value)));
|
|
584
|
-
}
|
|
585
|
-
catch (e) {
|
|
586
|
-
throw new ParsingError([], (_q = e === null || e === void 0 ? void 0 : e.message) !== null && _q !== void 0 ? _q : String(e));
|
|
587
|
-
}
|
|
588
|
-
break;
|
|
589
|
-
default:
|
|
590
|
-
throw new ParsingError([value], `value for ${key} cannot be converted to a Map`);
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
|
-
else if (((_r = fieldProps.Type) === null || _r === void 0 ? void 0 : _r.name) === "Set") {
|
|
594
|
-
if (value instanceof Array || Array.isArray(value)) {
|
|
595
|
-
model[key] = processValue(fieldProps, new Set(value));
|
|
596
|
-
}
|
|
597
|
-
else if (typeof value === "string") {
|
|
598
|
-
model[key] = processValue(fieldProps, new Set(JSON.parse(value)));
|
|
599
|
-
}
|
|
600
|
-
throw new ParsingError([value], `value for ${key} cannot be converted to a Set`);
|
|
601
|
-
}
|
|
602
644
|
else {
|
|
603
|
-
model[key] = processValue(fieldProps, new fieldProps.Type(value));
|
|
645
|
+
model[key] = checkOtherTypes(value, fieldProps.Type, () => processValue(fieldProps, new fieldProps.Type(value)));
|
|
604
646
|
}
|
|
605
647
|
if (fieldProps.readonly) {
|
|
606
648
|
Object.defineProperty(model, key, {
|
|
@@ -612,7 +654,7 @@ class Model {
|
|
|
612
654
|
R.forEach(([k, v]) => {
|
|
613
655
|
if (v.__callback__)
|
|
614
656
|
v.__callback__(k, v.properties, model, key);
|
|
615
|
-
}, R.toPairs((
|
|
657
|
+
}, R.toPairs((_k = fieldProps.customTags) !== null && _k !== void 0 ? _k : {}));
|
|
616
658
|
}, Array.from(props.fields.entries()));
|
|
617
659
|
return Object.seal(model);
|
|
618
660
|
}
|
package/data/model/property.cjs
CHANGED
|
@@ -129,6 +129,31 @@ const Field = (name, type = undefined) => (target, key) => {
|
|
|
129
129
|
props.parent = Object.getPrototypeOf(target).constructor.name;
|
|
130
130
|
model.namespacedModelInternalProps.set(target.constructor.name, props);
|
|
131
131
|
};
|
|
132
|
+
const UnionField = (types, name) => (target, key) => {
|
|
133
|
+
var _a, _b, _c;
|
|
134
|
+
const schema = {};
|
|
135
|
+
const props = (_a = model.namespacedModelInternalProps.get(target.constructor.name)) !== null && _a !== void 0 ? _a : {
|
|
136
|
+
fields: new Map(),
|
|
137
|
+
};
|
|
138
|
+
schema.description = (_b = name === null || name === void 0 ? void 0 : name.description) !== null && _b !== void 0 ? _b : "";
|
|
139
|
+
const fieldProp = (_c = props.fields.get(key)) !== null && _c !== void 0 ? _c : {};
|
|
140
|
+
fieldProp.name = typeof name === "string" ? name : typeof name === "object" ? name.name : key;
|
|
141
|
+
fieldProp.isUnion = true;
|
|
142
|
+
fieldProp.schema = schema;
|
|
143
|
+
fieldProp.unionTypes = types;
|
|
144
|
+
fieldProp.Type = {};
|
|
145
|
+
props.fields.set(key, fieldProp);
|
|
146
|
+
if (typeof name === "string" && name) {
|
|
147
|
+
if (fieldProp.aliases) {
|
|
148
|
+
fieldProp.aliases.push(name);
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
fieldProp.aliases = [name];
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
props.parent = Object.getPrototypeOf(target).constructor.name;
|
|
155
|
+
model.namespacedModelInternalProps.set(target.constructor.name, props);
|
|
156
|
+
};
|
|
132
157
|
/**
|
|
133
158
|
* A property that exists on the incoming data, that contains an array of same data types
|
|
134
159
|
* @param type Type of data in the array
|
|
@@ -144,8 +169,9 @@ const ArrayField = (type, name) => (target, key) => {
|
|
|
144
169
|
const schema = { dataType: types.DataType.ARRAY };
|
|
145
170
|
const dtype = Reflect.getMetadata("design:type", target, key);
|
|
146
171
|
const optional = dtype === model.Optional;
|
|
172
|
+
const fieldProp = (_b = props.fields.get(key)) !== null && _b !== void 0 ? _b : {};
|
|
147
173
|
schema.options = { useOptionalObj: optional, optional };
|
|
148
|
-
schema.description = (
|
|
174
|
+
schema.description = (_c = name === null || name === void 0 ? void 0 : name.description) !== null && _c !== void 0 ? _c : "";
|
|
149
175
|
if (type instanceof Number) {
|
|
150
176
|
schema.itemType = types.DataType.DOUBLE;
|
|
151
177
|
}
|
|
@@ -158,7 +184,10 @@ const ArrayField = (type, name) => (target, key) => {
|
|
|
158
184
|
else if (type instanceof model.Model) {
|
|
159
185
|
schema.options.recordClass = type;
|
|
160
186
|
}
|
|
161
|
-
|
|
187
|
+
else if (Array.isArray(type)) {
|
|
188
|
+
fieldProp.isUnion = true;
|
|
189
|
+
fieldProp.unionTypes = type;
|
|
190
|
+
}
|
|
162
191
|
fieldProp.name = key;
|
|
163
192
|
fieldProp.Type = type;
|
|
164
193
|
fieldProp.isArray = true;
|
|
@@ -310,5 +339,6 @@ exports.RaiseError = RaiseError;
|
|
|
310
339
|
exports.Range = Range;
|
|
311
340
|
exports.Readonly = Readonly;
|
|
312
341
|
exports.SchemaType = SchemaType;
|
|
342
|
+
exports.UnionField = UnionField;
|
|
313
343
|
exports.UpperBound = UpperBound;
|
|
314
344
|
exports.Validator = Validator;
|
package/data/model/property.d.ts
CHANGED
|
@@ -11,6 +11,10 @@ export declare const Field: (name?: string | {
|
|
|
11
11
|
name: string;
|
|
12
12
|
description: string;
|
|
13
13
|
}, type?: any) => (target: any, key: string) => void;
|
|
14
|
+
export declare const UnionField: (types: any[], name?: string | {
|
|
15
|
+
name: string;
|
|
16
|
+
description: string;
|
|
17
|
+
}) => (target: any, key: string) => void;
|
|
14
18
|
/**
|
|
15
19
|
* A property that exists on the incoming data, that contains an array of same data types
|
|
16
20
|
* @param type Type of data in the array
|
|
@@ -18,7 +22,7 @@ export declare const Field: (name?: string | {
|
|
|
18
22
|
* property name
|
|
19
23
|
* @constructor
|
|
20
24
|
*/
|
|
21
|
-
export declare const ArrayField: (type: any, name?: string | {
|
|
25
|
+
export declare const ArrayField: (type: any | any[], name?: string | {
|
|
22
26
|
name: string;
|
|
23
27
|
description: string;
|
|
24
28
|
}) => (target: any, key: string) => void;
|
package/data/model/property.mjs
CHANGED
|
@@ -108,6 +108,31 @@ const Field = (name, type = undefined) => (target, key) => {
|
|
|
108
108
|
props.parent = Object.getPrototypeOf(target).constructor.name;
|
|
109
109
|
namespacedModelInternalProps.set(target.constructor.name, props);
|
|
110
110
|
};
|
|
111
|
+
const UnionField = (types, name) => (target, key) => {
|
|
112
|
+
var _a, _b, _c;
|
|
113
|
+
const schema = {};
|
|
114
|
+
const props = (_a = namespacedModelInternalProps.get(target.constructor.name)) !== null && _a !== void 0 ? _a : {
|
|
115
|
+
fields: new Map(),
|
|
116
|
+
};
|
|
117
|
+
schema.description = (_b = name === null || name === void 0 ? void 0 : name.description) !== null && _b !== void 0 ? _b : "";
|
|
118
|
+
const fieldProp = (_c = props.fields.get(key)) !== null && _c !== void 0 ? _c : {};
|
|
119
|
+
fieldProp.name = typeof name === "string" ? name : typeof name === "object" ? name.name : key;
|
|
120
|
+
fieldProp.isUnion = true;
|
|
121
|
+
fieldProp.schema = schema;
|
|
122
|
+
fieldProp.unionTypes = types;
|
|
123
|
+
fieldProp.Type = {};
|
|
124
|
+
props.fields.set(key, fieldProp);
|
|
125
|
+
if (typeof name === "string" && name) {
|
|
126
|
+
if (fieldProp.aliases) {
|
|
127
|
+
fieldProp.aliases.push(name);
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
fieldProp.aliases = [name];
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
props.parent = Object.getPrototypeOf(target).constructor.name;
|
|
134
|
+
namespacedModelInternalProps.set(target.constructor.name, props);
|
|
135
|
+
};
|
|
111
136
|
/**
|
|
112
137
|
* A property that exists on the incoming data, that contains an array of same data types
|
|
113
138
|
* @param type Type of data in the array
|
|
@@ -123,8 +148,9 @@ const ArrayField = (type, name) => (target, key) => {
|
|
|
123
148
|
const schema = { dataType: DataType.ARRAY };
|
|
124
149
|
const dtype = Reflect.getMetadata("design:type", target, key);
|
|
125
150
|
const optional = dtype === Optional;
|
|
151
|
+
const fieldProp = (_b = props.fields.get(key)) !== null && _b !== void 0 ? _b : {};
|
|
126
152
|
schema.options = { useOptionalObj: optional, optional };
|
|
127
|
-
schema.description = (
|
|
153
|
+
schema.description = (_c = name === null || name === void 0 ? void 0 : name.description) !== null && _c !== void 0 ? _c : "";
|
|
128
154
|
if (type instanceof Number) {
|
|
129
155
|
schema.itemType = DataType.DOUBLE;
|
|
130
156
|
}
|
|
@@ -137,7 +163,10 @@ const ArrayField = (type, name) => (target, key) => {
|
|
|
137
163
|
else if (type instanceof Model) {
|
|
138
164
|
schema.options.recordClass = type;
|
|
139
165
|
}
|
|
140
|
-
|
|
166
|
+
else if (Array.isArray(type)) {
|
|
167
|
+
fieldProp.isUnion = true;
|
|
168
|
+
fieldProp.unionTypes = type;
|
|
169
|
+
}
|
|
141
170
|
fieldProp.name = key;
|
|
142
171
|
fieldProp.Type = type;
|
|
143
172
|
fieldProp.isArray = true;
|
|
@@ -279,4 +308,4 @@ const UpperBound = (value, inclusive = false) => createValidator(inclusive ? (v)
|
|
|
279
308
|
*/
|
|
280
309
|
const Range = (lower, upper, inclusive = false) => createValidator(inclusive ? (v) => lower <= v && v <= upper : (v) => lower <= v && v < upper, new InvalidValue(`value is not within the range of ${lower} <= v ` + (inclusive ? `<= ${upper}` : `< ${upper}`)));
|
|
281
310
|
|
|
282
|
-
export { Alias, ArrayField, Field, Ignore, LowerBound, MapField, RaiseError, Range, Readonly, SchemaType, UpperBound, Validator };
|
|
311
|
+
export { Alias, ArrayField, Field, Ignore, LowerBound, MapField, RaiseError, Range, Readonly, SchemaType, UnionField, UpperBound, Validator };
|
package/data/model.cjs
CHANGED
|
@@ -21,6 +21,7 @@ exports.RaiseError = property.RaiseError;
|
|
|
21
21
|
exports.Range = property.Range;
|
|
22
22
|
exports.Readonly = property.Readonly;
|
|
23
23
|
exports.SchemaType = property.SchemaType;
|
|
24
|
+
exports.UnionField = property.UnionField;
|
|
24
25
|
exports.UpperBound = property.UpperBound;
|
|
25
26
|
exports.Validator = property.Validator;
|
|
26
27
|
Object.defineProperty(exports, 'DataFormat', {
|
package/data/model.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { Model, Optional } from './model/model.mjs';
|
|
2
|
-
export { Alias, ArrayField, Field, Ignore, LowerBound, MapField, RaiseError, Range, Readonly, SchemaType, UpperBound, Validator } from './model/property.mjs';
|
|
2
|
+
export { Alias, ArrayField, Field, Ignore, LowerBound, MapField, RaiseError, Range, Readonly, SchemaType, UnionField, UpperBound, Validator } from './model/property.mjs';
|
|
3
3
|
export { DataFormat, DataType } from './model/types.mjs';
|
|
4
4
|
export { APIKeyCredentials, BasicCredentials, BearerCredentials, Credentials } from './model/credentials.mjs';
|
|
5
5
|
export { createModelClassAnnotationTag, createModelFieldAnnotationTag, getModelClassAnnotationTagProperties, getModelFieldAnnotationTagProperties } from './model/plugin.mjs';
|