UNPKG

@opra/common

Version:
82 lines (81 loc) 2.33 kB
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; }