class MetadataStore
implements IMetadataStore
Since 0.1.0

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.

Properties

readonly
controllers: Map<Constructor, Readonly<Record<string, unknown>>>

Controllers keyed by class.

readonly
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.

readonly
services: Map<Constructor, Readonly<Record<string, unknown>>>

Services keyed by class.

Methods

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(
target: Constructor,
handler: string,
): void

Appends a parameter to a method's accumulator.