Skip to content

Repository files navigation

opennext-oss-provider

An object storage provider library for OpenNext.js, supporting AWS S3 in Next.js environments and R2 storage in Cloudflare environments.

Features

  • ✅ Support for AWS S3 storage (for standard Next.js environments)
  • ✅ Support for Cloudflare R2 storage (for Cloudflare Workers environments)
  • ✅ Unified storage interface for easy switching between different environments
  • ✅ TypeScript support with complete type definitions
  • ✅ Automatic runtime environment detection with intelligent storage provider selection

Installation

Using npm:

npm install opennext-oss-provider

Using yarn:

yarn add opennext-oss-provider

Using pnpm:

pnpm add opennext-oss-provider

Usage

Basic Usage

import { createOssClient, StorageConfig } from 'opennext-oss-provider'

// Configure S3 storage (Next.js environment)
const s3Config: StorageConfig = {
  provider: 's3',
  accessKeyId: 'your-access-key',
  secretAccessKey: 'your-secret-key',
  region: 'us-east-1',
  bucketName: 'your-bucket-name',
  endpoint: 'https://s3.amazonaws.com' // Optional, supports custom endpoints
}

// Configure R2 storage (Cloudflare Workers environment)
const r2Config: StorageConfig = {
  provider: 'r2',
  bucketName: 'your-bucket-name',
  bindingName: 'R2_BUCKET' // Cloudflare Workers binding name
}

// Create storage client
const client = createOssClient(s3Config) // or r2Config

// Store object
await client.putObject('path/to/file.json', JSON.stringify({ data: 'example' }))

// Get object
const content = await client.getObject('path/to/file.json')
console.log(JSON.parse(content))

Using S3 in Next.js

// app/api/upload/route.ts
import { createOssClient } from 'opennext-oss-provider'
import { NextRequest, NextResponse } from 'next/server'

const s3Client = createOssClient({
  provider: 's3',
  accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
  secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
  region: process.env.AWS_REGION!,
  bucketName: process.env.S3_BUCKET_NAME!
})

export async function POST(request: NextRequest) {
  const data = await request.json()
  
  try {
    await s3Client.putObject(`uploads/${Date.now()}.json`, JSON.stringify(data))
    return NextResponse.json({ success: true })
  } catch (error) {
    return NextResponse.json({ error: 'Upload failed' }, { status: 500 })
  }
}

Using R2 in Cloudflare Workers

First, configure R2 binding in wrangler.toml:

[[r2_buckets]]
binding = "R2_BUCKET"
bucket_name = "your-bucket-name"

Then use it in your code:

// worker.ts
import { createOssClient } from 'opennext-oss-provider'

export default {
  async fetch(request: Request, env: Env) {
    const r2Client = createOssClient({
      provider: 'r2',
      bucketName: 'your-bucket-name',
      bindingName: 'R2_BUCKET'
    })
    
    // Handle upload
    if (request.method === 'POST') {
      const data = await request.json()
      await r2Client.putObject('data.json', JSON.stringify(data))
      return new Response('Uploaded', { status: 200 })
    }
    
    // Handle read
    if (request.method === 'GET') {
      const content = await r2Client.getObject('data.json')
      return new Response(content, {
        headers: { 'Content-Type': 'application/json' }
      })
    }
    
    return new Response('Method not allowed', { status: 405 })
  }
}

Adaptive Environment Configuration

Automatically select storage provider based on runtime environment:

import { createOssClient, StorageConfig } from 'opennext-oss-provider'

function getStorageConfig(): StorageConfig {
  // Detect if running in Cloudflare Workers environment
  if (typeof globalThis.caches !== 'undefined' && 'default' in globalThis.caches) {
    return {
      provider: 'r2',
      bucketName: process.env.R2_BUCKET_NAME!,
      bindingName: 'R2_BUCKET'
    }
  }
  
  // Default to S3
  return {
    provider: 's3',
    accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
    region: process.env.AWS_REGION!,
    bucketName: process.env.S3_BUCKET_NAME!
  }
}

const client = createOssClient(getStorageConfig())

API Documentation

IStorageClient Interface

All storage clients implement the unified IStorageClient interface:

interface IStorageClient {
  // Get object content
  getObject(key: string): Promise<string>
  
  // Store object
  putObject(key: string, content: string): Promise<void>
  
  // Get storage provider type
  getProvider(): StorageProvider
  
  // Get configuration
  getConfig(): StorageConfig
}

Configuration Types

S3Config

type S3Config = {
  provider: 's3'
  accessKeyId: string       // AWS access key ID
  secretAccessKey: string   // AWS secret access key
  region: string           // AWS region
  bucketName: string       // S3 bucket name
  endpoint?: string        // Optional: custom endpoint (supports S3-compatible services)
}

R2Config

type R2Config = {
  provider: 'r2'
  bucketName: string       // R2 bucket name
  bindingName: string      // Binding name in Cloudflare Workers
}

Environment Variables Examples

Next.js Environment (.env.local)

AWS_ACCESS_KEY_ID=your-access-key
AWS_SECRET_ACCESS_KEY=your-secret-key
AWS_REGION=us-east-1
S3_BUCKET_NAME=your-s3-bucket

Cloudflare Workers Environment (wrangler.toml)

name = "your-worker"
main = "src/index.ts"
compatibility_date = "2024-01-01"

[vars]
R2_BUCKET_NAME = "your-r2-bucket"

[[r2_buckets]]
binding = "R2_BUCKET"
bucket_name = "your-r2-bucket"

Important Notes

  1. R2 Limitations: R2 client requires running in Cloudflare Workers environment with properly configured R2 bindings.
  2. S3 Permissions: Ensure S3 access keys have read/write permissions for the specified bucket.
  3. Content Type: Current version defaults to storing all content as application/json. To support other types, extend the interface.
  4. Error Handling: Consider adding appropriate error handling and retry mechanisms in production environments.

Development

Build Project

yarn build

Run Tests

yarn test

Code Linting

yarn lint

Contributing

Issues and Pull Requests are welcome!

License

MIT

Related Links

About

An object storage provider library for OpenNext.js, supporting AWS S3 in Next.js environments and R2 storage in Cloudflare environments.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages