# services/registry-augmentation ## Purpose Declares the `auditService` slot on `@suaveplan/api-plugin/service-registry`'s `ServiceRegistry` interface via TypeScript module augmentation. Importing this module for its side effects (which the package root barrel does automatically) is sufficient — every consumer of `@suaveplan/api-plugin-audit` gets typed `ctx.getService("auditService")` access with the return type narrowed to `AuditService | undefined`, no casts. The file also cumulatively re-declares the host-side `app` slot so the audit plugin's `onInit(ctx)` resolves `ctx.getService("app")` to `Hono` even when the consumer has not explicitly imported `@suaveplan/api`'s registry-augmentation. TypeScript merges duplicate declarations across modules, so the cumulative augmentation is safe. ## Features - TypeScript module augmentation — zero runtime cost. - Cumulative — does not collide with `@suaveplan/api-plugin-auth`'s or `@suaveplan/api`'s own augmentations. - Side-effect imported by the package barrel so consumers do not need an explicit subpath import. ## Usage: Basic ```ts // In your app entry: import "@suaveplan/api-plugin-audit"; // side-effect: registers ServiceRegistry slot // In a sibling plugin's onInit: const audit = ctx.getService("auditService"); // typed as AuditService | undefined await audit?.log({ type: "user.created", severity: "info", actor: { userId: "u1" }, }); ``` ## Usage: Advanced ```ts // In a custom test harness that constructs PluginContext directly: import "@suaveplan/api-plugin-audit/services/audit-service"; // also surfaces the augmentation import { createPluginContext } from "@suaveplan/api-plugin"; const ctx = createPluginContext({ /* ... */ }); const audit = ctx.getService("auditService"); // AuditService | undefined ``` ## API Reference This file has no runtime exports; it contributes a single TypeScript `declare module "@suaveplan/api-plugin/service-registry"` block adding: - `auditService: AuditService` - `app: Hono` ## Implementation Notes The augmentation must live in a module that is reachable from the consumer's TypeScript program (either via a direct import or via a transitive dependency that pulls it in). Importing the package barrel of `@suaveplan/api-plugin-audit` covers the common case. If the augmentation is missing at compile time, `ctx.getService("auditService")` types as `never` per the `ServiceRegistry` defaults and fails the build with `Argument of type '"auditService"' is not assignable…`. That failure is the intended UX — it tells the operator the plugin barrel was not loaded.