Skip to content

Releases: maximseshuk/payload-storage-bunny

v3.0.0

Choose a tag to compare

@github-actions github-actions released this 05 Aug 22:39

A full rewrite of the plugin: per-collection zones and libraries, browser-direct uploads, S3-compatible storage, IP-locked signed URLs, a setup wizard, and a new documentation site.

Requires Payload CMS 3.83+ and Node.js 22+.

Important

Read this before upgrading. Four things change behavior — one of them touches your data, one of them sends a request from your server.

  1. Stream metadata moved into a stored bunnyData field, replacing bunnyVideoId / bunnyVideoMeta. Existing projects must run the data migration: on Postgres and SQLite the legacy columns are dropped the moment the v3 schema is pushed, so migrate before that. Skipping it means broken thumbnails, missing resolutions, and videoId queries returning nothing.
  2. Config keys were renamed or removed. Most of them throw at boot with a targeted message, so a v2 config fails fast instead of behaving oddly: apiKeyaccountApiKey, stream.tus.uploadTimeoutstream.tus.expiresIn, stream.tus.mimeTypesstream.mimeTypes, purge.apiKey and adminThumbnail removed, experimental dropped. Full table.
  3. Anonymous telemetry is on by default. It reports boolean feature flags, plugin and runtime versions, and a salted one-way project hash — no names, paths, URLs, or keys, and the server never reads your IP. Turn it off with telemetry: false, DO_NOT_TRACK=1, Payload's own opt-out, or by running in CI. Exactly what is sent.
  4. The in-plugin media preview UI is gone. Video preview now lives in the separate media-preview plugin; this package ships only a thin adapter on the ./media-preview subpath.

Step-by-step: Upgrade guide · Reference: Docs

⚠️ Breaking Changes

🚀 Features

  • Per-collection zones and libraries — a collection can point at its own storage zone or stream library, every setting is overridable per collection, and storage or stream can be switched off for one collection (2b9752e, df67c58, 30e42b3, eff125f)
  • Client-direct uploads — the browser sends files straight to Bunny, bypassing your server. The transport is chosen automatically: presigned S3 when the zone has storage.s3, otherwise a deployed Edge Script (9af1403, 4b98063)
  • S3-compatible storage backend — SigV4 upload and delete through a tiny dependency instead of the AWS SDK (28986f4)
  • Signed URLs with per-client IP locking and absolute expiry — a link can be bound to one IPv4 address and to a fixed moment, not just a sliding window (ce6bc52)
  • CLIinit provisions Bunny resources and prints your plugin config plus .env lines; bunny:deploy-edge-script deploys the upload Edge Script with per-zone secrets (8fe56c8)
  • Smaller additions — dynamic per-document prefix, animated WebP thumbnails for Stream, stream.referer for referrer-blocked libraries, and OpenAPI metadata consumed by payload-plugin-openapi (7c3e570, 6b52335, 1a0fa1d)

🐛 Bug Fixes

  • Signed URLs — the client IP is appended last in the token hash, matching Bunny's own order; IP-locked links were rejected before (4e9e5d4)
  • Upload responsesurl and thumbnailURL survive handleUpload, and empty bunnyData collapses to null instead of leaking an empty group (e6e7662, b259dcc)
  • Validation — webhook signatures are checked for version and algorithm, per-collection signedUrls and purge fail at boot when their key is missing, and the SQL migration survives a missing legacy column (a4a3dd7, edeeed6, 032867c)
  • Overrides and TUS — per-collection config inherits the global one correctly, and the TUS cleanup task no longer leaves stale sessions behind (6bc48af, 823610b)

🛠 Internals

  • src/ is grouped by runtime and dependency direction — shared → server → payload, one module owning the Bunny HTTP API, one ky client for every outbound request. The boundaries are enforced by lint rules rather than convention (dc4a5ad, 8a0fecd, 59ea19b)
  • Toolchain moved to oxlint, oxfmt, tsdown and tsx; tests split into unit, integration, and live end-to-end runs against real Bunny resources (28127d5, 25cdb35, ae95fc8)

📚 Documentation

