dimah-s3v0.4.1

Upload

Upload hooks for presign, confirm, and verified metadata.

Enable upload in config before these hooks run:

upload: { enabled: true },

Default method is "POST" (Presigned POST). Use "PUT" for providers without POST support (notably Cloudflare R2):

upload: { enabled: true, method: "PUT" },

Flow: presignGuardonPresigned → browser uploads to S3 → confirmGuardonConfirmed

Presign guard

upload: {
  enabled: true,
  presignGuard: async ({ key, fileSize }) => {
    if (fileSize && fileSize > 10 * 1024 * 1024) throw new Error("Too large");
  },
},

UploadPresignGuardContext

Prop

Type

import type { UploadPresignGuardContext } from "@dimah-s3/server";

fileSize, contentType, and metadata are client-declared — use onConfirmed for verified values.

On presigned

upload: {
  enabled: true,
  onPresigned: async ({ key, bucket, contentType }) => {
    console.log(`presigned: ${key} (${contentType}) in ${bucket}`);
  },
},

UploadOnPresignedContext

Prop

Type

import type { UploadOnPresignedContext } from "@dimah-s3/server";

Confirm guard

upload: {
  enabled: true,
  confirmGuard: async ({ key, bucket }) => {
    // authorize confirm for this key
  },
},

UploadConfirmGuardContext

Prop

Type

import type { UploadConfirmGuardContext } from "@dimah-s3/server";

On upload confirmed

upload: {
  enabled: true,
  onConfirmed: async ({ key, contentLength, eTag }) => {
    console.log(`confirmed: ${key} — ${contentLength} bytes, eTag: ${eTag}`);
  },
},

UploadOnConfirmedContext

Prop

Type

import type { UploadOnConfirmedContext } from "@dimah-s3/server";

contentLength and eTag are verified by S3.

Example

lib/s3.ts
import { dimahS3 } from "@dimah-s3/server";
import { s3Client, defaultBucket } from "@/lib/s3-client";

export const s3 = dimahS3({
  s3: s3Client,
  defaultBucket,

  upload: {
    enabled: true,
    presignGuard: async ({ key, fileSize }) => {
      if (fileSize && fileSize > 10 * 1024 * 1024) throw new Error("Too large");
    },
    onPresigned: async ({ key, bucket, contentType }) => {
      console.log(`presigned: ${key} (${contentType}) in ${bucket}`);
    },
    confirmGuard: async ({ key, bucket }) => {
      // authorize confirm
    },
    onConfirmed: async ({ key, contentLength, eTag }) => {
      console.log(`confirmed: ${key} — ${contentLength} bytes, eTag: ${eTag}`);
    },
  },

  download: { enabled: true },
  delete: { enabled: true },
});

On this page