/** * Storage driver contract + config types. * * A `StorageDriver` is the low-level object store (local disk, S3, …). It knows * how to put/get/delete raw bytes under a key — nothing about HTTP, multipart * parsing, validation, or URLs. The registry (`client.ts`) builds one driver per * configured store and the upload layer (`upload.ts`) drives them. This mirrors * `@wrnexus/db`'s driver/adapter split. */ /** Whether a store's objects are world-readable or served behind app auth. */ export type StoreAccess = "public" | "private"; /** An object read back from a store. */ export interface StoredObject { /** Object bytes as a web stream (preferred) or a buffer. */ body: ReadableStream | Uint8Array; /** MIME type to serve with. */ contentType: string; /** Size in bytes, when known. */ size?: number; } /** Metadata passed alongside the bytes on `put`. */ export interface PutMeta { contentType: string; /** Original client filename (informational only — NEVER used as a path). */ filename?: string; } /** The low-level object store. Implementations: `adapters/local.ts`, `adapters/s3.ts`. */ export interface StorageDriver { /** Persist `data` under `key` (overwrites). */ put(key: string, data: Uint8Array, meta: PutMeta): Promise; /** Fetch an object, or `null` if it doesn't exist. */ get(key: string): Promise; /** Remove an object. No error if it's already gone. */ delete(key: string): Promise; /** * A directly-servable absolute URL for a PUBLIC object (e.g. an S3/CDN URL), or * `null` when the framework should serve it (local public stores). Private * stores always return `null`. */ publicUrl(key: string): string | null; } /** Local-disk store. `dir` is resolved against the app root when relative. */ export interface LocalStoreConfig { driver: "local"; access: StoreAccess; /** Directory the files live under (e.g. "uploads/public"). */ dir: string; /** Reject files larger than this many bytes (per file). */ maxBytes?: number; /** Allowed types: MIME (`"image/*"`, `"application/pdf"`) and/or extensions (`".pdf"`). */ accept?: string[]; } /** S3 / S3-compatible store (AWS, Cloudflare R2, Backblaze B2, MinIO, DO Spaces). */ export interface S3StoreConfig { driver: "s3"; access: StoreAccess; bucket: string; region: string; accessKeyId: string; secretAccessKey: string; /** * Custom endpoint for non-AWS services, e.g. * `https://.r2.cloudflarestorage.com`. Omit for AWS S3. */ endpoint?: string; /** Force path-style URLs (`/bucket/key`). Defaults on for custom endpoints. */ forcePathStyle?: boolean; /** Public base URL for `publicUrl()` (a CDN or public bucket domain). */ publicBaseUrl?: string; maxBytes?: number; accept?: string[]; } export type StoreConfig = LocalStoreConfig | S3StoreConfig; /** The `storage` block in `wrnexus.config.ts`. */ export interface StorageConfig { /** Name of the store used when a call omits one. Defaults to the first store. */ default?: string; /** Named stores, reached with `getStore("")` / `upload("", …)`. */ stores: Record; }