3.7 KiB
registry-augmentation
(no submodules)
Purpose
Module-augmentation file that adds the eventRepository and
rsvpRepository slots to @suaveplan/api-plugin/service-registry's
ServiceRegistry interface. Importing this file for its side
effects — which the package root barrel does automatically — makes
ctx.getService("eventRepository") resolve to
IEventRepository | undefined for any downstream plugin's type
checker without a cast.
The file also re-declares the host-owned app and db slots so
this plugin's onInit / onReady can resolve them with full typing
even in consumer projects that have not explicitly imported
@suaveplan/api. TypeScript merges duplicate declare module
blocks, so the upstream @suaveplan/api's authoritative declaration
remains in effect for consumers that import it directly — this file
is purely additive.
Features
- Adds
eventRepository: IEventRepositoryandrsvpRepository: IRsvpRepositoryslots. - Re-declares
app: OpenAPIHonoanddb?: SurrealAdapterfor self-contained type resolution. - Zero runtime cost —
declare moduleproduces no JavaScript output. - Cumulative — does not conflict with
@suaveplan/api's own augmentation.
Usage: Basic Example
// Side-effect import — the package root barrel does this for you,
// but explicit imports are also supported.
import "@suaveplan/api-plugin-events";
import type { PluginContext } from "@suaveplan/api-plugin";
function inspect(ctx: PluginContext) {
const repo = ctx.getService("eventRepository");
// `repo` is typed as `IEventRepository | undefined`
}
Usage: Advanced Example
import type { PluginContext } from "@suaveplan/api-plugin";
import "@suaveplan/api-plugin-events"; // load the augmentation
export function createSearchSyncPlugin() {
return {
name: "search-sync",
dependencies: ["events"],
async onReady(ctx: PluginContext) {
const events = ctx.getService("eventRepository");
if (events === undefined) {
throw new Error("eventRepository not available");
}
// Wire a search-index sync against the typed surface
ctx.eventBus.on("event:created", async ({ eventId }) => {
const event = await events.findById(eventId);
if (event !== null) await searchIndex.index(event);
});
},
};
}
API Reference
This file exports no runtime values. The shape it produces is:
declare module "@suaveplan/api-plugin/service-registry" {
interface ServiceRegistry {
eventRepository: IEventRepository;
rsvpRepository: IRsvpRepository;
app: OpenAPIHono;
db?: SurrealAdapter;
}
}
Consumers reach the augmented type through any of:
import "@suaveplan/api-plugin-events"(package root barrel — loads the augmentation as a side effect).import "@suaveplan/api-plugin-events/services/registry-augmentation"if a consumer wants the augmentation without pulling in the rest of the package.
Implementation Notes
The pattern is identical to @suaveplan/api-plugin-search's
services/registry-augmentation.ts — every plugin owns the slots it
contributes, and the host-owned slots are re-declared cumulatively
so the plugin's own source files type-check without forcing a
consumer to import @suaveplan/api first. Cumulative module
augmentation is a non-negotiable feature of TypeScript and survives
both vite-plugin-dts and the canonical tsc --build pipeline.
The db slot is declared optional (db?: SurrealAdapter) to match
the upstream @suaveplan/api declaration; this plugin's onInit
treats undefined as the SERVICE_NOT_AVAILABLE failure case.