@opra/common 0.31.12 → 0.31.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/browser.js +86 -31
- package/cjs/document/data-type/complex-type-class.js +82 -33
- package/cjs/document/data-type/field-class.js +6 -3
- package/cjs/document/resource/crud-operation.js +4 -7
- package/cjs/helpers/responsive-map.js +6 -0
- package/esm/document/data-type/complex-type-class.js +82 -33
- package/esm/document/data-type/field-class.js +6 -3
- package/esm/document/resource/crud-operation.js +4 -7
- package/esm/helpers/responsive-map.js +6 -0
- package/package.json +1 -1
- package/types/document/data-type/complex-type-class.d.ts +4 -2
- package/types/document/data-type/data-type.d.ts +8 -3
- package/types/document/data-type/field-class.d.ts +1 -0
- package/types/document/resource/crud-operation.d.ts +2 -3
- package/types/helpers/responsive-map.d.ts +1 -0
- package/types/schema/data-type/field.interface.d.ts +10 -6
package/browser.js
CHANGED
|
@@ -350,6 +350,12 @@ var ResponsiveMap = class extends Map {
|
|
|
350
350
|
};
|
|
351
351
|
return new Proxy({}, finalHandler);
|
|
352
352
|
}
|
|
353
|
+
toObject() {
|
|
354
|
+
return Object.keys(this.keys()).reduce((trg, k) => {
|
|
355
|
+
trg[k] = this.get(k);
|
|
356
|
+
return trg;
|
|
357
|
+
}, {});
|
|
358
|
+
}
|
|
353
359
|
[(_a = kKeyMap, _b = kKeyOrder, _c = kWellKnownKeys, _d = kOptions, Symbol.iterator)]() {
|
|
354
360
|
return this.entries();
|
|
355
361
|
}
|
|
@@ -2148,9 +2154,10 @@ var FieldClass = class {
|
|
|
2148
2154
|
this.deprecated = init.deprecated;
|
|
2149
2155
|
this.examples = init.examples;
|
|
2150
2156
|
this.format = init.format;
|
|
2157
|
+
this.partialUpdate = init.partialUpdate;
|
|
2151
2158
|
}
|
|
2152
2159
|
exportSchema(options) {
|
|
2153
|
-
const isAnonymous = !this.type
|
|
2160
|
+
const isAnonymous = !this.type?.name || this.type?.kind === "ComplexType" && this.type.isAnonymous;
|
|
2154
2161
|
return omitUndefined({
|
|
2155
2162
|
type: this.type ? isAnonymous ? this.type.exportSchema(options) : this.type.name : void 0,
|
|
2156
2163
|
description: this.description,
|
|
@@ -2164,7 +2171,8 @@ var FieldClass = class {
|
|
|
2164
2171
|
translatable: this.translatable,
|
|
2165
2172
|
deprecated: this.deprecated,
|
|
2166
2173
|
examples: this.examples,
|
|
2167
|
-
format: this.format
|
|
2174
|
+
format: this.format,
|
|
2175
|
+
partialUpdate: this.partialUpdate
|
|
2168
2176
|
});
|
|
2169
2177
|
}
|
|
2170
2178
|
generateCodec(codec, options) {
|
|
@@ -2175,7 +2183,8 @@ var FieldClass = class {
|
|
|
2175
2183
|
let fn = this.type.generateCodec(codec, { ...options, designType: this.designType });
|
|
2176
2184
|
if (this.isArray)
|
|
2177
2185
|
fn = vg3.isArray(fn);
|
|
2178
|
-
|
|
2186
|
+
const partial = options?.partial && (this.partialUpdate || !this.isArray);
|
|
2187
|
+
return !partial && this.required ? vg3.required(fn) : vg3.optional(fn);
|
|
2179
2188
|
}
|
|
2180
2189
|
};
|
|
2181
2190
|
|
|
@@ -2362,8 +2371,12 @@ var ComplexTypeClass = class extends DataType {
|
|
|
2362
2371
|
return false;
|
|
2363
2372
|
}
|
|
2364
2373
|
generateCodec(codec, options) {
|
|
2365
|
-
const schema = this.
|
|
2366
|
-
const additionalFields = this.additionalFields instanceof DataType ? this.additionalFields.generateCodec(codec,
|
|
2374
|
+
const schema = this.generateCodecSchema(codec, options);
|
|
2375
|
+
const additionalFields = this.additionalFields instanceof DataType ? this.additionalFields.generateCodec(codec, {
|
|
2376
|
+
operation: options?.operation,
|
|
2377
|
+
caseSensitive: options?.caseSensitive,
|
|
2378
|
+
partial: options?.partial
|
|
2379
|
+
}) : this.additionalFields;
|
|
2367
2380
|
return vg4.isObject(schema, {
|
|
2368
2381
|
ctor: this.ctor,
|
|
2369
2382
|
additionalFields,
|
|
@@ -2371,34 +2384,78 @@ var ComplexTypeClass = class extends DataType {
|
|
|
2371
2384
|
caseInSensitive: !options?.caseSensitive
|
|
2372
2385
|
});
|
|
2373
2386
|
}
|
|
2387
|
+
generateCodecSchema(codec, options) {
|
|
2388
|
+
const opts = {
|
|
2389
|
+
...options,
|
|
2390
|
+
pick: (options?.pick || []).map((x) => x.toLowerCase()),
|
|
2391
|
+
omit: (options?.omit || []).map((x) => x.toLowerCase()),
|
|
2392
|
+
overwriteFields: options?.overwriteFields ? this._buildOverwriteFieldsTree(options.overwriteFields) : void 0
|
|
2393
|
+
};
|
|
2394
|
+
return this._generateCodecSchema(codec, opts);
|
|
2395
|
+
}
|
|
2374
2396
|
_generateCodecSchema(codec, options) {
|
|
2375
2397
|
const schema = {};
|
|
2376
|
-
const
|
|
2377
|
-
const
|
|
2378
|
-
const
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
const
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2398
|
+
const overwriteFields = options?.overwriteFields;
|
|
2399
|
+
const optionsPick = options?.pick || [];
|
|
2400
|
+
const optionsOmit = options?.omit || [];
|
|
2401
|
+
const fieldNames = [...this.fields.keys()];
|
|
2402
|
+
if (overwriteFields) {
|
|
2403
|
+
for (const k of Object.keys(overwriteFields)) {
|
|
2404
|
+
if (!this.fields.has(k))
|
|
2405
|
+
fieldNames.push(k);
|
|
2406
|
+
}
|
|
2407
|
+
}
|
|
2408
|
+
for (const fieldName of fieldNames) {
|
|
2409
|
+
const lowerName = fieldName.toLowerCase();
|
|
2410
|
+
const overwriteFieldInit = overwriteFields?.[fieldName];
|
|
2411
|
+
if (!overwriteFieldInit && (optionsOmit.find((x) => x === lowerName) || optionsPick.length && !optionsPick.find((x) => x === lowerName || x.startsWith(lowerName + "."))))
|
|
2385
2412
|
continue;
|
|
2413
|
+
const subOptions = {
|
|
2414
|
+
...options,
|
|
2415
|
+
pick: optionsPick.filter((x) => x.startsWith(lowerName + ".")).map((x) => x.substring(x.indexOf(".") + 1)),
|
|
2416
|
+
omit: optionsOmit.filter((x) => x.startsWith(lowerName + ".")).map((x) => x.substring(x.indexOf(".") + 1)),
|
|
2417
|
+
overwriteFields: overwriteFieldInit?.overrideFields
|
|
2418
|
+
};
|
|
2386
2419
|
let f;
|
|
2387
|
-
if (
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2420
|
+
if (overwriteFieldInit) {
|
|
2421
|
+
const field = this.fields.get(fieldName);
|
|
2422
|
+
const init = { ...field, ...overwriteFieldInit, name: fieldName };
|
|
2423
|
+
if (!(init.type instanceof DataType))
|
|
2424
|
+
init.type = this.document.getDataType(init.type || "any");
|
|
2425
|
+
f = new ApiField(this, init);
|
|
2392
2426
|
} else
|
|
2393
|
-
f =
|
|
2394
|
-
schema[f.name] = f.generateCodec(codec,
|
|
2395
|
-
...options,
|
|
2396
|
-
pick: overwriteField ? [] : pickOption.filter((x) => x.startsWith(nameLower + ".")).map((x) => x.substring(x.indexOf(".") + 1)),
|
|
2397
|
-
omit: overwriteField ? [] : omitOption.filter((x) => x.startsWith(nameLower + ".")).map((x) => x.substring(x.indexOf(".") + 1))
|
|
2398
|
-
});
|
|
2427
|
+
f = this.getField(fieldName);
|
|
2428
|
+
schema[f.name] = f.generateCodec(codec, subOptions);
|
|
2399
2429
|
}
|
|
2400
2430
|
return schema;
|
|
2401
2431
|
}
|
|
2432
|
+
_buildOverwriteFieldsTree(obj) {
|
|
2433
|
+
const tree = {};
|
|
2434
|
+
for (let k of Object.keys(obj)) {
|
|
2435
|
+
const v = obj[k];
|
|
2436
|
+
if (!k.includes(".")) {
|
|
2437
|
+
const field = this.fields.get(k);
|
|
2438
|
+
if (field)
|
|
2439
|
+
k = field.name;
|
|
2440
|
+
tree[k] = { ...tree[k], ...v };
|
|
2441
|
+
continue;
|
|
2442
|
+
}
|
|
2443
|
+
const keyPath = k.split(".");
|
|
2444
|
+
let subTree = tree;
|
|
2445
|
+
while (keyPath.length) {
|
|
2446
|
+
let j = keyPath.shift();
|
|
2447
|
+
const field = this.fields.get(j);
|
|
2448
|
+
if (field)
|
|
2449
|
+
j = field.name;
|
|
2450
|
+
const treeItem = subTree[j] = subTree[j] || {};
|
|
2451
|
+
if (keyPath.length) {
|
|
2452
|
+
subTree = treeItem.overrideFields = treeItem.overrideFields || {};
|
|
2453
|
+
} else
|
|
2454
|
+
Object.assign(treeItem, v);
|
|
2455
|
+
}
|
|
2456
|
+
}
|
|
2457
|
+
return tree;
|
|
2458
|
+
}
|
|
2402
2459
|
};
|
|
2403
2460
|
|
|
2404
2461
|
// ../../build/common/esm/document/data-type/complex-type.js
|
|
@@ -11121,22 +11178,20 @@ var CrudOperation = class extends Endpoint {
|
|
|
11121
11178
|
this.encodeReturning = vg7.isAny();
|
|
11122
11179
|
this.returnType = init.returnType instanceof DataType ? init.returnType : this.resource.document.getDataType(init.returnType || "any");
|
|
11123
11180
|
this.encodeReturning = this.returnType.generateCodec("encode", { operation: "read" });
|
|
11124
|
-
|
|
11125
|
-
|
|
11126
|
-
if (init.options?.outputOverwriteFields)
|
|
11127
|
-
this.outputOverwriteFields = new ResponsiveMap(init.options.outputOverwriteFields);
|
|
11181
|
+
this.inputOverwriteFields = init.options.inputOverwriteFields;
|
|
11182
|
+
this.outputOverwriteFields = init.options.outputOverwriteFields;
|
|
11128
11183
|
}
|
|
11129
11184
|
exportSchema(options) {
|
|
11130
11185
|
const schema = super.exportSchema(options);
|
|
11131
11186
|
if (this.inputOverwriteFields) {
|
|
11132
11187
|
const trg = schema.options.inputOverwriteFields = {};
|
|
11133
|
-
|
|
11188
|
+
Object.keys(this.inputOverwriteFields).forEach(([k, o]) => {
|
|
11134
11189
|
trg[k] = ApiField.prototype.exportSchema.call(o, options);
|
|
11135
11190
|
});
|
|
11136
11191
|
}
|
|
11137
11192
|
if (this.outputOverwriteFields) {
|
|
11138
11193
|
const trg = schema.options.outputOverwriteFields = {};
|
|
11139
|
-
|
|
11194
|
+
Object.keys(this.outputOverwriteFields).forEach(([k, o]) => {
|
|
11140
11195
|
trg[k] = ApiField.prototype.exportSchema.call(o, options);
|
|
11141
11196
|
});
|
|
11142
11197
|
}
|
|
@@ -163,9 +163,13 @@ class ComplexTypeClass extends data_type_js_1.DataType {
|
|
|
163
163
|
return false;
|
|
164
164
|
}
|
|
165
165
|
generateCodec(codec, options) {
|
|
166
|
-
const schema = this.
|
|
166
|
+
const schema = this.generateCodecSchema(codec, options);
|
|
167
167
|
const additionalFields = this.additionalFields instanceof data_type_js_1.DataType
|
|
168
|
-
? this.additionalFields.generateCodec(codec,
|
|
168
|
+
? this.additionalFields.generateCodec(codec, {
|
|
169
|
+
operation: options?.operation,
|
|
170
|
+
caseSensitive: options?.caseSensitive,
|
|
171
|
+
partial: options?.partial
|
|
172
|
+
})
|
|
169
173
|
: this.additionalFields;
|
|
170
174
|
return vg.isObject(schema, {
|
|
171
175
|
ctor: this.ctor,
|
|
@@ -174,45 +178,90 @@ class ComplexTypeClass extends data_type_js_1.DataType {
|
|
|
174
178
|
caseInSensitive: !options?.caseSensitive
|
|
175
179
|
});
|
|
176
180
|
}
|
|
181
|
+
generateCodecSchema(codec, options) {
|
|
182
|
+
const opts = {
|
|
183
|
+
...options,
|
|
184
|
+
pick: (options?.pick || []).map(x => x.toLowerCase()),
|
|
185
|
+
omit: (options?.omit || []).map(x => x.toLowerCase()),
|
|
186
|
+
overwriteFields: options?.overwriteFields ? this._buildOverwriteFieldsTree(options.overwriteFields) : undefined,
|
|
187
|
+
};
|
|
188
|
+
return this._generateCodecSchema(codec, opts);
|
|
189
|
+
}
|
|
177
190
|
_generateCodecSchema(codec, options) {
|
|
178
191
|
const schema = {};
|
|
179
|
-
const
|
|
180
|
-
const
|
|
181
|
-
const
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
192
|
+
const overwriteFields = options?.overwriteFields;
|
|
193
|
+
const optionsPick = options?.pick || [];
|
|
194
|
+
const optionsOmit = options?.omit || [];
|
|
195
|
+
const fieldNames = [...this.fields.keys()];
|
|
196
|
+
// Add field name from overwriteFields which doesn't exist in this.fields
|
|
197
|
+
if (overwriteFields) {
|
|
198
|
+
for (const k of Object.keys(overwriteFields)) {
|
|
199
|
+
if (!this.fields.has(k))
|
|
200
|
+
fieldNames.push(k);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
// Process fields
|
|
204
|
+
for (const fieldName of fieldNames) {
|
|
205
|
+
const lowerName = fieldName.toLowerCase();
|
|
206
|
+
const overwriteFieldInit = overwriteFields?.[fieldName];
|
|
207
|
+
// If field omitted or not in pick list we ignore it unless overwriteField defined
|
|
208
|
+
if (!overwriteFieldInit &&
|
|
209
|
+
(optionsOmit.find(x => x === lowerName) ||
|
|
210
|
+
(optionsPick.length && !optionsPick.find(x => x === lowerName || x.startsWith(lowerName + '.')))))
|
|
193
211
|
continue;
|
|
212
|
+
const subOptions = {
|
|
213
|
+
...options,
|
|
214
|
+
pick: optionsPick
|
|
215
|
+
.filter(x => x.startsWith(lowerName + '.'))
|
|
216
|
+
.map(x => x.substring(x.indexOf('.') + 1)),
|
|
217
|
+
omit: optionsOmit
|
|
218
|
+
.filter(x => x.startsWith(lowerName + '.'))
|
|
219
|
+
.map(x => x.substring(x.indexOf('.') + 1)),
|
|
220
|
+
overwriteFields: overwriteFieldInit?.overrideFields
|
|
221
|
+
};
|
|
194
222
|
let f;
|
|
195
|
-
if (
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
223
|
+
if (overwriteFieldInit) {
|
|
224
|
+
const field = this.fields.get(fieldName);
|
|
225
|
+
const init = { ...field, ...overwriteFieldInit, name: fieldName };
|
|
226
|
+
if (!(init.type instanceof data_type_js_1.DataType))
|
|
227
|
+
init.type = this.document.getDataType(init.type || 'any');
|
|
228
|
+
f = new field_js_1.ApiField(this, init);
|
|
200
229
|
}
|
|
201
230
|
else
|
|
202
|
-
f =
|
|
203
|
-
schema[f.name] = f.generateCodec(codec,
|
|
204
|
-
...options,
|
|
205
|
-
pick: overwriteField ? [] :
|
|
206
|
-
pickOption
|
|
207
|
-
.filter(x => x.startsWith(nameLower + '.'))
|
|
208
|
-
.map(x => x.substring(x.indexOf('.') + 1)),
|
|
209
|
-
omit: overwriteField ? [] :
|
|
210
|
-
omitOption
|
|
211
|
-
.filter(x => x.startsWith(nameLower + '.'))
|
|
212
|
-
.map(x => x.substring(x.indexOf('.') + 1)),
|
|
213
|
-
});
|
|
231
|
+
f = this.getField(fieldName);
|
|
232
|
+
schema[f.name] = f.generateCodec(codec, subOptions);
|
|
214
233
|
}
|
|
215
234
|
return schema;
|
|
216
235
|
}
|
|
236
|
+
_buildOverwriteFieldsTree(obj) {
|
|
237
|
+
const tree = {};
|
|
238
|
+
for (let k of Object.keys(obj)) {
|
|
239
|
+
const v = obj[k];
|
|
240
|
+
if (!k.includes('.')) {
|
|
241
|
+
// Fix field name
|
|
242
|
+
const field = this.fields.get(k);
|
|
243
|
+
if (field)
|
|
244
|
+
k = field.name;
|
|
245
|
+
tree[k] = { ...tree[k], ...v };
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
const keyPath = k.split('.');
|
|
249
|
+
let subTree = tree;
|
|
250
|
+
while (keyPath.length) {
|
|
251
|
+
let j = keyPath.shift();
|
|
252
|
+
// Fix field name
|
|
253
|
+
const field = this.fields.get(j);
|
|
254
|
+
if (field)
|
|
255
|
+
j = field.name;
|
|
256
|
+
const treeItem = subTree[j] = subTree[j] || {};
|
|
257
|
+
if (keyPath.length) {
|
|
258
|
+
subTree = treeItem.overrideFields = treeItem.overrideFields || {};
|
|
259
|
+
}
|
|
260
|
+
else
|
|
261
|
+
Object.assign(treeItem, v);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return tree;
|
|
265
|
+
}
|
|
217
266
|
}
|
|
218
267
|
exports.ComplexTypeClass = ComplexTypeClass;
|
|
@@ -23,10 +23,11 @@ class FieldClass {
|
|
|
23
23
|
this.deprecated = init.deprecated;
|
|
24
24
|
this.examples = init.examples;
|
|
25
25
|
this.format = init.format;
|
|
26
|
+
this.partialUpdate = init.partialUpdate;
|
|
26
27
|
}
|
|
27
28
|
exportSchema(options) {
|
|
28
|
-
const isAnonymous = !this.type
|
|
29
|
-
(this.type
|
|
29
|
+
const isAnonymous = !this.type?.name ||
|
|
30
|
+
(this.type?.kind === 'ComplexType' && this.type.isAnonymous);
|
|
30
31
|
return (0, index_js_1.omitUndefined)({
|
|
31
32
|
type: this.type
|
|
32
33
|
? (isAnonymous ? this.type.exportSchema(options) : this.type.name)
|
|
@@ -43,6 +44,7 @@ class FieldClass {
|
|
|
43
44
|
deprecated: this.deprecated,
|
|
44
45
|
examples: this.examples,
|
|
45
46
|
format: this.format,
|
|
47
|
+
partialUpdate: this.partialUpdate,
|
|
46
48
|
});
|
|
47
49
|
}
|
|
48
50
|
generateCodec(codec, options) {
|
|
@@ -53,7 +55,8 @@ class FieldClass {
|
|
|
53
55
|
let fn = this.type.generateCodec(codec, { ...options, designType: this.designType });
|
|
54
56
|
if (this.isArray)
|
|
55
57
|
fn = vg.isArray(fn);
|
|
56
|
-
|
|
58
|
+
const partial = options?.partial && (this.partialUpdate || !this.isArray);
|
|
59
|
+
return !partial && this.required ? vg.required(fn) : vg.optional(fn);
|
|
57
60
|
}
|
|
58
61
|
}
|
|
59
62
|
exports.FieldClass = FieldClass;
|
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.CrudOperation = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const vg = tslib_1.__importStar(require("valgen"));
|
|
6
|
-
const index_js_1 = require("../../helpers/index.js");
|
|
7
6
|
const data_type_js_1 = require("../data-type/data-type.js");
|
|
8
7
|
const field_js_1 = require("../data-type/field.js");
|
|
9
8
|
const endpoint_js_1 = require("./endpoint.js");
|
|
@@ -22,23 +21,21 @@ class CrudOperation extends endpoint_js_1.Endpoint {
|
|
|
22
21
|
this.returnType = init.returnType instanceof data_type_js_1.DataType
|
|
23
22
|
? init.returnType : this.resource.document.getDataType(init.returnType || 'any');
|
|
24
23
|
this.encodeReturning = this.returnType.generateCodec('encode', { operation: 'read' });
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (init.options?.outputOverwriteFields)
|
|
28
|
-
this.outputOverwriteFields = new index_js_1.ResponsiveMap(init.options.outputOverwriteFields);
|
|
24
|
+
this.inputOverwriteFields = init.options.inputOverwriteFields;
|
|
25
|
+
this.outputOverwriteFields = init.options.outputOverwriteFields;
|
|
29
26
|
}
|
|
30
27
|
exportSchema(options) {
|
|
31
28
|
const schema = super.exportSchema(options);
|
|
32
29
|
if (this.inputOverwriteFields) {
|
|
33
30
|
const trg = schema.options.inputOverwriteFields = {};
|
|
34
|
-
|
|
31
|
+
Object.keys(this.inputOverwriteFields)
|
|
35
32
|
.forEach(([k, o]) => {
|
|
36
33
|
trg[k] = field_js_1.ApiField.prototype.exportSchema.call(o, options);
|
|
37
34
|
});
|
|
38
35
|
}
|
|
39
36
|
if (this.outputOverwriteFields) {
|
|
40
37
|
const trg = schema.options.outputOverwriteFields = {};
|
|
41
|
-
|
|
38
|
+
Object.keys(this.outputOverwriteFields)
|
|
42
39
|
.forEach(([k, o]) => {
|
|
43
40
|
trg[k] = field_js_1.ApiField.prototype.exportSchema.call(o, options);
|
|
44
41
|
});
|
|
@@ -154,6 +154,12 @@ class ResponsiveMap extends Map {
|
|
|
154
154
|
};
|
|
155
155
|
return new Proxy({}, finalHandler);
|
|
156
156
|
}
|
|
157
|
+
toObject() {
|
|
158
|
+
return Object.keys(this.keys()).reduce((trg, k) => {
|
|
159
|
+
trg[k] = this.get(k);
|
|
160
|
+
return trg;
|
|
161
|
+
}, {});
|
|
162
|
+
}
|
|
157
163
|
[(_a = kKeyMap, _b = kKeyOrder, _c = kWellKnownKeys, _d = kOptions, Symbol.iterator)]() {
|
|
158
164
|
return this.entries();
|
|
159
165
|
}
|
|
@@ -159,9 +159,13 @@ export class ComplexTypeClass extends DataType {
|
|
|
159
159
|
return false;
|
|
160
160
|
}
|
|
161
161
|
generateCodec(codec, options) {
|
|
162
|
-
const schema = this.
|
|
162
|
+
const schema = this.generateCodecSchema(codec, options);
|
|
163
163
|
const additionalFields = this.additionalFields instanceof DataType
|
|
164
|
-
? this.additionalFields.generateCodec(codec,
|
|
164
|
+
? this.additionalFields.generateCodec(codec, {
|
|
165
|
+
operation: options?.operation,
|
|
166
|
+
caseSensitive: options?.caseSensitive,
|
|
167
|
+
partial: options?.partial
|
|
168
|
+
})
|
|
165
169
|
: this.additionalFields;
|
|
166
170
|
return vg.isObject(schema, {
|
|
167
171
|
ctor: this.ctor,
|
|
@@ -170,44 +174,89 @@ export class ComplexTypeClass extends DataType {
|
|
|
170
174
|
caseInSensitive: !options?.caseSensitive
|
|
171
175
|
});
|
|
172
176
|
}
|
|
177
|
+
generateCodecSchema(codec, options) {
|
|
178
|
+
const opts = {
|
|
179
|
+
...options,
|
|
180
|
+
pick: (options?.pick || []).map(x => x.toLowerCase()),
|
|
181
|
+
omit: (options?.omit || []).map(x => x.toLowerCase()),
|
|
182
|
+
overwriteFields: options?.overwriteFields ? this._buildOverwriteFieldsTree(options.overwriteFields) : undefined,
|
|
183
|
+
};
|
|
184
|
+
return this._generateCodecSchema(codec, opts);
|
|
185
|
+
}
|
|
173
186
|
_generateCodecSchema(codec, options) {
|
|
174
187
|
const schema = {};
|
|
175
|
-
const
|
|
176
|
-
const
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
const
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
188
|
+
const overwriteFields = options?.overwriteFields;
|
|
189
|
+
const optionsPick = options?.pick || [];
|
|
190
|
+
const optionsOmit = options?.omit || [];
|
|
191
|
+
const fieldNames = [...this.fields.keys()];
|
|
192
|
+
// Add field name from overwriteFields which doesn't exist in this.fields
|
|
193
|
+
if (overwriteFields) {
|
|
194
|
+
for (const k of Object.keys(overwriteFields)) {
|
|
195
|
+
if (!this.fields.has(k))
|
|
196
|
+
fieldNames.push(k);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
// Process fields
|
|
200
|
+
for (const fieldName of fieldNames) {
|
|
201
|
+
const lowerName = fieldName.toLowerCase();
|
|
202
|
+
const overwriteFieldInit = overwriteFields?.[fieldName];
|
|
203
|
+
// If field omitted or not in pick list we ignore it unless overwriteField defined
|
|
204
|
+
if (!overwriteFieldInit &&
|
|
205
|
+
(optionsOmit.find(x => x === lowerName) ||
|
|
206
|
+
(optionsPick.length && !optionsPick.find(x => x === lowerName || x.startsWith(lowerName + '.')))))
|
|
189
207
|
continue;
|
|
208
|
+
const subOptions = {
|
|
209
|
+
...options,
|
|
210
|
+
pick: optionsPick
|
|
211
|
+
.filter(x => x.startsWith(lowerName + '.'))
|
|
212
|
+
.map(x => x.substring(x.indexOf('.') + 1)),
|
|
213
|
+
omit: optionsOmit
|
|
214
|
+
.filter(x => x.startsWith(lowerName + '.'))
|
|
215
|
+
.map(x => x.substring(x.indexOf('.') + 1)),
|
|
216
|
+
overwriteFields: overwriteFieldInit?.overrideFields
|
|
217
|
+
};
|
|
190
218
|
let f;
|
|
191
|
-
if (
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
219
|
+
if (overwriteFieldInit) {
|
|
220
|
+
const field = this.fields.get(fieldName);
|
|
221
|
+
const init = { ...field, ...overwriteFieldInit, name: fieldName };
|
|
222
|
+
if (!(init.type instanceof DataType))
|
|
223
|
+
init.type = this.document.getDataType(init.type || 'any');
|
|
224
|
+
f = new ApiField(this, init);
|
|
196
225
|
}
|
|
197
226
|
else
|
|
198
|
-
f =
|
|
199
|
-
schema[f.name] = f.generateCodec(codec,
|
|
200
|
-
...options,
|
|
201
|
-
pick: overwriteField ? [] :
|
|
202
|
-
pickOption
|
|
203
|
-
.filter(x => x.startsWith(nameLower + '.'))
|
|
204
|
-
.map(x => x.substring(x.indexOf('.') + 1)),
|
|
205
|
-
omit: overwriteField ? [] :
|
|
206
|
-
omitOption
|
|
207
|
-
.filter(x => x.startsWith(nameLower + '.'))
|
|
208
|
-
.map(x => x.substring(x.indexOf('.') + 1)),
|
|
209
|
-
});
|
|
227
|
+
f = this.getField(fieldName);
|
|
228
|
+
schema[f.name] = f.generateCodec(codec, subOptions);
|
|
210
229
|
}
|
|
211
230
|
return schema;
|
|
212
231
|
}
|
|
232
|
+
_buildOverwriteFieldsTree(obj) {
|
|
233
|
+
const tree = {};
|
|
234
|
+
for (let k of Object.keys(obj)) {
|
|
235
|
+
const v = obj[k];
|
|
236
|
+
if (!k.includes('.')) {
|
|
237
|
+
// Fix field name
|
|
238
|
+
const field = this.fields.get(k);
|
|
239
|
+
if (field)
|
|
240
|
+
k = field.name;
|
|
241
|
+
tree[k] = { ...tree[k], ...v };
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
const keyPath = k.split('.');
|
|
245
|
+
let subTree = tree;
|
|
246
|
+
while (keyPath.length) {
|
|
247
|
+
let j = keyPath.shift();
|
|
248
|
+
// Fix field name
|
|
249
|
+
const field = this.fields.get(j);
|
|
250
|
+
if (field)
|
|
251
|
+
j = field.name;
|
|
252
|
+
const treeItem = subTree[j] = subTree[j] || {};
|
|
253
|
+
if (keyPath.length) {
|
|
254
|
+
subTree = treeItem.overrideFields = treeItem.overrideFields || {};
|
|
255
|
+
}
|
|
256
|
+
else
|
|
257
|
+
Object.assign(treeItem, v);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return tree;
|
|
261
|
+
}
|
|
213
262
|
}
|
|
@@ -19,10 +19,11 @@ export class FieldClass {
|
|
|
19
19
|
this.deprecated = init.deprecated;
|
|
20
20
|
this.examples = init.examples;
|
|
21
21
|
this.format = init.format;
|
|
22
|
+
this.partialUpdate = init.partialUpdate;
|
|
22
23
|
}
|
|
23
24
|
exportSchema(options) {
|
|
24
|
-
const isAnonymous = !this.type
|
|
25
|
-
(this.type
|
|
25
|
+
const isAnonymous = !this.type?.name ||
|
|
26
|
+
(this.type?.kind === 'ComplexType' && this.type.isAnonymous);
|
|
26
27
|
return omitUndefined({
|
|
27
28
|
type: this.type
|
|
28
29
|
? (isAnonymous ? this.type.exportSchema(options) : this.type.name)
|
|
@@ -39,6 +40,7 @@ export class FieldClass {
|
|
|
39
40
|
deprecated: this.deprecated,
|
|
40
41
|
examples: this.examples,
|
|
41
42
|
format: this.format,
|
|
43
|
+
partialUpdate: this.partialUpdate,
|
|
42
44
|
});
|
|
43
45
|
}
|
|
44
46
|
generateCodec(codec, options) {
|
|
@@ -49,6 +51,7 @@ export class FieldClass {
|
|
|
49
51
|
let fn = this.type.generateCodec(codec, { ...options, designType: this.designType });
|
|
50
52
|
if (this.isArray)
|
|
51
53
|
fn = vg.isArray(fn);
|
|
52
|
-
|
|
54
|
+
const partial = options?.partial && (this.partialUpdate || !this.isArray);
|
|
55
|
+
return !partial && this.required ? vg.required(fn) : vg.optional(fn);
|
|
53
56
|
}
|
|
54
57
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import * as vg from 'valgen';
|
|
2
|
-
import { ResponsiveMap } from '../../helpers/index.js';
|
|
3
2
|
import { DataType } from '../data-type/data-type.js';
|
|
4
3
|
import { ApiField } from '../data-type/field.js';
|
|
5
4
|
import { Endpoint } from './endpoint.js';
|
|
@@ -18,23 +17,21 @@ export class CrudOperation extends Endpoint {
|
|
|
18
17
|
this.returnType = init.returnType instanceof DataType
|
|
19
18
|
? init.returnType : this.resource.document.getDataType(init.returnType || 'any');
|
|
20
19
|
this.encodeReturning = this.returnType.generateCodec('encode', { operation: 'read' });
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
if (init.options?.outputOverwriteFields)
|
|
24
|
-
this.outputOverwriteFields = new ResponsiveMap(init.options.outputOverwriteFields);
|
|
20
|
+
this.inputOverwriteFields = init.options.inputOverwriteFields;
|
|
21
|
+
this.outputOverwriteFields = init.options.outputOverwriteFields;
|
|
25
22
|
}
|
|
26
23
|
exportSchema(options) {
|
|
27
24
|
const schema = super.exportSchema(options);
|
|
28
25
|
if (this.inputOverwriteFields) {
|
|
29
26
|
const trg = schema.options.inputOverwriteFields = {};
|
|
30
|
-
|
|
27
|
+
Object.keys(this.inputOverwriteFields)
|
|
31
28
|
.forEach(([k, o]) => {
|
|
32
29
|
trg[k] = ApiField.prototype.exportSchema.call(o, options);
|
|
33
30
|
});
|
|
34
31
|
}
|
|
35
32
|
if (this.outputOverwriteFields) {
|
|
36
33
|
const trg = schema.options.outputOverwriteFields = {};
|
|
37
|
-
|
|
34
|
+
Object.keys(this.outputOverwriteFields)
|
|
38
35
|
.forEach(([k, o]) => {
|
|
39
36
|
trg[k] = ApiField.prototype.exportSchema.call(o, options);
|
|
40
37
|
});
|
|
@@ -151,6 +151,12 @@ export class ResponsiveMap extends Map {
|
|
|
151
151
|
};
|
|
152
152
|
return new Proxy({}, finalHandler);
|
|
153
153
|
}
|
|
154
|
+
toObject() {
|
|
155
|
+
return Object.keys(this.keys()).reduce((trg, k) => {
|
|
156
|
+
trg[k] = this.get(k);
|
|
157
|
+
return trg;
|
|
158
|
+
}, {});
|
|
159
|
+
}
|
|
154
160
|
[(_a = kKeyMap, _b = kKeyOrder, _c = kWellKnownKeys, _d = kOptions, Symbol.iterator)]() {
|
|
155
161
|
return this.entries();
|
|
156
162
|
}
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Type } from 'ts-gems';
|
|
1
|
+
import { RequiredSome, Type } from 'ts-gems';
|
|
2
2
|
import * as vg from 'valgen';
|
|
3
3
|
import { ResponsiveMap } from '../../helpers/index.js';
|
|
4
4
|
import { OpraSchema } from '../../schema/index.js';
|
|
@@ -30,5 +30,7 @@ export declare class ComplexTypeClass extends DataType {
|
|
|
30
30
|
isTypeOf(t: Type | Function): boolean;
|
|
31
31
|
extendsFrom(t: string | Type | DataType): boolean;
|
|
32
32
|
generateCodec(codec: 'decode' | 'encode', options?: DataType.GenerateCodecOptions): vg.Validator;
|
|
33
|
-
|
|
33
|
+
generateCodecSchema(codec: 'decode' | 'encode', options?: DataType.GenerateCodecOptions): vg.ObjectSchema;
|
|
34
|
+
protected _generateCodecSchema(codec: 'decode' | 'encode', options?: RequiredSome<DataType.GenerateCodecOptions, 'pick' | 'omit'>): vg.ObjectSchema;
|
|
35
|
+
protected _buildOverwriteFieldsTree(obj: Record<string, DataType.OverrideFieldsConfig>): Record<string, DataType.OverrideFieldsConfig>;
|
|
34
36
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { RequiredSome, Type } from 'ts-gems';
|
|
1
|
+
import { RequiredSome, StrictOmit, Type } from 'ts-gems';
|
|
2
2
|
import * as vg from 'valgen';
|
|
3
|
-
import { ResponsiveMap } from '../../helpers/index.js';
|
|
4
3
|
import { OpraSchema } from '../../schema/index.js';
|
|
5
4
|
import type { ApiDocument } from '../api-document.js';
|
|
6
5
|
import { nodeInspectCustom } from '../utils/inspect.util.js';
|
|
@@ -39,13 +38,19 @@ export declare namespace DataType {
|
|
|
39
38
|
}
|
|
40
39
|
interface OwnProperties {
|
|
41
40
|
}
|
|
41
|
+
type GenerateCodecField = StrictOmit<ApiField.InitArguments, 'type' | 'name'> & {
|
|
42
|
+
type?: DataType | string;
|
|
43
|
+
};
|
|
44
|
+
type OverrideFieldsConfig = GenerateCodecField & {
|
|
45
|
+
overrideFields?: Record<string, OverrideFieldsConfig>;
|
|
46
|
+
};
|
|
42
47
|
interface GenerateCodecOptions {
|
|
43
48
|
caseSensitive?: boolean;
|
|
44
49
|
pick?: string[];
|
|
45
50
|
omit?: string[];
|
|
46
51
|
partial?: boolean;
|
|
47
52
|
operation?: 'read' | 'write';
|
|
48
|
-
overwriteFields?:
|
|
53
|
+
overwriteFields?: Record<string, OverrideFieldsConfig>;
|
|
49
54
|
designType?: Type;
|
|
50
55
|
}
|
|
51
56
|
}
|
|
@@ -22,6 +22,7 @@ export declare class FieldClass {
|
|
|
22
22
|
deprecated?: boolean | string;
|
|
23
23
|
examples?: any[] | Record<string, any>;
|
|
24
24
|
format?: string;
|
|
25
|
+
partialUpdate?: boolean;
|
|
25
26
|
constructor(owner: ComplexType, init: ApiField.InitArguments);
|
|
26
27
|
exportSchema(options?: {
|
|
27
28
|
webSafe?: boolean;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { StrictOmit } from 'ts-gems';
|
|
2
2
|
import * as vg from 'valgen';
|
|
3
|
-
import { ResponsiveMap } from '../../helpers/index.js';
|
|
4
3
|
import { OpraSchema } from '../../schema/index.js';
|
|
5
4
|
import { DataType } from '../data-type/data-type.js';
|
|
6
5
|
import { ApiField } from '../data-type/field.js';
|
|
@@ -18,8 +17,8 @@ export declare class CrudOperation extends Endpoint {
|
|
|
18
17
|
decodeInput: vg.Validator;
|
|
19
18
|
returnType: DataType;
|
|
20
19
|
encodeReturning: vg.Validator;
|
|
21
|
-
inputOverwriteFields?:
|
|
22
|
-
outputOverwriteFields?:
|
|
20
|
+
inputOverwriteFields?: Record<string, ApiField.InitArguments>;
|
|
21
|
+
outputOverwriteFields?: Record<string, ApiField.InitArguments>;
|
|
23
22
|
constructor(resource: Resource, name: string, init: CrudOperation.InitArguments);
|
|
24
23
|
exportSchema(options?: {
|
|
25
24
|
webSafe?: boolean;
|
|
@@ -27,6 +27,7 @@ export declare class ResponsiveMap<V> extends Map<string, V> {
|
|
|
27
27
|
delete(key: string): boolean;
|
|
28
28
|
sort(compareFn?: (a: string, b: string) => number): this;
|
|
29
29
|
getProxy(handler?: ProxyHandler<Record<string, V>>): Record<string, V>;
|
|
30
|
+
toObject(): Record<string, V>;
|
|
30
31
|
[Symbol.iterator](): IterableIterator<[string, V]>;
|
|
31
32
|
protected _getOriginalKey(key: string): string;
|
|
32
33
|
protected _getStoringKey(key: string): string;
|
|
@@ -10,7 +10,7 @@ export type Field = {
|
|
|
10
10
|
*/
|
|
11
11
|
description?: string;
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
13
|
+
* Indicates if the field value is an array
|
|
14
14
|
*/
|
|
15
15
|
isArray?: boolean;
|
|
16
16
|
/**
|
|
@@ -18,19 +18,19 @@ export type Field = {
|
|
|
18
18
|
*/
|
|
19
19
|
default?: any;
|
|
20
20
|
/**
|
|
21
|
-
*
|
|
21
|
+
* Indicates the fixed value of the field. The value of the field can not be any other value.
|
|
22
22
|
*/
|
|
23
23
|
fixed?: string | number | boolean;
|
|
24
24
|
/**
|
|
25
|
-
*
|
|
25
|
+
* Indicates if field value required in create operation
|
|
26
26
|
*/
|
|
27
27
|
required?: boolean;
|
|
28
28
|
/**
|
|
29
|
-
*
|
|
29
|
+
* Indicates if the field is readonly
|
|
30
30
|
*/
|
|
31
31
|
readonly?: boolean;
|
|
32
32
|
/**
|
|
33
|
-
*
|
|
33
|
+
* Indicates if the field is writeonly
|
|
34
34
|
*/
|
|
35
35
|
writeonly?: boolean;
|
|
36
36
|
/**
|
|
@@ -47,8 +47,12 @@ export type Field = {
|
|
|
47
47
|
*/
|
|
48
48
|
examples?: any[] | Record<string, any>;
|
|
49
49
|
/**
|
|
50
|
-
*
|
|
50
|
+
* Indicates if the field is deprecated and can be removed in the next
|
|
51
51
|
*/
|
|
52
52
|
deprecated?: boolean | string;
|
|
53
53
|
format?: string;
|
|
54
|
+
/**
|
|
55
|
+
* Indicates if partial update enabled for this field
|
|
56
|
+
*/
|
|
57
|
+
partialUpdate?: boolean;
|
|
54
58
|
};
|