89 lines
3.1 KiB
TypeScript
89 lines
3.1 KiB
TypeScript
/**
|
|
* 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> | 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<void>;
|
|
/** Fetch an object, or `null` if it doesn't exist. */
|
|
get(key: string): Promise<StoredObject | null>;
|
|
/** Remove an object. No error if it's already gone. */
|
|
delete(key: string): Promise<void>;
|
|
/**
|
|
* 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://<acct>.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("<name>")` / `upload("<name>", …)`. */
|
|
stores: Record<string, StoreConfig>;
|
|
}
|