Skip to content

feat(plugin-cloud-storage): implement prefix option across all adapters#16213

Closed
JarrodMFlesch wants to merge 14 commits intomainfrom
worktree-add-prefix-to-storage-adapters
Closed

feat(plugin-cloud-storage): implement prefix option across all adapters#16213
JarrodMFlesch wants to merge 14 commits intomainfrom
worktree-add-prefix-to-storage-adapters

Conversation

@JarrodMFlesch
Copy link
Copy Markdown
Contributor

Summary

Implements the existing prefix option across all storage adapters. While R2 already used this option for organizational namespacing (storing files under paths like my-project/uploads/image.png), the other adapters (S3, GCS, Azure, Vercel Blob) weren't using it. This makes the feature functional across all storage adapters except Uploadthing, which doesn't support custom paths.

The implementation extracts shared sanitization logic into a sanitizePrefix utility and updates joinPrefixes to distinguish between config-controlled prefixes (trusted) and user-controlled prefixes (sanitized).

…zation

Add utility function to normalize and join multiple prefix segments.
Handles trailing slashes, empty values, and path traversal protection.
- Add prefix option to R2StorageOptions for base prefix across all files
- Update handleUpload, handleDelete, handleMultiPartUpload to use joinPrefixes
- Fix staticHandler to use getFilePrefix (dynamic lookup) instead of static prefix
- Update initClientUploads to pass basePrefix to server handler
Add prefix option to GcsStorageOptions that prepends a base path to all
file keys. Uses joinPrefixes utility to combine basePrefix with
collection-level prefix. Updated all key-constructing functions:
handleUpload, handleDelete, staticHandler, generateURL, and
generateSignedURL.
- Add collections for testing basePrefix (MediaWithBasePrefix, MediaWithBasePrefixAndCollectionPrefix)
- Add tests for upload with basePrefix only
- Add tests for upload with basePrefix + collection prefix
- Add tests for delete at basePrefix path
- Add tests for delete at basePrefix + collection prefix path
- Configure S3 storage with basePrefix option in test config
- Separate basePrefix collections into their own S3 adapter instance
- Add cleanup for basePrefix upload tests to delete created documents
Add documentation for the new `prefix` option at the adapter level for all
storage adapters. This includes:

- Added `prefix` to configuration options tables for all adapters (Vercel Blob,
  S3, Azure, GCS, Uploadthing, R2)
- Added Configuration Options table for R2 adapter (was missing)
- Added `prefix` to Plugin options table for plugin-cloud-storage
- Updated Collection-specific options `prefix` description to clarify how it
  combines with adapter-level prefix
- Added new "Prefix Namespacing" section explaining:
  - How adapter-level and collection-level prefixes work together
  - Complete example showing prefix usage patterns
  - Use cases (multi-environment, multi-project, organizational namespacing)
…takes object

- Extract sanitizePrefix to shared utility
- joinPrefixes now takes { basePrefix, prefix } object
- Only sanitizes prefix (user-controlled), not basePrefix (config)
- All storage adapters updated to new signature
…o-storage-adapters

# Conflicts:
#	packages/plugin-cloud-storage/src/utilities/getFilePrefix.ts
#	packages/storage-azure/src/staticHandler.ts
#	packages/storage-gcs/src/staticHandler.ts
#	packages/storage-r2/src/staticHandler.ts
#	packages/storage-vercel-blob/src/staticHandler.ts
@JarrodMFlesch JarrodMFlesch requested a review from denolfe as a code owner April 8, 2026 17:45
@JarrodMFlesch JarrodMFlesch changed the title feat(storage-adapters): implement prefix option across all adapters feat(plugin-cloud-storage): implement prefix option across all adapters Apr 8, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 8, 2026

📦 esbuild Bundle Analysis for payload

This analysis was generated by esbuild-bundle-analyzer. 🤖
This PR introduced no changes to the esbuild bundle! 🙌

@JarrodMFlesch
Copy link
Copy Markdown
Contributor Author

Closed in favor of #16230

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant