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

2.9 KiB

registry-augmentation.ts — ServiceRegistry slot for eventBusService

Purpose

Augments @suaveplan/api-plugin/service-registry's ServiceRegistry interface to advertise the eventBusService slot the plugin registers at boot. Downstream plugins typed against the augmented registry see ctx.getService("eventBusService") resolve to EventBusService | undefined without any cast. Mirrors the pattern used by @suaveplan/api-plugin-auth's registry-augmentation.ts.

The module re-declares the host-side slots (app, openAPIRegistry, logger, eventBus, clock) as a cumulative augmentation so the plugin's onInit(ctx) can resolve them with full typing even when the consumer has not separately imported @suaveplan/api. TypeScript merges duplicate interface ServiceRegistry { ... } declarations, so the duplication is safe alongside @suaveplan/api's own augmentation.

Features

  • Side-effect-only module — importing it surfaces the augmentation to every consumer.
  • Re-declares the host-owned slots so the plugin compiles in isolation.
  • Marks openAPIRegistry as optional — the plugin tolerates a host that does not register an OpenAPI registry by mounting routes on the Hono app only.

Usage: Basic

import "@suaveplan/api-plugin-event-bus/services/registry-augmentation";

// elsewhere — typed without any cast
const bus = ctx.getService("eventBusService");

Usage: Advanced

import type { EventBusService } from "@suaveplan/api-plugin-event-bus";
import "@suaveplan/api-plugin-event-bus/services/registry-augmentation";

function consume(getService: <K extends string>(name: K) => unknown) {
    // Augmentation makes the literal "eventBusService" resolve
    // cleanly against the registry interface.
    return getService("eventBusService") as EventBusService | undefined;
}

API Reference

This module exports nothing at runtime. The declaration:

declare module "@suaveplan/api-plugin/service-registry" {
    interface ServiceRegistry {
        eventBusService: EventBusService;
        app: OpenAPIHono;
        openAPIRegistry?: OpenAPIRegistry;
        logger: LoggerLike;
        eventBus: EventBusLike;
        clock: Clock;
    }
}

is the entire surface.

Implementation Notes

  • An empty export {}; keeps the file in module scope — TypeScript treats files with only declare statements as scripts otherwise.
  • The host-owned re-declarations match the canonical slot names used in @suaveplan/api's own augmentation. If those slot names change upstream, this file must follow.
  • openAPIRegistry?: OpenAPIRegistry differs from @suaveplan/api's required declaration on purpose — the event-bus plugin tolerates hosts without OpenAPI by mounting routes on the Hono app alone. TypeScript's module-merging treats the optional declaration as a widening, so consumers importing both modules still see the required form.