/** * The S3-compatible request layer every S3 provider shares: AWS Signature V4 * signing for header-signed requests and presigned GET links, plus an * SSRF-guarded fetch with connect and idle timeouts. * * Paths are path-style (`//`), which S3, R2, MinIO and Supabase * all accept. */ export interface S3ClientConfig { region: string; bucket: string; accessKeyId: string; secretAccessKey: string; endpoint: string; } export type S3Method = "DELETE" | "GET" | "HEAD" | "POST" | "PUT"; export interface SignedS3RequestOptions { method: S3Method; query?: Record; body?: Uint8Array; contentType?: string; /** An HTTP Range header value, such as `bytes=0-1023`. */ range?: string | undefined; timeoutMs: number; /** * The deployment configured this endpoint and its keys (not a workspace), * so it may sit on a private network or use plain HTTP. Without it, only * the `S3_ENDPOINT`/`R2_ENDPOINT` endpoint with the deployment's own keys * may. */ trustedEndpoint?: boolean; } export interface PresignS3GetOptions { /** Seconds until the link stops working: 1 to 604800 (seven days). */ expiresInSeconds: number; /** Overrides the Content-Type the bucket sends with the object. */ responseContentType?: string | undefined; /** Overrides the Content-Disposition the bucket sends with the object. */ responseContentDisposition?: string | undefined; /** Overrides the Cache-Control the bucket sends with the object. */ responseCacheControl?: string | undefined; /** Signing time; tests pin it. Defaults to now. */ now?: Date; } /** * The env-configured S3 endpoint origin, when `endpoint` is exactly it. The * deployment chose that endpoint, so it may sit on a private network (a * self-hosted MinIO, for example); endpoints saved in workspace settings may * not. */ export declare function trustedDeploymentS3Origin(endpoint: string): string | undefined; /** * Fetches an S3 URL through the SSRF guard. `timeoutMs` bounds the wait for * response headers and then each gap between body chunks, so a hung endpoint * can't hold a request open forever. Headers only arrive once an upload's * body is sent, so the header wait also allows the body time at 32 KiB/s, up * to 15 more minutes. */ export declare function fetchS3WithTimeout(url: string, init: RequestInit, timeoutMs: number, trustedPrivateOrigin?: string): Promise; /** Releases a response body the caller doesn't need. */ export declare function cancelS3ResponseBody(response: Response): Promise; /** * The start of an S3 error response's body, for an error message. It reads * at most `maxBytes` and cancels the rest, so an endpoint can't make the app * hold a huge or endless error body in memory. */ export declare function readS3ErrorText(response: Response, maxBytes?: number): Promise; export declare function sha256Hex(data: Uint8Array): Promise; /** URI-encodes one value the way SigV4 requires (RFC 3986 unreserved set). */ export declare function rfc3986(value: string): string; /** The canonical path-style URI for an object, refusing dot segments. */ export declare function s3ObjectUri(config: Pick, key: string): string; export interface SignedS3Headers { url: string; headers: Record; } /** Signs a request with an `Authorization` header (SigV4). */ export declare function signS3Request(config: S3ClientConfig, key: string, options: Omit & { now?: Date; }): Promise; /** * Sends a SigV4-signed request through the SSRF guard. Requests carry signed * credentials and private bytes, so only the deployment's own endpoint and * keys may sit on a private network or use plain HTTP. */ export declare function signedS3Request(config: S3ClientConfig, key: string, options: SignedS3RequestOptions): Promise; /** * Returns a GET link for one object that works without credentials until it * expires (SigV4 query signing). Anyone holding the link can read the object * until then, so keep the expiry short. */ export declare function presignS3GetUrl(config: S3ClientConfig, key: string, options: PresignS3GetOptions): Promise;