@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.
Files changed (29) hide show
  1. package/browser.js +131 -42
  2. package/cjs/document/data-type/builtin/email.type.js +16 -0
  3. package/cjs/document/data-type/builtin/index.js +3 -1
  4. package/cjs/document/data-type/builtin/url.type.js +16 -0
  5. package/cjs/document/data-type/complex-type-class.js +82 -33
  6. package/cjs/document/data-type/field-class.js +8 -3
  7. package/cjs/document/factory/type-document-factory.js +2 -2
  8. package/cjs/document/resource/crud-operation.js +4 -7
  9. package/cjs/exception/opra-exception.js +3 -2
  10. package/cjs/helpers/responsive-map.js +6 -0
  11. package/esm/document/data-type/builtin/email.type.js +13 -0
  12. package/esm/document/data-type/builtin/index.js +3 -1
  13. package/esm/document/data-type/builtin/url.type.js +13 -0
  14. package/esm/document/data-type/complex-type-class.js +82 -33
  15. package/esm/document/data-type/field-class.js +8 -3
  16. package/esm/document/factory/type-document-factory.js +3 -3
  17. package/esm/document/resource/crud-operation.js +4 -7
  18. package/esm/exception/opra-exception.js +3 -2
  19. package/esm/helpers/responsive-map.js +6 -0
  20. package/package.json +3 -3
  21. package/types/document/data-type/builtin/email.type.d.ts +2 -0
  22. package/types/document/data-type/builtin/index.d.ts +3 -1
  23. package/types/document/data-type/builtin/url.type.d.ts +2 -0
  24. package/types/document/data-type/complex-type-class.d.ts +4 -2
  25. package/types/document/data-type/data-type.d.ts +8 -3
  26. package/types/document/data-type/field-class.d.ts +2 -0
  27. package/types/document/resource/crud-operation.d.ts +2 -3
  28. package/types/helpers/responsive-map.d.ts +1 -0
  29. 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: inDevelopment ? this.stack?.split("\n") : void 0
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.name || this.type.kind === "ComplexType" && this.type.isAnonymous;
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
- return !options?.partial && this.required ? vg3.required(fn) : vg3.optional(fn);
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._generateCodecSchema(codec, options);
2364
- const additionalFields = this.additionalFields instanceof DataType ? this.additionalFields.generateCodec(codec, options) : this.additionalFields;
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 pickOption = (options?.pick || []).map((x) => x.toLowerCase());
2375
- const omitOption = (options?.omit || []).map((x) => x.toLowerCase());
2376
- const dedupedFieldNames = (options?.overwriteFields ? Array.from(/* @__PURE__ */ new Set([...this.fields.keys(), ...options?.overwriteFields.keys()])) : Array.from(this.fields.keys())).map((x) => x.toLowerCase());
2377
- for (const nameLower of dedupedFieldNames) {
2378
- const overwriteField = options?.overwriteFields?.get(nameLower);
2379
- const field = this.fields.get(nameLower);
2380
- if (!(field || overwriteField))
2381
- continue;
2382
- if (!overwriteField && (omitOption.find((x) => x === nameLower) || pickOption.length && !pickOption.find((x) => x === nameLower || x.startsWith(nameLower + "."))))
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 (overwriteField) {
2386
- f = { ...overwriteField };
2387
- if (!field)
2388
- f.type = this.document.getDataType("any");
2389
- Object.setPrototypeOf(f, field || ApiField.prototype);
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 = field;
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/uuid.type.js
2947
- import { isUUID } from "valgen";
2948
- var UuidType = class UuidType2 {
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, "UuidType");
3009
+ __name(this, "EmailType");
2951
3010
  }
2952
3011
  };