The docs were rewritten from scratch and now live at payload-storage-bunny.seshuk.im — configuration reference, guides, an API reference, and a step-by-step upgrade guide (cc5d237, 3c7210c).

Thanks to Mintlify for their open-source program and for the access that made this documentation site possible.


This release took a while to put together. If the plugin saves you time, a star or a coffee is always appreciated — and issues and pull requests are just as welcome.

Full Changelog: v2.2.0...v3.0.0

v2.2.0

Choose a tag to compare

@maximseshuk maximseshuk released this 12 Jul 22:15

This is the final v2.x release before v3.0.0.

🚀 New Features

  • TUS checkAccess Body: The TUS checkAccess callback now receives the parsed auth request body as a second argument (collection, filename, filetype, filesize), so you can gate uploads before the video is created (#17 - Thanks to @madaxen86)
  • Dynamic Upload Prefix: The storage prefix can now be set per-document via data.prefix from a collection hook (for example, per-tenant folders); uploads without it are unchanged (#18 - Thanks to @mengidd)

🐛 Bug Fixes

  • URL Transform: Fixed applyUrlTransform throwing on relative (access-controlled) URLs, and existing query parameters are now preserved
  • Storage Query Parameters: Request query parameters are now preserved when proxying storage files through Payload (for example, Bunny Image Optimizer parameters with access control enabled)
  • TUS Save Detection: Fixed post-upload "saved" detection that compared the document update event by object identity instead of its updatedAt
  • Non-Upload Collections: The plugin now fails fast with a clear error when a configured collection has no upload config

🛠️ Development

  • CI: test-build now runs on push and pull requests; workflow actions updated to their latest versions, pnpm is resolved from the packageManager field, and npm provenance is enabled for publishing

Full Changelog: v2.1.1...v2.2.0

v2.1.1

Choose a tag to compare

@maximseshuk maximseshuk released this 05 Oct 10:22

🐛 Bug Fixes

  • Collection Hooks: Fixed issue where user's collection hooks (beforeChange, afterRead,
    afterDelete, etc.) were being lost when the plugin initialized
  • Thumbnail Config: Fixed bug where setting thumbnail: false at the collection level wasn't
    working properly

🌍 Translations

  • Tamil: Added Tamil (ta) language support

🛠️ Development

  • Dependencies Update: Updated development dependencies to Payload 3.57

Full Changelog: v2.1.0...v2.1.1

v2.1.0

Choose a tag to compare

@maximseshuk maximseshuk released this 29 Sep 15:53

Users upgrading from v2.0.x should follow the Migration Guide to update their configuration.

🚀 New Features

  • Stream-Only Support: Plugin now supports using only Bunny Stream without Bunny Storage configuration
  • Thumbnail Config Rename: adminThumbnail configuration renamed to thumbnail for better clarity and consistency

🐛 Bug Fixes

  • Thumbnail Time Validation: Fixed issue where thumbnailTime: 0 was incorrectly treated as invalid value (#12 - Thanks to @christophemenager for reporting)

🛠️ Improvements

  • Backward Compatibility: Old adminThumbnail config still supported with deprecation warning (will be removed in v2.2.0)

📝 Documentation

  • GitHub Callouts: Enhanced documentation with proper GitHub callouts
  • Stream-Only Examples: Added configuration examples for stream-only setups

Full Changelog: v2.0.2...v2.1.0

v2.0.2

Choose a tag to compare

@maximseshuk maximseshuk released this 26 Sep 13:18

🛠️ Improvements

  • Build Configuration: Improved build configuration with resolveFully: true option for better module resolution

📝 Documentation

  • Added Bunny.net referral banner and partnership disclosure to README

Full Changelog: v2.0.1...v2.0.2

v2.0.1

Choose a tag to compare

@maximseshuk maximseshuk released this 22 Sep 10:57

🚀 New Features

  • Admin Thumbnail Size Selection: Enhanced admin thumbnail handler with sizeName parameter support for using specific upload sizes
  • Multi-Language Support: Complete internationalization with translations for all 43 PayloadCMS supported languages

🐛 Bug Fixes

  • Signed URL Generation: Fixed URL decoding in signed URL generation for proper path handling

📝 Documentation

  • Improved consistency across documentation and better onboarding experience

Full Changelog: v2.0.0...v2.0.1

v2.0.0

Choose a tag to compare

@maximseshuk maximseshuk released this 05 Sep 13:58

⚠️ Breaking Changes

This is a major version upgrade with breaking changes:

  1. Payload CMS Version: Requires Payload CMS 3.53.0 or higher
  2. Configuration Structure:
    • Removed options wrapper - move all configs to top level
    • stream.libraryId now requires number instead of string
    • stream.mp4Fallback is now boolean instead of { enabled: boolean }
    • purge.enabled removed - purging enabled by presence of apiKey
  3. Removed Features:
    • experimental.replaceSaveButtonComponent no longer needed or supported

Users upgrading from v1.x must follow the Migration Guide to update their configuration.

🚀 New Features

  • TUS Resumable Uploads: Support for resumable uploads using TUS protocol
  • Signed URLs: Secure file access with geo-restrictions and expiration
  • Advanced URL Transform: Customize file URLs with query parameters or custom functions
  • Stream Cleanup: Automatic cleanup of failed upload sessions

See README.md for detailed configuration examples and usage.

🛠️ Improvements

  • Simplified Configuration: Flattened configuration structure for better developer experience
  • Code Reorganization: Split handlers into separate modules for better maintenance and performance

Full Changelog: v1.2.2...v2.0.0

v1.2.2

Choose a tag to compare

@maximseshuk maximseshuk released this 15 Aug 11:51

✨ New Features

  • Experimental Features: Added experimental options to address Payload CMS issues. Introduced experimental.replaceSaveButtonComponent option as a temporary workaround for Payload CMS issue #13182 that causes unnecessary file re-downloads during field updates.

    Documentation

🛠️ Development

  • Development Environment: Added Payload CMS development playground

Full Changelog: v1.2.1...v1.2.2

v1.2.1

Choose a tag to compare

@maximseshuk maximseshuk released this 16 Jul 15:31

🐛 Bug Fixes

  • Fixed Upload Hanging Issue: Resolved issue where image uploads would get stuck in loading state with submitting indicator (#6 - Thanks to @alexisoney and @jsc604 for reporting and providing detailed investigation)

    • Pinned ky dependency to version 1.7.5 to avoid hanging bug in 1.8.1 on Node versions below 22
    • Ensures compatibility with Node versions below 22
  • Fixed Main Filename Assignment: Resolved issue where main filename was randomly being set to one of the 'sizes' filenames instead of the original filename (#7 - Thanks to @DavidOliver and @alexisoney for reporting and providing solution)

    • Removed filename mutation in upload handler following S3 adapter pattern
    • Fixed filename handling logic to ensure main image retains correct filename
    • Improved filename consistency across different image sizes

🛠️ Improvements

  • Code Quality: Minor code formatting improvements and refactoring for better maintainability
    • Updated Prettier configuration and ignore rules
    • Improved code consistency across the codebase

Full Changelog: v1.2.0...v1.2.1

v1.2.0

Choose a tag to compare

@maximseshuk maximseshuk released this 23 Mar 16:02

🚀 New Features

  • Automatic CDN Cache Purging for Storage Files
    • Automatically purge CDN cache after file uploads and deletions
    • Configurable with options for async operation
    • Ensures visitors always see the most up-to-date content

🛠️ Improvements

  • Admin Thumbnail Configuration: Enhanced documentation for using existing appendTimestamp option with Bunny CDN's Vary Cache settings

🐛 Bug Fixes

  • Error with cropping or replacing images (#3 - Thanks to @PP-Tom for reporting)
  • Can't update metadata on an existing image (#4 - Thanks to @wongdigital for reporting)

📝 Documentation

  • Added new "CDN Cache Management" section explaining both purging and how to properly configure Bunny CDN's Vary Cache to work with timestamp parameters
  • Updated examples with cache purging configuration
  • Clearer instructions for obtaining and using the Bunny API key

Full Changelog: v1.1.0...v1.2.0