first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,59 @@
# `plugin.ts`
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
The plugin factory for `@suaveplan/api-plugin-export`. Construction-time it validates options through `ExportPluginOptionsSchema` (rejecting with `ExportError(EXPORT.INVALID_CONFIG)` on failure) and returns a `PluginDescriptor` with three lifecycle hooks. `onInit` registers the in-memory `providers` + `jobs` maps on the augmented `ServiceRegistry`. `onReady` resolves the host `app` (`OpenAPIHono`) and mounts the export routes at the configured `basePath`. `onClose` clears both maps so a re-registration of the plugin starts clean.
## Features
- Caller-supplied options are honoured end-to-end — the upstream `_config`-discard bug is fixed at migration time.
- Side-effect import of `registry-augmentation` makes `ctx.getService("exportProviders")` / `ctx.getService("exportJobs")` type-narrow correctly at every call site that imports this module.
- `registerDataProvider(providers, provider)` is a convenience the upstream package shipped — re-exposed here so downstream code does not need to construct the providers map by hand.
- `onReady` mounts routes via `ctx.getService("app")` (the suaveplanent of upstream's `ctx.app.route(...)` call) so the plugin participates in the rest of the plugin ecosystem cleanly.
## Usage: Basic
```ts
import { createExportPlugin } from "@suaveplan/api-plugin-export";
const registry = createPluginRegistry();
registry.register(createExportPlugin({ basePath: "/v1/exports", maxRows: 10_000 }));
await registry.init();
await registry.ready();
```
## Usage: Advanced
```ts
import {
createExportPlugin,
registerDataProvider,
type DataProvider,
} from "@suaveplan/api-plugin-export";
const plugin = createExportPlugin({ defaultFormat: "json" });
// later, after onInit completes:
const providers = ctx.getService("exportProviders");
if (providers) {
const userProvider: DataProvider = {
resource: "users",
fetch: async () => db.select("user").get(),
};
registerDataProvider(providers, userProvider);
}
```
## API Reference
| Symbol | Kind | Notes |
|---|---|---|
| `createExportPlugin(options?)` | function | Returns `PluginDescriptor<ExportPluginOptions>`. Throws `EXPORT.INVALID_CONFIG` on bad input. |
| `registerDataProvider(providers, provider)` | function | `providers.set(provider.resource, provider)` helper. |
## Implementation Notes
The descriptor uses `defaults: config` so the `PluginContext`-level `getOwnConfig()` returns the merged, fully-defaulted options shape — downstream plugins that read the plugin config (or that the host orchestrator inspects) see the same values the route handler uses. The `app` lookup in `onReady` returns `OpenAPIHono | undefined` (per the `ServiceRegistry` augmentation in `@suaveplan/api`), so the missing case is checked explicitly with an `ExportError(INVALID_CONFIG)` — this is a misconfiguration of the host, not of the plugin options, but the same code is correct because the host failed to seed the `app` slot before plugin registration. `runOnInit` is async even though it does no `await` because the lifecycle hook signature requires it; making it async eliminates a subtle TypeScript variance gotcha when the registry awaits the return value. The runtime maps are held on a `PluginRuntime` interface so the three hook helpers can pass state without resorting to module-scope `let` (which would conflict with multiple plugin instances co-existing in one process).