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,58 @@
# `plugin.ts`
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Authoritative `createFileUploadPlugin` factory. Wraps the resolved configuration in a `PluginDescriptor<FileUploadPluginConfig>` and executes a 6-step `onInit` lifecycle: resolve required `app` service → construct default storage + session-store → build the `FileUploadService` and register it in the host `ServiceRegistry` → install `requireAuth()` on `basePath/*` → register the 6 OpenAPI routes via `definePluginRoutes` → schedule the cleanup-expired interval. The descriptor's `onClose` clears the interval so plugin teardown leaves no dangling timers.
## Features
- Zod-validated factory boundary — invalid options throw `FileUploadError(UPLOAD.INVALID_INPUT)` carrying the `ZodError` as `cause`.
- Default storage (`MemoryUploadStorage`) and session store (`MemoryUploadSessionStore`) when none supplied; production callers swap in `FileSystemUploadStorage` or a Surreal-backed adapter via options.
- Cleanup interval auto-tuned to `sessionTtlMs / 4` (minimum 1 s) so expired sessions are reclaimed within one quarter-TTL of expiry.
- `requireAuth()` middleware installed on the configured `basePath/*` so every route is principal-gated without per-handler boilerplate.
- Falls back to direct Hono mounting (and logs a warning) when no `OpenAPIRegistry` is in the host `ServiceRegistry`.
- `setInterval` handle is `unref`'d so plugin lifecycle does not pin the event loop after `onClose`.
## Usage: Basic
```ts
import { createFileUploadPlugin } from "@suaveplan/api-plugin-file-upload";
const plugin = createFileUploadPlugin();
await pluginRegistry.register(plugin);
```
## Usage: Advanced
```ts
import {
createFileUploadPlugin,
FileSystemUploadStorage,
} from "@suaveplan/api-plugin-file-upload";
const plugin = createFileUploadPlugin({
basePath: "/api/v1/uploads",
singleShotLimitBytes: 32 * 1024 * 1024,
maxFileSizeBytes: 4 * 1024 * 1024 * 1024,
defaultChunkSize: 8 * 1024 * 1024,
sessionTtlMs: 6 * 60 * 60 * 1000,
allowedMimeTypes: ["image/png", "image/jpeg", "application/pdf"],
storage: new FileSystemUploadStorage({ rootDir: "/var/lib/uploads" }),
});
await pluginRegistry.register(plugin);
```
## API Reference
- `createFileUploadPlugin(options?: FileUploadPluginOptions): PluginDescriptor<FileUploadPluginConfig>` — see file-level JSDoc for the full lifecycle.
## Implementation Notes
- The Zod schema validates structurally — a misshapen `storage` or `sessionStore` value is rejected before the descriptor is constructed, not at first request time.
- The route-rebase step rewrites every route entry's `path` to include `basePath` so `definePluginRoutes` and the served OpenAPI doc share a single ground truth.
- `requireAuth()` is imported from `@suaveplan/api-plugin-auth` so the plugin gains the same anonymous→401 contract every other auth-aware plugin uses.
- `cleanupExpired` is invoked with the current wall clock; if a test injects a `clock` override into `createFileUploadService` directly, the interval should be paused (tests do not exercise the scheduler).