Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,83 @@
# services/registry-augmentation
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
This module is a TypeScript `declare module` augmentation. It adds the
`searchIndexes` slot to `@suaveplan/api-plugin`'s canonical
`ServiceRegistry` interface so any consumer importing
`@suaveplan/api-plugin-search` automatically sees
`ctx.getService("searchIndexes")` resolve to
`Map<string, SearchIndex> | undefined`. Without this augmentation the
`getService` call would fail TypeScript compilation because the
default `ServiceRegistry` is empty by design.
## Features
- Adds `searchIndexes: Map<string, SearchIndex>` to the augmented
registry.
- Re-declares the host-side `app: OpenAPIHono` slot owned by
`@suaveplan/api` so the search plugin's `onInit` can resolve `app`
with full typing even in isolated unit tests that do not import
`@suaveplan/api`. TypeScript merges duplicate `declare module`
declarations transparently.
- Side-effect-only module — importing the package barrel applies the
augmentation automatically; there is nothing to call.
## Usage: Basic
```ts
import "@suaveplan/api-plugin-search"; // side-effect augmentation
import type { PluginContext } from "@suaveplan/api-plugin";
function consume(ctx: PluginContext): void {
const indexes = ctx.getService("searchIndexes");
// indexes: Map<string, SearchIndex> | undefined
}
```
## Usage: Advanced
Sibling plugins that operate on the search index map can mutate it
safely once the search plugin has run — the map is a live reference,
not a snapshot:
```ts
declare module "@suaveplan/api-plugin/service-registry" {
interface ServiceRegistry {
analyticsCollector: { onIndexEvent(event: string): void };
}
}
async function onReady(ctx: PluginContext): Promise<void> {
const indexes = ctx.getService("searchIndexes");
if (indexes !== undefined) {
// …operate on indexes…
}
}
```
## API Reference
This module has no public runtime exports — it augments the
`ServiceRegistry` interface from
`@suaveplan/api-plugin/service-registry`. After import the augmented
interface carries:
| Slot | Type |
|---|---|
| `searchIndexes` | `Map<string, SearchIndex>` |
| `app` | `OpenAPIHono` (re-declared from `@suaveplan/api`) |
## Implementation Notes
The module pattern (`declare module "@suaveplan/api-plugin/service-registry" {…}`)
relies on TypeScript's declaration merging. Multiple packages
augmenting the same interface union their fields automatically; no
package owns the registry exclusively. The empty `export {}` at the
bottom forces this file to be a module rather than a script so the
`declare module` is a proper augmentation rather than ambient
declaration.

View File

@@ -0,0 +1,27 @@
/**
* ServiceRegistry module augmentation — declares the `searchIndexes`
* slot on `@suaveplan/api-plugin/service-registry`'s `ServiceRegistry`
* interface so downstream plugins typed against the augmented registry
* see `ctx.getService("searchIndexes")` resolve to
* `Map<string, SearchIndex> | undefined` without any cast.
*
* Importing this module for its side effects (which the package root
* barrel does automatically) is sufficient — every consumer of
* `@suaveplan/api-plugin-search` gets typed `searchIndexes` access.
*
* The host-side slot `app` is owned by `@suaveplan/api`'s own
* registry-augmentation module. We re-declare it here as a
* cumulative augmentation so the search plugin's `onInit(ctx)` can
* resolve it with full typing even when the consumer has not
* explicitly imported `@suaveplan/api`. TypeScript merges duplicate
* declarations.
*/
import type { OpenAPIHono } from "@hono/zod-openapi";
import type { SearchIndex } from "../types/types.js";
declare module "@suaveplan/api-plugin/service-registry" {
interface ServiceRegistry {
searchIndexes: Map<string, SearchIndex>;
app: OpenAPIHono;
}
}