Files
skills/docs/api-stack/api/api-plugin-event-bus/src/services/registry-augmentation.md
2026-05-29 08:20:56 +01:00

84 lines
2.9 KiB
Markdown

# `registry-augmentation.ts` — `ServiceRegistry` slot for `eventBusService`
## Purpose
Augments `@suaveplan/api-plugin/service-registry`'s `ServiceRegistry`
interface to advertise the `eventBusService` slot the plugin
registers at boot. Downstream plugins typed against the augmented
registry see `ctx.getService("eventBusService")` resolve to
`EventBusService | undefined` without any cast. Mirrors the pattern
used by `@suaveplan/api-plugin-auth`'s `registry-augmentation.ts`.
The module re-declares the host-side slots (`app`, `openAPIRegistry`,
`logger`, `eventBus`, `clock`) as a cumulative augmentation so the
plugin's `onInit(ctx)` can resolve them with full typing even when the
consumer has not separately imported `@suaveplan/api`. TypeScript
merges duplicate `interface ServiceRegistry { ... }` declarations, so
the duplication is safe alongside `@suaveplan/api`'s own
augmentation.
## Features
- Side-effect-only module — importing it surfaces the augmentation to
every consumer.
- Re-declares the host-owned slots so the plugin compiles in
isolation.
- Marks `openAPIRegistry` as optional — the plugin tolerates a host
that does not register an OpenAPI registry by mounting routes on
the Hono app only.
## Usage: Basic
```ts
import "@suaveplan/api-plugin-event-bus/services/registry-augmentation";
// elsewhere — typed without any cast
const bus = ctx.getService("eventBusService");
```
## Usage: Advanced
```ts
import type { EventBusService } from "@suaveplan/api-plugin-event-bus";
import "@suaveplan/api-plugin-event-bus/services/registry-augmentation";
function consume(getService: <K extends string>(name: K) => unknown) {
// Augmentation makes the literal "eventBusService" resolve
// cleanly against the registry interface.
return getService("eventBusService") as EventBusService | undefined;
}
```
## API Reference
This module exports nothing at runtime. The declaration:
```ts
declare module "@suaveplan/api-plugin/service-registry" {
interface ServiceRegistry {
eventBusService: EventBusService;
app: OpenAPIHono;
openAPIRegistry?: OpenAPIRegistry;
logger: LoggerLike;
eventBus: EventBusLike;
clock: Clock;
}
}
```
is the entire surface.
## Implementation Notes
- An empty `export {};` keeps the file in module scope — TypeScript
treats files with only `declare` statements as scripts otherwise.
- The host-owned re-declarations match the canonical slot names used
in `@suaveplan/api`'s own augmentation. If those slot names change
upstream, this file must follow.
- `openAPIRegistry?: OpenAPIRegistry` differs from `@suaveplan/api`'s
required declaration on purpose — the event-bus plugin tolerates
hosts without OpenAPI by mounting routes on the Hono app alone.
TypeScript's module-merging treats the optional declaration as a
widening, so consumers importing both modules still see the
required form.