@opra/common
Version:
Opra common package
124 lines (123 loc) • 4.44 kB
JavaScript
;
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;
}