dimah-s3v0.4.1

Multipart

Multipart hooks for large-file upload flows.

Enable multipart in config before these hooks run:

multipart: { enabled: true },

Flow: initGuardonInitpartGuard (per part) → completeGuardonComplete · abortGuardonAbort

Init guard

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

MultipartInitGuardContext

Prop

Type

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

partGuard, completeGuard, and abortGuard use richer contexts that include uploadId (and part/parts fields where relevant).

Part guard

Runs before each part presign. Context includes uploadId, partNumber, and optional partSize.

multipart: {
  enabled: true,
  partGuard: async ({ key, uploadId, partNumber, partSize }) => {
    // runs before each part presign
  },
},

MultipartPartGuardContext

Prop

Type

Complete guard

Runs before completing the multipart upload. Context includes uploadId and parts.

multipart: {
  enabled: true,
  completeGuard: async ({ key, uploadId, parts }) => {
    // authorize complete
  },
},

MultipartCompleteGuardContext

Prop

Type

Abort guard

Runs before aborting the multipart upload. Context includes uploadId.

multipart: {
  enabled: true,
  abortGuard: async ({ key, uploadId }) => {
    // authorize abort
  },
},

MultipartAbortGuardContext

Prop

Type

List parts guard

multipart: {
  enabled: true,
  listGuard: async ({ key, uploadId }) => {
    // same auth check as init/complete
  },
},

MultipartListGuardContext

Prop

Type

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

On init

multipart: {
  enabled: true,
  onInit: async ({ key, uploadId }) => {
    console.log(`init: ${key} (uploadId: ${uploadId})`);
  },
},

MultipartOnInitContext

Prop

Type

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

On complete

multipart: {
  enabled: true,
  onComplete: async ({ key, uploadId, contentLength, eTag }) => {
    console.log(`complete: ${key} — ${contentLength} bytes, eTag: ${eTag}`);
  },
},

MultipartOnCompleteContext

Prop

Type

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

contentLength in onComplete is verified by S3.

On abort

multipart: {
  enabled: true,
  onAbort: async ({ key, uploadId }) => {
    console.log(`abort: ${key} (uploadId: ${uploadId})`);
  },
},

MultipartOnAbortContext

Prop

Type

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

Example

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

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

  multipart: {
    enabled: true,
    initGuard: async ({ key, fileSize }) => {
      if (fileSize && fileSize > 5 * 1024 * 1024 * 1024)
        throw new Error("Too large");
    },
    partGuard: async ({ key, bucket }) => {},
    completeGuard: async ({ key, bucket }) => {},
    abortGuard: async ({ key, bucket }) => {},
    listGuard: async ({ key, uploadId }) => {},
    onInit: async ({ key, uploadId }) => {
      console.log(`init: ${key} (uploadId: ${uploadId})`);
    },
    onComplete: async ({ key, uploadId, contentLength, eTag }) => {
      console.log(`complete: ${key} — ${contentLength} bytes, eTag: ${eTag}`);
    },
    onAbort: async ({ key, uploadId }) => {
      console.log(`abort: ${key} (uploadId: ${uploadId})`);
    },
  },

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

On this page