@opra/common 0.31.11 → 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 +131 -42
- package/cjs/document/data-type/builtin/email.type.js +16 -0
- package/cjs/document/data-type/builtin/index.js +3 -1
- package/cjs/document/data-type/builtin/url.type.js +16 -0
- package/cjs/document/data-type/complex-type-class.js +82 -33
- package/cjs/document/data-type/field-class.js +8 -3
- package/cjs/document/factory/type-document-factory.js +2 -2
- package/cjs/document/resource/crud-operation.js +4 -7
- package/cjs/exception/opra-exception.js +3 -2
- package/cjs/helpers/responsive-map.js +6 -0
- package/esm/document/data-type/builtin/email.type.js +13 -0
- package/esm/document/data-type/builtin/index.js +3 -1
- package/esm/document/data-type/builtin/url.type.js +13 -0
- package/esm/document/data-type/complex-type-class.js +82 -33
- package/esm/document/data-type/field-class.js +8 -3
- package/esm/document/factory/type-document-factory.js +3 -3
- package/esm/document/resource/crud-operation.js +4 -7
- package/esm/exception/opra-exception.js +3 -2
- package/esm/helpers/responsive-map.js +6 -0
- package/package.json +3 -3
- package/types/document/data-type/builtin/email.type.d.ts +2 -0
- package/types/document/data-type/builtin/index.d.ts +3 -1
- package/types/document/data-type/builtin/url.type.d.ts +2 -0
- 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 +2 -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 +14 -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
|
}
|
|
@@ -509,7 +515,6 @@ var i18n = I18n.createInstance();
|
|
|
509
515
|
i18n.init().catch(() => void 0);
|
|
510
516
|
|
|
511
517
|
// ../../build/common/esm/exception/opra-exception.js
|
|
512
|
-
var inDevelopment = (process.env.NODE_ENV || "").startsWith("dev");
|
|
513
518
|
var OpraException = class extends Error {
|
|
514
519
|
static {
|
|
515
520
|
__name(this, "OpraException");
|
|
@@ -542,13 +547,14 @@ var OpraException = class extends Error {
|
|
|
542
547
|
return i18n.deep(this.message);
|
|
543
548
|
}
|
|
544
549
|
toJSON() {
|
|
550
|
+
const env = process.env.NODE_ENV;
|
|
545
551
|
return omitUndefined({
|
|
546
552
|
message: this.message,
|
|
547
553
|
severity: this.severity,
|
|
548
554
|
system: this.system,
|
|
549
555
|
code: this.code,
|
|
550
556
|
details: this.details,
|
|
551
|
-
stack:
|
|
557
|
+
stack: env === "dev" || env === "development" || env === "test" ? this.stack?.split("\n") : void 0
|
|
552
558
|
}, true);
|
|
553
559
|
}
|
|
554
560
|
init(issue) {
|
|
@@ -2144,12 +2150,14 @@ var FieldClass = class {
|
|
|
2144
2150
|
this.readonly = init.readonly;
|
|
2145
2151
|
this.writeonly = init.writeonly;
|
|
2146
2152
|
this.exclusive = init.exclusive;
|
|
2153
|
+
this.translatable = init.translatable;
|
|
2147
2154
|
this.deprecated = init.deprecated;
|
|
2148
2155
|
this.examples = init.examples;
|
|
2149
2156
|
this.format = init.format;
|
|
2157
|
+
this.partialUpdate = init.partialUpdate;
|
|
2150
2158
|
}
|
|
2151
2159
|
exportSchema(options) {
|
|
2152
|
-
const isAnonymous = !this.type
|
|
2160
|
+
const isAnonymous = !this.type?.name || this.type?.kind === "ComplexType" && this.type.isAnonymous;
|
|
2153
2161
|
return omitUndefined({
|
|
2154
2162
|
type: this.type ? isAnonymous ? this.type.exportSchema(options) : this.type.name : void 0,
|
|
2155
2163
|
description: this.description,
|
|
@@ -2160,9 +2168,11 @@ var FieldClass = class {
|
|
|
2160
2168
|
readonly: this.readonly,
|
|
2161
2169
|
writeonly: this.writeonly,
|
|
2162
2170
|
exclusive: this.exclusive,
|
|
2171
|
+
translatable: this.translatable,
|
|
2163
2172
|
deprecated: this.deprecated,
|
|
2164
2173
|
examples: this.examples,
|
|
2165
|
-
format: this.format
|
|
2174
|
+
format: this.format,
|
|
2175
|
+
partialUpdate: this.partialUpdate
|
|
2166
2176
|
});
|
|
2167
2177
|
}
|
|
2168
2178
|
generateCodec(codec, options) {
|
|
@@ -2173,7 +2183,8 @@ var FieldClass = class {
|
|
|
2173
2183
|
let fn = this.type.generateCodec(codec, { ...options, designType: this.designType });
|
|
2174
2184
|
if (this.isArray)
|
|
2175
2185
|
fn = vg3.isArray(fn);
|
|
2176
|
-
|
|
2186
|
+
const partial = options?.partial && (this.partialUpdate || !this.isArray);
|
|
2187
|
+
return !partial && this.required ? vg3.required(fn) : vg3.optional(fn);
|
|
2177
2188
|
}
|
|
2178
2189
|
};
|
|
2179
2190
|
|
|
@@ -2360,8 +2371,12 @@ var ComplexTypeClass = class extends DataType {
|
|
|
2360
2371
|
return false;
|
|
2361
2372
|
}
|
|
2362
2373
|
generateCodec(codec, options) {
|
|
2363
|
-
const schema = this.
|
|
2364
|
-
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;
|
|
2365
2380
|
return vg4.isObject(schema, {
|
|
2366
2381
|
ctor: this.ctor,
|
|
2367
2382
|
additionalFields,
|
|
@@ -2369,34 +2384,78 @@ var ComplexTypeClass = class extends DataType {
|
|
|
2369
2384
|
caseInSensitive: !options?.caseSensitive
|
|
2370
2385
|
});
|
|
2371
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
|
+
}
|
|
2372
2396
|
_generateCodecSchema(codec, options) {
|
|
2373
2397
|
const schema = {};
|
|
2374
|
-
const
|
|
2375
|
-
const
|
|
2376
|
-
const
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
const
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
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 + "."))))
|
|
2383
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
|
+
};
|
|
2384
2419
|
let f;
|
|
2385
|
-
if (
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
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);
|
|
2390
2426
|
} else
|
|
2391
|
-
f =
|
|
2392
|
-
schema[f.name] = f.generateCodec(codec,
|
|
2393
|
-
...options,
|
|
2394
|
-
pick: overwriteField ? [] : pickOption.filter((x) => x.startsWith(nameLower + ".")).map((x) => x.substring(x.indexOf(".") + 1)),
|
|
2395
|
-
omit: overwriteField ? [] : omitOption.filter((x) => x.startsWith(nameLower + ".")).map((x) => x.substring(x.indexOf(".") + 1))
|
|
2396
|
-
});
|
|
2427
|
+
f = this.getField(fieldName);
|
|
2428
|
+
schema[f.name] = f.generateCodec(codec, subOptions);
|
|
2397
2429
|
}
|
|
2398
2430
|
return schema;
|
|
2399
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
|
+
}
|
|
2400
2459
|
};
|
|
2401
2460
|
|
|
2402
2461
|
// ../../build/common/esm/document/data-type/complex-type.js
|
|
@@ -2943,20 +3002,20 @@ DatetimeType = __decorate([
|
|
|
2943
3002
|
})
|
|
2944
3003
|
], DatetimeType);
|
|
2945
3004
|
|
|
2946
|
-
// ../../build/common/esm/document/data-type/builtin/
|
|
2947
|
-
import {
|
|
2948
|
-
var
|
|
3005
|
+
// ../../build/common/esm/document/data-type/builtin/email.type.js
|
|
3006
|
+
import { isEmail } from "valgen";
|
|
3007
|
+
var EmailType = class EmailType2 {
|
|
2949
3008
|
static {
|
|
2950
|
-
__name(this, "
|
|
3009
|
+
__name(this, "EmailType");
|
|
2951
3010
|
}
|
|
2952
3011
|
};
|
|
2953
|
-
|
|
3012
|
+
EmailType = __decorate([
|
|
2954
3013
|
SimpleType2({
|
|
2955
|
-
description: "
|
|
2956
|
-
decoder:
|
|
2957
|
-
encoder:
|
|
3014
|
+
description: "An email value",
|
|
3015
|
+
decoder: isEmail(),
|
|
3016
|
+
encoder: isEmail()
|
|
2958
3017
|
})
|
|
2959
|
-
],
|
|
3018
|
+
], EmailType);
|
|
2960
3019
|
|
|
2961
3020
|
// ../../build/common/esm/document/data-type/builtin/integer.type.js
|
|
2962
3021
|
import { isInteger } from "valgen";
|
|
@@ -3070,6 +3129,36 @@ TimeType = __decorate([
|
|
|
3070
3129
|
})
|
|
3071
3130
|
], TimeType);
|
|
3072
3131
|
|
|
3132
|
+
// ../../build/common/esm/document/data-type/builtin/url.type.js
|
|
3133
|
+
import { isURL as isURL2 } from "valgen";
|
|
3134
|
+
var UrlType = class UrlType2 {
|
|
3135
|
+
static {
|
|
3136
|
+
__name(this, "UrlType");
|
|
3137
|
+
}
|
|
3138
|
+
};
|
|
3139
|
+
UrlType = __decorate([
|
|
3140
|
+
SimpleType2({
|
|
3141
|
+
description: "A Uniform Resource Identifier Reference (RFC 3986 icon) value",
|
|
3142
|
+
decoder: isURL2(),
|
|
3143
|
+
encoder: isURL2()
|
|
3144
|
+
})
|
|
3145
|
+
], UrlType);
|
|
3146
|
+
|
|
3147
|
+
// ../../build/common/esm/document/data-type/builtin/uuid.type.js
|
|
3148
|
+
import { isUUID } from "valgen";
|
|
3149
|
+
var UuidType = class UuidType2 {
|
|
3150
|
+
static {
|
|
3151
|
+
__name(this, "UuidType");
|
|
3152
|
+
}
|
|
3153
|
+
};
|
|
3154
|
+
UuidType = __decorate([
|
|
3155
|
+
SimpleType2({
|
|
3156
|
+
description: "A Universal Unique Identifier (UUID) value",
|
|
3157
|
+
decoder: isUUID(),
|
|
3158
|
+
encoder: isUUID()
|
|
3159
|
+
})
|
|
3160
|
+
], UuidType);
|
|
3161
|
+
|
|
3073
3162
|
// ../../build/common/esm/document/data-type/mapped-type.js
|
|
3074
3163
|
import "reflect-metadata";
|
|
3075
3164
|
import merge8 from "putil-merge";
|
|
@@ -3343,6 +3432,7 @@ var TypeDocumentFactory = class _TypeDocumentFactory {
|
|
|
3343
3432
|
BigintType,
|
|
3344
3433
|
BooleanType,
|
|
3345
3434
|
DateType,
|
|
3435
|
+
EmailType,
|
|
3346
3436
|
IntegerType,
|
|
3347
3437
|
NullType,
|
|
3348
3438
|
NumberType,
|
|
@@ -3353,6 +3443,7 @@ var TypeDocumentFactory = class _TypeDocumentFactory {
|
|
|
3353
3443
|
StringType,
|
|
3354
3444
|
DatetimeType,
|
|
3355
3445
|
TimeType,
|
|
3446
|
+
UrlType,
|
|
3356
3447
|
UuidType
|
|
3357
3448
|
]
|
|
3358
3449
|
};
|
|
@@ -11087,22 +11178,20 @@ var CrudOperation = class extends Endpoint {
|
|
|
11087
11178
|
this.encodeReturning = vg7.isAny();
|
|
11088
11179
|
this.returnType = init.returnType instanceof DataType ? init.returnType : this.resource.document.getDataType(init.returnType || "any");
|
|
11089
11180
|
this.encodeReturning = this.returnType.generateCodec("encode", { operation: "read" });
|
|
11090
|
-
|
|
11091
|
-
|
|
11092
|
-
if (init.options?.outputOverwriteFields)
|
|
11093
|
-
this.outputOverwriteFields = new ResponsiveMap(init.options.outputOverwriteFields);
|
|
11181
|
+
this.inputOverwriteFields = init.options.inputOverwriteFields;
|
|
11182
|
+
this.outputOverwriteFields = init.options.outputOverwriteFields;
|
|
11094
11183
|
}
|
|
11095
11184
|
exportSchema(options) {
|
|
11096
11185
|
const schema = super.exportSchema(options);
|
|
11097
11186
|
if (this.inputOverwriteFields) {
|
|
11098
11187
|
const trg = schema.options.inputOverwriteFields = {};
|
|
11099
|
-
|
|
11188
|
+
Object.keys(this.inputOverwriteFields).forEach(([k, o]) => {
|
|
11100
11189
|
trg[k] = ApiField.prototype.exportSchema.call(o, options);
|
|
11101
11190
|
});
|
|
11102
11191
|
}
|
|
11103
11192
|
if (this.outputOverwriteFields) {
|
|
11104
11193
|
const trg = schema.options.outputOverwriteFields = {};
|
|
11105
|
-
|
|
11194
|
+
Object.keys(this.outputOverwriteFields).forEach(([k, o]) => {
|
|
11106
11195
|
trg[k] = ApiField.prototype.exportSchema.call(o, options);
|
|
11107
11196
|
});
|
|
11108
11197
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EmailType = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const valgen_1 = require("valgen");
|
|
6
|
+
const simple_type_js_1 = require("../simple-type.js");
|
|
7
|
+
let EmailType = class EmailType {
|
|
8
|
+
};
|
|
9
|
+
exports.EmailType = EmailType;
|
|
10
|
+
exports.EmailType = EmailType = tslib_1.__decorate([
|
|
11
|
+
(0, simple_type_js_1.SimpleType)({
|
|
12
|
+
description: 'An email value',
|
|
13
|
+
decoder: (0, valgen_1.isEmail)(),
|
|
14
|
+
encoder: (0, valgen_1.isEmail)()
|
|
15
|
+
})
|
|
16
|
+
], EmailType);
|
|
@@ -9,7 +9,7 @@ tslib_1.__exportStar(require("./bigint.type.js"), exports);
|
|
|
9
9
|
tslib_1.__exportStar(require("./boolean.type.js"), exports);
|
|
10
10
|
tslib_1.__exportStar(require("./date.type.js"), exports);
|
|
11
11
|
tslib_1.__exportStar(require("./datetime.type.js"), exports);
|
|
12
|
-
tslib_1.__exportStar(require("./
|
|
12
|
+
tslib_1.__exportStar(require("./email.type.js"), exports);
|
|
13
13
|
tslib_1.__exportStar(require("./integer.type.js"), exports);
|
|
14
14
|
tslib_1.__exportStar(require("./null.type.js"), exports);
|
|
15
15
|
tslib_1.__exportStar(require("./number.type.js"), exports);
|
|
@@ -17,3 +17,5 @@ tslib_1.__exportStar(require("./object.type.js"), exports);
|
|
|
17
17
|
tslib_1.__exportStar(require("./object-id.type.js"), exports);
|
|
18
18
|
tslib_1.__exportStar(require("./string.type.js"), exports);
|
|
19
19
|
tslib_1.__exportStar(require("./time.type.js"), exports);
|
|
20
|
+
tslib_1.__exportStar(require("./url.type.js"), exports);
|
|
21
|
+
tslib_1.__exportStar(require("./uuid.type.js"), exports);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UrlType = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const valgen_1 = require("valgen");
|
|
6
|
+
const simple_type_js_1 = require("../simple-type.js");
|
|
7
|
+
let UrlType = class UrlType {
|
|
8
|
+
};
|
|
9
|
+
exports.UrlType = UrlType;
|
|
10
|
+
exports.UrlType = UrlType = tslib_1.__decorate([
|
|
11
|
+
(0, simple_type_js_1.SimpleType)({
|
|
12
|
+
description: 'A Uniform Resource Identifier Reference (RFC 3986 icon) value',
|
|
13
|
+
decoder: (0, valgen_1.isURL)(),
|
|
14
|
+
encoder: (0, valgen_1.isURL)()
|
|
15
|
+
})
|
|
16
|
+
], UrlType);
|
|
@@ -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;
|
|
@@ -19,13 +19,15 @@ class FieldClass {
|
|
|
19
19
|
this.readonly = init.readonly;
|
|
20
20
|
this.writeonly = init.writeonly;
|
|
21
21
|
this.exclusive = init.exclusive;
|
|
22
|
+
this.translatable = init.translatable;
|
|
22
23
|
this.deprecated = init.deprecated;
|
|
23
24
|
this.examples = init.examples;
|
|
24
25
|
this.format = init.format;
|
|
26
|
+
this.partialUpdate = init.partialUpdate;
|
|
25
27
|
}
|
|
26
28
|
exportSchema(options) {
|
|
27
|
-
const isAnonymous = !this.type
|
|
28
|
-
(this.type
|
|
29
|
+
const isAnonymous = !this.type?.name ||
|
|
30
|
+
(this.type?.kind === 'ComplexType' && this.type.isAnonymous);
|
|
29
31
|
return (0, index_js_1.omitUndefined)({
|
|
30
32
|
type: this.type
|
|
31
33
|
? (isAnonymous ? this.type.exportSchema(options) : this.type.name)
|
|
@@ -38,9 +40,11 @@ class FieldClass {
|
|
|
38
40
|
readonly: this.readonly,
|
|
39
41
|
writeonly: this.writeonly,
|
|
40
42
|
exclusive: this.exclusive,
|
|
43
|
+
translatable: this.translatable,
|
|
41
44
|
deprecated: this.deprecated,
|
|
42
45
|
examples: this.examples,
|
|
43
46
|
format: this.format,
|
|
47
|
+
partialUpdate: this.partialUpdate,
|
|
44
48
|
});
|
|
45
49
|
}
|
|
46
50
|
generateCodec(codec, options) {
|
|
@@ -51,7 +55,8 @@ class FieldClass {
|
|
|
51
55
|
let fn = this.type.generateCodec(codec, { ...options, designType: this.designType });
|
|
52
56
|
if (this.isArray)
|
|
53
57
|
fn = vg.isArray(fn);
|
|
54
|
-
|
|
58
|
+
const partial = options?.partial && (this.partialUpdate || !this.isArray);
|
|
59
|
+
return !partial && this.required ? vg.required(fn) : vg.optional(fn);
|
|
55
60
|
}
|
|
56
61
|
}
|
|
57
62
|
exports.FieldClass = FieldClass;
|
|
@@ -97,9 +97,9 @@ class TypeDocumentFactory {
|
|
|
97
97
|
}
|
|
98
98
|
},
|
|
99
99
|
types: [index_js_3.AnyType, index_js_3.Base64Type, index_js_3.BigintType, index_js_3.BooleanType,
|
|
100
|
-
index_js_3.DateType, index_js_3.IntegerType, index_js_3.NullType, index_js_3.NumberType, index_js_3.ObjectIdType,
|
|
100
|
+
index_js_3.DateType, index_js_3.EmailType, index_js_3.IntegerType, index_js_3.NullType, index_js_3.NumberType, index_js_3.ObjectIdType,
|
|
101
101
|
index_js_3.ObjectType, index_js_3.ApproxDateType, index_js_3.ApproxDatetimeType,
|
|
102
|
-
index_js_3.StringType, index_js_3.DatetimeType, index_js_3.TimeType, index_js_3.UuidType
|
|
102
|
+
index_js_3.StringType, index_js_3.DatetimeType, index_js_3.TimeType, index_js_3.UrlType, index_js_3.UuidType
|
|
103
103
|
]
|
|
104
104
|
};
|
|
105
105
|
const factory = new TypeDocumentFactory();
|
|
@@ -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
|
});
|
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.OpraException = void 0;
|
|
4
4
|
const index_js_1 = require("../helpers/index.js");
|
|
5
5
|
const index_js_2 = require("../i18n/index.js");
|
|
6
|
-
const inDevelopment = (process.env.NODE_ENV || '').startsWith('dev');
|
|
7
6
|
/**
|
|
8
7
|
* Defines the base Opra exception, which is handled by the default Exceptions Handler.
|
|
9
8
|
*/
|
|
@@ -37,13 +36,15 @@ class OpraException extends Error {
|
|
|
37
36
|
return index_js_2.i18n.deep(this.message);
|
|
38
37
|
}
|
|
39
38
|
toJSON() {
|
|
39
|
+
const env = process.env.NODE_ENV;
|
|
40
40
|
return (0, index_js_1.omitUndefined)({
|
|
41
41
|
message: this.message,
|
|
42
42
|
severity: this.severity,
|
|
43
43
|
system: this.system,
|
|
44
44
|
code: this.code,
|
|
45
45
|
details: this.details,
|
|
46
|
-
stack:
|
|
46
|
+
stack: env === 'dev' || env === 'development' || env === 'test'
|
|
47
|
+
? this.stack?.split('\n') : undefined
|
|
47
48
|
}, true);
|
|
48
49
|
}
|
|
49
50
|
init(issue) {
|
|
@@ -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
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { isEmail } from 'valgen';
|
|
3
|
+
import { SimpleType } from '../simple-type.js';
|
|
4
|
+
let EmailType = class EmailType {
|
|
5
|
+
};
|
|
6
|
+
EmailType = __decorate([
|
|
7
|
+
SimpleType({
|
|
8
|
+
description: 'An email value',
|
|
9
|
+
decoder: isEmail(),
|
|
10
|
+
encoder: isEmail()
|
|
11
|
+
})
|
|
12
|
+
], EmailType);
|
|
13
|
+
export { EmailType };
|
|
@@ -6,7 +6,7 @@ export * from './bigint.type.js';
|
|
|
6
6
|
export * from './boolean.type.js';
|
|
7
7
|
export * from './date.type.js';
|
|
8
8
|
export * from './datetime.type.js';
|
|
9
|
-
export * from './
|
|
9
|
+
export * from './email.type.js';
|
|
10
10
|
export * from './integer.type.js';
|
|
11
11
|
export * from './null.type.js';
|
|
12
12
|
export * from './number.type.js';
|
|
@@ -14,3 +14,5 @@ export * from './object.type.js';
|
|
|
14
14
|
export * from './object-id.type.js';
|
|
15
15
|
export * from './string.type.js';
|
|
16
16
|
export * from './time.type.js';
|
|
17
|
+
export * from './url.type.js';
|
|
18
|
+
export * from './uuid.type.js';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { isURL } from 'valgen';
|
|
3
|
+
import { SimpleType } from '../simple-type.js';
|
|
4
|
+
let UrlType = class UrlType {
|
|
5
|
+
};
|
|
6
|
+
UrlType = __decorate([
|
|
7
|
+
SimpleType({
|
|
8
|
+
description: 'A Uniform Resource Identifier Reference (RFC 3986 icon) value',
|
|
9
|
+
decoder: isURL(),
|
|
10
|
+
encoder: isURL()
|
|
11
|
+
})
|
|
12
|
+
], UrlType);
|
|
13
|
+
export { UrlType };
|
|
@@ -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
|
}
|
|
@@ -15,13 +15,15 @@ export class FieldClass {
|
|
|
15
15
|
this.readonly = init.readonly;
|
|
16
16
|
this.writeonly = init.writeonly;
|
|
17
17
|
this.exclusive = init.exclusive;
|
|
18
|
+
this.translatable = init.translatable;
|
|
18
19
|
this.deprecated = init.deprecated;
|
|
19
20
|
this.examples = init.examples;
|
|
20
21
|
this.format = init.format;
|
|
22
|
+
this.partialUpdate = init.partialUpdate;
|
|
21
23
|
}
|
|
22
24
|
exportSchema(options) {
|
|
23
|
-
const isAnonymous = !this.type
|
|
24
|
-
(this.type
|
|
25
|
+
const isAnonymous = !this.type?.name ||
|
|
26
|
+
(this.type?.kind === 'ComplexType' && this.type.isAnonymous);
|
|
25
27
|
return omitUndefined({
|
|
26
28
|
type: this.type
|
|
27
29
|
? (isAnonymous ? this.type.exportSchema(options) : this.type.name)
|
|
@@ -34,9 +36,11 @@ export class FieldClass {
|
|
|
34
36
|
readonly: this.readonly,
|
|
35
37
|
writeonly: this.writeonly,
|
|
36
38
|
exclusive: this.exclusive,
|
|
39
|
+
translatable: this.translatable,
|
|
37
40
|
deprecated: this.deprecated,
|
|
38
41
|
examples: this.examples,
|
|
39
42
|
format: this.format,
|
|
43
|
+
partialUpdate: this.partialUpdate,
|
|
40
44
|
});
|
|
41
45
|
}
|
|
42
46
|
generateCodec(codec, options) {
|
|
@@ -47,6 +51,7 @@ export class FieldClass {
|
|
|
47
51
|
let fn = this.type.generateCodec(codec, { ...options, designType: this.designType });
|
|
48
52
|
if (this.isArray)
|
|
49
53
|
fn = vg.isArray(fn);
|
|
50
|
-
|
|
54
|
+
const partial = options?.partial && (this.partialUpdate || !this.isArray);
|
|
55
|
+
return !partial && this.required ? vg.required(fn) : vg.optional(fn);
|
|
51
56
|
}
|
|
52
57
|
}
|
|
@@ -2,7 +2,7 @@ import { validator } from 'valgen';
|
|
|
2
2
|
import { cloneObject, isConstructor, resolveThunk, ResponsiveMap } from '../../helpers/index.js';
|
|
3
3
|
import { OpraSchema } from '../../schema/index.js';
|
|
4
4
|
import { DATATYPE_METADATA } from '../constants.js';
|
|
5
|
-
import { AnyType, ApproxDatetimeType, ApproxDateType, Base64Type, BigintType, BooleanType, DatetimeType, DateType, IntegerType, NullType, NumberType, ObjectIdType, ObjectType, StringType, TimeType, UuidType } from '../data-type/builtin/index.js';
|
|
5
|
+
import { AnyType, ApproxDatetimeType, ApproxDateType, Base64Type, BigintType, BooleanType, DatetimeType, DateType, EmailType, IntegerType, NullType, NumberType, ObjectIdType, ObjectType, StringType, TimeType, UrlType, UuidType } from '../data-type/builtin/index.js';
|
|
6
6
|
import { ComplexType } from '../data-type/complex-type.js';
|
|
7
7
|
import { EnumType } from '../data-type/enum-type.js';
|
|
8
8
|
import { MappedType } from '../data-type/mapped-type.js';
|
|
@@ -94,9 +94,9 @@ export class TypeDocumentFactory {
|
|
|
94
94
|
}
|
|
95
95
|
},
|
|
96
96
|
types: [AnyType, Base64Type, BigintType, BooleanType,
|
|
97
|
-
DateType, IntegerType, NullType, NumberType, ObjectIdType,
|
|
97
|
+
DateType, EmailType, IntegerType, NullType, NumberType, ObjectIdType,
|
|
98
98
|
ObjectType, ApproxDateType, ApproxDatetimeType,
|
|
99
|
-
StringType, DatetimeType, TimeType, UuidType
|
|
99
|
+
StringType, DatetimeType, TimeType, UrlType, UuidType
|
|
100
100
|
]
|
|
101
101
|
};
|
|
102
102
|
const factory = new TypeDocumentFactory();
|
|
@@ -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
|
});
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { omitUndefined } from '../helpers/index.js';
|
|
2
2
|
import { i18n } from '../i18n/index.js';
|
|
3
|
-
const inDevelopment = (process.env.NODE_ENV || '').startsWith('dev');
|
|
4
3
|
/**
|
|
5
4
|
* Defines the base Opra exception, which is handled by the default Exceptions Handler.
|
|
6
5
|
*/
|
|
@@ -34,13 +33,15 @@ export class OpraException extends Error {
|
|
|
34
33
|
return i18n.deep(this.message);
|
|
35
34
|
}
|
|
36
35
|
toJSON() {
|
|
36
|
+
const env = process.env.NODE_ENV;
|
|
37
37
|
return omitUndefined({
|
|
38
38
|
message: this.message,
|
|
39
39
|
severity: this.severity,
|
|
40
40
|
system: this.system,
|
|
41
41
|
code: this.code,
|
|
42
42
|
details: this.details,
|
|
43
|
-
stack:
|
|
43
|
+
stack: env === 'dev' || env === 'development' || env === 'test'
|
|
44
|
+
? this.stack?.split('\n') : undefined
|
|
44
45
|
}, true);
|
|
45
46
|
}
|
|
46
47
|
init(issue) {
|
|
@@ -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,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opra/common",
|
|
3
|
-
"version": "0.31.
|
|
3
|
+
"version": "0.31.13",
|
|
4
4
|
"description": "Opra common package",
|
|
5
5
|
"author": "Panates",
|
|
6
6
|
"license": "MIT",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"putil-varhelpers": "^1.6.5",
|
|
47
47
|
"reflect-metadata": "^0.1.13",
|
|
48
48
|
"uid": "^2.0.1",
|
|
49
|
-
"valgen": "^4.2.
|
|
49
|
+
"valgen": "^4.2.5"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@browsery/fs": "^0.4.0",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"@browsery/util": "^0.4.0",
|
|
55
55
|
"@types/encodeurl": "^1.0.2",
|
|
56
56
|
"@types/lodash.omit": "^4.5.9",
|
|
57
|
-
"@types/validator": "^13.11.
|
|
57
|
+
"@types/validator": "^13.11.7",
|
|
58
58
|
"path-browserify": "^1.0.1",
|
|
59
59
|
"ts-gems": "^2.5.0"
|
|
60
60
|
},
|
|
@@ -6,7 +6,7 @@ export * from './bigint.type.js';
|
|
|
6
6
|
export * from './boolean.type.js';
|
|
7
7
|
export * from './date.type.js';
|
|
8
8
|
export * from './datetime.type.js';
|
|
9
|
-
export * from './
|
|
9
|
+
export * from './email.type.js';
|
|
10
10
|
export * from './integer.type.js';
|
|
11
11
|
export * from './null.type.js';
|
|
12
12
|
export * from './number.type.js';
|
|
@@ -14,3 +14,5 @@ export * from './object.type.js';
|
|
|
14
14
|
export * from './object-id.type.js';
|
|
15
15
|
export * from './string.type.js';
|
|
16
16
|
export * from './time.type.js';
|
|
17
|
+
export * from './url.type.js';
|
|
18
|
+
export * from './uuid.type.js';
|
|
@@ -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
|
}
|
|
@@ -18,9 +18,11 @@ export declare class FieldClass {
|
|
|
18
18
|
readonly?: boolean;
|
|
19
19
|
writeonly?: boolean;
|
|
20
20
|
exclusive?: boolean;
|
|
21
|
+
translatable?: boolean;
|
|
21
22
|
deprecated?: boolean | string;
|
|
22
23
|
examples?: any[] | Record<string, any>;
|
|
23
24
|
format?: string;
|
|
25
|
+
partialUpdate?: boolean;
|
|
24
26
|
constructor(owner: ComplexType, init: ApiField.InitArguments);
|
|
25
27
|
exportSchema(options?: {
|
|
26
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
|
/**
|
|
@@ -38,13 +38,21 @@ export type Field = {
|
|
|
38
38
|
* The client side should include the Field name in the "include" query parameter.
|
|
39
39
|
*/
|
|
40
40
|
exclusive?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* If true, this Field is a candidate for translations
|
|
43
|
+
*/
|
|
44
|
+
translatable?: boolean;
|
|
41
45
|
/**
|
|
42
46
|
* Defines example values for the field
|
|
43
47
|
*/
|
|
44
48
|
examples?: any[] | Record<string, any>;
|
|
45
49
|
/**
|
|
46
|
-
*
|
|
50
|
+
* Indicates if the field is deprecated and can be removed in the next
|
|
47
51
|
*/
|
|
48
52
|
deprecated?: boolean | string;
|
|
49
53
|
format?: string;
|
|
54
|
+
/**
|
|
55
|
+
* Indicates if partial update enabled for this field
|
|
56
|
+
*/
|
|
57
|
+
partialUpdate?: boolean;
|
|
50
58
|
};
|