@opra/common 0.31.12 → 0.32.0

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 CHANGED
@@ -350,6 +350,12 @@ var ResponsiveMap = class extends Map {
350
350
  };
351
351
  return new Proxy({}, finalHandler);
352
352
  }
353
+ toObject() {
354
+ return Object.keys(this.keys()).reduce((trg, k) => {
355
+ trg[k] = this.get(k);
356
+ return trg;
357
+ }, {});
358
+ }
353
359
  [(_a = kKeyMap, _b = kKeyOrder, _c = kWellKnownKeys, _d = kOptions, Symbol.iterator)]() {
354
360
  return this.entries();
355
361
  }
@@ -2148,9 +2154,10 @@ var FieldClass = class {
2148
2154
  this.deprecated = init.deprecated;
2149
2155
  this.examples = init.examples;
2150
2156
  this.format = init.format;
2157
+ this.partialUpdate = init.partialUpdate;
2151
2158
  }
2152
2159
  exportSchema(options) {
2153
- const isAnonymous = !this.type.name || this.type.kind === "ComplexType" && this.type.isAnonymous;
2160
+ const isAnonymous = !this.type?.name || this.type?.kind === "ComplexType" && this.type.isAnonymous;
2154
2161
  return omitUndefined({
2155
2162
  type: this.type ? isAnonymous ? this.type.exportSchema(options) : this.type.name : void 0,
2156
2163
  description: this.description,
@@ -2164,7 +2171,8 @@ var FieldClass = class {
2164
2171
  translatable: this.translatable,
2165
2172
  deprecated: this.deprecated,
2166
2173
  examples: this.examples,
2167
- format: this.format
2174
+ format: this.format,
2175
+ partialUpdate: this.partialUpdate
2168
2176
  });
2169
2177
  }
2170
2178
  generateCodec(codec, options) {
@@ -2172,7 +2180,11 @@ var FieldClass = class {
2172
2180
  return vg3.isUndefined();
2173
2181
  if (options?.operation === "write" && this.readonly)
2174
2182
  return vg3.isUndefined();
2175
- let fn = this.type.generateCodec(codec, { ...options, designType: this.designType });
2183
+ let fn = this.type.generateCodec(codec, {
2184
+ ...options,
2185
+ designType: this.designType,
2186
+ partial: options?.partial && (this.partialUpdate || !this.isArray)
2187
+ });
2176
2188
  if (this.isArray)
2177
2189
  fn = vg3.isArray(fn);
2178
2190
  return !options?.partial && this.required ? vg3.required(fn) : vg3.optional(fn);
@@ -2362,43 +2374,92 @@ var ComplexTypeClass = class extends DataType {
2362
2374
  return false;
2363
2375
  }
2364
2376
  generateCodec(codec, options) {
2365
- const schema = this._generateCodecSchema(codec, options);
2366
- const additionalFields = this.additionalFields instanceof DataType ? this.additionalFields.generateCodec(codec, options) : this.additionalFields;
2377
+ const schema = this.generateCodecSchema(codec, options);
2378
+ const additionalFields = this.additionalFields instanceof DataType ? this.additionalFields.generateCodec(codec, {
2379
+ operation: options?.operation,
2380
+ caseSensitive: options?.caseSensitive,
2381
+ partial: options?.partial
2382
+ }) : this.additionalFields;
2367
2383
  return vg4.isObject(schema, {
2368
2384
  ctor: this.ctor,
2369
2385
  additionalFields,
2370
2386
  name: this.name,
2371
- caseInSensitive: !options?.caseSensitive
2387
+ caseInSensitive: !options?.caseSensitive,
2388
+ onFail: options?.onFail
2372
2389
  });
2373
2390
  }
2391
+ generateCodecSchema(codec, options) {
2392
+ const opts = {
2393
+ ...options,
2394
+ pick: (options?.pick || []).map((x) => x.toLowerCase()),
2395
+ omit: (options?.omit || []).map((x) => x.toLowerCase()),
2396
+ overwriteFields: options?.overwriteFields ? this._buildOverwriteFieldsTree(options.overwriteFields) : void 0
2397
+ };
2398
+ return this._generateCodecSchema(codec, opts);
2399
+ }
2374
2400
  _generateCodecSchema(codec, options) {
2375
2401
  const schema = {};
2376
- const pickOption = (options?.pick || []).map((x) => x.toLowerCase());
2377
- const omitOption = (options?.omit || []).map((x) => x.toLowerCase());
2378
- const dedupedFieldNames = (options?.overwriteFields ? Array.from(/* @__PURE__ */ new Set([...this.fields.keys(), ...options?.overwriteFields.keys()])) : Array.from(this.fields.keys())).map((x) => x.toLowerCase());
2379
- for (const nameLower of dedupedFieldNames) {
2380
- const overwriteField = options?.overwriteFields?.get(nameLower);
2381
- const field = this.fields.get(nameLower);
2382
- if (!(field || overwriteField))
2383
- continue;
2384
- if (!overwriteField && (omitOption.find((x) => x === nameLower) || pickOption.length && !pickOption.find((x) => x === nameLower || x.startsWith(nameLower + "."))))
2402
+ const overwriteFields = options?.overwriteFields;
2403
+ const optionsPick = options?.pick || [];
2404
+ const optionsOmit = options?.omit || [];
2405
+ const fieldNames = [...this.fields.keys()];
2406
+ if (overwriteFields) {
2407
+ for (const k of Object.keys(overwriteFields)) {
2408
+ if (!this.fields.has(k))
2409
+ fieldNames.push(k);
2410
+ }
2411
+ }
2412
+ for (const fieldName of fieldNames) {
2413
+ const lowerName = fieldName.toLowerCase();
2414
+ const overwriteFieldInit = overwriteFields?.[fieldName];
2415
+ if (!overwriteFieldInit && (optionsOmit.find((x) => x === lowerName) || optionsPick.length && !optionsPick.find((x) => x === lowerName || x.startsWith(lowerName + "."))))
2385
2416
  continue;
2417
+ const subOptions = {
2418
+ ...options,
2419
+ pick: optionsPick.filter((x) => x.startsWith(lowerName + ".")).map((x) => x.substring(x.indexOf(".") + 1)),
2420
+ omit: optionsOmit.filter((x) => x.startsWith(lowerName + ".")).map((x) => x.substring(x.indexOf(".") + 1)),
2421
+ overwriteFields: overwriteFieldInit?.overrideFields
2422
+ };
2386
2423
  let f;
2387
- if (overwriteField) {
2388
- f = { ...overwriteField };
2389
- if (!field)
2390
- f.type = this.document.getDataType("any");
2391
- Object.setPrototypeOf(f, field || ApiField.prototype);
2424
+ if (overwriteFieldInit) {
2425
+ const field = this.fields.get(fieldName);
2426
+ const init = { ...field, ...overwriteFieldInit, name: fieldName };
2427
+ if (!(init.type instanceof DataType))
2428
+ init.type = this.document.getDataType(init.type || "any");
2429
+ f = new ApiField(this, init);
2392
2430
  } else
2393
- f = field;
2394
- schema[f.name] = f.generateCodec(codec, {
2395
- ...options,
2396
- pick: overwriteField ? [] : pickOption.filter((x) => x.startsWith(nameLower + ".")).map((x) => x.substring(x.indexOf(".") + 1)),
2397
- omit: overwriteField ? [] : omitOption.filter((x) => x.startsWith(nameLower + ".")).map((x) => x.substring(x.indexOf(".") + 1))
2398
- });
2431
+ f = this.getField(fieldName);
2432
+ schema[f.name] = f.generateCodec(codec, subOptions);
2399
2433
  }
2400
2434
  return schema;
2401
2435
  }
2436
+ _buildOverwriteFieldsTree(obj) {
2437
+ const tree = {};
2438
+ for (let k of Object.keys(obj)) {
2439
+ const v = obj[k];
2440
+ if (!k.includes(".")) {
2441
+ const field = this.fields.get(k);
2442
+ if (field)
2443
+ k = field.name;
2444
+ tree[k] = { ...tree[k], ...v };
2445
+ continue;
2446
+ }
2447
+ const keyPath = k.split(".");
2448
+ let subTree = tree;
2449
+ while (keyPath.length) {
2450
+ let j = keyPath.shift();
2451
+ const field = this.fields.get(j);
2452
+ if (field)
2453
+ j = field.name;
2454
+ const treeItem = subTree[j] = subTree[j] || {};
2455
+ if (keyPath.length) {
2456
+ subTree = treeItem.overrideFields = treeItem.overrideFields || {};
2457
+ } else
2458
+ Object.assign(treeItem, v);
2459
+ }
2460
+ }
2461
+ return tree;
2462
+ }
2402
2463
  };
2403
2464
 
2404
2465
  // ../../build/common/esm/document/data-type/complex-type.js
@@ -2641,20 +2702,20 @@ var TypeDocument = class extends DocumentBase {
2641
2702
  getComplexType(nameOrCtor, silent) {
2642
2703
  if (nameOrCtor === Object)
2643
2704
  nameOrCtor = "object";
2644
- const t = this.getDataType(nameOrCtor);
2645
- if (!t && silent)
2646
- return;
2647
- if (t && t.kind === opra_schema_ns_exports.ComplexType.Kind)
2648
- return t;
2649
- throw new NotAcceptableError(`Data type "${t.name}" is not a ComplexType`);
2705
+ const t = this.getDataType(nameOrCtor, silent);
2706
+ if (t) {
2707
+ if (t && t.kind === opra_schema_ns_exports.ComplexType.Kind)
2708
+ return t;
2709
+ throw new NotAcceptableError(`Data type "${t.name}" is not a ComplexType`);
2710
+ }
2650
2711
  }
2651
2712
  getSimpleType(nameOrCtor, silent) {
2652
- const t = this.getDataType(nameOrCtor);
2653
- if (!t && silent)
2654
- return;
2655
- if (t && t.kind === opra_schema_ns_exports.SimpleType.Kind)
2656
- return t;
2657
- throw new NotAcceptableError(`Data type "${t.name || t}" is not a SimpleType`);
2713
+ const t = this.getDataType(nameOrCtor, silent);
2714
+ if (t) {
2715
+ if (t && t.kind === opra_schema_ns_exports.SimpleType.Kind)
2716
+ return t;
2717
+ throw new NotAcceptableError(`Data type "${t.name || t}" is not a SimpleType`);
2718
+ }
2658
2719
  }
2659
2720
  getEnumType(nameOrCtor, silent) {
2660
2721
  const t = this.getDataType(nameOrCtor);
@@ -2675,7 +2736,7 @@ var TypeDocument = class extends DocumentBase {
2675
2736
  for (const [ns, r] of this.references.entries()) {
2676
2737
  if (ns.toLowerCase() === "opra")
2677
2738
  continue;
2678
- references[ns] = r.url ? r.url : r.exportSchema(options);
2739
+ references[ns] = r.exportSchema(options);
2679
2740
  i++;
2680
2741
  }
2681
2742
  if (i)
@@ -3396,7 +3457,10 @@ var TypeDocumentFactory = class _TypeDocumentFactory {
3396
3457
  }
3397
3458
  async addReferences(references) {
3398
3459
  const { document } = this;
3399
- for (const [ns, r] of Object.entries(references)) {
3460
+ let ns;
3461
+ let r;
3462
+ for ([ns, r] of Object.entries(references)) {
3463
+ r = await r;
3400
3464
  if (typeof r === "string") {
3401
3465
  document.references.set(ns, await this.initDocumentFromUrl(r));
3402
3466
  } else if (r instanceof TypeDocument)
@@ -11121,22 +11185,20 @@ var CrudOperation = class extends Endpoint {
11121
11185
  this.encodeReturning = vg7.isAny();
11122
11186
  this.returnType = init.returnType instanceof DataType ? init.returnType : this.resource.document.getDataType(init.returnType || "any");
11123
11187
  this.encodeReturning = this.returnType.generateCodec("encode", { operation: "read" });
11124
- if (init.options?.inputOverwriteFields)
11125
- this.inputOverwriteFields = new ResponsiveMap(init.options.inputOverwriteFields);
11126
- if (init.options?.outputOverwriteFields)
11127
- this.outputOverwriteFields = new ResponsiveMap(init.options.outputOverwriteFields);
11188
+ this.inputOverwriteFields = init.options?.inputOverwriteFields;
11189
+ this.outputOverwriteFields = init.options?.outputOverwriteFields;
11128
11190
  }
11129
11191
  exportSchema(options) {
11130
11192
  const schema = super.exportSchema(options);
11131
11193
  if (this.inputOverwriteFields) {
11132
11194
  const trg = schema.options.inputOverwriteFields = {};
11133
- Array.from(this.inputOverwriteFields.entries()).forEach(([k, o]) => {
11195
+ Object.keys(this.inputOverwriteFields).forEach(([k, o]) => {
11134
11196
  trg[k] = ApiField.prototype.exportSchema.call(o, options);
11135
11197
  });
11136
11198
  }
11137
11199
  if (this.outputOverwriteFields) {
11138
11200
  const trg = schema.options.outputOverwriteFields = {};
11139
- Array.from(this.outputOverwriteFields.entries()).forEach(([k, o]) => {
11201
+ Object.keys(this.outputOverwriteFields).forEach(([k, o]) => {
11140
11202
  trg[k] = ApiField.prototype.exportSchema.call(o, options);
11141
11203
  });
11142
11204
  }
@@ -163,56 +163,106 @@ 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,
172
176
  additionalFields,
173
177
  name: this.name,
174
- caseInSensitive: !options?.caseSensitive
178
+ caseInSensitive: !options?.caseSensitive,
179
+ onFail: options?.onFail
175
180
  });
176
181
  }
182
+ generateCodecSchema(codec, options) {
183
+ const opts = {
184
+ ...options,
185
+ pick: (options?.pick || []).map(x => x.toLowerCase()),
186
+ omit: (options?.omit || []).map(x => x.toLowerCase()),
187
+ overwriteFields: options?.overwriteFields ? this._buildOverwriteFieldsTree(options.overwriteFields) : undefined,
188
+ };
189
+ return this._generateCodecSchema(codec, opts);
190
+ }
177
191
  _generateCodecSchema(codec, options) {
178
192
  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 + '.')))))
193
+ const overwriteFields = options?.overwriteFields;
194
+ const optionsPick = options?.pick || [];
195
+ const optionsOmit = options?.omit || [];
196
+ const fieldNames = [...this.fields.keys()];
197
+ // Add field name from overwriteFields which doesn't exist in this.fields
198
+ if (overwriteFields) {
199
+ for (const k of Object.keys(overwriteFields)) {
200
+ if (!this.fields.has(k))
201
+ fieldNames.push(k);
202
+ }
203
+ }
204
+ // Process fields
205
+ for (const fieldName of fieldNames) {
206
+ const lowerName = fieldName.toLowerCase();
207
+ const overwriteFieldInit = overwriteFields?.[fieldName];
208
+ // If field omitted or not in pick list we ignore it unless overwriteField defined
209
+ if (!overwriteFieldInit &&
210
+ (optionsOmit.find(x => x === lowerName) ||
211
+ (optionsPick.length && !optionsPick.find(x => x === lowerName || x.startsWith(lowerName + '.')))))
193
212
  continue;
213
+ const subOptions = {
214
+ ...options,
215
+ pick: optionsPick
216
+ .filter(x => x.startsWith(lowerName + '.'))
217
+ .map(x => x.substring(x.indexOf('.') + 1)),
218
+ omit: optionsOmit
219
+ .filter(x => x.startsWith(lowerName + '.'))
220
+ .map(x => x.substring(x.indexOf('.') + 1)),
221
+ overwriteFields: overwriteFieldInit?.overrideFields
222
+ };
194
223
  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);
224
+ if (overwriteFieldInit) {
225
+ const field = this.fields.get(fieldName);
226
+ const init = { ...field, ...overwriteFieldInit, name: fieldName };
227
+ if (!(init.type instanceof data_type_js_1.DataType))
228
+ init.type = this.document.getDataType(init.type || 'any');
229
+ f = new field_js_1.ApiField(this, init);
200
230
  }
201
231
  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
- });
232
+ f = this.getField(fieldName);
233
+ schema[f.name] = f.generateCodec(codec, subOptions);
214
234
  }
215
235
  return schema;
216
236
  }
237
+ _buildOverwriteFieldsTree(obj) {
238
+ const tree = {};
239
+ for (let k of Object.keys(obj)) {
240
+ const v = obj[k];
241
+ if (!k.includes('.')) {
242
+ // Fix field name
243
+ const field = this.fields.get(k);
244
+ if (field)
245
+ k = field.name;
246
+ tree[k] = { ...tree[k], ...v };
247
+ continue;
248
+ }
249
+ const keyPath = k.split('.');
250
+ let subTree = tree;
251
+ while (keyPath.length) {
252
+ let j = keyPath.shift();
253
+ // Fix field name
254
+ const field = this.fields.get(j);
255
+ if (field)
256
+ j = field.name;
257
+ const treeItem = subTree[j] = subTree[j] || {};
258
+ if (keyPath.length) {
259
+ subTree = treeItem.overrideFields = treeItem.overrideFields || {};
260
+ }
261
+ else
262
+ Object.assign(treeItem, v);
263
+ }
264
+ }
265
+ return tree;
266
+ }
217
267
  }
218
268
  exports.ComplexTypeClass = ComplexTypeClass;
@@ -23,10 +23,11 @@ class FieldClass {
23
23
  this.deprecated = init.deprecated;
24
24
  this.examples = init.examples;
25
25
  this.format = init.format;
26
+ this.partialUpdate = init.partialUpdate;
26
27
  }
27
28
  exportSchema(options) {
28
- const isAnonymous = !this.type.name ||
29
- (this.type.kind === 'ComplexType' && this.type.isAnonymous);
29
+ const isAnonymous = !this.type?.name ||
30
+ (this.type?.kind === 'ComplexType' && this.type.isAnonymous);
30
31
  return (0, index_js_1.omitUndefined)({
31
32
  type: this.type
32
33
  ? (isAnonymous ? this.type.exportSchema(options) : this.type.name)
@@ -43,6 +44,7 @@ class FieldClass {
43
44
  deprecated: this.deprecated,
44
45
  examples: this.examples,
45
46
  format: this.format,
47
+ partialUpdate: this.partialUpdate,
46
48
  });
47
49
  }
48
50
  generateCodec(codec, options) {
@@ -50,7 +52,11 @@ class FieldClass {
50
52
  return vg.isUndefined();
51
53
  if (options?.operation === 'write' && this.readonly)
52
54
  return vg.isUndefined();
53
- let fn = this.type.generateCodec(codec, { ...options, designType: this.designType });
55
+ let fn = this.type.generateCodec(codec, {
56
+ ...options,
57
+ designType: this.designType,
58
+ partial: options?.partial && (this.partialUpdate || !this.isArray)
59
+ });
54
60
  if (this.isArray)
55
61
  fn = vg.isArray(fn);
56
62
  return !options?.partial && this.required ? vg.required(fn) : vg.optional(fn);
@@ -108,7 +108,10 @@ class TypeDocumentFactory {
108
108
  }
109
109
  async addReferences(references) {
110
110
  const { document } = this;
111
- for (const [ns, r] of Object.entries(references)) {
111
+ let ns;
112
+ let r;
113
+ for ([ns, r] of Object.entries(references)) {
114
+ r = await r;
112
115
  if (typeof r === 'string') {
113
116
  document.references.set(ns, await this.initDocumentFromUrl(r));
114
117
  }
@@ -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
  });
@@ -148,20 +148,20 @@ class TypeDocument extends document_base_js_1.DocumentBase {
148
148
  getComplexType(nameOrCtor, silent) {
149
149
  if (nameOrCtor === Object)
150
150
  nameOrCtor = 'object';
151
- const t = this.getDataType(nameOrCtor);
152
- if (!t && silent)
153
- return;
154
- if (t && t.kind === index_js_3.OpraSchema.ComplexType.Kind)
155
- return t;
156
- throw new index_js_1.NotAcceptableError(`Data type "${t.name}" is not a ComplexType`);
151
+ const t = this.getDataType(nameOrCtor, silent);
152
+ if (t) {
153
+ if (t && t.kind === index_js_3.OpraSchema.ComplexType.Kind)
154
+ return t;
155
+ throw new index_js_1.NotAcceptableError(`Data type "${t.name}" is not a ComplexType`);
156
+ }
157
157
  }
158
158
  getSimpleType(nameOrCtor, silent) {
159
- const t = this.getDataType(nameOrCtor);
160
- if (!t && silent)
161
- return;
162
- if (t && t.kind === index_js_3.OpraSchema.SimpleType.Kind)
163
- return t;
164
- throw new index_js_1.NotAcceptableError(`Data type "${t.name || t}" is not a SimpleType`);
159
+ const t = this.getDataType(nameOrCtor, silent);
160
+ if (t) {
161
+ if (t && t.kind === index_js_3.OpraSchema.SimpleType.Kind)
162
+ return t;
163
+ throw new index_js_1.NotAcceptableError(`Data type "${t.name || t}" is not a SimpleType`);
164
+ }
165
165
  }
166
166
  getEnumType(nameOrCtor, silent) {
167
167
  const t = this.getDataType(nameOrCtor);
@@ -182,7 +182,7 @@ class TypeDocument extends document_base_js_1.DocumentBase {
182
182
  for (const [ns, r] of this.references.entries()) {
183
183
  if (ns.toLowerCase() === 'opra')
184
184
  continue;
185
- references[ns] = r.url ? r.url : r.exportSchema(options);
185
+ references[ns] = r.exportSchema(options);
186
186
  i++;
187
187
  }
188
188
  if (i)
@@ -154,6 +154,12 @@ class ResponsiveMap extends Map {
154
154
  };
155
155
  return new Proxy({}, finalHandler);
156
156
  }
157
+ toObject() {
158
+ return Object.keys(this.keys()).reduce((trg, k) => {
159
+ trg[k] = this.get(k);
160
+ return trg;
161
+ }, {});
162
+ }
157
163
  [(_a = kKeyMap, _b = kKeyOrder, _c = kWellKnownKeys, _d = kOptions, Symbol.iterator)]() {
158
164
  return this.entries();
159
165
  }
@@ -159,55 +159,105 @@ 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,
168
172
  additionalFields,
169
173
  name: this.name,
170
- caseInSensitive: !options?.caseSensitive
174
+ caseInSensitive: !options?.caseSensitive,
175
+ onFail: options?.onFail
171
176
  });
172
177
  }
178
+ generateCodecSchema(codec, options) {
179
+ const opts = {
180
+ ...options,
181
+ pick: (options?.pick || []).map(x => x.toLowerCase()),
182
+ omit: (options?.omit || []).map(x => x.toLowerCase()),
183
+ overwriteFields: options?.overwriteFields ? this._buildOverwriteFieldsTree(options.overwriteFields) : undefined,
184
+ };
185
+ return this._generateCodecSchema(codec, opts);
186
+ }
173
187
  _generateCodecSchema(codec, options) {
174
188
  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 + '.')))))
189
+ const overwriteFields = options?.overwriteFields;
190
+ const optionsPick = options?.pick || [];
191
+ const optionsOmit = options?.omit || [];
192
+ const fieldNames = [...this.fields.keys()];
193
+ // Add field name from overwriteFields which doesn't exist in this.fields
194
+ if (overwriteFields) {
195
+ for (const k of Object.keys(overwriteFields)) {
196
+ if (!this.fields.has(k))
197
+ fieldNames.push(k);
198
+ }
199
+ }
200
+ // Process fields
201
+ for (const fieldName of fieldNames) {
202
+ const lowerName = fieldName.toLowerCase();
203
+ const overwriteFieldInit = overwriteFields?.[fieldName];
204
+ // If field omitted or not in pick list we ignore it unless overwriteField defined
205
+ if (!overwriteFieldInit &&
206
+ (optionsOmit.find(x => x === lowerName) ||
207
+ (optionsPick.length && !optionsPick.find(x => x === lowerName || x.startsWith(lowerName + '.')))))
189
208
  continue;
209
+ const subOptions = {
210
+ ...options,
211
+ pick: optionsPick
212
+ .filter(x => x.startsWith(lowerName + '.'))
213
+ .map(x => x.substring(x.indexOf('.') + 1)),
214
+ omit: optionsOmit
215
+ .filter(x => x.startsWith(lowerName + '.'))
216
+ .map(x => x.substring(x.indexOf('.') + 1)),
217
+ overwriteFields: overwriteFieldInit?.overrideFields
218
+ };
190
219
  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);
220
+ if (overwriteFieldInit) {
221
+ const field = this.fields.get(fieldName);
222
+ const init = { ...field, ...overwriteFieldInit, name: fieldName };
223
+ if (!(init.type instanceof DataType))
224
+ init.type = this.document.getDataType(init.type || 'any');
225
+ f = new ApiField(this, init);
196
226
  }
197
227
  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
- });
228
+ f = this.getField(fieldName);
229
+ schema[f.name] = f.generateCodec(codec, subOptions);
210
230
  }