2953
- UuidType = __decorate([
3012
+ EmailType = __decorate([
2954
3013
  SimpleType2({
2955
- description: "A Universal Unique Identifier (UUID) value",
2956
- decoder: isUUID(),
2957
- encoder: isUUID()
3014
+ description: "An email value",
3015
+ decoder: isEmail(),
3016
+ encoder: isEmail()
2958
3017
  })
2959
- ], UuidType);
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
- if (init.options?.inputOverwriteFields)
11091
- this.inputOverwriteFields = new ResponsiveMap(init.options.inputOverwriteFields);
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
- Array.from(this.inputOverwriteFields.entries()).forEach(([k, o]) => {
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
- Array.from(this.outputOverwriteFields.entries()).forEach(([k, o]) => {
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("./uuid.type.js"), exports);
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._generateCodecSchema(codec, options);
166
+ const schema = this.generateCodecSchema(codec, options);
167
167
  const additionalFields = this.additionalFields instanceof data_type_js_1.DataType
168
- ? this.additionalFields.generateCodec(codec, options)
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 pickOption = (options?.pick || []).map(x => x.toLowerCase());
180
- const omitOption = (options?.omit || []).map(x => x.toLowerCase());
181
- const dedupedFieldNames = (options?.overwriteFields
182
- ? Array.from(new Set([...this.fields.keys(), ...options?.overwriteFields.keys()]))
183
- : Array.from(this.fields.keys())).map(x => x.toLowerCase());
184
- for (const nameLower of dedupedFieldNames) {
185
- const overwriteField = options?.overwriteFields?.get(nameLower);
186
- const field = this.fields.get(nameLower);
187
- /* istanbul ignore next */
188
- if (!(field || overwriteField))
189
- continue;
190
- if (!overwriteField &&
191
- (omitOption.find(x => x === nameLower) ||
192
- (pickOption.length && !pickOption.find(x => x === nameLower || x.startsWith(nameLower + '.')))))
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 (overwriteField) {
196
- f = { ...overwriteField };
197
- if (!field)
198
- f.type = this.document.getDataType('any');
199
- Object.setPrototypeOf(f, field || field_js_1.ApiField.prototype);
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 = field;
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.name ||
28
- (this.type.kind === 'ComplexType' && this.type.isAnonymous);
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
- return !options?.partial && this.required ? vg.required(fn) : vg.optional(fn);
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
- if (init.options?.inputOverwriteFields)
26
- this.inputOverwriteFields = new index_js_1.ResponsiveMap(init.options.inputOverwriteFields);
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
- Array.from(this.inputOverwriteFields.entries())
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
- Array.from(this.outputOverwriteFields.entries())
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: inDevelopment ? this.stack?.split('\n') : undefined
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 './uuid.type.js';
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._generateCodecSchema(codec, options);
162
+ const schema = this.generateCodecSchema(codec, options);
163
163
  const additionalFields = this.additionalFields instanceof DataType
164
- ? this.additionalFields.generateCodec(codec, options)
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 pickOption = (options?.pick || []).map(x => x.toLowerCase());
176
- const omitOption = (options?.omit || []).map(x => x.toLowerCase());
177
- const dedupedFieldNames = (options?.overwriteFields
178
- ? Array.from(new Set([...this.fields.keys(), ...options?.overwriteFields.keys()]))
179
- : Array.from(this.fields.keys())).map(x => x.toLowerCase());
180
- for (const nameLower of dedupedFieldNames) {
181
- const overwriteField = options?.overwriteFields?.get(nameLower);
182
- const field = this.fields.get(nameLower);
183
- /* istanbul ignore next */
184
- if (!(field || overwriteField))
185
- continue;
186
- if (!overwriteField &&
187
- (omitOption.find(x => x === nameLower) ||
188
- (pickOption.length && !pickOption.find(x => x === nameLower || x.startsWith(nameLower + '.')))))
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 (overwriteField) {
192
- f = { ...overwriteField };
193
- if (!field)
194
- f.type = this.document.getDataType('any');
195
- Object.setPrototypeOf(f, field || ApiField.prototype);
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 = field;
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.name ||
24
- (this.type.kind === 'ComplexType' && this.type.isAnonymous);
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
- return !options?.partial && this.required ? vg.required(fn) : vg.optional(fn);
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
- if (init.options?.inputOverwriteFields)
22
- this.inputOverwriteFields = new ResponsiveMap(init.options.inputOverwriteFields);
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
- Array.from(this.inputOverwriteFields.entries())
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
- Array.from(this.outputOverwriteFields.entries())
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: inDevelopment ? this.stack?.split('\n') : undefined
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.11",
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.4"
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.6",
57
+ "@types/validator": "^13.11.7",
58
58
  "path-browserify": "^1.0.1",
59
59
  "ts-gems": "^2.5.0"
60
60
  },
@@ -0,0 +1,2 @@
1
+ export declare class EmailType {
2
+ }
@@ -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 './uuid.type.js';
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,2 @@
1
+ export declare class UrlType {
2
+ }
@@ -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
- protected _generateCodecSchema(codec: 'decode' | 'encode', options?: DataType.GenerateCodecOptions): vg.ObjectSchema;
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?: ResponsiveMap<ApiField.InitArguments>;
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?: ResponsiveMap<ApiField.InitArguments>;
22
- outputOverwriteFields?: ResponsiveMap<ApiField.InitArguments>;
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
- * Defines if the field value is an array
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
- * Defines the fixed value of the field. The value of the field can not be any other value.
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
- * Defines if field value required in create operation
25
+ * Indicates if field value required in create operation
26
26
  */
27
27
  required?: boolean;
28
28
  /**
29
- * Defines if the field is readonly
29
+ * Indicates if the field is readonly
30
30
  */
31
31
  readonly?: boolean;
32
32
  /**
33
- * Defines if the field is writeonly
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
- * Defines if the field is deprecated and can be removed in the next
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
  };