Open
Conversation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
8aa55b2 to
dc03947
Compare
…tion Coding is not user-configurable; move encoder and decoder as internal properties on StorageClient with fixed snake_case encoding strategy. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
url is now a first-class parameter of StorageClient's init, stored directly on the client rather than nested inside configuration. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Cover every public type, property, initializer, and method in the Storage module with DocC-style doc comments, parameter lists, return/throws descriptions, and ## Example code blocks. Also fix a pre-existing bug where the `fileSizeLimit` and `allowedMimeTypes` property docs were swapped in `BucketOptions`. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…eAPI type name Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…o Types.swift, rename StorageFileApi to StorageFileAPI Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Captures the full v2 API redesign for the Storage module including typed value types (ResizeMode, ImageFormat, SortOrder, StorageByteCount), DownloadBehavior enum, upload progress reporting, method signature consolidation, and backend-verified type corrections. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Introduces StorageByteCount with Int64 backing, factory methods (.bytes/.kilobytes/.megabytes/.gigabytes), and ExpressibleByIntegerLiteral conformance. Replaces raw strings/integers at call sites in future tasks. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…eFormat Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…imit to StorageByteCount Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ation and DownloadBehavior
…ation and DownloadBehavior Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…osure Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… and FileInfo Storage object IDs are uuid columns in the database (gen_random_uuid()), so FileUploadResponse.id and FileInfo.id are typed as UUID instead of String. FileObject.id was already UUID?. Bucket.id remains String (user-defined names). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- BucketOptions: public → isPublic, fileSizeLimit String? → StorageByteCount? - FileSearchView: FileInfo.id UUID → uuidString, SortBy.order String → SortOrder Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rCode - Adds StorageErrorCode (RawRepresentable) with static constants for all known server error strings; new constants are never a breaking change - StorageError gains errorCode: StorageErrorCode, statusCode: Int?, underlyingResponse, underlyingData, isNotFound, isUnauthorized - Removes Decodable conformance; ServerErrorResponse (private) handles JSON decoding in translateStorageError - translateStorageError consolidated to StorageClient (internal); always produces StorageError — HTTPError no longer escapes Storage operations - exists(path:) simplified to a single catch clause using isNotFound Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
grdsdev
commented
Apr 30, 2026
…all sites Replace `.download` with `.withOriginalName` and `.downloadAs(_:)` with `.named(_:)` so the parameter label and case name are no longer identical (`download: .download` → `download: .withOriginalName`). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…r cases Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…current suite interference On Linux, Swift Testing runs suites concurrently. Calling Mocker.removeAll() in init() (which fires before each test) races with other suites' just-registered mocks, causing StorageBucketAPITests to time out. Each test registers mocks for unique URL+method combinations so global cleanup is not needed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…t assertions StorageError now includes underlyingResponse and underlyingData which contain runtime-varying content (headers, raw bytes), making .dump snapshots non- deterministic. Replace with XCTAssertEqual checks on statusCode and message. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Contributor
Author
Code reviewFound 4 issues:
supabase-swift/Sources/Storage/MultipartBuilder.swift Lines 64 to 77 in e9a99e7
supabase-swift/Sources/Storage/StorageError.swift Lines 151 to 161 in e9a99e7
supabase-swift/Sources/Storage/StorageFileAPI.swift Lines 169 to 173 in e9a99e7
supabase-swift/Sources/Storage/StorageClient.swift Lines 314 to 320 in e9a99e7 🤖 Generated with Claude Code - If this code review was useful, please react with 👍. Otherwise, react with 👎. |
- Remove addFileStreamed from MultipartBuilder — it was byte-for-byte
identical to addFile with a misleading "streamed" name; streaming is
determined by buildToTempFile() vs buildInMemory(), not the add method
- Narrow isNotFound to HTTP 404 only; move the 400 check into exists()
with a comment explaining why the Storage server returns 400 for HEAD
requests on non-existent objects, preventing bad-request errors from
being silently swallowed in other call sites
- Always send x-upsert header in _uploadOrUpdate regardless of HTTP
method, so update() (PUT) respects FileOptions.upsert consistently
with _uploadToSignedURL
- Make ServerErrorResponse.message optional so error responses that
omit the message field (e.g. {"error":"unauthorized"}) still produce
a structured StorageError instead of falling back to .unknown
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… contract After narrowing isNotFound to exclude HTTP 400, the test asserting error.isNotFound for a bare 400/unknown error now correctly expects false. The 400 case is covered by exists() directly, which is verified by the existing exists_400_error test in StorageFileAPITests. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR is a major overhaul of the Storage module — Storage v3. It replaces the old class hierarchy with a modern, value-type-forward Swift API, introduces typed domain values, adds upload progress reporting, rewrites error handling, and ships comprehensive DocC documentation.
Architecture
New
StorageClientreplacesStorageApi+StorageBucketApiThe old
StorageApibase class andStorageBucketApisubclass are removed. All bucket and file operations now live on the newStorageClientstruct.StorageClient.urlis a first-class initialiser parameter, no longer nested insideStorageClientConfiguration.StorageClientwith a fixedsnake_casestrategy and are no longer user-configurable viaStorageClientConfiguration.@unchecked Sendableclasses are gone; the new types are properSendablestructs where needed.translateStorageError) is now internal toStorageClient.HTTPErrorno longer leaks out of Storage operations — callers always receiveStorageError.StorageFileApi→StorageFileAPIThe file API type is renamed to follow Swift's acronym capitalisation convention. The old
StorageFileApi.swift(747 lines) is replaced byStorageFileAPI.swift(1 128 lines) with full typed APIs.MultipartFormDatareplaced byMultipartBuilderThe old 717-line Alamofire-derived
MultipartFormDataclass is replaced with a 279-line value-typeMultipartBuilderstruct:addText,addData,addFile,addFileStreamed).buildInMemory()) and temp-file streaming (buildToTempFile()) for large uploads.Types consolidated into
Types.swiftBucketOptions,TransformOptions, and several response types that were scattered across individual files are now in a singleTypes.swift.New Typed Value Types (Breaking)
String(resize mode)ResizeMode.cover,.contain,.fillString?(image format)ImageFormat?.origin,.avif,.webp,.jpeg,.pngString(sort order)SortOrder.asc,.descString?(file size limit)StorageByteCount?.bytes(),.kilobytes(),.megabytes(),.gigabytes(),ExpressibleByIntegerLiteralBool(download flag)DownloadBehavior?.withOriginalName,.named("filename.pdf");nil= no downloadBucketOptionschangespublicrenamed toisPublic(avoids Swift keyword collision).fileSizeLimitchanged fromString?toStorageByteCount?.TransformOptionschangesSortBy.orderchangecreateSignedURL/createSignedURLschangesexpiresInnow takesDurationinstead of a rawInt(seconds). Thedownloadparameter usesDownloadBehavior?instead ofBool— passnil(the default) to omit the download query parameter.Other API Changes (Breaking)
FileObjectV2→FileInfo: the v2 response type is renamed to the simplerFileInfo.FileInfo.idandFileUploadResponse.idare nowUUID: Storage object IDs aregen_random_uuid()in the database, so these are now properly typed.SearchOptions.prefixis now internal: it was never meant to be set directly by callers.FileOptions.duplexandFileOptions.headersremoved: these were implementation details that leaked into the public API.uploadFileconvenience removed: the mainuploadoverloads cover all cases.Upload Progress Reporting
Upload methods now accept an optional trailing closure for progress:
New
UploadProgresstype exposestotalBytesSent,totalBytesExpectedToSend, andfractionCompleted.Typed Error Handling
StorageErrorCodetype —RawRepresentablewith static constants for all known server error strings (e.g..notFound,.objectNotFound,.bucketNotFound). Adding new constants is never a breaking change.StorageErrorgains:errorCode: StorageErrorCode,statusCode: Int?,underlyingResponse,underlyingData,isNotFound,isUnauthorized.StorageErrorno longer conforms toDecodable— JSON decoding is an internal implementation detail.exists(path:)is simplified to a singlecatchclause usingisNotFound.Documentation
All public types, properties, initialisers, and methods in the Storage module now have DocC-style doc comments with parameter lists, return/throws descriptions, and
## Examplecode blocks. Also fixes a pre-existing bug where thefileSizeLimitandallowedMimeTypesdoc comments were swapped inBucketOptions.Other Changes
Package.swift: macOS minimum version bumped from 12 → 13.Mocker: updated from 1.7.0 → 1.7.1.FoundationNetworkingimport added toStorageFileAPIfor Linux builds..gitignore: ignores.claude/,.claire/,docs/superpowers/.Test Coverage
MultipartBuilderTests.swiftStorageByteCountTests.swiftExpressibleByIntegerLiteralUploadProgressTests.swiftfractionCompleted, edge casesValueTypesTests.swiftResizeMode,ImageFormat,SortOrder,DownloadBehaviorraw valuesExisting
StorageErrorTests,StorageFileAPITests,StorageBucketAPITests,TransformOptionsTests,BucketOptionsTests, and integration tests are updated for the new APIs.