211
231
  return schema;
212
232
  }
233
+ _buildOverwriteFieldsTree(obj) {
234
+ const tree = {};
235
+ for (let k of Object.keys(obj)) {
236
+ const v = obj[k];
237
+ if (!k.includes('.')) {
238
+ // Fix field name
239
+ const field = this.fields.get(k);
240
+ if (field)
241
+ k = field.name;
242
+ tree[k] = { ...tree[k], ...v };
243
+ continue;
244
+ }
245
+ const keyPath = k.split('.');
246
+ let subTree = tree;
247
+ while (keyPath.length) {
248
+ let j = keyPath.shift();
249
+ // Fix field name
250
+ const field = this.fields.get(j);
251
+ if (field)
252
+ j = field.name;
253
+ const treeItem = subTree[j] = subTree[j] || {};
254
+ if (keyPath.length) {
255
+ subTree = treeItem.overrideFields = treeItem.overrideFields || {};
256
+ }
257
+ else
258
+ Object.assign(treeItem, v);
259
+ }
260
+ }
261
+ return tree;
262
+ }
213
263
  }
@@ -19,10 +19,11 @@ export class FieldClass {
19
19
  this.deprecated = init.deprecated;
20
20
  this.examples = init.examples;
21
21
  this.format = init.format;
22
+ this.partialUpdate = init.partialUpdate;
22
23
  }
