JSPM

@paschendale/r2-presigned-url

1.0.0
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 151
  • Score
    100M100P100Q95935F
  • License MIT

Generate presigned URLs for Cloudflare R2 storage using AWS Signature Version 4 - Compatible with Cloudflare Workers

Package Exports

  • @paschendale/r2-presigned-url
  • @paschendale/r2-presigned-url/dist/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@paschendale/r2-presigned-url) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

R2 Presigned URL Generator

A lightweight, zero-dependency TypeScript library for generating presigned URLs for Cloudflare R2 storage using AWS Signature Version 4. Compatible with Cloudflare Workers and Node.js environments.

Features

  • Zero Dependencies - Uses only Web Crypto API and built-in browser/Node.js APIs
  • Cloudflare Workers Compatible - No Node.js-specific dependencies
  • TypeScript Support - Full type definitions included
  • AWS Signature Version 4 - Standard-compliant signature generation
  • Multiple HTTP Methods - Support for PUT, GET, and POST requests
  • Comprehensive Validation - Input validation and error handling
  • Testing Utilities - Built-in test function for debugging

Installation

npm install r2-presigned-url

Quick Start

import { generateR2PresignedUrl, R2Credentials } from 'r2-presigned-url';

const credentials: R2Credentials = {
  R2_ACCESS_KEY_ID: 'your-access-key',
  R2_SECRET_ACCESS_KEY: 'your-secret-key',
  R2_ACCOUNT_ID: 'your-account-id',
  R2_BUCKET: 'my-bucket'
};

const url = await generateR2PresignedUrl(
  {
    key: 'uploads/file.jpg',
    contentType: 'image/jpeg',
    expiresIn: 3600 // 1 hour
  },
  credentials
);

console.log('Presigned URL:', url);

API Reference

generateR2PresignedUrl(options, credentials)

Generates a presigned URL for R2 storage operations.

Parameters

  • options (PresignedUrlOptions):

    • key (string): The object key (path) in the R2 bucket
    • contentType (string): MIME type of the file
    • expiresIn (number): URL expiration time in seconds (max 604800 = 7 days)
    • method (optional): HTTP method - 'PUT' (default), 'GET', or 'POST'
  • credentials (R2Credentials):

    • R2_ACCESS_KEY_ID (string): Cloudflare R2 Access Key ID
    • R2_SECRET_ACCESS_KEY (string): Cloudflare R2 Secret Access Key
    • R2_ACCOUNT_ID (string): Cloudflare Account ID
    • R2_BUCKET (optional): R2 Bucket name (defaults to 'development')

Returns

  • Promise<string>: The presigned URL

testPresignedUrlGeneration(credentials)

Tests the presigned URL generation with sample data.

Parameters

  • credentials (R2Credentials): R2 credentials to test with

Returns

  • Promise<TestResult>: Test results with success status and debug info

Usage Examples

Upload a File

import { generateR2PresignedUrl } from 'r2-presigned-url';

const uploadUrl = await generateR2PresignedUrl(
  {
    key: 'uploads/document.pdf',
    contentType: 'application/pdf',
    expiresIn: 1800 // 30 minutes
  },
  credentials
);

// Use the URL to upload the file
const response = await fetch(uploadUrl, {
  method: 'PUT',
  body: file,
  headers: {
    'Content-Type': 'application/pdf'
  }
});

Download a File

const downloadUrl = await generateR2PresignedUrl(
  {
    key: 'uploads/document.pdf',
    contentType: 'application/pdf',
    expiresIn: 3600,
    method: 'GET'
  },
  credentials
);

// Use the URL to download the file
const response = await fetch(downloadUrl);
const file = await response.blob();

Testing

import { testPresignedUrlGeneration } from 'r2-presigned-url';

const result = await testPresignedUrlGeneration(credentials);

if (result.success) {
  console.log('✅ Test passed!');
  console.log('Generated URL:', result.url);
  console.log('Signature:', result.debug?.signature);
} else {
  console.error('❌ Test failed:', result.error);
}

Cloudflare Workers Example

// workers/index.ts
import { generateR2PresignedUrl } from 'r2-presigned-url';

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    if (request.method === 'POST') {
      const { key, contentType } = await request.json();
      
      const credentials = {
        R2_ACCESS_KEY_ID: env.R2_ACCESS_KEY_ID,
        R2_SECRET_ACCESS_KEY: env.R2_SECRET_ACCESS_KEY,
        R2_ACCOUNT_ID: env.R2_ACCOUNT_ID,
        R2_BUCKET: env.R2_BUCKET
      };

      try {
        const url = await generateR2PresignedUrl(
          {
            key,
            contentType,
            expiresIn: 3600
          },
          credentials
        );

        return new Response(JSON.stringify({ url }), {
          headers: { 'Content-Type': 'application/json' }
        });
      } catch (error) {
        return new Response(
          JSON.stringify({ error: error.message }), 
          { status: 400, headers: { 'Content-Type': 'application/json' } }
        );
      }
    }

    return new Response('Method not allowed', { status: 405 });
  }
};

Environment Variables

For Cloudflare Workers, add these to your wrangler.toml:

[vars]
R2_ACCESS_KEY_ID = "your-access-key"
R2_SECRET_ACCESS_KEY = "your-secret-key"
R2_ACCOUNT_ID = "your-account-id"
R2_BUCKET = "your-bucket-name"

Error Handling

The library throws descriptive errors for common issues:

try {
  const url = await generateR2PresignedUrl(options, credentials);
} catch (error) {
  if (error.message.includes('Missing required R2 credentials')) {
    // Handle missing credentials
  } else if (error.message.includes('Invalid parameters')) {
    // Handle invalid parameters
  } else {
    // Handle other errors
  }
}

Browser Compatibility

This library uses the Web Crypto API, which is supported in:

  • Chrome 37+
  • Firefox 34+
  • Safari 11+
  • Edge 12+
  • Node.js 15+

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests if applicable
  5. Submit a pull request

License

MIT License - see LICENSE file for details.

Changelog

1.0.0

  • Initial release
  • AWS Signature Version 4 implementation
  • Cloudflare Workers compatibility
  • TypeScript support
  • Comprehensive error handling