import { container } from './container' import { metadataRegistry } from './metadata-registry' import type { ClassConstructor, Scope } from './types' // Global registry for service metadata const serviceRegistry = new Map< ClassConstructor, { scope: Scope autorun: boolean decoratorType: string params: any[] } >() export interface InjectableOptions { scope?: Scope autorun?: boolean } export function Injectable(options: InjectableOptions = {}): ClassDecorator { const { scope = 'singleton', autorun = false } = options return (target: Function): void => { const constructor = target as ClassConstructor serviceRegistry.set(constructor, { scope, autorun, decoratorType: 'service', params: [], }) // Register in container immediately container.register(constructor, scope, autorun, [], 'service') } } export interface ControllerOptions { path?: string version?: string scope?: Scope } export function Controller( path: string = '/', options: ControllerOptions = {}, ): ClassDecorator { const { version, scope = 'singleton' } = options return (target: Function): void => { const constructor = target as ClassConstructor // Save additional controller metadata const controllerMeta = { path, version, scope, autorun: false, decoratorType: 'controller', params: [], } serviceRegistry.set(constructor, controllerMeta) // Register in container container.register(constructor, scope, false, [], 'controller') } } export interface MiddlewareOptions { scope?: Scope order?: number } export function Middleware(options: MiddlewareOptions = {}): ClassDecorator { const { scope = 'singleton', order = 0 } = options return (target: Function): void => { const constructor = target as ClassConstructor const middlewareMeta = { scope, autorun: false, decoratorType: 'middleware', params: [], order, } serviceRegistry.set(constructor, middlewareMeta) // Register in container container.register(constructor, scope, false, [], 'middleware') } } export interface RepositoryOptions { scope?: Scope entity?: string } export function Repository(options: RepositoryOptions = {}): ClassDecorator { const { scope = 'singleton', entity } = options return (target: Function): void => { const constructor = target as ClassConstructor const repositoryMeta = { scope, autorun: false, decoratorType: 'repository', params: [], entity, } serviceRegistry.set(constructor, repositoryMeta) // Register in container container.register(constructor, scope, false, [], 'repository') } } export interface BootstrapOptions { scope?: Scope priority?: number } export function Bootstrap(options: BootstrapOptions = {}): ClassDecorator { const { scope = 'singleton', priority = 0 } = options return (target: Function): void => { const constructor = target as ClassConstructor const bootstrapMeta = { scope, autorun: true, // Bootstrap services run automatically decoratorType: 'bootstrap', params: [], priority, } serviceRegistry.set(constructor, bootstrapMeta) // Register in container container.register(constructor, scope, true, [], 'bootstrap') } } // Function to get all registered services export function getAllRegisteredServices(): Map { return serviceRegistry } // Function to get services by decorator type export function getServicesByType(decoratorType: string): ClassConstructor[] { return Array.from(serviceRegistry.entries()) .filter(([_, meta]) => meta.decoratorType === decoratorType) .map(([constructor, _]) => constructor) } // Function to clear the registry (useful for testing) export function clearServiceRegistry(): void { serviceRegistry.clear() } // Inject decorator for parameter dependency injection export function Inject(token: any): ParameterDecorator { return (target, _propertyKey, index) => { metadataRegistry.registerParamType(target as any, index, token) } }