Concrete IMetadataStore. Decorators call the merge*/add*
methods; the DecoratorPlugin and other consumers read the readonly
controllers, services, and routes maps.
A single module-level instance (metadataStore) is shared by all
decorators in the process — decorators are applied at class-definition
time and have no context to receive a store instance.
controllers: Map<Constructor, Readonly<Record<string, unknown>>>
Controllers keyed by class.
routes: Map<Constructor,ReadonlyArray<Readonly<Record<string, unknown>>>>
Materialized route metadata, one entry per (controller, HTTP verb). Derived from the internal per-method accumulators so the result is independent of decorator application order.
services: Map<Constructor, Readonly<Record<string, unknown>>>
Services keyed by class.
addCustomDecorator(record: CustomDecoratorRecord): void
Records a custom decorator for replay at registration time.
addRouteBinding(target: Constructor,handler: string,method: HttpMethod,path: string): void
Adds an HTTP verb + path binding to a method (@Get, @Post, …).
clear(): void
Removes all stored metadata. Intended for test isolation — decorators applied at module-evaluation time are NOT re-run, so callers that rely on decorated fixtures should not clear between tests using those fixtures.
ctorOptional(target: Constructor): ReadonlySet<number>
Returns the constructor-argument indices a class marked @Optional.
getController(target: Constructor): ControllerMetadata | undefined
Returns a class's controller metadata, or undefined.
getCustomDecorators(): readonly CustomDecoratorRecord[]
Returns all recorded custom decorators.
getMethods(target: Constructor): ReadonlyMap<string, MethodMeta>
Returns the method accumulators for a controller.
getModule(target: Constructor): ModuleMetadata | undefined
Returns a class's module declaration, if it has one.
getOrCreateMethod(target: Constructor,handler: string): MethodMeta
Returns the (mutable) method accumulator for a controller method, creating it if absent.
getRoutesFor(target: Constructor): RouteMetadata[]
Returns the materialized RouteMetadata entries for a
controller — one per (method, HTTP verb). Unlike the
IMetadataStore.routes getter (loosely typed for external
consumers), this returns the concrete shape the plugin composes routes
from.
getService(target: Constructor): ServiceMetadata | undefined
Returns a class's service metadata, or undefined.
hasController(target: Constructor): boolean
Reports whether a class has controller metadata.
hasService(target: Constructor): boolean
Reports whether a class has service metadata.
mergeController(target: Constructor,partial: Partial<ControllerMetadata>): void
Merges a partial into a class's controller metadata, creating it if absent. Arrays append; scalar fields replace.
mergeCtorOptional(target: Constructor,index: number): void
Marks one constructor parameter as optional, keyed by its argument index.
Stored separately from the token map because @Optional and @Inject are
independent decorators on the same parameter and may be applied in either
order; recording them in one structure would make the result depend on that
order.
mergeModule(target: Constructor,partial: Partial<ModuleMetadata>): void
Merges a partial module declaration into a class's metadata.
Every module member is additive, matching the existing collection-valued decorator metadata behavior.
mergeService(target: Constructor,partial: Partial<ServiceMetadata>): void
Merges a partial into a class's service metadata, creating it if absent.
mutateMethod(target: Constructor,handler: string,mutate: (meta: MethodMeta) => void): void
Merges a partial into a method's accumulator. Arrays append; scalar
fields replace. Parameter decorators append to params.
setCtorOptional(target: Constructor,indices: Iterable<number>): void
Replaces a class's optional-argument set outright.
mergeService REPLACES inject while mergeCtorOptional
ACCUMULATES, so two stacked @Inject(...) decorators would leave the
winning token list paired with the loser's optional indices — silently
marking a required dependency absent-tolerant, or naming an index the
shorter replacement list cannot cover, which effectiveOptional then
refuses at startup. Inject writes both fields through one call each so the
last decorator to apply owns the whole declaration.
storeParam(): void
Appends a parameter to a method's accumulator.