# `plugin.ts` _(no submodules)_ ## Purpose Authoritative `createFileUploadPlugin` factory. Wraps the resolved configuration in a `PluginDescriptor` 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` — 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).