/** * Chat upload handler: the server side of ``'s batteries-included * attachments. Mount it at `app/api/uploads/route.ts` (the same endpoint the * composer POSTs to) and files "just work": stored on the local disk in dev, * on Veryfront Cloud (or a `BlobStorage` you pass) once deployed. * * ```ts * // app/api/uploads/route.ts * import { createChatUploadHandler } from "veryfront/chat/uploads"; * * function authorize(request: Request) { * const token = Deno.env.get("UPLOAD_TOKEN"); * return Boolean(token && request.headers.get("authorization") === `Bearer ${token}`); * } * * export const { POST, GET, DELETE } = createChatUploadHandler({ authorize }); * ``` * * `POST` stores the multipart `file` field and returns `{ id, url, name, * mediaType, size }`. The composer sends that `url` as a `file` message part, * which the runtime fetches, so the URL must be reachable by the runtime * (true for local dev, where `GET` streams the file back from the same origin). * * @module chat/upload-handler */ import "../../_dnt.polyfills.js"; import type { BlobStorage } from "../workflow/blob/types.js"; /** Result returned by a chat upload-route authorizer. */ export type ChatUploadAuthorizationResult = boolean | Response; /** Authorizes one chat upload-route request. */ export type ChatUploadAuthorize = (request: Request) => ChatUploadAuthorizationResult | Promise; /** Configuration for {@link createChatUploadHandler}. */ export interface ChatUploadHandlerConfig { /** Max accepted file size in bytes. @default 25 MB */ maxFileSize?: number; /** Max complete multipart body size. @default maxFileSize + 64 KiB */ maxBodySize?: number; /** Storage backend. Defaults to local disk in dev, Veryfront Cloud when deployed. */ storage?: BlobStorage; /** * Gate every request. Only literal `true` permits access; return `false` or * a `Response` to reject. * Required unless `allowUnauthenticated` is explicitly set. */ authorize?: ChatUploadAuthorize; /** * Allow POST, GET, and DELETE without an authorization callback. * Use this only for local prototypes or deliberately public upload routes. */ allowUnauthenticated?: boolean; /** * Expose every stored upload through GET requests without an `id`. * Keep this disabled unless every authorized caller can access every upload. * @default false */ allowListing?: boolean; } /** * Select the blob backend for chat uploads: an explicitly configured storage * wins, then Veryfront Cloud once deployed, then local disk. * * Exported so the deployment-dependent selection can be pinned by a test * without performing a real upload. */ export declare function resolveStorage(config: ChatUploadHandlerConfig): BlobStorage; /** * Build `{ POST, GET, DELETE }` route handlers for chat attachments. * Auto-selects local disk storage in dev and Veryfront Cloud once deployed, or * the `storage` you provide. Every route fails closed unless an authorizer * returns literal `true` or unauthenticated access is explicitly enabled. * Multipart request bodies and file bytes are bounded independently. * `GET` without an `id` (the listing used by `useAttachments` on mount) * responds `400` unless `allowListing: true` opts in. Enable it only when * every authorized caller may access every stored upload. `DELETE ?id=` * removes the file from storage. */ export declare function createChatUploadHandler(config?: ChatUploadHandlerConfig): { POST: (request: Request) => Promise; GET: (request: Request) => Promise; DELETE: (request: Request) => Promise; }; //# sourceMappingURL=upload-handler.d.ts.map