import type { SyncRequestContext } from './context.js'; export interface BlobUploadRequest { readonly blobId: string; readonly bytes: Uint8Array; /** Advisory MIME type from the upload `Content-Type`, if any. */ readonly mediaType?: string; } export interface BlobDownloadResult { /** * The blob bytes, when served inline. **Absent** when the host configured * `blobSignedUrls` and a `url` was issued: the sync server exits the egress * path and the client fetches `url` directly (§5.9.5 always-issue). */ readonly bytes?: Uint8Array; readonly headers: Record; /** * §5.9.5 delegated presign (always-issue): a provider-signed GET URL for * the bytes, issued only after the row-derived authorization check passed. * Present iff the host configured `blobSignedUrls`; when present, `bytes` is * absent and the client MUST fetch the URL directly (no host auth), verify * the content address, and on failure re-request this endpoint — never fall * through (§5.9.5 recovery rule). */ readonly url?: string; readonly urlExpiresAtMs?: number; } /** `POST /blobs/{blobId}/upload-grant` request body (§5.9.3). */ export interface BlobUploadGrantRequest { readonly blobId: string; /** Declared uncompressed size — the size-cap check runs against this. */ readonly byteLength: number; /** Advisory MIME type, if any. */ readonly mediaType?: string; } /** * `POST /blobs/{blobId}/upload-grant` result (§5.9.3). Exactly one of: * `{url, urlExpiresAtMs}` — a presigned PUT the client uses direct-to-storage; * or `{present: true}` — the blob already exists (idempotent §5.9.3), so the * client skips the PUT; or `{}` (no fields) — the host has no presigned-upload * store configured, so the client streams through the direct PUT endpoint * (§5.9.3 capability, not fallback). */ export interface BlobUploadGrantResult { readonly url?: string; readonly urlExpiresAtMs?: number; readonly present?: boolean; } /** `PUT /blobs/{blobId}` (§5.9.3). Host auth is the adapter's job. */ export declare function handleBlobUpload(ctx: SyncRequestContext, request: BlobUploadRequest): Promise; /** * `GET /blobs/{blobId}` (§5.9.5). Authorization derives from the * referencing rows: the actor may download iff at least one row in the * reference index passes the §3.4 scope check for the actor. */ export declare function handleBlobDownload(ctx: SyncRequestContext, blobId: string): Promise; /** * `POST /blobs/{blobId}/upload-grant` (§5.9.3 presigned upload). Host * auth is the adapter's job — uploading is host-auth-only, not scope-bearing, * so any authenticated actor may obtain a grant within the size cap (§5.9.3). * * The size cap is enforced HERE, up front, against the declared `byteLength` * (the object-store hop cannot re-check the streamed byte count). Integrity is * NOT checked here: the object store places bytes at the content-addressed key, * and the address is verified at reference time (§5.9.6 push existence) and on * every download (§5.9.5/§5.1). Returns a presigned single PUT, or a * `present` marker if the blob already exists (idempotent §5.9.3), or an empty * result when no presigned-upload store is configured (client streams direct). */ export declare function handleBlobUploadGrant(ctx: SyncRequestContext, request: BlobUploadGrantRequest): Promise;