@opra/common
Version:
Opra common package
82 lines (81 loc) • 2.33 kB
JavaScript
import 'reflect-metadata';
import { omitUndefined } from '@jsopen/objects';
import { asMutable } from 'ts-gems';
import { vg } from 'valgen';
import { OpraSchema } from '../../schema/index.js';
import { DATATYPE_METADATA, DECORATOR } from '../constants.js';
import { DataType } from './data-type.js';
/**
* @class UnionType
*/
export const UnionType = function (...args) {
// UnionType factory
if (!this) {
return UnionType[DECORATOR].apply(undefined, args);
}
// Constructor
const [owner, initArgs, context] = args;
DataType.call(this, owner, initArgs, context);
const _this = asMutable(this);
_this.kind = OpraSchema.UnionType.Kind;
_this.discriminator = initArgs.discriminator;
_this.types = [];
for (const base of initArgs.types) {
_this.types.push(base);
}
};
/**
*
* @class UnionType
*/
class UnionTypeClass extends DataType {
toJSON(options) {
const superJson = super.toJSON(options);
return omitUndefined({
...superJson,
kind: this.kind,
discriminator: this.discriminator,
types: this.types.map(base => {
const baseName = this.node.getDataTypeNameWithNs(base);
return baseName ? baseName : base.toJSON(options);
}),
});
}
generateCodec(codec, options) {
const codecs = this.types.map(t => {
const fn = t.generateCodec(codec, options);
if ((t.kind === OpraSchema.ComplexType.Kind ||
t.kind === OpraSchema.MappedType.Kind) &&
t.discriminatorField) {
return [
fn,
{ [t.discriminatorField]: vg.isEqual(t.discriminatorValue) },
];
}
return fn;
});
return vg.oneOf(codecs);
}
extendsFrom() {
return false;
}
_locateBase() {
return;
}
}
UnionType.prototype = UnionTypeClass.prototype;
UnionType[DECORATOR] = UnionTypeFactory;
/**
*
*/
function UnionTypeFactory(clasRefs, options) {
class UnionClass {
}
const metadata = {
...options,
kind: OpraSchema.UnionType.Kind,
types: clasRefs,
};
Reflect.defineMetadata(DATATYPE_METADATA, metadata, UnionClass);
return UnionClass;
}