Skip to content

Commit 46eb0ab

Browse files
authored
feat(storage): add purgeBucketCache to invalidate CDN cache for a whole bucket (#1608)
## Summary Adds `StorageBucketApi.purgeBucketCache(id, {transformations})` to invalidate the CDN cache for every object in a bucket. Issues `DELETE /cdn/{bucket}` against the storage base URL and returns the server's success message. When `transformations` is `true`, only the resized/formatted variants are purged, leaving the original cached objects intact; otherwise the bucket cache is purged. Requires the service-role key and the tenant `purgeCache` feature enabled on the storage server. > Stacked on top of #1607 (`SDK-1331`, object-level purge). Base this PR against `main` once #1607 merges. **Outcome:** implemented **Reference:** supabase-js PR [#2429](supabase/supabase-js#2429) (`storage.file_buckets.purge_bucket_cache`) ## Compliance matrix - `storage.file_buckets.purge_bucket_cache` → `implemented` (symbol `StorageBucketApi.purgeBucketCache`) ## Tests Added unit tests in `packages/storage_client/test/basic_test.dart` covering the DELETE endpoint/URL and the `transformations` query parameter. SDK-1332
1 parent 3ad736b commit 46eb0ab

3 files changed

Lines changed: 62 additions & 0 deletions

File tree

packages/storage_client/lib/src/storage_bucket_api.dart

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,35 @@ class StorageBucketApi {
134134
return (response as Map<String, dynamic>)['message'] as String;
135135
}
136136

137+
/// Purges the CDN cache for an entire bucket.
138+
///
139+
/// Invalidates the CDN cache for every object in the bucket [id]. Maps to
140+
/// `DELETE /cdn/{bucket}` on the storage server.
141+
///
142+
/// When [transformations] is `true`, only the resized/formatted variants are
143+
/// purged, leaving the original cached files intact. When omitted the bucket
144+
/// cache is purged.
145+
///
146+
/// Requires the service-role key and the tenant `purgeCache` feature to be
147+
/// enabled on the storage server.
148+
Future<String> purgeBucketCache(
149+
String id, {
150+
bool transformations = false,
151+
}) async {
152+
var requestUrl = Uri.parse('$url/cdn/$id');
153+
if (transformations) {
154+
requestUrl = requestUrl.replace(
155+
queryParameters: {'transformations': 'true'},
156+
);
157+
}
158+
final response = await storageFetch.delete(
159+
requestUrl.toString(),
160+
{},
161+
options: FetchOptions(headers),
162+
);
163+
return (response as Map<String, dynamic>)['message'] as String;
164+
}
165+
137166
/// Creates a new analytics bucket backed by the Apache Iceberg table format.
138167
///
139168
/// [id] is the unique identifier for the bucket you are creating.

packages/storage_client/test/basic_test.dart

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,35 @@ void main() {
154154
expect(response, 'Deleted');
155155
});
156156

157+
test('should purgeBucketCache issuing DELETE to /cdn/{bucket}', () async {
158+
customHttpClient.response = {'message': 'success'};
159+
160+
final response = await client.purgeBucketCache('test_bucket');
161+
162+
final request = customHttpClient.receivedRequests.last;
163+
expect(request.method, 'DELETE');
164+
expect(
165+
request.url.toString(),
166+
endsWith('/storage/v1/cdn/test_bucket'),
167+
);
168+
expect(request.url.query, isEmpty);
169+
expect(response, 'success');
170+
});
171+
172+
test('should purgeBucketCache with transformations query param', () async {
173+
customHttpClient.response = {'message': 'success'};
174+
175+
final response = await client.purgeBucketCache(
176+
'test_bucket',
177+
transformations: true,
178+
);
179+
180+
final request = customHttpClient.receivedRequests.last;
181+
expect(request.method, 'DELETE');
182+
expect(request.url.queryParameters['transformations'], 'true');
183+
expect(response, 'success');
184+
});
185+
157186
test('should create analytics bucket', () async {
158187
customHttpClient.response = testAnalyticsBucketJson;
159188

sdk-compliance.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,10 @@ features:
442442
status: implemented
443443
symbols:
444444
- StorageFileApi.purgeCache
445+
storage.file_buckets.purge_bucket_cache:
446+
status: implemented
447+
symbols:
448+
- StorageBucketApi.purgeBucketCache
445449
storage.file_buckets.create_signed_url:
446450
status: implemented
447451
symbols:

0 commit comments

Comments
 (0)