2.0 beta — new releases can include breaking changes. Stable 1.x docs
dimah-s3v2.0.0-beta.0
Bring Your Own Backend

Upload

Implement single-part presigning and server-side confirmation for a custom backend.

  1. upload — your backend picks the object key and returns a presigned URL (POST fields or PUT headers) and a ticket.
  2. The browser uploads directly to S3.
  3. confirm — the browser sends the ticket. Your backend verifies the object with HeadObject and returns what S3 reports.

Large files: Multipart.

Presign

The payload declares the file as name, size, and type. checksum is a base64 SHA-256 of the file. The client sends it when the route's catalog entry has checksum: true; sign it into the request so S3 checks it.

Prop

Type

Return fields when method is "POST", and headers when it is "PUT". The browser appends fields to the form before the file, or sends exactly headers on the PUT.

Prop

Type

Confirm

confirm sends only the ticket from the presign response. Read the route and key from it, never from the client.

Prop

Type

Return the size and type from HeadObject, not the declared ones. If the object is missing or does not match what was declared, throw an APIError with a catalog code, such as OBJECT_NOT_FOUND or UPLOAD_SIZE_MISMATCH.

Prop

Type

Example

Paths are yours. @dimah-s3/server uses POST /api/s3/presign/upload and POST /api/s3/presign/upload/confirm.

lib/s3-api/upload.ts
import type {
  TicketPayload,
  S3RequestOptions,
  UploadConfirmResponse,
  UploadPayload,
  UploadPresignResponse,
} from "@dimah-s3/core";
import { $fetch, call } from "./fetch";

export const upload = (payload: UploadPayload, options?: S3RequestOptions) =>
  $fetch<UploadPresignResponse>("/presign", {
    method: "POST",
    body: payload,
    ...call(options),
  });

export const confirm = (payload: TicketPayload, options?: S3RequestOptions) =>
  $fetch<UploadConfirmResponse>("/confirm", {
    method: "POST",
    body: payload,
    ...call(options),
  });

$fetch and call come from the skeleton.

On this page