@opra/common 1.13.0 → 1.15.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/index.cjs +5 -5
- package/browser/index.mjs +5 -5
- package/cjs/document/common/document-node.js +11 -0
- package/cjs/document/data-type/complex-type-base.js +1 -1
- package/cjs/document/data-type/complex-type.js +4 -0
- package/cjs/document/data-type/mapped-type.js +4 -0
- package/cjs/document/data-type/mixin-type.js +4 -6
- package/cjs/document/data-type/union-type.js +84 -0
- package/cjs/document/factory/data-type.factory.js +45 -0
- package/cjs/document/index.js +1 -0
- package/cjs/schema/data-type/union-type.interface.js +7 -0
- package/cjs/schema/opra-schema.js +1 -0
- package/cjs/schema/type-guards.js +7 -1
- package/esm/document/common/document-node.js +11 -0
- package/esm/document/data-type/complex-type-base.js +1 -1
- package/esm/document/data-type/complex-type.js +4 -0
- package/esm/document/data-type/mapped-type.js +4 -0
- package/esm/document/data-type/mixin-type.js +4 -6
- package/esm/document/data-type/union-type.js +81 -0
- package/esm/document/factory/data-type.factory.js +45 -0
- package/esm/document/index.js +1 -0
- package/esm/schema/data-type/union-type.interface.js +4 -0
- package/esm/schema/opra-schema.js +1 -0
- package/esm/schema/type-guards.js +6 -1
- package/package.json +7 -4
- package/types/document/common/document-node.d.ts +7 -0
- package/types/document/data-type/complex-type.d.ts +3 -1
- package/types/document/data-type/mapped-type.d.ts +2 -0
- package/types/document/data-type/mixin-type.d.ts +22 -12
- package/types/document/data-type/union-type.d.ts +73 -0
- package/types/document/factory/data-type.factory.d.ts +12 -2
- package/types/document/index.d.ts +1 -0
- package/types/schema/data-type/complex-type.interface.d.ts +2 -0
- package/types/schema/data-type/data-type.interface.d.ts +3 -2
- package/types/schema/data-type/field.interface.d.ts +4 -0
- package/types/schema/data-type/mapped-type.interface.d.ts +2 -0
- package/types/schema/data-type/union-type.interface.d.ts +15 -0
- package/types/schema/opra-schema.d.ts +1 -0
- package/types/schema/type-guards.d.ts +2 -0
|
@@ -119,5 +119,16 @@ class DocumentNode {
|
|
|
119
119
|
return t;
|
|
120
120
|
throw new TypeError(`Data type "${t.name || t}" is not a MixinType`);
|
|
121
121
|
}
|
|
122
|
+
/**
|
|
123
|
+
* Returns EnumType instance by name or Constructor.
|
|
124
|
+
* Returns undefined if not found
|
|
125
|
+
* Throws error if data type is not a UnionType
|
|
126
|
+
*/
|
|
127
|
+
getUnionType(nameOrCtor, scope) {
|
|
128
|
+
const t = this.getDataType(nameOrCtor, scope);
|
|
129
|
+
if (t.kind === index_js_1.OpraSchema.UnionType.Kind)
|
|
130
|
+
return t;
|
|
131
|
+
throw new TypeError(`Data type "${t.name || t}" is not a MixinType`);
|
|
132
|
+
}
|
|
122
133
|
}
|
|
123
134
|
exports.DocumentNode = DocumentNode;
|
|
@@ -285,7 +285,7 @@ class ComplexTypeBaseClass extends data_type_js_1.DataType {
|
|
|
285
285
|
_generateFieldCodec(codec, field, context) {
|
|
286
286
|
let fn = field.type.generateCodec(codec, context);
|
|
287
287
|
if (field.fixed)
|
|
288
|
-
fn = valgen_1.vg.
|
|
288
|
+
fn = valgen_1.vg.isEqual(field.fixed);
|
|
289
289
|
if (field.isArray)
|
|
290
290
|
fn = valgen_1.vg.isArray(fn);
|
|
291
291
|
return fn;
|
|
@@ -24,6 +24,8 @@ exports.ComplexType = function (...args) {
|
|
|
24
24
|
complex_type_base_js_1.ComplexTypeBase.call(this, owner, initArgs, context);
|
|
25
25
|
const _this = (0, ts_gems_1.asMutable)(this);
|
|
26
26
|
_this.kind = index_js_1.OpraSchema.ComplexType.Kind;
|
|
27
|
+
_this.discriminatorField = initArgs.discriminatorField;
|
|
28
|
+
_this.discriminatorValue = initArgs.discriminatorValue;
|
|
27
29
|
if (initArgs.base) {
|
|
28
30
|
context.enter('.base', () => {
|
|
29
31
|
// noinspection SuspiciousTypeOfGuard
|
|
@@ -84,6 +86,8 @@ class ComplexTypeClass extends complex_type_base_js_1.ComplexTypeBase {
|
|
|
84
86
|
? baseName
|
|
85
87
|
: this.base.toJSON(options)
|
|
86
88
|
: undefined,
|
|
89
|
+
discriminatorField: this.discriminatorField,
|
|
90
|
+
discriminatorValue: this.discriminatorValue,
|
|
87
91
|
};
|
|
88
92
|
if (this.additionalFields) {
|
|
89
93
|
if (this.additionalFields instanceof data_type_js_1.DataType) {
|
|
@@ -72,6 +72,8 @@ exports.MappedType = function (...args) {
|
|
|
72
72
|
}
|
|
73
73
|
if (initArgs.base.keyField && isInheritedPredicate(initArgs.base.keyField))
|
|
74
74
|
_this.keyField = initArgs.base.keyField;
|
|
75
|
+
_this.discriminatorField = initArgs.base.discriminatorField;
|
|
76
|
+
_this.discriminatorValue = initArgs.base.discriminatorValue;
|
|
75
77
|
}
|
|
76
78
|
};
|
|
77
79
|
/**
|
|
@@ -101,6 +103,8 @@ class MappedTypeClass extends complex_type_base_js_1.ComplexTypeBase {
|
|
|
101
103
|
omit: this.omit,
|
|
102
104
|
partial: this.partial,
|
|
103
105
|
required: this.required,
|
|
106
|
+
discriminatorField: this.discriminatorField,
|
|
107
|
+
discriminatorValue: this.discriminatorValue,
|
|
104
108
|
});
|
|
105
109
|
}
|
|
106
110
|
_locateBase(callback) {
|
|
@@ -15,8 +15,9 @@ const data_type_js_1 = require("./data-type.js");
|
|
|
15
15
|
*/
|
|
16
16
|
exports.MixinType = function (...args) {
|
|
17
17
|
// MixinType factory
|
|
18
|
-
if (!this)
|
|
18
|
+
if (!this) {
|
|
19
19
|
return exports.MixinType[constants_js_1.DECORATOR].apply(undefined, args);
|
|
20
|
+
}
|
|
20
21
|
// Constructor
|
|
21
22
|
const [owner, initArgs, context] = args;
|
|
22
23
|
complex_type_base_js_1.ComplexTypeBase.call(this, owner, initArgs, context);
|
|
@@ -85,12 +86,9 @@ exports.MixinType[constants_js_1.DECORATOR] = MixinTypeFactory;
|
|
|
85
86
|
/**
|
|
86
87
|
*
|
|
87
88
|
*/
|
|
88
|
-
function MixinTypeFactory(
|
|
89
|
+
function MixinTypeFactory(clasRefs, options) {
|
|
89
90
|
// Filter undefined items
|
|
90
|
-
|
|
91
|
-
const options = typeof args[args.length - 1] === 'object'
|
|
92
|
-
? args[args.length - 1]
|
|
93
|
-
: undefined;
|
|
91
|
+
clasRefs = clasRefs.filter(x => typeof x === 'function');
|
|
94
92
|
if (!clasRefs.length)
|
|
95
93
|
throw new TypeError('No Class has been provided');
|
|
96
94
|
if (clasRefs.length === 1)
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UnionType = void 0;
|
|
4
|
+
require("reflect-metadata");
|
|
5
|
+
const objects_1 = require("@jsopen/objects");
|
|
6
|
+
const ts_gems_1 = require("ts-gems");
|
|
7
|
+
const valgen_1 = require("valgen");
|
|
8
|
+
const index_js_1 = require("../../schema/index.js");
|
|
9
|
+
const constants_js_1 = require("../constants.js");
|
|
10
|
+
const data_type_js_1 = require("./data-type.js");
|
|
11
|
+
/**
|
|
12
|
+
* @class UnionType
|
|
13
|
+
*/
|
|
14
|
+
exports.UnionType = function (...args) {
|
|
15
|
+
// UnionType factory
|
|
16
|
+
if (!this) {
|
|
17
|
+
return exports.UnionType[constants_js_1.DECORATOR].apply(undefined, args);
|
|
18
|
+
}
|
|
19
|
+
// Constructor
|
|
20
|
+
const [owner, initArgs, context] = args;
|
|
21
|
+
data_type_js_1.DataType.call(this, owner, initArgs, context);
|
|
22
|
+
const _this = (0, ts_gems_1.asMutable)(this);
|
|
23
|
+
_this.kind = index_js_1.OpraSchema.UnionType.Kind;
|
|
24
|
+
_this.discriminator = initArgs.discriminator;
|
|
25
|
+
_this.types = [];
|
|
26
|
+
for (const base of initArgs.types) {
|
|
27
|
+
_this.types.push(base);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
*
|
|
32
|
+
* @class UnionType
|
|
33
|
+
*/
|
|
34
|
+
class UnionTypeClass extends data_type_js_1.DataType {
|
|
35
|
+
toJSON(options) {
|
|
36
|
+
const superJson = super.toJSON(options);
|
|
37
|
+
return (0, objects_1.omitUndefined)({
|
|
38
|
+
...superJson,
|
|
39
|
+
kind: this.kind,
|
|
40
|
+
discriminator: this.discriminator,
|
|
41
|
+
types: this.types.map(base => {
|
|
42
|
+
const baseName = this.node.getDataTypeNameWithNs(base);
|
|
43
|
+
return baseName ? baseName : base.toJSON(options);
|
|
44
|
+
}),
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
generateCodec(codec, options) {
|
|
48
|
+
const codecs = this.types.map(t => {
|
|
49
|
+
const fn = t.generateCodec(codec, options);
|
|
50
|
+
if ((t.kind === index_js_1.OpraSchema.ComplexType.Kind ||
|
|
51
|
+
t.kind === index_js_1.OpraSchema.MappedType.Kind) &&
|
|
52
|
+
t.discriminatorField) {
|
|
53
|
+
return [
|
|
54
|
+
fn,
|
|
55
|
+
{ [t.discriminatorField]: valgen_1.vg.isEqual(t.discriminatorValue) },
|
|
56
|
+
];
|
|
57
|
+
}
|
|
58
|
+
return fn;
|
|
59
|
+
});
|
|
60
|
+
return valgen_1.vg.oneOf(codecs);
|
|
61
|
+
}
|
|
62
|
+
extendsFrom() {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
_locateBase() {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
exports.UnionType.prototype = UnionTypeClass.prototype;
|
|
70
|
+
exports.UnionType[constants_js_1.DECORATOR] = UnionTypeFactory;
|
|
71
|
+
/**
|
|
72
|
+
*
|
|
73
|
+
*/
|
|
74
|
+
function UnionTypeFactory(clasRefs, options) {
|
|
75
|
+
class UnionClass {
|
|
76
|
+
}
|
|
77
|
+
const metadata = {
|
|
78
|
+
...options,
|
|
79
|
+
kind: index_js_1.OpraSchema.UnionType.Kind,
|
|
80
|
+
types: clasRefs,
|
|
81
|
+
};
|
|
82
|
+
Reflect.defineMetadata(constants_js_1.DATATYPE_METADATA, metadata, UnionClass);
|
|
83
|
+
return UnionClass;
|
|
84
|
+
}
|
|
@@ -12,6 +12,7 @@ const enum_type_js_1 = require("../data-type/enum-type.js");
|
|
|
12
12
|
const mapped_type_js_1 = require("../data-type/mapped-type.js");
|
|
13
13
|
const mixin_type_js_1 = require("../data-type/mixin-type.js");
|
|
14
14
|
const simple_type_js_1 = require("../data-type/simple-type.js");
|
|
15
|
+
const union_type_js_1 = require("../data-type/union-type.js");
|
|
15
16
|
const initializingSymbol = Symbol('initializing');
|
|
16
17
|
/**
|
|
17
18
|
*
|
|
@@ -266,6 +267,9 @@ class DataTypeFactory {
|
|
|
266
267
|
out.ctor = ctor;
|
|
267
268
|
await this._prepareSimpleTypeArgs(context, owner, out, metadata);
|
|
268
269
|
break;
|
|
270
|
+
case index_js_2.OpraSchema.UnionType.Kind:
|
|
271
|
+
await this._prepareUnionTypeArgs(context, owner, out, metadata);
|
|
272
|
+
break;
|
|
269
273
|
default:
|
|
270
274
|
/** istanbul ignore next */
|
|
271
275
|
return context.addError(`Invalid data type kind ${metadata.kind}`);
|
|
@@ -288,6 +292,8 @@ class DataTypeFactory {
|
|
|
288
292
|
static async _prepareComplexTypeArgs(context, owner, initArgs, metadata) {
|
|
289
293
|
await this._prepareDataTypeArgs(context, initArgs, metadata);
|
|
290
294
|
initArgs.keyField = metadata.keyField;
|
|
295
|
+
initArgs.discriminatorField = metadata.discriminatorField;
|
|
296
|
+
initArgs.discriminatorValue = metadata.discriminatorValue;
|
|
291
297
|
await context.enterAsync('.base', async () => {
|
|
292
298
|
let baseArgs;
|
|
293
299
|
if (metadata.base) {
|
|
@@ -384,6 +390,8 @@ class DataTypeFactory {
|
|
|
384
390
|
}
|
|
385
391
|
static async _prepareMappedTypeArgs(context, owner, initArgs, metadata) {
|
|
386
392
|
await this._prepareDataTypeArgs(context, initArgs, metadata);
|
|
393
|
+
initArgs.discriminatorField = metadata.discriminatorField;
|
|
394
|
+
initArgs.discriminatorValue = metadata.discriminatorValue;
|
|
387
395
|
await context.enterAsync('.base', async () => {
|
|
388
396
|
let baseArgs;
|
|
389
397
|
if (metadata.base) {
|
|
@@ -431,6 +439,22 @@ class DataTypeFactory {
|
|
|
431
439
|
}
|
|
432
440
|
});
|
|
433
441
|
}
|
|
442
|
+
static async _prepareUnionTypeArgs(context, owner, initArgs, metadata) {
|
|
443
|
+
await this._prepareDataTypeArgs(context, initArgs, metadata);
|
|
444
|
+
initArgs.types = [];
|
|
445
|
+
await context.enterAsync('.types', async () => {
|
|
446
|
+
const _initTypes = metadata.types;
|
|
447
|
+
let i = 0;
|
|
448
|
+
for (const t of _initTypes) {
|
|
449
|
+
await context.enterAsync(`[${i++}]`, async () => {
|
|
450
|
+
const baseArgs = await this._importDataTypeArgs(context, owner, t);
|
|
451
|
+
if (!baseArgs)
|
|
452
|
+
return;
|
|
453
|
+
initArgs.types.push(preferName(baseArgs));
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
});
|
|
457
|
+
}
|
|
434
458
|
static _createDataType(context, owner, args) {
|
|
435
459
|
let dataType = owner.node.findDataType(typeof args === 'string' ? args : args.name || '');
|
|
436
460
|
if (dataType instanceof data_type_js_1.DataType)
|
|
@@ -455,6 +479,8 @@ class DataTypeFactory {
|
|
|
455
479
|
return this._createMixinType(context, owner, initArgs);
|
|
456
480
|
case index_js_2.OpraSchema.SimpleType.Kind:
|
|
457
481
|
return this._createSimpleType(context, owner, initArgs);
|
|
482
|
+
case index_js_2.OpraSchema.UnionType.Kind:
|
|
483
|
+
return this._createUnionType(context, owner, initArgs);
|
|
458
484
|
default:
|
|
459
485
|
break;
|
|
460
486
|
}
|
|
@@ -562,6 +588,25 @@ class DataTypeFactory {
|
|
|
562
588
|
simple_type_js_1.SimpleType.apply(dataType, [owner, initArgs]);
|
|
563
589
|
return dataType;
|
|
564
590
|
}
|
|
591
|
+
static _createUnionType(context, owner, args) {
|
|
592
|
+
const dataType = args._instance || {};
|
|
593
|
+
Object.setPrototypeOf(dataType, union_type_js_1.UnionType.prototype);
|
|
594
|
+
const initArgs = (0, index_js_1.cloneObject)(args);
|
|
595
|
+
if (args.types) {
|
|
596
|
+
context.enter('.types', () => {
|
|
597
|
+
initArgs.types = [];
|
|
598
|
+
let i = 0;
|
|
599
|
+
for (const t of args.types) {
|
|
600
|
+
context.enter(`[${i++}]`, () => {
|
|
601
|
+
const base = this._createDataType(context, owner, t);
|
|
602
|
+
initArgs.types.push(base);
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
});
|
|
606
|
+
}
|
|
607
|
+
union_type_js_1.UnionType.apply(dataType, [owner, initArgs]);
|
|
608
|
+
return dataType;
|
|
609
|
+
}
|
|
565
610
|
}
|
|
566
611
|
exports.DataTypeFactory = DataTypeFactory;
|
|
567
612
|
function preferName(initArgs) {
|
package/cjs/document/index.js
CHANGED
|
@@ -37,6 +37,7 @@ tslib_1.__exportStar(require("./data-type/pick-type.js"), exports);
|
|
|
37
37
|
tslib_1.__exportStar(require("./data-type/primitive-types/index.js"), exports);
|
|
38
38
|
tslib_1.__exportStar(require("./data-type/required-type.js"), exports);
|
|
39
39
|
tslib_1.__exportStar(require("./data-type/simple-type.js"), exports);
|
|
40
|
+
tslib_1.__exportStar(require("./data-type/union-type.js"), exports);
|
|
40
41
|
tslib_1.__exportStar(require("./factory/api-document.factory.js"), exports);
|
|
41
42
|
tslib_1.__exportStar(require("./http/http-api.js"), exports);
|
|
42
43
|
tslib_1.__exportStar(require("./http/http-controller.js"), exports);
|
|
@@ -10,6 +10,7 @@ tslib_1.__exportStar(require("./data-type/field.interface.js"), exports);
|
|
|
10
10
|
tslib_1.__exportStar(require("./data-type/mapped-type.interface.js"), exports);
|
|
11
11
|
tslib_1.__exportStar(require("./data-type/mixin-type.interface.js"), exports);
|
|
12
12
|
tslib_1.__exportStar(require("./data-type/simple-type.interface.js"), exports);
|
|
13
|
+
tslib_1.__exportStar(require("./data-type/union-type.interface.js"), exports);
|
|
13
14
|
tslib_1.__exportStar(require("./data-type-container.interface.js"), exports);
|
|
14
15
|
tslib_1.__exportStar(require("./http/http-controller.interface.js"), exports);
|
|
15
16
|
tslib_1.__exportStar(require("./http/http-media-type.interface.js"), exports);
|
|
@@ -6,12 +6,14 @@ exports.isSimpleType = isSimpleType;
|
|
|
6
6
|
exports.isMixinType = isMixinType;
|
|
7
7
|
exports.isMappedType = isMappedType;
|
|
8
8
|
exports.isEnumType = isEnumType;
|
|
9
|
+
exports.isUnionType = isUnionType;
|
|
9
10
|
exports.isHttpController = isHttpController;
|
|
10
11
|
const complex_type_interface_js_1 = require("./data-type/complex-type.interface.js");
|
|
11
12
|
const enum_type_interface_js_1 = require("./data-type/enum-type.interface.js");
|
|
12
13
|
const mapped_type_interface_js_1 = require("./data-type/mapped-type.interface.js");
|
|
13
14
|
const mixin_type_interface_js_1 = require("./data-type/mixin-type.interface.js");
|
|
14
15
|
const simple_type_interface_js_1 = require("./data-type/simple-type.interface.js");
|
|
16
|
+
const union_type_interface_js_1 = require("./data-type/union-type.interface.js");
|
|
15
17
|
const http_controller_interface_js_1 = require("./http/http-controller.interface.js");
|
|
16
18
|
function isDataType(obj) {
|
|
17
19
|
return (obj &&
|
|
@@ -20,7 +22,8 @@ function isDataType(obj) {
|
|
|
20
22
|
obj.kind === enum_type_interface_js_1.EnumType.Kind ||
|
|
21
23
|
obj.kind === mapped_type_interface_js_1.MappedType.Kind ||
|
|
22
24
|
obj.kind === simple_type_interface_js_1.SimpleType.Kind ||
|
|
23
|
-
obj.kind === mixin_type_interface_js_1.MixinType.Kind
|
|
25
|
+
obj.kind === mixin_type_interface_js_1.MixinType.Kind ||
|
|
26
|
+
obj.kind === union_type_interface_js_1.UnionType.Kind));
|
|
24
27
|
}
|
|
25
28
|
function isComplexType(obj) {
|
|
26
29
|
return obj && typeof obj === 'object' && obj.kind === complex_type_interface_js_1.ComplexType.Kind;
|
|
@@ -37,6 +40,9 @@ function isMappedType(obj) {
|
|
|
37
40
|
function isEnumType(obj) {
|
|
38
41
|
return obj && typeof obj === 'object' && obj.kind === enum_type_interface_js_1.EnumType.Kind;
|
|
39
42
|
}
|
|
43
|
+
function isUnionType(obj) {
|
|
44
|
+
return obj && typeof obj === 'object' && obj.kind === union_type_interface_js_1.UnionType.Kind;
|
|
45
|
+
}
|
|
40
46
|
function isHttpController(obj) {
|
|
41
47
|
return obj && typeof obj === 'object' && obj.kind === http_controller_interface_js_1.HttpController.Kind;
|
|
42
48
|
}
|
|
@@ -116,4 +116,15 @@ export class DocumentNode {
|
|
|
116
116
|
return t;
|
|
117
117
|
throw new TypeError(`Data type "${t.name || t}" is not a MixinType`);
|
|
118
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* Returns EnumType instance by name or Constructor.
|
|
121
|
+
* Returns undefined if not found
|
|
122
|
+
* Throws error if data type is not a UnionType
|
|
123
|
+
*/
|
|
124
|
+
getUnionType(nameOrCtor, scope) {
|
|
125
|
+
const t = this.getDataType(nameOrCtor, scope);
|
|
126
|
+
if (t.kind === OpraSchema.UnionType.Kind)
|
|
127
|
+
return t;
|
|
128
|
+
throw new TypeError(`Data type "${t.name || t}" is not a MixinType`);
|
|
129
|
+
}
|
|
119
130
|
}
|
|
@@ -282,7 +282,7 @@ class ComplexTypeBaseClass extends DataType {
|
|
|
282
282
|
_generateFieldCodec(codec, field, context) {
|
|
283
283
|
let fn = field.type.generateCodec(codec, context);
|
|
284
284
|
if (field.fixed)
|
|
285
|
-
fn = vg.
|
|
285
|
+
fn = vg.isEqual(field.fixed);
|
|
286
286
|
if (field.isArray)
|
|
287
287
|
fn = vg.isArray(fn);
|
|
288
288
|
return fn;
|
|
@@ -21,6 +21,8 @@ export const ComplexType = function (...args) {
|
|
|
21
21
|
ComplexTypeBase.call(this, owner, initArgs, context);
|
|
22
22
|
const _this = asMutable(this);
|
|
23
23
|
_this.kind = OpraSchema.ComplexType.Kind;
|
|
24
|
+
_this.discriminatorField = initArgs.discriminatorField;
|
|
25
|
+
_this.discriminatorValue = initArgs.discriminatorValue;
|
|
24
26
|
if (initArgs.base) {
|
|
25
27
|
context.enter('.base', () => {
|
|
26
28
|
// noinspection SuspiciousTypeOfGuard
|
|
@@ -81,6 +83,8 @@ class ComplexTypeClass extends ComplexTypeBase {
|
|
|
81
83
|
? baseName
|
|
82
84
|
: this.base.toJSON(options)
|
|
83
85
|
: undefined,
|
|
86
|
+
discriminatorField: this.discriminatorField,
|
|
87
|
+
discriminatorValue: this.discriminatorValue,
|
|
84
88
|
};
|
|
85
89
|
if (this.additionalFields) {
|
|
86
90
|
if (this.additionalFields instanceof DataType) {
|
|
@@ -69,6 +69,8 @@ export const MappedType = function (...args) {
|
|
|
69
69
|
}
|
|
70
70
|
if (initArgs.base.keyField && isInheritedPredicate(initArgs.base.keyField))
|
|
71
71
|
_this.keyField = initArgs.base.keyField;
|
|
72
|
+
_this.discriminatorField = initArgs.base.discriminatorField;
|
|
73
|
+
_this.discriminatorValue = initArgs.base.discriminatorValue;
|
|
72
74
|
}
|
|
73
75
|
};
|
|
74
76
|
/**
|
|
@@ -98,6 +100,8 @@ class MappedTypeClass extends ComplexTypeBase {
|
|
|
98
100
|
omit: this.omit,
|
|
99
101
|
partial: this.partial,
|
|
100
102
|
required: this.required,
|
|
103
|
+
discriminatorField: this.discriminatorField,
|
|
104
|
+
discriminatorValue: this.discriminatorValue,
|
|
101
105
|
});
|
|
102
106
|
}
|
|
103
107
|
_locateBase(callback) {
|
|
@@ -12,8 +12,9 @@ import { DataType } from './data-type.js';
|
|
|
12
12
|
*/
|
|
13
13
|
export const MixinType = function (...args) {
|
|
14
14
|
// MixinType factory
|
|
15
|
-
if (!this)
|
|
15
|
+
if (!this) {
|
|
16
16
|
return MixinType[DECORATOR].apply(undefined, args);
|
|
17
|
+
}
|
|
17
18
|
// Constructor
|
|
18
19
|
const [owner, initArgs, context] = args;
|
|
19
20
|
ComplexTypeBase.call(this, owner, initArgs, context);
|
|
@@ -82,12 +83,9 @@ MixinType[DECORATOR] = MixinTypeFactory;
|
|
|
82
83
|
/**
|
|
83
84
|
*
|
|
84
85
|
*/
|
|
85
|
-
function MixinTypeFactory(
|
|
86
|
+
function MixinTypeFactory(clasRefs, options) {
|
|
86
87
|
// Filter undefined items
|
|
87
|
-
|
|
88
|
-
const options = typeof args[args.length - 1] === 'object'
|
|
89
|
-
? args[args.length - 1]
|
|
90
|
-
: undefined;
|
|
88
|
+
clasRefs = clasRefs.filter(x => typeof x === 'function');
|
|
91
89
|
if (!clasRefs.length)
|
|
92
90
|
throw new TypeError('No Class has been provided');
|
|
93
91
|
if (clasRefs.length === 1)
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { omitUndefined } from '@jsopen/objects';
|
|
3
|
+
import { asMutable } from 'ts-gems';
|
|
4
|
+
import { vg } from 'valgen';
|
|
5
|
+
import { OpraSchema } from '../../schema/index.js';
|
|
6
|
+
import { DATATYPE_METADATA, DECORATOR } from '../constants.js';
|
|
7
|
+
import { DataType } from './data-type.js';
|
|
8
|
+
/**
|
|
9
|
+
* @class UnionType
|
|
10
|
+
*/
|
|
11
|
+
export const UnionType = function (...args) {
|
|
12
|
+
// UnionType factory
|
|
13
|
+
if (!this) {
|
|
14
|
+
return UnionType[DECORATOR].apply(undefined, args);
|
|
15
|
+
}
|
|
16
|
+
// Constructor
|
|
17
|
+
const [owner, initArgs, context] = args;
|
|
18
|
+
DataType.call(this, owner, initArgs, context);
|
|
19
|
+
const _this = asMutable(this);
|
|
20
|
+
_this.kind = OpraSchema.UnionType.Kind;
|
|
21
|
+
_this.discriminator = initArgs.discriminator;
|
|
22
|
+
_this.types = [];
|
|
23
|
+
for (const base of initArgs.types) {
|
|
24
|
+
_this.types.push(base);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
*
|
|
29
|
+
* @class UnionType
|
|
30
|
+
*/
|
|
31
|
+
class UnionTypeClass extends DataType {
|
|
32
|
+
toJSON(options) {
|
|
33
|
+
const superJson = super.toJSON(options);
|
|
34
|
+
return omitUndefined({
|
|
35
|
+
...superJson,
|
|
36
|
+
kind: this.kind,
|
|
37
|
+
discriminator: this.discriminator,
|
|
38
|
+
types: this.types.map(base => {
|
|
39
|
+
const baseName = this.node.getDataTypeNameWithNs(base);
|
|
40
|
+
return baseName ? baseName : base.toJSON(options);
|
|
41
|
+
}),
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
generateCodec(codec, options) {
|
|
45
|
+
const codecs = this.types.map(t => {
|
|
46
|
+
const fn = t.generateCodec(codec, options);
|
|
47
|
+
if ((t.kind === OpraSchema.ComplexType.Kind ||
|
|
48
|
+
t.kind === OpraSchema.MappedType.Kind) &&
|
|
49
|
+
t.discriminatorField) {
|
|
50
|
+
return [
|
|
51
|
+
fn,
|
|
52
|
+
{ [t.discriminatorField]: vg.isEqual(t.discriminatorValue) },
|
|
53
|
+
];
|
|
54
|
+
}
|
|
55
|
+
return fn;
|
|
56
|
+
});
|
|
57
|
+
return vg.oneOf(codecs);
|
|
58
|
+
}
|
|
59
|
+
extendsFrom() {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
_locateBase() {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
UnionType.prototype = UnionTypeClass.prototype;
|
|
67
|
+
UnionType[DECORATOR] = UnionTypeFactory;
|
|
68
|
+
/**
|
|
69
|
+
*
|
|
70
|
+
*/
|
|
71
|
+
function UnionTypeFactory(clasRefs, options) {
|
|
72
|
+
class UnionClass {
|
|
73
|
+
}
|
|
74
|
+
const metadata = {
|
|
75
|
+
...options,
|
|
76
|
+
kind: OpraSchema.UnionType.Kind,
|
|
77
|
+
types: clasRefs,
|
|
78
|
+
};
|
|
79
|
+
Reflect.defineMetadata(DATATYPE_METADATA, metadata, UnionClass);
|
|
80
|
+
return UnionClass;
|
|
81
|
+
}
|
|
@@ -9,6 +9,7 @@ import { EnumType } from '../data-type/enum-type.js';
|
|
|
9
9
|
import { MappedType } from '../data-type/mapped-type.js';
|
|
10
10
|
import { MixinType } from '../data-type/mixin-type.js';
|
|
11
11
|
import { SimpleType } from '../data-type/simple-type.js';
|
|
12
|
+
import { UnionType } from '../data-type/union-type.js';
|
|
12
13
|
const initializingSymbol = Symbol('initializing');
|
|
13
14
|
/**
|
|
14
15
|
*
|
|
@@ -263,6 +264,9 @@ export class DataTypeFactory {
|
|
|
263
264
|
out.ctor = ctor;
|
|
264
265
|
await this._prepareSimpleTypeArgs(context, owner, out, metadata);
|
|
265
266
|
break;
|
|
267
|
+
case OpraSchema.UnionType.Kind:
|
|
268
|
+
await this._prepareUnionTypeArgs(context, owner, out, metadata);
|
|
269
|
+
break;
|
|
266
270
|
default:
|
|
267
271
|
/** istanbul ignore next */
|
|
268
272
|
return context.addError(`Invalid data type kind ${metadata.kind}`);
|
|
@@ -285,6 +289,8 @@ export class DataTypeFactory {
|
|
|
285
289
|
static async _prepareComplexTypeArgs(context, owner, initArgs, metadata) {
|
|
286
290
|
await this._prepareDataTypeArgs(context, initArgs, metadata);
|
|
287
291
|
initArgs.keyField = metadata.keyField;
|
|
292
|
+
initArgs.discriminatorField = metadata.discriminatorField;
|
|
293
|
+
initArgs.discriminatorValue = metadata.discriminatorValue;
|
|
288
294
|
await context.enterAsync('.base', async () => {
|
|
289
295
|
let baseArgs;
|
|
290
296
|
if (metadata.base) {
|
|
@@ -381,6 +387,8 @@ export class DataTypeFactory {
|
|
|
381
387
|
}
|
|
382
388
|
static async _prepareMappedTypeArgs(context, owner, initArgs, metadata) {
|
|
383
389
|
await this._prepareDataTypeArgs(context, initArgs, metadata);
|
|
390
|
+
initArgs.discriminatorField = metadata.discriminatorField;
|
|
391
|
+
initArgs.discriminatorValue = metadata.discriminatorValue;
|
|
384
392
|
await context.enterAsync('.base', async () => {
|
|
385
393
|
let baseArgs;
|
|
386
394
|
if (metadata.base) {
|
|
@@ -428,6 +436,22 @@ export class DataTypeFactory {
|
|
|
428
436
|
}
|
|
429
437
|
});
|
|
430
438
|
}
|
|
439
|
+
static async _prepareUnionTypeArgs(context, owner, initArgs, metadata) {
|
|
440
|
+
await this._prepareDataTypeArgs(context, initArgs, metadata);
|
|
441
|
+
initArgs.types = [];
|
|
442
|
+
await context.enterAsync('.types', async () => {
|
|
443
|
+
const _initTypes = metadata.types;
|
|
444
|
+
let i = 0;
|
|
445
|
+
for (const t of _initTypes) {
|
|
446
|
+
await context.enterAsync(`[${i++}]`, async () => {
|
|
447
|
+
const baseArgs = await this._importDataTypeArgs(context, owner, t);
|
|
448
|
+
if (!baseArgs)
|
|
449
|
+
return;
|
|
450
|
+
initArgs.types.push(preferName(baseArgs));
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
});
|
|
454
|
+
}
|
|
431
455
|
static _createDataType(context, owner, args) {
|
|
432
456
|
let dataType = owner.node.findDataType(typeof args === 'string' ? args : args.name || '');
|
|
433
457
|
if (dataType instanceof DataType)
|
|
@@ -452,6 +476,8 @@ export class DataTypeFactory {
|
|
|
452
476
|
return this._createMixinType(context, owner, initArgs);
|
|
453
477
|
case OpraSchema.SimpleType.Kind:
|
|
454
478
|
return this._createSimpleType(context, owner, initArgs);
|
|
479
|
+
case OpraSchema.UnionType.Kind:
|
|
480
|
+
return this._createUnionType(context, owner, initArgs);
|
|
455
481
|
default:
|
|
456
482
|
break;
|
|
457
483
|
}
|
|
@@ -559,6 +585,25 @@ export class DataTypeFactory {
|
|
|
559
585
|
SimpleType.apply(dataType, [owner, initArgs]);
|
|
560
586
|
return dataType;
|
|
561
587
|
}
|
|
588
|
+
static _createUnionType(context, owner, args) {
|
|
589
|
+
const dataType = args._instance || {};
|
|
590
|
+
Object.setPrototypeOf(dataType, UnionType.prototype);
|
|
591
|
+
const initArgs = cloneObject(args);
|
|
592
|
+
if (args.types) {
|
|
593
|
+
context.enter('.types', () => {
|
|
594
|
+
initArgs.types = [];
|
|
595
|
+
let i = 0;
|
|
596
|
+
for (const t of args.types) {
|
|
597
|
+
context.enter(`[${i++}]`, () => {
|
|
598
|
+
const base = this._createDataType(context, owner, t);
|
|
599
|
+
initArgs.types.push(base);
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
});
|
|
603
|
+
}
|
|
604
|
+
UnionType.apply(dataType, [owner, initArgs]);
|
|
605
|
+
return dataType;
|
|
606
|
+
}
|
|
562
607
|
}
|
|
563
608
|
function preferName(initArgs) {
|
|
564
609
|
return typeof initArgs === 'object'
|
package/esm/document/index.js
CHANGED
|
@@ -33,6 +33,7 @@ export * from './data-type/pick-type.js';
|
|
|
33
33
|
export * from './data-type/primitive-types/index.js';
|
|
34
34
|
export * from './data-type/required-type.js';
|
|
35
35
|
export * from './data-type/simple-type.js';
|
|
36
|
+
export * from './data-type/union-type.js';
|
|
36
37
|
export * from './factory/api-document.factory.js';
|
|
37
38
|
export * from './http/http-api.js';
|
|
38
39
|
export * from './http/http-controller.js';
|
|
@@ -7,6 +7,7 @@ export * from './data-type/field.interface.js';
|
|
|
7
7
|
export * from './data-type/mapped-type.interface.js';
|
|
8
8
|
export * from './data-type/mixin-type.interface.js';
|
|
9
9
|
export * from './data-type/simple-type.interface.js';
|
|
10
|
+
export * from './data-type/union-type.interface.js';
|
|
10
11
|
export * from './data-type-container.interface.js';
|
|
11
12
|
export * from './http/http-controller.interface.js';
|
|
12
13
|
export * from './http/http-media-type.interface.js';
|
|
@@ -3,6 +3,7 @@ import { EnumType } from './data-type/enum-type.interface.js';
|
|
|
3
3
|
import { MappedType } from './data-type/mapped-type.interface.js';
|
|
4
4
|
import { MixinType } from './data-type/mixin-type.interface.js';
|
|
5
5
|
import { SimpleType } from './data-type/simple-type.interface.js';
|
|
6
|
+
import { UnionType } from './data-type/union-type.interface.js';
|
|
6
7
|
import { HttpController } from './http/http-controller.interface.js';
|
|
7
8
|
export function isDataType(obj) {
|
|
8
9
|
return (obj &&
|
|
@@ -11,7 +12,8 @@ export function isDataType(obj) {
|
|
|
11
12
|
obj.kind === EnumType.Kind ||
|
|
12
13
|
obj.kind === MappedType.Kind ||
|
|
13
14
|
obj.kind === SimpleType.Kind ||
|
|
14
|
-
obj.kind === MixinType.Kind
|
|
15
|
+
obj.kind === MixinType.Kind ||
|
|
16
|
+
obj.kind === UnionType.Kind));
|
|
15
17
|
}
|
|
16
18
|
export function isComplexType(obj) {
|
|
17
19
|
return obj && typeof obj === 'object' && obj.kind === ComplexType.Kind;
|
|
@@ -28,6 +30,9 @@ export function isMappedType(obj) {
|
|
|
28
30
|
export function isEnumType(obj) {
|
|
29
31
|
return obj && typeof obj === 'object' && obj.kind === EnumType.Kind;
|
|
30
32
|
}
|
|
33
|
+
export function isUnionType(obj) {
|
|
34
|
+
return obj && typeof obj === 'object' && obj.kind === UnionType.Kind;
|
|
35
|
+
}
|
|
31
36
|
export function isHttpController(obj) {
|
|
32
37
|
return obj && typeof obj === 'object' && obj.kind === HttpController.Kind;
|
|
33
38
|
}
|