Skip to content

arraypress/storage-s3

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@arraypress/storage-s3

S3-compatible storage adapter for @arraypress/storage. Works with AWS S3, Cloudflare R2 (via S3 API), MinIO, DigitalOcean Spaces, and any S3-compatible service.

Works in Node.js, Cloudflare Workers, Deno, Bun, and any runtime that supports the AWS SDK.

Installation

npm install @arraypress/storage-s3 @arraypress/storage

This package depends on @aws-sdk/client-s3 and @aws-sdk/s3-request-presigner (installed automatically).

Usage

AWS S3

import { createS3Storage } from '@arraypress/storage-s3';

const storage = createS3Storage({
  bucket: 'my-bucket',
  region: 'us-east-1',
  accessKeyId: process.env.AWS_ACCESS_KEY_ID,
  secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
  publicUrl: 'https://my-bucket.s3.amazonaws.com',
});

// Upload
await storage.upload({
  key: 'uploads/photo.jpg',
  body: fileBuffer,
  contentType: 'image/jpeg',
});

// Download
const file = await storage.download('uploads/photo.jpg');
if (file) {
  console.log(file.contentType); // 'image/jpeg'
  console.log(file.size);        // bytes
}

// Signed URLs (for direct client uploads)
const signed = await storage.getSignedUploadUrl({
  key: 'uploads/new-file.jpg',
  contentType: 'image/jpeg',
  expiresIn: 3600,
});
console.log(signed.url); // Pre-signed URL for PUT

Cloudflare R2 via S3 API

Use this adapter when you need signed URLs with R2 (the native R2 bindings have limited presigned URL support).

import { createS3Storage } from '@arraypress/storage-s3';

const storage = createS3Storage({
  bucket: 'my-bucket',
  region: 'auto',
  endpoint: 'https://ACCOUNT_ID.r2.cloudflarestorage.com',
  accessKeyId: env.R2_ACCESS_KEY_ID,
  secretAccessKey: env.R2_SECRET_ACCESS_KEY,
  publicUrl: 'https://media.mystore.com',
});

MinIO (Self-Hosted S3)

import { createS3Storage } from '@arraypress/storage-s3';

const storage = createS3Storage({
  bucket: 'my-bucket',
  region: 'us-east-1',
  endpoint: 'http://localhost:9000',
  accessKeyId: 'minioadmin',
  secretAccessKey: 'minioadmin',
  forcePathStyle: true, // Required for MinIO
});

With Hono

import { Hono } from 'hono';
import { createS3Storage } from '@arraypress/storage-s3';

const app = new Hono();

app.post('/upload', async (c) => {
  const storage = createS3Storage({
    bucket: 'my-bucket',
    region: 'us-east-1',
    accessKeyId: process.env.AWS_ACCESS_KEY_ID,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
  });

  const body = await c.req.arrayBuffer();

  const result = await storage.upload({
    key: `uploads/${Date.now()}.jpg`,
    body: new Uint8Array(body),
    contentType: 'image/jpeg',
  });

  return c.json(result);
});

Multipart Uploads

const mpu = await storage.createMultipartUpload('large-file.zip', {
  contentType: 'application/zip',
});

const part1 = await mpu.uploadPart(1, chunk1);
const part2 = await mpu.uploadPart(2, chunk2);

await mpu.complete([part1, part2]);

API Reference

createS3Storage(options): Storage

Creates a Storage adapter backed by any S3-compatible service.

Options

Option Type Required Description
bucket string Yes S3 bucket name
region string Yes AWS region (e.g. 'us-east-1'). Use 'auto' for R2.
endpoint string No S3-compatible endpoint URL
accessKeyId string Yes AWS access key ID
secretAccessKey string Yes AWS secret access key
publicUrl string No Public URL prefix for getPublicUrl()
forcePathStyle boolean No Force path-style URLs (required for MinIO). Default: false.

Re-exported from @arraypress/storage

  • Storage interface
  • StorageError class
  • contentHash(), contentAddressedKey(), safeDisposition() helpers
  • All type definitions

License

MIT

About

S3-compatible storage adapter for @arraypress/storage (AWS S3, R2 via S3 API, MinIO)

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors