Files
suaveplan/packages/api/api-plugin-banking/src/services/registry-augmentation.md
2026-05-27 23:29:53 +01:00

3.0 KiB

Service-registry augmentation

Purpose

This module is a type-only side-effect import that augments the canonical ServiceRegistry interface from @suaveplan/api-plugin/service-registry to surface the slots the banking plugin reads and writes: its own bankingService, the host-supplied app (the OpenAPIHono instance routes are mounted on), and the upstream-supplied db (the DatabaseAdapter registered by @suaveplan/api-plugin-database). After the augmentation, ctx.getService("bankingService") types as BankingService | undefined in any consumer file that imports the banking package barrel.

Features

  • Zero-runtime side effect — the declare module block compiles to nothing.
  • Cumulative augmentation: re-declaring app and db does not conflict with the host packages' own declarations; TypeScript merges duplicate interface members.
  • Picks up the augmentation automatically when consumers import @suaveplan/api-plugin-banking for any reason (the package root barrel forwards the side effect).

Usage: Basic

import "@suaveplan/api-plugin-banking"; // type-only side effect

function handler(ctx: PluginContext) {
    const service = ctx.getService("bankingService");
    // service: BankingService | undefined
}

Usage: Advanced

Direct subpath import for code that wants the augmentation without the runtime package — pure-type files such as host scaffolding can reference the slot type:

import "@suaveplan/api-plugin-banking/services/registry-augmentation";
import type { ServiceRegistry } from "@suaveplan/api-plugin/service-registry";

declare const reg: ServiceRegistry;
reg.bankingService.transferFunds(/* ... */);

API Reference

The module exports nothing at runtime. The interface it augments:

declare module "@suaveplan/api-plugin/service-registry" {
    interface ServiceRegistry {
        bankingService: BankingService;
        app: OpenAPIHono;
        db: DatabaseAdapter;
    }
}

After the augmentation:

  • ctx.getService("bankingService") → BankingService | undefined
  • ctx.getService("app") → OpenAPIHono | undefined
  • ctx.getService("db") → DatabaseAdapter | undefined

Implementation Notes

The pattern (declare-merge the host slot and the plugin's own slot inside the plugin's package) follows the genesis convention set by @suaveplan/api-plugin-search. The host packages (@suaveplan/api for app, @suaveplan/api-plugin-database for db) declare their own slots; we re-declare them here so the banking plugin compiles against a consumer's tsconfig that does not transitively import those host modules' augmentation files.

Re-declaration is safe because TypeScript merges interface members across declare module blocks. If two packages declared the same slot with conflicting types, the build would fail at the augmentation point rather than silently picking one — this gives a clear compile-time signal if a future change ever drifts the bankingService slot's type out of sync.