2.7 KiB
2.7 KiB
services/registry-augmentation — TypeScript module augmentation for the host ServiceRegistry
Purpose
Augments the ServiceRegistry interface owned by
@suaveplan/api-plugin/service-registry so consumers see the
rateLimitService slot typed as RateLimitService (rather than
unknown) when they call ctx.getService("rateLimitService"). Without
this declaration the host's typed lookup would fall back to the
default unknown and downstream plugins would have to cast.
Re-declares the canonical host-side slots (app, logger, eventBus,
clock) too so the plugin's own onInit(ctx) can resolve them
without forcing the consumer to import @suaveplan/api's
registry-augmentation manually. TypeScript merges duplicate declare module blocks, so this addition is purely additive.
Features
- Module augmentation lives in a side-effect-only import — the package barrel imports it first so the declaration is in scope for every consumer.
- Exports a no-op
registerRateLimitServiceSlot()so the module is preserved through dead-code elimination and a side-effect import surfaces the augmentation reliably. - Cumulative — does not collide with
@suaveplan/api's augmentation; TypeScript merges them.
Usage: Basic
// Anywhere that imports the package barrel:
import "@suaveplan/api-plugin-rate-limit";
// `ctx.getService("rateLimitService")` now narrows to
// `RateLimitService | undefined`.
Usage: Advanced
// Inside another plugin's onInit:
import { registerRateLimitServiceSlot } from "@suaveplan/api-plugin-rate-limit";
registerRateLimitServiceSlot(); // ensures bundler keeps the side-effect import
const service = ctx.getService("rateLimitService");
if (service === undefined) {
throw new MyError(MY_CODES.MISSING_DEP, "rateLimitService not registered");
}
await service.check({ ip, path, method });
API Reference
- Module augmentation:
declare module "@suaveplan/api-plugin/service-registry"addsrateLimitService: RateLimitServiceplus the canonical host slots. function registerRateLimitServiceSlot(): void— no-op runtime export. Call it inside a function body if your bundler is aggressive about pruning side-effect-only imports.
Implementation Notes
- The declaration uses a regular
import typechain so the runtime cost is zero — no module is loaded at runtime to satisfy the augmentation. - The host
appslot is typed asOpenAPIHonofrom@hono/zod-openapito mirror@suaveplan/api's declaration. PlainHonoapps work too; theOpenAPIHonotype is a structural superset. - Adding new slots requires updating the augmentation here AND publishing a major version — consumers' compile output depends on the interface shape.