@stnekroman/tstools
Version:
Set of handy tools for TypeScript development
57 lines (56 loc) • 2.04 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.applyInstanceDecorators = applyInstanceDecorators;
exports.RunInstanceDecorators = RunInstanceDecorators;
exports.DeferInstanceDecorator = DeferInstanceDecorator;
const DeferInstanceDecoratorsMetadataSymbol = Symbol('DeferInstanceDecoratorsMetadata');
function getDeferInstanceDecoratorsMetadata(target) {
if (target.hasOwnProperty(DeferInstanceDecoratorsMetadataSymbol)) {
return target[DeferInstanceDecoratorsMetadataSymbol];
}
return undefined;
}
function getOrCreateDeferInstanceDecoratorsMetadata(target) {
let metadata;
if (target.hasOwnProperty(DeferInstanceDecoratorsMetadataSymbol)) {
metadata = target[DeferInstanceDecoratorsMetadataSymbol];
}
else {
metadata = {
decorators: [],
};
Object.defineProperty(target, DeferInstanceDecoratorsMetadataSymbol, {
value: metadata,
});
}
return metadata;
}
function applyInstanceDecorators(instance, ctr, metadata = getDeferInstanceDecoratorsMetadata(ctr.prototype)) {
if (metadata) {
for (const [propertyName, decorator] of metadata.decorators) {
decorator(instance, propertyName, Object.getOwnPropertyDescriptor(instance, propertyName));
}
}
}
function RunInstanceDecorators() {
return (ctr) => {
const metadata = getDeferInstanceDecoratorsMetadata(ctr.prototype);
if (!metadata) {
return ctr;
}
const newCtr = class extends ctr {
constructor(...args) {
super(...args);
applyInstanceDecorators(this, ctr, metadata);
}
};
Object.defineProperty(newCtr, 'name', { value: ctr.name });
return newCtr;
};
}
function DeferInstanceDecorator(decorator) {
return (target, propertyName) => {
const metadata = getOrCreateDeferInstanceDecoratorsMetadata(target);
metadata.decorators.push([propertyName, decorator]);
};
}