23
24
  exportSchema(options) {
24
- const isAnonymous = !this.type.name ||
25
- (this.type.kind === 'ComplexType' && this.type.isAnonymous);
25
+ const isAnonymous = !this.type?.name ||
26
+ (this.type?.kind === 'ComplexType' && this.type.isAnonymous);
26
27
  return omitUndefined({
27
28
  type: this.type
28
29
  ? (isAnonymous ? this.type.exportSchema(options) : this.type.name)
@@ -39,6 +40,7 @@ export class FieldClass {
39
40
  deprecated: this.deprecated,
40
41
  examples: this.examples,
41
42
  format: this.format,
43
+ partialUpdate: this.partialUpdate,
42
44
  });
43
45
  }
44
46
  generateCodec(codec, options) {
@@ -46,7 +48,11 @@ export class FieldClass {
46
48
  return vg.isUndefined();
47
49
  if (options?.operation === 'write' && this.readonly)
48
50
  return vg.isUndefined();
49
- let fn = this.type.generateCodec(codec, { ...options, designType: this.designType });
51
+ let fn = this.type.generateCodec(codec, {
52
+ ...options,
53
+ designType: this.designType,
54
+ partial: options?.partial && (this.partialUpdate || !this.isArray)
55
+ });
50
56
  if (this.isArray)
51
57
  fn = vg.isArray(fn);
52
58
  return !options?.partial && this.required ? vg.required(fn) : vg.optional(fn);
@@ -105,7 +105,10 @@ export class TypeDocumentFactory {
105
105
  }
106
106
  async addReferences(references) {
107
107
  const { document } = this;
108
- for (const [ns, r] of Object.entries(references)) {
108
+ let ns;
109
+ let r;
110
+ for ([ns, r] of Object.entries(references)) {
111
+ r = await r;
109
112
  if (typeof r === 'string') {
110
113
  document.references.set(ns, await this.initDocumentFromUrl(r));
111
114
  }
@@ -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
  });
@@ -145,20 +145,20 @@ export class TypeDocument extends DocumentBase {
145
145
  getComplexType(nameOrCtor, silent) {
146
146
  if (nameOrCtor === Object)
147
147
  nameOrCtor = 'object';
148
- const t = this.getDataType(nameOrCtor);
149
- if (!t && silent)
150
- return;
151
- if (t && t.kind === OpraSchema.ComplexType.Kind)
152
- return t;
153
- throw new NotAcceptableError(`Data type "${t.name}" is not a ComplexType`);
148
+ const t = this.getDataType(nameOrCtor, silent);
149
+ if (t) {
150
+ if (t && t.kind === OpraSchema.ComplexType.Kind)
151
+ return t;
152
+ throw new NotAcceptableError(`Data type "${t.name}" is not a ComplexType`);
153
+ }
154
154
  }
155
155
  getSimpleType(nameOrCtor, silent) {
156
- const t = this.getDataType(nameOrCtor);
157
- if (!t && silent)
158
- return;
159
- if (t && t.kind === OpraSchema.SimpleType.Kind)
160
- return t;
161
- throw new NotAcceptableError(`Data type "${t.name || t}" is not a SimpleType`);
156
+ const t = this.getDataType(nameOrCtor, silent);
157
+ if (t) {
158
+ if (t && t.kind === OpraSchema.SimpleType.Kind)
159
+ return t;
160
+ throw new NotAcceptableError(`Data type "${t.name || t}" is not a SimpleType`);
161
+ }
162
162
  }
163
163
  getEnumType(nameOrCtor, silent) {
164
164
  const t = this.getDataType(nameOrCtor);
@@ -179,7 +179,7 @@ export class TypeDocument extends DocumentBase {
179
179
  for (const [ns, r] of this.references.entries()) {
180
180
  if (ns.toLowerCase() === 'opra')
181
181
  continue;
182
- references[ns] = r.url ? r.url : r.exportSchema(options);
182
+ references[ns] = r.exportSchema(options);
183
183
  i++;
184
184
  }
185
185
  if (i)
@@ -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.12",
3
+ "version": "0.32.0",
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.5"
49
+ "valgen": "^4.3.1"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@browsery/fs": "^0.4.0",
@@ -56,7 +56,7 @@
56
56
  "@types/lodash.omit": "^4.5.9",
57
57
  "@types/validator": "^13.11.7",
58
58
  "path-browserify": "^1.0.1",
59
- "ts-gems": "^2.5.0"
59
+ "ts-gems": "^2.7.1"
60
60
  },
61
61
  "engines": {
62
62
  "node": ">=16.0",
@@ -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,20 @@ 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
- pick?: string[];
45
- omit?: string[];
49
+ pick?: string[] | readonly string[];
50
+ omit?: string[] | readonly string[];
46
51
  partial?: boolean;
47
52
  operation?: 'read' | 'write';
48
- overwriteFields?: ResponsiveMap<ApiField.InitArguments>;
53
+ overwriteFields?: Record<string, OverrideFieldsConfig>;
49
54
  designType?: Type;
55
+ onFail?: vg.OnFailFunction;
50
56
  }
51
57
  }
@@ -22,6 +22,7 @@ export declare class FieldClass {
22
22
  deprecated?: boolean | string;
23
23
  examples?: any[] | Record<string, any>;
24
24
  format?: string;
25
+ partialUpdate?: boolean;
25
26
  constructor(owner: ComplexType, init: ApiField.InitArguments);
26
27
  exportSchema(options?: {
27
28
  webSafe?: boolean;
@@ -2,7 +2,6 @@ import { PartialSome, StrictOmit, Type } from 'ts-gems';
2
2
  import { ResponsiveMap } from '../../helpers/index.js';
3
3
  import { OpraSchema } from '../../schema/index.js';
4
4
  import { ThunkAsync } from '../../types.js';
5
- import type { ApiDocument } from '../api-document.js';
6
5
  import { ComplexType } from '../data-type/complex-type.js';
7
6
  import { DataType } from '../data-type/data-type.js';
8
7
  import { EnumType } from '../data-type/enum-type.js';
@@ -10,9 +9,10 @@ import { MappedType } from '../data-type/mapped-type.js';
10
9
  import { MixinType } from '../data-type/mixin-type.js';
11
10
  import { SimpleType } from '../data-type/simple-type.js';
12
11
  import { TypeDocument } from '../type-document.js';
12
+ type ReferenceUnion = string | OpraSchema.TypeDocument | TypeDocument;
13
13
  export declare namespace TypeDocumentFactory {
14
14
  interface InitArguments extends PartialSome<StrictOmit<OpraSchema.TypeDocument, 'references' | 'types'>, 'version'> {
15
- references?: Record<string, string | OpraSchema.ApiDocument | ApiDocument>;
15
+ references?: Record<string, ReferenceUnion | Promise<ReferenceUnion>>;
16
16
  types?: ThunkAsync<Type | EnumType.EnumObject | EnumType.EnumArray>[] | Record<string, OpraSchema.DataType>;
17
17
  noBuiltinTypes?: boolean;
18
18
  }
@@ -49,8 +49,9 @@ export declare class TypeDocumentFactory {
49
49
  protected initDocument(init: TypeDocumentFactory.InitArguments): Promise<TypeDocument>;
50
50
  initDocumentFromUrl(url: string): Promise<TypeDocument>;
51
51
  protected createBuiltinTypeDocument(): Promise<TypeDocument>;
52
- protected addReferences(references: Record<string, string | OpraSchema.TypeDocument | TypeDocument>): Promise<void>;
52
+ protected addReferences(references: Record<string, ReferenceUnion | Promise<ReferenceUnion>>): Promise<void>;
53
53
  protected importDataType(thunk: ThunkAsync<string | Type | EnumType.EnumObject | EnumType.EnumArray | OpraSchema.DataType>): Promise<DataType>;
54
54
  protected prepareDataTypeInitArguments(schema: TypeDocumentFactory.DataTypeInitializer | OpraSchema.DataType, ctor?: Type): Promise<TypeDocumentFactory.DataTypeInitializer | undefined>;
55
55
  protected createDataTypeInstance(kind: OpraSchema.DataType.Kind, name?: string): DataType;
56
56
  }
57
+ export {};
@@ -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
  /**
@@ -47,8 +47,12 @@ export type Field = {
47
47
  */
48
48
  examples?: any[] | Record<string, any>;
49
49
  /**
50
- * 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
51
51
  */
52
52
  deprecated?: boolean | string;
53
53
  format?: string;
54
+ /**
55
+ * Indicates if partial update enabled for this field
56
+ */
57
+ partialUpdate?: boolean;
54
58
  };
package/types/types.d.ts CHANGED
@@ -1,11 +1,7 @@
1
- import { Builtin, DeepPickWritable, Type } from 'ts-gems';
2
- export type PartialInput<T> = DeepNullablePartial<DeepPickWritable<T>>;
3
- export type PartialOutput<T> = DeepNullablePartial<T>;
4
- type DeepNullablePartial<T> = T extends Builtin ? T : T extends Promise<infer U> ? Promise<DeepNullablePartial<U>> : T extends (infer U)[] ? DeepNullablePartial<U>[] : {
5
- [P in keyof T]?: DeepNullablePartial<Exclude<T[P], undefined>> | null;
6
- };
1
+ import { DeepPickWritable, HighDeepNullish, Type } from 'ts-gems';
2
+ export type PartialInput<T> = HighDeepNullish<DeepPickWritable<T>>;
3
+ export type PartialOutput<T> = HighDeepNullish<T>;
7
4
  export type Thunk<T> = T | (() => T);
8
- export type ThunkAsync<T> = T | Promise<T> | (() => T) | (() => Promise<T>);
5
+ export type ThunkAsync<T> = Thunk<T> | Thunk<Promise<T>>;
9
6
  export type TypeThunk<T = any> = Thunk<Type<T>>;
10
7
  export type TypeThunkAsync<T = any> = ThunkAsync<Type<T>>;
11
- export {};