@itrocks/uses
Version:
Apply reusable mixins to your classes effortlessly with the @Uses decorator
57 lines • 1.98 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Super = Super;
exports.Uses = Uses;
exports.usesOf = usesOf;
const class_type_1 = require("@itrocks/class-type");
const class_1 = require("@itrocks/decorator/class");
function Super(self) {
return Object.getPrototypeOf(Object.getPrototypeOf(self));
}
function uses(target, mixins) {
const builtTarget = (() => class extends target {
constructor(...args) {
super(...args);
for (const mixin of mixins)
this[mixin.name](...args);
}
})();
for (const mixin of mixins) {
const already = ['constructor'];
let proto = mixin.prototype;
while (proto.constructor !== Object) {
for (const [name, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(proto))) {
if (already.includes(name))
continue;
already.push(name);
Object.defineProperty(builtTarget.prototype, name, descriptor);
}
proto = Object.getPrototypeOf(proto);
}
}
for (const mixin of mixins) {
Object.defineProperty(builtTarget.prototype, mixin.name, {
configurable: true,
enumerable: false,
value: function (...args) { Object.assign(this, new mixin(...args)); },
writable: true
});
}
return builtTarget;
}
const USES = Symbol('uses');
function Uses(...mixins) {
return (target) => {
mixins = mixins.concat(usesOf(target));
const builtTarget = uses(target, mixins);
(0, class_1.decorate)(USES, mixins)(builtTarget);
return builtTarget;
};
}
function usesOf(target, resolveBuiltClass = false) {
const usesOf = (0, class_1.ownDecoratorOf)(target, USES, []);
return resolveBuiltClass
? usesOf.map(type => (0, class_type_1.baseType)(type))
: usesOf;
}
//# sourceMappingURL=uses.js.map