hivest-js
Version:
A simple, fast and minimalist framework for Node.js that allows you to create modular applications with dependency injection using decorators
185 lines • 7.94 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.HttpDelete = exports.HttpPatch = exports.HttpPut = exports.HttpGet = exports.HttpPost = void 0;
exports.Injectable = Injectable;
exports.Register = Register;
exports.Inject = Inject;
exports.Controller = Controller;
exports.Middleware = Middleware;
exports.HttpMiddleware = HttpMiddleware;
exports.EventListener = EventListener;
exports.EventEmitter = EventEmitter;
exports.ErrorHandlerMiddleware = ErrorHandlerMiddleware;
require("reflect-metadata");
const tsyringe_1 = require("tsyringe");
function Injectable() {
return (0, tsyringe_1.injectable)();
}
function Register(token) {
return (target) => {
tsyringe_1.container.registerSingleton(token, target);
return target;
};
}
function Inject(token) {
return (target, propertyKey, parameterIndex) => {
return (0, tsyringe_1.inject)(token)(target, propertyKey, parameterIndex);
};
}
// Controller decorator to define base path for the controller
function Controller(options) {
return (target) => {
// Apply Injectable decorator first
(0, tsyringe_1.injectable)()(target);
// Store the controller path in metadata
Reflect.defineMetadata('controller:path', options.path || '', target);
return target;
};
}
// Middleware decorator to define middleware class where all methods are treated as middleware
function Middleware(options) {
return (target) => {
// Apply Injectable decorator first
(0, tsyringe_1.injectable)()(target);
// Store the middleware path in metadata (optional)
Reflect.defineMetadata('controller:path', options?.path || '', target);
// Mark this class as a middleware class
Reflect.defineMetadata('controller:isMiddleware', true, target);
// Get all method names from the prototype
const methodNames = Object.getOwnPropertyNames(target.prototype).filter((name) => name !== 'constructor' && typeof target.prototype[name] === 'function');
// Create middleware items for all methods that don't already have decorators
const existingItems = Reflect.getMetadata('controller:items', target) || [];
const existingMethodNames = existingItems.map((item) => item.propertyKey);
const newItems = methodNames
.filter((methodName) => !existingMethodNames.includes(methodName))
.map((methodName) => ({
type: 'middleware',
handler: target.prototype[methodName],
propertyKey: methodName,
}));
// Combine existing items with new middleware items
Reflect.defineMetadata('controller:items', [...existingItems, ...newItems], target);
return target;
};
}
// Middleware decorator to define middleware methods within a controller
function HttpMiddleware() {
return (target, propertyKey, descriptor) => {
const items = Reflect.getMetadata('controller:items', target.constructor) || [];
items.push({
type: 'middleware',
handler: descriptor.value,
propertyKey: String(propertyKey),
});
Reflect.defineMetadata('controller:items', items, target.constructor);
return descriptor;
};
}
const createHttpMethodDecorator = (method) => (path) => (target, context, ...args) => {
// Handle new decorator proposal (stage 3)
if (context && typeof context === 'object' && 'name' in context) {
const items = Reflect.getMetadata('controller:items', target.constructor) || [];
items.push({
type: 'route',
method,
path: path || '',
handler: target[context.name],
propertyKey: context.name,
});
Reflect.defineMetadata('controller:items', items, target.constructor);
return target[context.name];
}
// Handle legacy decorator proposal
const propertyKey = context;
const descriptor = args[0];
const items = Reflect.getMetadata('controller:items', target.constructor) || [];
items.push({
type: 'route',
method,
path: path || '',
handler: descriptor?.value || target[propertyKey],
propertyKey: String(propertyKey),
});
Reflect.defineMetadata('controller:items', items, target.constructor);
return descriptor?.value || target[propertyKey];
};
exports.HttpPost = createHttpMethodDecorator('post');
exports.HttpGet = createHttpMethodDecorator('get');
exports.HttpPut = createHttpMethodDecorator('put');
exports.HttpPatch = createHttpMethodDecorator('patch');
exports.HttpDelete = createHttpMethodDecorator('delete');
// Event system decorators
function EventListener(eventName) {
return (target, context, ...args) => {
// Handle new decorator proposal (stage 3)
if (context && typeof context === 'object' && 'name' in context) {
const listeners = Reflect.getMetadata('event:listeners', target.constructor) || [];
listeners.push({
eventName,
handler: target[context.name],
propertyKey: context.name,
});
Reflect.defineMetadata('event:listeners', listeners, target.constructor);
return target[context.name];
}
// Handle legacy decorator proposal
const propertyKey = context;
const descriptor = args[0];
const listeners = Reflect.getMetadata('event:listeners', target.constructor) || [];
listeners.push({
eventName,
handler: descriptor?.value || target[propertyKey],
propertyKey: String(propertyKey),
});
Reflect.defineMetadata('event:listeners', listeners, target.constructor);
return descriptor?.value || target[propertyKey];
};
}
function EventEmitter(eventName) {
return (target, context, ...args) => {
// Handle new decorator proposal (stage 3)
if (context && typeof context === 'object' && 'name' in context) {
const emitters = Reflect.getMetadata('event:emitters', target.constructor) || [];
emitters.push({
eventName,
propertyKey: context.name,
});
Reflect.defineMetadata('event:emitters', emitters, target.constructor);
return target[context.name];
}
// Handle legacy decorator proposal
const propertyKey = context;
const descriptor = args[0];
const emitters = Reflect.getMetadata('event:emitters', target.constructor) || [];
emitters.push({
eventName,
propertyKey: String(propertyKey),
});
Reflect.defineMetadata('event:emitters', emitters, target.constructor);
return descriptor?.value || target[propertyKey];
};
}
/**
* Decorator para marcar uma classe como middleware de error handler
* O AppModule detecta automaticamente e registra como error handler
*/
function ErrorHandlerMiddleware() {
return (target) => {
// Apply Injectable decorator first
(0, tsyringe_1.injectable)()(target);
// Mark this class as an error handler middleware
Reflect.defineMetadata('controller:isErrorHandler', true, target);
// Get all method names from the prototype
const methodNames = Object.getOwnPropertyNames(target.prototype).filter((name) => name !== 'constructor' && typeof target.prototype[name] === 'function');
// Create error handler items for all methods
const errorHandlerItems = methodNames.map((methodName) => ({
type: 'errorHandler',
handler: target.prototype[methodName],
propertyKey: methodName,
}));
// Store error handler items in metadata
Reflect.defineMetadata('controller:errorHandlers', errorHandlerItems, target);
return target;
};
}
//# sourceMappingURL=decorators.js.map