Initial Commit
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
# 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
|
||||
|
||||
```ts
|
||||
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:
|
||||
|
||||
```ts
|
||||
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:
|
||||
|
||||
```ts
|
||||
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.
|
||||
Reference in New Issue
Block a user