UNPKG

@opra/common

Version:
124 lines (123 loc) 4.44 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MixinType = void 0; require("reflect-metadata"); const objects_1 = require("@jsopen/objects"); const ts_gems_1 = require("ts-gems"); const index_js_1 = require("../../helpers/index.js"); const index_js_2 = require("../../schema/index.js"); const constants_js_1 = require("../constants.js"); const api_field_js_1 = require("./api-field.js"); const complex_type_base_js_1 = require("./complex-type-base.js"); const data_type_js_1 = require("./data-type.js"); /** * @class MixinType */ exports.MixinType = function (...args) { // MixinType factory if (!this) { return exports.MixinType[constants_js_1.DECORATOR].apply(undefined, args); } // Constructor const [owner, initArgs, context] = args; complex_type_base_js_1.ComplexTypeBase.call(this, owner, initArgs, context); const _this = (0, ts_gems_1.asMutable)(this); _this.kind = index_js_2.OpraSchema.MixinType.Kind; _this.types = []; for (const base of initArgs.types) { if (_this.additionalFields !== true) { if (base.additionalFields === true) _this.additionalFields = true; else if (!_this.additionalFields) _this.additionalFields = base.additionalFields; } for (const v of base.fields('*')) { const field = new api_field_js_1.ApiField(this, v); _this._fields.set(field.name, field); } _this.types.push(base); if (base.keyField) _this.keyField = base.keyField; } }; /** * * @class MixinType */ class MixinTypeClass extends complex_type_base_js_1.ComplexTypeBase { extendsFrom(baseType) { if (!(baseType instanceof data_type_js_1.DataType)) baseType = this.node.getDataType(baseType); if (!(baseType instanceof complex_type_base_js_1.ComplexTypeBase)) return false; if (baseType === this) return true; for (const t of this.types) { if (t.extendsFrom(baseType)) return true; } return false; } toJSON(options) { const superJson = super.toJSON(options); return (0, objects_1.omitUndefined)({ ...superJson, kind: this.kind, types: this.types.map(base => { const baseName = this.node.getDataTypeNameWithNs(base); return baseName ? baseName : base.toJSON(options); }), }); } _locateBase(callback) { for (const t of this.types) { if (callback(t)) return t; if (t._locateBase) { const x = t._locateBase(callback); if (x) return x; } } } } exports.MixinType.prototype = MixinTypeClass.prototype; exports.MixinType[constants_js_1.DECORATOR] = MixinTypeFactory; /** * */ function MixinTypeFactory(clasRefs, options) { // Filter undefined items clasRefs = clasRefs.filter(x => typeof x === 'function'); if (!clasRefs.length) throw new TypeError('No Class has been provided'); if (clasRefs.length === 1) return clasRefs[0]; const className = clasRefs[0].name + 'Mixin'; const MixinClass = { [className]: class { constructor() { for (const c of clasRefs) (0, index_js_1.inheritPropertyInitializers)(this, c); } }, }[className]; const metadata = { ...options, kind: index_js_2.OpraSchema.MixinType.Kind, types: [], }; Reflect.defineMetadata(constants_js_1.DATATYPE_METADATA, metadata, MixinClass); for (const c of clasRefs) { const itemMeta = Reflect.getMetadata(constants_js_1.DATATYPE_METADATA, c); if (!(itemMeta && (itemMeta.kind === index_js_2.OpraSchema.ComplexType.Kind || itemMeta.kind === index_js_2.OpraSchema.MixinType.Kind || itemMeta.kind === index_js_2.OpraSchema.MappedType.Kind))) { throw new TypeError(`Class "${c.name}" is not a ${index_js_2.OpraSchema.ComplexType.Kind}, ${index_js_2.OpraSchema.MixinType.Kind} or ${index_js_2.OpraSchema.MappedType.Kind}`); } metadata.types.push(c); (0, index_js_1.mergePrototype)(MixinClass.prototype, c.prototype); } return MixinClass; }