UNPKG

seyfert

Version:

The most advanced framework for discord bots

91 lines (90 loc) 3.23 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.mix = void 0; exports.Mixin = Mixin; /** * Gets the descriptors of a class. * @param c The class to get the descriptors of. * @returns The descriptors of the class. */ function getDenoDescriptors(c) { const protos = [c.prototype]; let v = c; while ((v = Object.getPrototypeOf(v))) { if (v.prototype) protos.push(v.prototype); } return protos.map(x => Object.getOwnPropertyDescriptors(x)); } /** * Gets the descriptors of a class. * @param c The class to get the descriptors of. * @returns The descriptors of the class. */ function getNodeDescriptors(c) { let proto = c.prototype; const result = []; while (proto) { const descriptors = Object.getOwnPropertyDescriptors(proto); // @ts-expect-error this is not a function in all cases if (descriptors.valueOf.configurable) break; result.push(descriptors); proto = proto.__proto__; } return result; } function getDescriptors(c) { //@ts-expect-error // biome-ignore lint/correctness/noUndeclaredVariables: <explanation> return typeof Deno === 'undefined' ? getNodeDescriptors(c) : getDenoDescriptors(c); } /** * Mixes a class with other classes. * @param args The classes to mix. * @returns The mixed class. */ function Mixin(...args) { const ignoreOverwriteToString = Object.keys(Object.getOwnPropertyDescriptors(args[0].prototype)).includes('toString'); function MixedClass(...constructorArgs) { for (const i of args) { const descriptors = getDescriptors(i).toReversed(); for (const j of descriptors) { // @ts-expect-error Object.assign(this, new j.constructor.value(...constructorArgs)); for (const descriptorK in j) { if (descriptorK === 'constructor') continue; if (descriptorK in MixedClass.prototype && descriptorK !== 'toString') continue; const descriptor = j[descriptorK]; if (descriptor.value) { if (descriptorK === 'toString' && ignoreOverwriteToString) { MixedClass.prototype[descriptorK] = args[0].prototype.toString; continue; } MixedClass.prototype[descriptorK] = descriptor.value; continue; } if (descriptor.get || descriptor.set) { Object.defineProperty(MixedClass.prototype, descriptorK, { get: descriptor.get, set: descriptor.set, }); } } } } } return MixedClass; } const mix = (...ingredients) => (decoratedClass) => { ingredients.unshift(decoratedClass); const mixedClass = Mixin(...ingredients); Object.defineProperty(mixedClass, 'name', { value: decoratedClass.name, writable: false, }); return mixedClass; }; exports.mix = mix;