X Enterprises
fastify-ximagepipeline

S3 / R2 Utilities

Low-level S3-compatible storage helpers for uploading, downloading, deleting, listing, and signing objects — importable standalone from the pipeline plugin.

S3 / R2 Utilities

Imported from @xenterprises/fastify-ximagepipeline/s3. These helpers wrap the AWS SDK v3 S3Client for use with Cloudflare R2 or any S3-compatible service. The plugin uses them internally for staging uploads and processed media storage; they are also available for standalone use in scripts or custom workers.

Usage

import {
  initializeS3Client,
  uploadToS3,
  downloadFromS3,
  deleteFromS3,
  listFromS3,
  getSignedUrlForS3,
  getPublicUrl,
  batchDeleteFromS3,
} from '@xenterprises/fastify-ximagepipeline/s3'

Functions

initializeS3Client(config)

Create a configured S3Client instance for R2 or an AWS-compatible endpoint.

Parameters:

NameTypeRequiredDescription
config.endpointstringYesR2 or S3-compatible endpoint URL.
config.accessKeyIdstringYesAccess key ID.
config.secretAccessKeystringYesSecret access key.
config.bucketstringYesBucket name.
config.regionstringNoAWS region. Default "auto" (correct for R2).

Returns: S3Client — An initialized AWS SDK v3 S3Client.


uploadToS3(client, bucket, key, buffer, options?)

Upload a buffer to S3/R2 with optional metadata and cache control headers.

Parameters:

NameTypeRequiredDescription
clientS3ClientYesInitialized S3 client.
bucketstringYesTarget bucket name.
keystringYesObject key (storage path).
bufferBufferYesFile content to upload.
options.contentTypestringNoMIME type. Defaults to "application/octet-stream".
options.metadataRecord<string, string>NoCustom S3 metadata key-value pairs.
options.cacheControlstringNoCache-Control header value.
options.aclstringNoObject ACL (e.g. "public-read").

Returns: Promise<void>


downloadFromS3(client, bucket, key)

Download an object from S3/R2 as a buffer.

Parameters:

NameTypeRequiredDescription
clientS3ClientYesInitialized S3 client.
bucketstringYesBucket name.
keystringYesObject key to download.

Returns: Promise<Buffer>


deleteFromS3(client, bucket, key)

Delete a single object from S3/R2.

Parameters:

NameTypeRequiredDescription
clientS3ClientYesInitialized S3 client.
bucketstringYesBucket name.
keystringYesObject key to delete.

Returns: Promise<void>


listFromS3(client, bucket, prefix)

List all objects under a given key prefix.

Parameters:

NameTypeRequiredDescription
clientS3ClientYesInitialized S3 client.
bucketstringYesBucket name.
prefixstringYesKey prefix to filter by (e.g. "staging/", "media/user-123/").

Returns: Promise<Array<{ key: string; size: number; lastModified: Date }>> — Objects matching the prefix.


getSignedUrlForS3(client, bucket, key, expiresIn?)

Generate a pre-signed URL for temporary access to a private object.

Parameters:

NameTypeRequiredDescription
clientS3ClientYesInitialized S3 client.
bucketstringYesBucket name.
keystringYesObject key to sign.
expiresInnumberNoExpiry in seconds. Default 3600 (1 hour).

Returns: Promise<string> — A pre-signed URL valid for expiresIn seconds.


getPublicUrl(r2Config, key)

Generate a public URL for an object without signing.

Parameters:

NameTypeRequiredDescription
r2ConfigobjectYesThe r2 config object used to initialize the plugin (must include endpoint and bucket).
keystringYesObject key.

Returns: string — Full public URL: https://<endpoint>/<bucket>/<key>.


batchDeleteFromS3(client, bucket, prefix)

Delete up to 1000 objects matching a key prefix in a single S3 batch-delete call.

Parameters:

NameTypeRequiredDescription
clientS3ClientYesInitialized S3 client.
bucketstringYesBucket name.
prefixstringYesKey prefix — all matching objects will be deleted.

Returns: Promise<{ deleted: number }> — Count of objects removed.


Examples

Initialize a client and upload a file

import { initializeS3Client, uploadToS3, getPublicUrl } from '@xenterprises/fastify-ximagepipeline/s3'

const r2Config = {
  endpoint: process.env.R2_ENDPOINT,
  accessKeyId: process.env.R2_ACCESS_KEY_ID,
  secretAccessKey: process.env.R2_SECRET_ACCESS_KEY,
  bucket: process.env.R2_BUCKET,
}

const client = initializeS3Client(r2Config)

const buffer = fs.readFileSync('./thumbnail.webp')
await uploadToS3(client, r2Config.bucket, 'media/thumb.webp', buffer, {
  contentType: 'image/webp',
  cacheControl: 'public, max-age=31536000',
})

const url = getPublicUrl(r2Config, 'media/thumb.webp')
console.log(url) // https://r2.example.com/my-bucket/media/thumb.webp

Generate a signed URL for a private asset

import { initializeS3Client, getSignedUrlForS3 } from '@xenterprises/fastify-ximagepipeline/s3'

const client = initializeS3Client(r2Config)

fastify.get('/originals/:key', async (request, reply) => {
  const url = await getSignedUrlForS3(
    client,
    r2Config.bucket,
    `originals/${request.params.key}`,
    900 // 15 minutes
  )
  return reply.redirect(url)
})

Clean up a user's staging files

import { initializeS3Client, batchDeleteFromS3 } from '@xenterprises/fastify-ximagepipeline/s3'

const client = initializeS3Client(r2Config)

const { deleted } = await batchDeleteFromS3(
  client,
  r2Config.bucket,
  `staging/user-${userId}/`
)

console.log(`Removed ${deleted} staging objects`)

Download then reprocess

import { initializeS3Client, downloadFromS3, uploadToS3 } from '@xenterprises/fastify-ximagepipeline/s3'
import { processImage } from '@xenterprises/fastify-ximagepipeline/image'

const client = initializeS3Client(r2Config)

const original = await downloadFromS3(client, r2Config.bucket, 'originals/photo.jpg')
const { variants } = await processImage(original, 'gallery', pluginConfig)

for (const [name, buf] of Object.entries(variants)) {
  await uploadToS3(client, r2Config.bucket, `media/photo-${name}.webp`, buf, {
    contentType: 'image/webp',
  })
}

AI Context

import: "@xenterprises/fastify-ximagepipeline/s3"
use-when: >
  When you need direct S3/R2 operations (upload, download, delete, list, signed URLs)
  outside of the plugin's automatic pipeline — e.g. in migration scripts, custom workers,
  or tooling that shares the same R2 bucket as the image pipeline.
functions:
  - initializeS3Client: Create an S3Client from R2/S3 config
  - uploadToS3: Upload a buffer with metadata and cache headers
  - downloadFromS3: Download an object as a Buffer
  - deleteFromS3: Delete a single object by key
  - listFromS3: List objects by key prefix
  - getSignedUrlForS3: Generate a temporary pre-signed URL (default 1 hour)
  - getPublicUrl: Build a public URL without signing
  - batchDeleteFromS3: Delete up to 1000 objects by prefix in one call
Copyright © 2026