stratakit
Version:
stratakit - Meta-framework React puro con Auto Router automático, file-based routing, SEO automático y performance superior
214 lines (213 loc) • 6.44 kB
JavaScript
export class MiddlewareManager {
middlewares = new Map();
/**
* Registrar middleware
*/
register(name, middleware) {
this.middlewares.set(name, middleware);
}
/**
* Ejecutar middlewares en secuencia
*/
async execute(middlewareNames, context) {
let currentContext = { ...context };
let index = 0;
const next = async () => {
if (index >= middlewareNames.length) {
return { success: true, data: currentContext.data };
}
const middlewareName = middlewareNames[index++];
const middleware = this.middlewares.get(middlewareName);
if (!middleware) {
throw new Error(`Middleware '${middlewareName}' not found`);
}
try {
const result = await middleware(currentContext, next);
if (result.abort) {
return result;
}
if (result.redirect) {
return result;
}
if (result.data) {
currentContext.data = { ...currentContext.data, ...result.data };
}
return result;
}
catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error'
};
}
};
return next();
}
/**
* Obtener middleware por nombre
*/
get(name) {
return this.middlewares.get(name);
}
/**
* Listar todos los middlewares
*/
list() {
return Array.from(this.middlewares.keys());
}
/**
* Eliminar middleware
*/
remove(name) {
return this.middlewares.delete(name);
}
}
// Instancia global del manager
export const middlewareManager = new MiddlewareManager();
// ============================================================================
// MIDDLEWARES PREDEFINIDOS
// ============================================================================
/**
* Middleware de autenticación
*/
export const authMiddleware = async (context, next) => {
if (!context.isAuthenticated) {
return {
success: false,
redirect: '/login',
error: 'Authentication required'
};
}
return next();
};
/**
* Middleware de autorización
*/
export const createPermissionMiddleware = (requiredPermissions) => {
return async (context, next) => {
const hasPermission = requiredPermissions.every(permission => context.permissions.includes(permission));
if (!hasPermission) {
return {
success: false,
redirect: '/unauthorized',
error: 'Insufficient permissions'
};
}
return next();
};
};
/**
* Middleware de rate limiting
*/
export const createRateLimitMiddleware = (maxRequests, windowMs) => {
const requests = new Map();
return async (context, next) => {
const key = context.path;
const now = Date.now();
const record = requests.get(key);
if (!record || now > record.resetTime) {
requests.set(key, { count: 1, resetTime: now + windowMs });
return next();
}
if (record.count >= maxRequests) {
return {
success: false,
error: 'Rate limit exceeded',
abort: true
};
}
record.count++;
return next();
};
};
/**
* Middleware de validación de datos
*/
export const createValidationMiddleware = (schema) => {
return async (context, next) => {
try {
// Aquí implementarías la validación con tu librería preferida
// Por ejemplo, con Zod, Joi, Yup, etc.
const isValid = true; // Placeholder
if (!isValid) {
return {
success: false,
error: 'Validation failed',
abort: true
};
}
return next();
}
catch (error) {
return {
success: false,
error: 'Validation error',
abort: true
};
}
};
};
/**
* Middleware de logging
*/
export const loggingMiddleware = async (context, next) => {
const startTime = Date.now();
console.log(`[${new Date().toISOString()}] ${context.path} - Starting middleware chain`);
const result = await next();
const duration = Date.now() - startTime;
console.log(`[${new Date().toISOString()}] ${context.path} - Completed in ${duration}ms`);
return result;
};
/**
* Middleware de cache
*/
export const createCacheMiddleware = (ttl = 300000) => {
const cache = new Map();
return async (context, next) => {
const key = `${context.path}:${JSON.stringify(context.query)}`;
const cached = cache.get(key);
if (cached && Date.now() < cached.expires) {
return {
success: true,
data: cached.data
};
}
const result = await next();
if (result.success && result.data) {
cache.set(key, {
data: result.data,
expires: Date.now() + ttl
});
}
return result;
};
};
/**
* Middleware de CORS
*/
export const corsMiddleware = async (context, next) => {
// Aquí implementarías la lógica de CORS
// Por ahora es un placeholder
return next();
};
/**
* Middleware de seguridad
*/
export const securityMiddleware = async (context, next) => {
// Verificar headers de seguridad
const securityHeaders = {
'X-Content-Type-Options': 'nosniff',
'X-Frame-Options': 'DENY',
'X-XSS-Protection': '1; mode=block',
'Referrer-Policy': 'strict-origin-when-cross-origin'
};
// Aquí añadirías los headers a la respuesta
context.data = { ...context.data, headers: securityHeaders };
return next();
};
// Registrar middlewares predefinidos
middlewareManager.register('auth', authMiddleware);
middlewareManager.register('logging', loggingMiddleware);
middlewareManager.register('cors', corsMiddleware);
middlewareManager.register('security', securityMiddleware);
export default middlewareManager;