@opra/common
Version:
Opra common package
125 lines (124 loc) • 4.37 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.EnumType = void 0;
require("reflect-metadata");
const objects_1 = require("@jsopen/objects");
const ts_gems_1 = require("ts-gems");
const valgen_1 = require("valgen");
const index_js_1 = require("../../helpers/index.js");
const index_js_2 = require("../../schema/index.js");
const constants_js_1 = require("../constants.js");
const data_type_js_1 = require("./data-type.js");
/**
* @class EnumType
*/
exports.EnumType = function (...args) {
// Injector
if (!this)
return exports.EnumType[constants_js_1.DECORATOR].apply(undefined, args);
// Constructor
const [owner, initArgs, context] = args;
data_type_js_1.DataType.call(this, owner, initArgs, context);
const _this = (0, ts_gems_1.asMutable)(this);
_this.kind = index_js_2.OpraSchema.EnumType.Kind;
if (initArgs.base) {
// noinspection SuspiciousTypeOfGuard
if (!(initArgs.base instanceof exports.EnumType)) {
throw new TypeError(`"${initArgs.base.kind}" can't be set as base for a "${_this.kind}"`);
}
_this.base = initArgs.base;
}
_this.instance = initArgs.instance;
_this.ownAttributes = (0, index_js_1.cloneObject)(initArgs.attributes || {});
_this.attributes = _this.base ? (0, index_js_1.cloneObject)(_this.base.attributes) : {};
for (const [k, el] of Object.entries(_this.ownAttributes)) {
_this.attributes[k] = el;
}
};
/**
* @class EnumType
*/
class EnumTypeClass extends data_type_js_1.DataType {
extendsFrom(baseType) {
if (!(baseType instanceof data_type_js_1.DataType))
baseType = this.node.getDataType(baseType);
if (!(baseType instanceof exports.EnumType))
return false;
if (baseType === this)
return true;
return !!this.base?.extendsFrom(baseType);
}
generateCodec() {
return valgen_1.vg.isEnum(Object.keys(this.attributes));
}
toJSON(options) {
const superJson = super.toJSON(options);
const baseName = this.base
? this.node.getDataTypeNameWithNs(this.base)
: undefined;
return (0, objects_1.omitUndefined)({
...superJson,
kind: this.kind,
base: baseName,
attributes: (0, index_js_1.cloneObject)(this.ownAttributes),
});
}
_locateBase(callback) {
if (!this.base)
return;
if (callback(this.base))
return this.base;
if (this.base._locateBase)
return this.base._locateBase(callback);
}
}
exports.EnumType.prototype = EnumTypeClass.prototype;
Object.assign(exports.EnumType, EnumTypeClass);
/**
*
*/
function EnumTypeFactory(enumSource, ...args) {
const base = args.length >= 2 ? args[0] : undefined;
const options = args.length >= 2 ? args[1] : args[0];
let attributes = {};
let out = enumSource;
if (Array.isArray(enumSource)) {
if (base) {
if (!Array.isArray(base))
throw new TypeError('Both "target" and "base" arguments should be array');
out = [...base, ...enumSource];
}
attributes = {};
enumSource.forEach(k => {
const description = options?.meanings?.[k];
attributes[k] = (0, objects_1.omitUndefined)({ description });
});
}
else {
if (base) {
if (Array.isArray(base))
throw new TypeError('Both "target" and "base" arguments should be enum object');
out = { ...base, ...enumSource };
}
Object.keys(enumSource).forEach(k => {
const description = options?.meanings?.[k];
attributes[enumSource[k]] = (0, objects_1.omitUndefined)({ alias: k, description });
});
}
const metadata = {
kind: index_js_2.OpraSchema.EnumType.Kind,
attributes,
base: options?.base,
name: options?.name,
description: options?.description,
};
Object.defineProperty(enumSource, constants_js_1.DATATYPE_METADATA, {
value: metadata,
enumerable: false,
configurable: true,
writable: true,
});
return out;
}
exports.EnumType.prototype = EnumTypeClass.prototype;
exports.EnumType[constants_js_1.DECORATOR] = EnumTypeFactory;