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

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" adds rateLimitService: RateLimitService plus 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 type chain so the runtime cost is zero — no module is loaded at runtime to satisfy the augmentation.
  • The host app slot is typed as OpenAPIHono from @hono/zod-openapi to mirror @suaveplan/api's declaration. Plain Hono apps work too; the OpenAPIHono type 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.