Skip to content

feat(storage): add CDN cache purging for files and buckets - #1358

Open
AndroidPoet wants to merge 1 commit into
supabase:mainfrom
AndroidPoet:feat/storage-purge-cdn-cache
Open

AndroidPoet wants to merge 1 commit into
supabase:mainfrom
AndroidPoet:feat/storage-purge-cdn-cache

Conversation

@AndroidPoet

Copy link
Copy Markdown
Contributor

Adds purgeCache(path:transformationsOnly:) on a bucket's file API and purgeBucketCache(_:transformationsOnly:) on the Storage client, over Storage's DELETE /cdn/{bucket}/{path} and DELETE /cdn/{bucket} endpoints. After replacing a file at the same path, a backend can drop the stale CDN copy instead of waiting out cacheControl or adding a cache-busting parameter to every URL.

try await supabase.storage.from("avatars").purgeCache(path: "user123.png")
try await supabase.storage.purgeBucketCache("avatars", transformationsOnly: true)

Marks storage.file_buckets.purge_cache and storage.file_buckets.purge_bucket_cache implemented in sdk-compliance.yaml. The JS and Flutter clients already ship both.

Shape

  • Both return nothing, like emptyBucket and deleteBucket. Storage answers {"message":"success"}, which carries nothing a caller can act on.
  • transformationsOnly: becomes ?transformations=true, sent only when true. JS and Flutter name it transformations, but transformations: true reads as "purge the variants too", when it actually purges only the variants and leaves the original cached.
  • The file path goes through the same _getFinalPath and appendingPathComponent as info and exists, so a leading / is stripped and the key is percent-encoded. The JS client first shipped this without encoding and fixed it afterwards (fix(storage): url-encode object key in CDN purge methods supabase-js#2545); purgeCachePercentEncodesThePath pins it here.
  • The bucket id is interpolated as-is, like every other bucket route in this client.

Worth knowing

  • Storage serves these routes only to the service role, and only when a CDN purge endpoint is configured (CDN_PURGE_ENDPOINT_URL, plus the purgeCache tenant feature on multi-tenant deployments). The doc comments say so.
  • The bucket route and the transformations flag arrived in Storage v1.61.0 (feat: add ability to purge cdn for whole buckets, tenant, and transformations storage#1133). On an older self-hosted Storage, purgeBucketCache gets a route-not-found 404, and purgeCache(path:transformationsOnly: true) purges the whole file, because the older file route ignores the query.

Testing

Five request-snapshot tests: a file, a file with transformationsOnly, a file path that needs percent-encoding, a bucket, and a bucket with transformationsOnly. Dropping the query item makes both transformationsOnly tests fail.

I also ran all four calls through the SDK with a throwaway test (not part of this PR) against Storage v1.77.4 on the local stack, with CDN_PURGE_ENDPOINT_URL pointed at a stub that logs what Storage forwards:

POST /purge {"type":"object","tenant":{"ref":"stub"},"bucketId":"avatars","objectName":"folder/my file.png"}
POST /purge {"type":"object-transforms","tenant":{"ref":"stub"},"bucketId":"avatars","objectName":"folder/my file.png"}
POST /purge {"type":"bucket","tenant":{"ref":"stub"},"bucketId":"avatars"}
POST /purge {"type":"bucket-transforms","tenant":{"ref":"stub"},"bucketId":"avatars"}

The two file calls passed folder/my file.png and /folder/my file.png, and both reached the purge endpoint as the same object name. The bucket call with the anon key threw StorageError with kind .server, status 403 and Access denied: Invalid role.

The capability matrix checks from validate-sdk-compliance-swift.yml (pinned capability-matrix-v1.6.0) pass locally against main, with symbol graphs dumped and normalized the way CI does it.

$ swift test --skip IntegrationTests   # exit 0
8 test runs, all passed: 1332 tests in 134 suites, 171 of them in StorageTests

$ swift-format lint --recursive --strict Sources Tests   # exit 0
$ ./scripts/spell-check.sh   # exit 0, 404 files checked, 0 issues
$ ./scripts/test-docs.sh   # exit 0, no warnings from the changed files

Review first

The transformationsOnly: label, which departs from the JS and Flutter spelling on purpose.

Adds `StorageFileApi.purgeCache(path:transformationsOnly:)` and
`SupabaseStorageClient.purgeBucketCache(_:transformationsOnly:)`, covering
`storage.file_buckets.purge_cache` and `storage.file_buckets.purge_bucket_cache`.
@AndroidPoet
AndroidPoet requested review from a team and grdsdev as code owners September 16, 2026 18:52
@coderabbitai

coderabbitai Bot commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 19560064-9f7c-48e7-8bcd-dbf741e72953

📥 Commits

Reviewing files that changed from the base of the PR and between a61ef23 and dcbbee3.

📒 Files selected for processing (6)
  • Sources/Storage/StorageFileApi.swift
  • Sources/Storage/SupabaseStorage.swift
  • Sources/Storage/SupabaseStorageClient+Buckets.swift
  • Tests/StorageTests/StorageBucketAPITests.swift
  • Tests/StorageTests/StorageFileAPITests.swift
  • sdk-compliance.yaml

Included review availability: Your plan provides up to 4 included reviews per hour; 3 remain after this review.


📝 Summary

Summary by CodeRabbit

  • New Features

    • Added options to purge the cache for an entire storage bucket or an individual file.
    • Added support for purging only transformed file variants.
    • File paths, including spaces, are safely encoded in purge requests.
  • Documentation

    • Updated storage API documentation to include cache management operations.

Walkthrough

Storage adds file-level and bucket-level cache purge APIs. Both APIs send DELETE requests to CDN cache endpoints. When transformationsOnly is true, each request includes transformations=true. File-level requests preserve percent-encoded paths. Tests cover standard requests, transformation-only requests, and file paths containing spaces. SDK compliance entries now mark both capabilities as implemented.

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant StorageSDK
  participant CDNCacheEndpoint
  Caller->>StorageSDK: Request file or bucket cache purge
  StorageSDK->>CDNCacheEndpoint: DELETE cache endpoint
  CDNCacheEndpoint-->>StorageSDK: Success response
  StorageSDK-->>Caller: Completion
Loading

Priority: ➖ Normal

Change: Feature

Merge Risk: ⚪ Minimal · up to dcbbe

The new cache-purge APIs are covered for file, bucket, transformation-only, and encoded-path requests. No actionable merge risk remains.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant