@opra/common 1.17.4 → 1.17.5
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.
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ComplexTypeBase = exports.FIELD_PATH_PATTERN = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const hash_object_1 = tslib_1.__importDefault(require("hash-object"));
|
|
4
6
|
const ts_gems_1 = require("ts-gems");
|
|
5
7
|
const valgen_1 = require("valgen");
|
|
6
8
|
const index_js_1 = require("../../helpers/index.js");
|
|
@@ -199,14 +201,16 @@ class ComplexTypeBaseClass extends data_type_js_1.DataType {
|
|
|
199
201
|
*
|
|
200
202
|
*/
|
|
201
203
|
generateCodec(codec, options) {
|
|
202
|
-
const
|
|
203
|
-
?
|
|
204
|
-
:
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
204
|
+
const context = options?.cache
|
|
205
|
+
? options
|
|
206
|
+
: {
|
|
207
|
+
...options,
|
|
208
|
+
projection: Array.isArray(options?.projection)
|
|
209
|
+
? (0, index_js_1.parseFieldsProjection)(options.projection)
|
|
210
|
+
: options?.projection,
|
|
211
|
+
currentPath: '',
|
|
212
|
+
};
|
|
213
|
+
const schema = this._generateSchema(codec, context);
|
|
210
214
|
let additionalFields;
|
|
211
215
|
if (this.additionalFields instanceof data_type_js_1.DataType) {
|
|
212
216
|
additionalFields = this.additionalFields.generateCodec(codec, options);
|
|
@@ -218,10 +222,10 @@ class ComplexTypeBaseClass extends data_type_js_1.DataType {
|
|
|
218
222
|
additionalFields = 'error';
|
|
219
223
|
else {
|
|
220
224
|
const message = additionalFields[1];
|
|
221
|
-
additionalFields = (0, valgen_1.validator)((input,
|
|
225
|
+
additionalFields = (0, valgen_1.validator)((input, ctx, _this) => ctx.fail(_this, message, input));
|
|
222
226
|
}
|
|
223
227
|
}
|
|
224
|
-
|
|
228
|
+
const fn = valgen_1.vg.isObject(schema, {
|
|
225
229
|
ctor: this.name === 'object' ? Object : this.ctor,
|
|
226
230
|
additionalFields,
|
|
227
231
|
name: this.name,
|
|
@@ -229,8 +233,17 @@ class ComplexTypeBaseClass extends data_type_js_1.DataType {
|
|
|
229
233
|
caseInSensitive: options?.caseInSensitive,
|
|
230
234
|
onFail: options?.onFail,
|
|
231
235
|
});
|
|
236
|
+
if (context.level === 0 && context.forwardCallbacks?.size) {
|
|
237
|
+
for (const cb of context.forwardCallbacks) {
|
|
238
|
+
cb();
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return fn;
|
|
232
242
|
}
|
|
233
243
|
_generateSchema(codec, context) {
|
|
244
|
+
context.cache = context.cache || new Map();
|
|
245
|
+
context.level = context.level || 0;
|
|
246
|
+
context.forwardCallbacks = context.forwardCallbacks || new Set();
|
|
234
247
|
const schema = {};
|
|
235
248
|
const { currentPath, projection } = context;
|
|
236
249
|
const pickList = !!(projection && Object.values(projection).find(p => !p.sign));
|
|
@@ -263,14 +276,40 @@ class ComplexTypeBaseClass extends data_type_js_1.DataType {
|
|
|
263
276
|
continue;
|
|
264
277
|
}
|
|
265
278
|
}
|
|
266
|
-
const
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
279
|
+
const subProjection = typeof projection === 'object'
|
|
280
|
+
? projection[fieldName]?.projection || '*'
|
|
281
|
+
: projection;
|
|
282
|
+
let cacheItem = context.cache.get(field.type);
|
|
283
|
+
const cacheKey = typeof subProjection === 'string'
|
|
284
|
+
? subProjection
|
|
285
|
+
: (0, hash_object_1.default)(subProjection || {});
|
|
286
|
+
if (!cacheItem) {
|
|
287
|
+
cacheItem = {};
|
|
288
|
+
context.cache.set(field.type, cacheItem);
|
|
289
|
+
}
|
|
290
|
+
let fn = cacheItem[cacheKey];
|
|
291
|
+
/** If in progress (circular) */
|
|
292
|
+
if (fn === null) {
|
|
293
|
+
// Temporary set any
|
|
294
|
+
fn = valgen_1.vg.isAny();
|
|
295
|
+
context.forwardCallbacks.add(() => {
|
|
296
|
+
fn = cacheItem[cacheKey];
|
|
297
|
+
schema[fieldName] =
|
|
298
|
+
context.partial || !field.required
|
|
299
|
+
? valgen_1.vg.optional(fn)
|
|
300
|
+
: valgen_1.vg.required(fn);
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
else if (!fn) {
|
|
304
|
+
cacheItem[cacheKey] = null;
|
|
305
|
+
fn = this._generateFieldCodec(codec, field, {
|
|
306
|
+
...context,
|
|
307
|
+
partial: context.partial === 'deep' ? context.partial : undefined,
|
|
308
|
+
projection: subProjection,
|
|
309
|
+
currentPath: currentPath + (currentPath ? '.' : '') + fieldName,
|
|
310
|
+
});
|
|
311
|
+
cacheItem[cacheKey] = fn;
|
|
312
|
+
}
|
|
274
313
|
schema[fieldName] =
|
|
275
314
|
context.partial || !field.required ? valgen_1.vg.optional(fn) : valgen_1.vg.required(fn);
|
|
276
315
|
}
|
|
@@ -281,7 +320,10 @@ class ComplexTypeBaseClass extends data_type_js_1.DataType {
|
|
|
281
320
|
return schema;
|
|
282
321
|
}
|
|
283
322
|
_generateFieldCodec(codec, field, context) {
|
|
284
|
-
let fn = field.type.generateCodec(codec,
|
|
323
|
+
let fn = field.type.generateCodec(codec, {
|
|
324
|
+
...context,
|
|
325
|
+
level: context.level + 1,
|
|
326
|
+
});
|
|
285
327
|
if (field.fixed)
|
|
286
328
|
fn = valgen_1.vg.isEqual(field.fixed);
|
|
287
329
|
if (field.isArray)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import hashObject from 'hash-object';
|
|
1
2
|
import { asMutable } from 'ts-gems';
|
|
2
3
|
import { validator, vg } from 'valgen';
|
|
3
4
|
import { parseFieldsProjection, ResponsiveMap, } from '../../helpers/index.js';
|
|
@@ -196,14 +197,16 @@ class ComplexTypeBaseClass extends DataType {
|
|
|
196
197
|
*
|
|
197
198
|
*/
|
|
198
199
|
generateCodec(codec, options) {
|
|
199
|
-
const
|
|
200
|
-
?
|
|
201
|
-
:
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
200
|
+
const context = options?.cache
|
|
201
|
+
? options
|
|
202
|
+
: {
|
|
203
|
+
...options,
|
|
204
|
+
projection: Array.isArray(options?.projection)
|
|
205
|
+
? parseFieldsProjection(options.projection)
|
|
206
|
+
: options?.projection,
|
|
207
|
+
currentPath: '',
|
|
208
|
+
};
|
|
209
|
+
const schema = this._generateSchema(codec, context);
|
|
207
210
|
let additionalFields;
|
|
208
211
|
if (this.additionalFields instanceof DataType) {
|
|
209
212
|
additionalFields = this.additionalFields.generateCodec(codec, options);
|
|
@@ -215,10 +218,10 @@ class ComplexTypeBaseClass extends DataType {
|
|
|
215
218
|
additionalFields = 'error';
|
|
216
219
|
else {
|
|
217
220
|
const message = additionalFields[1];
|
|
218
|
-
additionalFields = validator((input,
|
|
221
|
+
additionalFields = validator((input, ctx, _this) => ctx.fail(_this, message, input));
|
|
219
222
|
}
|
|
220
223
|
}
|
|
221
|
-
|
|
224
|
+
const fn = vg.isObject(schema, {
|
|
222
225
|
ctor: this.name === 'object' ? Object : this.ctor,
|
|
223
226
|
additionalFields,
|
|
224
227
|
name: this.name,
|
|
@@ -226,8 +229,17 @@ class ComplexTypeBaseClass extends DataType {
|
|
|
226
229
|
caseInSensitive: options?.caseInSensitive,
|
|
227
230
|
onFail: options?.onFail,
|
|
228
231
|
});
|
|
232
|
+
if (context.level === 0 && context.forwardCallbacks?.size) {
|
|
233
|
+
for (const cb of context.forwardCallbacks) {
|
|
234
|
+
cb();
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return fn;
|
|
229
238
|
}
|
|
230
239
|
_generateSchema(codec, context) {
|
|
240
|
+
context.cache = context.cache || new Map();
|
|
241
|
+
context.level = context.level || 0;
|
|
242
|
+
context.forwardCallbacks = context.forwardCallbacks || new Set();
|
|
231
243
|
const schema = {};
|
|
232
244
|
const { currentPath, projection } = context;
|
|
233
245
|
const pickList = !!(projection && Object.values(projection).find(p => !p.sign));
|
|
@@ -260,14 +272,40 @@ class ComplexTypeBaseClass extends DataType {
|
|
|
260
272
|
continue;
|
|
261
273
|
}
|
|
262
274
|
}
|
|
263
|
-
const
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
275
|
+
const subProjection = typeof projection === 'object'
|
|
276
|
+
? projection[fieldName]?.projection || '*'
|
|
277
|
+
: projection;
|
|
278
|
+
let cacheItem = context.cache.get(field.type);
|
|
279
|
+
const cacheKey = typeof subProjection === 'string'
|
|
280
|
+
? subProjection
|
|
281
|
+
: hashObject(subProjection || {});
|
|
282
|
+
if (!cacheItem) {
|
|
283
|
+
cacheItem = {};
|
|
284
|
+
context.cache.set(field.type, cacheItem);
|
|
285
|
+
}
|
|
286
|
+
let fn = cacheItem[cacheKey];
|
|
287
|
+
/** If in progress (circular) */
|
|
288
|
+
if (fn === null) {
|
|
289
|
+
// Temporary set any
|
|
290
|
+
fn = vg.isAny();
|
|
291
|
+
context.forwardCallbacks.add(() => {
|
|
292
|
+
fn = cacheItem[cacheKey];
|
|
293
|
+
schema[fieldName] =
|
|
294
|
+
context.partial || !field.required
|
|
295
|
+
? vg.optional(fn)
|
|
296
|
+
: vg.required(fn);
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
else if (!fn) {
|
|
300
|
+
cacheItem[cacheKey] = null;
|
|
301
|
+
fn = this._generateFieldCodec(codec, field, {
|
|
302
|
+
...context,
|
|
303
|
+
partial: context.partial === 'deep' ? context.partial : undefined,
|
|
304
|
+
projection: subProjection,
|
|
305
|
+
currentPath: currentPath + (currentPath ? '.' : '') + fieldName,
|
|
306
|
+
});
|
|
307
|
+
cacheItem[cacheKey] = fn;
|
|
308
|
+
}
|
|
271
309
|
schema[fieldName] =
|
|
272
310
|
context.partial || !field.required ? vg.optional(fn) : vg.required(fn);
|
|
273
311
|
}
|
|
@@ -278,7 +316,10 @@ class ComplexTypeBaseClass extends DataType {
|
|
|
278
316
|
return schema;
|
|
279
317
|
}
|
|
280
318
|
_generateFieldCodec(codec, field, context) {
|
|
281
|
-
let fn = field.type.generateCodec(codec,
|
|
319
|
+
let fn = field.type.generateCodec(codec, {
|
|
320
|
+
...context,
|
|
321
|
+
level: context.level + 1,
|
|
322
|
+
});
|
|
282
323
|
if (field.fixed)
|
|
283
324
|
fn = vg.isEqual(field.fixed);
|
|
284
325
|
if (field.isArray)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opra/common",
|
|
3
|
-
"version": "1.17.
|
|
3
|
+
"version": "1.17.5",
|
|
4
4
|
"description": "Opra common package",
|
|
5
5
|
"author": "Panates",
|
|
6
6
|
"license": "MIT",
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"@browsery/type-is": "^1.6.18-r8",
|
|
13
13
|
"@jsopen/objects": "^1.6.2",
|
|
14
14
|
"fast-tokenizer": "^1.7.0",
|
|
15
|
+
"hash-object": "^5.0.1",
|
|
15
16
|
"putil-promisify": "^1.10.1",
|
|
16
17
|
"putil-varhelpers": "^1.6.5",
|
|
17
18
|
"reflect-metadata": "^0.2.2",
|
|
@@ -73,13 +73,14 @@ declare abstract class ComplexTypeBaseClass extends DataType {
|
|
|
73
73
|
*
|
|
74
74
|
*/
|
|
75
75
|
generateCodec(codec: 'encode' | 'decode', options?: DataType.GenerateCodecOptions): Validator;
|
|
76
|
-
protected _generateSchema(codec: 'encode' | 'decode', context:
|
|
77
|
-
|
|
78
|
-
projection?: FieldsProjection | '*';
|
|
79
|
-
}): IsObject.Schema;
|
|
80
|
-
protected _generateFieldCodec(codec: 'encode' | 'decode', field: ApiField, context: StrictOmit<DataType.GenerateCodecOptions, 'projection'> & {
|
|
81
|
-
currentPath: string;
|
|
82
|
-
projection?: FieldsProjection | '*';
|
|
83
|
-
}): Validator;
|
|
76
|
+
protected _generateSchema(codec: 'encode' | 'decode', context: GenerateCodecContext): IsObject.Schema;
|
|
77
|
+
protected _generateFieldCodec(codec: 'encode' | 'decode', field: ApiField, context: GenerateCodecContext): Validator;
|
|
84
78
|
}
|
|
79
|
+
type GenerateCodecContext = StrictOmit<DataType.GenerateCodecOptions, 'projection'> & {
|
|
80
|
+
currentPath: string;
|
|
81
|
+
projection?: FieldsProjection | '*';
|
|
82
|
+
level?: number;
|
|
83
|
+
cache?: Map<DataType, Record<string, Validator | null>>;
|
|
84
|
+
forwardCallbacks?: Set<Function>;
|
|
85
|
+
};
|
|
85
86
|
export {};
|