Skip to content

refactor(runtime): isolate HTTPRuntime target - #1121

Merged
grdsdev merged 29 commits into
mainfrom
claude/httpruntime-target-085a05
Jul 28, 2026
Merged

refactor(runtime): isolate HTTPRuntime target#1121
grdsdev merged 29 commits into
mainfrom
claude/httpruntime-target-085a05

Conversation

@grdsdev

@grdsdev grdsdev commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Summary

Isolates the zero-dependency HTTPRuntime target out of #1099 into its own branch (no OpenAPI codegen tool, no generated Storage client), plus a new HTTPRuntimeTestHelpers target for stubbing HTTPRuntime requests under Swift Testing.

Test plan

  • swift build
  • swift test --filter HTTPRuntimeTests (10 tests)
  • swift test --filter HTTPRuntimeTestHelpersTests (18 tests)
  • ./scripts/spell-check.sh
  • ./scripts/format.sh (no changes)
  • Linux build verified locally via Docker (swift:6.1 image)

grdsdev added 22 commits July 11, 2026 07:36
…e deleted SSE parser after the package-scoping edit

The manual public->package access-control pass left HTTPRuntime non-compiling:
checkStatus still referenced HTTPResponse's now-removed bare status/isSuccess
(now only on .head), MultipartFormData's new builder API members defaulted to
internal instead of package, and ServerSentEvents.swift was deleted outright
rather than rescoped, breaking SSE stream parsing entirely.
Follow-up to the HTTPRuntime target isolation: registers the test
target in the shared Xcode scheme, adds its spell-check terms, and
updates Package.resolved to drop dependencies no longer pulled in by
this trimmed-down package graph.
…ase, add addHeader

- HTTPTransport.send/stream now throw typed HTTPError instead of any Error;
  URLSessionTransport already only ever threw HTTPError.transport, so this
  just tightens the contract. Dropped the redundant `throws` on the private
  makeURLRequest helper, which never actually threw.
- Removed HTTPBody.multipart: callers now build the multipart body themselves
  via MultipartFormData.buildToTempFile(), set Content-Type, and pass .file.
  Keeps HTTPTransport from needing to know about multipart assembly.
- Added HTTPRequestBuilder.addHeader(_:value:), which merges into an existing
  header (joined with "; ") instead of replacing it, for repeated directives
  like Prefer. Both setHeader and addHeader resolve the target key
  case-insensitively so differently-cased calls merge into one header
  instead of creating duplicates.
Supabase's own clients don't need it; downstream consumers can parse
the raw streamed chunks themselves if they want SSE framing.
…sed doc references

- checkStatus now requires a catch-all APIError type instead of falling
  back to a bare unexpectedStatus(status:body:) case, and reports decode
  failures as unexpectedResponse(response:underlyingError:) with the full
  response attached.
- Commented out the still-unused HTTPError.encoding case.
- Dropped doc comments referencing the (now removed) OpenAPI codegen tool.
…uild

- TransferProgress/ProgressHandler were left `public` when the rest of
  HTTPRuntime was scoped down to `package`; the capability-matrix CI
  check flagged them as new, unregistered public API. Scope them to
  `package` like everything else in this target.
- FoundationNetworking (swift-corelibs-foundation on Linux) has no
  async byte-streaming API (`bytes(for:)`/`AsyncBytes`), so
  URLSessionTransport.stream() failed to compile on Linux. Branch on
  `canImport(FoundationNetworking)`: Linux buffers the full response
  via `data(for:)` and yields it as a single chunk instead of
  streaming incrementally; Apple platforms keep the existing
  incremental byte-stream implementation.
…e and dictionary

Adds HTTPRuntimeTestHelpersTests to the shared Xcode scheme in alphabetical order between HelpersTests and HTTPRuntimeTests. Includes dictionary.txt entries for Xcode-related terms and formatting fixes to HTTPRuntimeTestHelpers source files.
@grdsdev
grdsdev requested a review from a team as a code owner July 13, 2026 09:38
Comment thread Sources/HTTPRuntime/HTTPRequest.swift Outdated
grdsdev added 2 commits July 27, 2026 15:48
…rget-085a05

# Conflicts:
#	Package.resolved
#	Package.swift
…r directives

addHeader joined repeated directives with "; ", conflicting with this repo's
Prefer convention (HTTPFields.appendOrUpdate, PostgrestQueryBuilder/
PostgrestTransformBuilder all use ","), which would make two addHeader("Prefer", ...)
calls read as one directive-with-parameter instead of two. Also replace an
existing directive sharing the same key prefix instead of duplicating it,
mirroring appendOrUpdate.

Addresses review feedback from spydon on #1121.
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e9775c42-e9e3-43f0-914f-f0f56ecb2e5a

📥 Commits

Reviewing files that changed from the base of the PR and between e57ee1e and d428c01.

📒 Files selected for processing (2)
  • Sources/HTTPRuntime/MultipartFormData.swift
  • dictionary.txt
🚧 Files skipped from review as they are similar to previous changes (2)
  • dictionary.txt
  • Sources/HTTPRuntime/MultipartFormData.swift

📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • Added HTTP runtime building blocks for requests, responses (buffered + streaming), typed API errors, and status checking.
    • Introduced URLSession-backed transport with optional upload progress.
    • Added multipart form-data builder, ISO-8601 JSON coding, path percent-encoding helpers, and free-form JSON value support.
    • Added test utilities for HTTP stubbing and curl-style request snapshot rendering.
  • Tests
    • Added coverage for multipart creation, request building, encoding, path rules, JSON value behavior, and all stub/test helpers.
  • Chores
    • Updated Swift package targets, test scheme entries, and .gitignore.

Walkthrough

Adds the HTTPRuntime package with request and response models, URL construction, status handling, JSON and multipart utilities, path encoding, transfer progress, and URLSession-backed transport. Adds HTTPRuntimeTestHelpers with ordered HTTP stubs, scoped test traits, curl rendering, and request snapshots. Registers both test bundles, adds runtime and helper coverage, updates dictionary entries, and stops ignoring docs/superpowers/.

Sequence Diagram(s)

sequenceDiagram
  participant HTTPRequestBuilder
  participant URLSessionTransport
  participant URLSession
  participant HTTPResponse
  HTTPRequestBuilder->>URLSessionTransport: build HTTPRequest
  URLSessionTransport->>URLSession: send URLRequest
  URLSession-->>URLSessionTransport: return response data and headers
  URLSessionTransport->>HTTPResponse: construct HTTPResponse
  HTTPResponse->>HTTPResponse: validate status and decode APIError
Loading

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.

docs/superpowers/ was already gitignored (deduped a redundant earlier
entry too) but these two files were tracked before the rule existed.
@grdsdev
grdsdev requested a review from spydon July 27, 2026 18:58
@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Capability matrix drift detected

The following capabilities are marked implemented in swift but have no registered symbols to verify:

  • auth.passkey.register_passkey (no symbols list — cannot confirm implementation exists)
  • auth.passkey.sign_in_with_passkey (no symbols list — cannot confirm implementation exists)
  • client.authentication_integration.third_party_auth (no symbols list — cannot confirm implementation exists)
  • client.authentication_integration.cross_client_token_sync (no symbols list — cannot confirm implementation exists)
  • client.authentication_integration.oauth_flow_type (no symbols list — cannot confirm implementation exists)
  • client.authentication_integration.session_url_detection (no symbols list — cannot confirm implementation exists)
  • client.session_management.custom_storage (no symbols list — cannot confirm implementation exists)
  • client.session_management.persist_session (no symbols list — cannot confirm implementation exists)
  • client.request_configuration.global_headers (no symbols list — cannot confirm implementation exists)
  • client.observability.trace_propagation (no symbols list — cannot confirm implementation exists)
  • database.query.from_table (no symbols list — cannot confirm implementation exists)
  • database.query.select (no symbols list — cannot confirm implementation exists)
  • database.query.schema_selection (no symbols list — cannot confirm implementation exists)
  • database.query.rpc (no symbols list — cannot confirm implementation exists)
  • database.mutate.insert (no symbols list — cannot confirm implementation exists)
  • database.mutate.update (no symbols list — cannot confirm implementation exists)
  • database.mutate.upsert (no symbols list — cannot confirm implementation exists)
  • database.mutate.delete (no symbols list — cannot confirm implementation exists)
  • database.mutate.select_after_mutation (no symbols list — cannot confirm implementation exists)
  • database.using_filters.eq (no symbols list — cannot confirm implementation exists)
  • database.using_filters.neq (no symbols list — cannot confirm implementation exists)
  • database.using_filters.gt (no symbols list — cannot confirm implementation exists)
  • database.using_filters.gte (no symbols list — cannot confirm implementation exists)
  • database.using_filters.lt (no symbols list — cannot confirm implementation exists)
  • database.using_filters.lte (no symbols list — cannot confirm implementation exists)
  • database.using_filters.like (no symbols list — cannot confirm implementation exists)
  • database.using_filters.ilike (no symbols list — cannot confirm implementation exists)
  • database.using_filters.is (no symbols list — cannot confirm implementation exists)
  • database.using_filters.in (no symbols list — cannot confirm implementation exists)
  • database.using_filters.contains (no symbols list — cannot confirm implementation exists)
  • database.using_filters.contained_by (no symbols list — cannot confirm implementation exists)
  • database.using_filters.range_gt (no symbols list — cannot confirm implementation exists)
  • database.using_filters.range_gte (no symbols list — cannot confirm implementation exists)
  • database.using_filters.range_lt (no symbols list — cannot confirm implementation exists)
  • database.using_filters.range_lte (no symbols list — cannot confirm implementation exists)
  • database.using_filters.range_adjacent (no symbols list — cannot confirm implementation exists)
  • database.using_filters.overlaps (no symbols list — cannot confirm implementation exists)
  • database.using_filters.text_search (no symbols list — cannot confirm implementation exists)
  • database.using_filters.match (no symbols list — cannot confirm implementation exists)
  • database.using_filters.not (no symbols list — cannot confirm implementation exists)
  • database.using_filters.or (no symbols list — cannot confirm implementation exists)
  • database.using_filters.raw (no symbols list — cannot confirm implementation exists)
  • database.using_filters.regex (no symbols list — cannot confirm implementation exists)
  • database.using_filters.regex_icase (no symbols list — cannot confirm implementation exists)
  • database.using_filters.is_distinct (no symbols list — cannot confirm implementation exists)
  • database.using_filters.like_all (no symbols list — cannot confirm implementation exists)
  • database.using_filters.like_any (no symbols list — cannot confirm implementation exists)
  • database.using_filters.ilike_all (no symbols list — cannot confirm implementation exists)
  • database.using_filters.ilike_any (no symbols list — cannot confirm implementation exists)
  • database.using_modifiers.order (no symbols list — cannot confirm implementation exists)
  • database.using_modifiers.limit (no symbols list — cannot confirm implementation exists)
  • database.using_modifiers.range (no symbols list — cannot confirm implementation exists)
  • database.using_modifiers.single_row (no symbols list — cannot confirm implementation exists)
  • database.using_modifiers.strip_nulls (no symbols list — cannot confirm implementation exists)
  • database.using_modifiers.format_csv (no symbols list — cannot confirm implementation exists)
  • database.using_modifiers.format_geojson (no symbols list — cannot confirm implementation exists)
  • database.using_modifiers.max_affected_rows (no symbols list — cannot confirm implementation exists)
  • database.using_modifiers.request_cancellation (no symbols list — cannot confirm implementation exists)
  • database.configuration.auto_retry (no symbols list — cannot confirm implementation exists)
  • functions.invocation.invoke (no symbols list — cannot confirm implementation exists)
  • functions.invocation.set_auth_token (no symbols list — cannot confirm implementation exists)
  • functions.invocation.method_override (no symbols list — cannot confirm implementation exists)
  • functions.invocation.streaming_response (no symbols list — cannot confirm implementation exists)
  • functions.invocation.request_cancellation (no symbols list — cannot confirm implementation exists)
  • realtime.client.connect (no symbols list — cannot confirm implementation exists)
  • realtime.client.disconnect (no symbols list — cannot confirm implementation exists)
  • realtime.client.get_channels (no symbols list — cannot confirm implementation exists)
  • realtime.client.remove_channel (no symbols list — cannot confirm implementation exists)
  • realtime.client.remove_all_channels (no symbols list — cannot confirm implementation exists)
  • realtime.client.connection_state (no symbols list — cannot confirm implementation exists)
  • realtime.client.listen_heartbeats (no symbols list — cannot confirm implementation exists)
  • realtime.client.set_auth_token (no symbols list — cannot confirm implementation exists)
  • realtime.client.channel (no symbols list — cannot confirm implementation exists)
  • realtime.channel.subscribe (no symbols list — cannot confirm implementation exists)
  • realtime.channel.unsubscribe (no symbols list — cannot confirm implementation exists)
  • realtime.channel.send (no symbols list — cannot confirm implementation exists)
  • realtime.channel.broadcast_http (no symbols list — cannot confirm implementation exists)
  • realtime.subscriptions.postgres_changes (no symbols list — cannot confirm implementation exists)
  • realtime.subscriptions.subscribe_presence (no symbols list — cannot confirm implementation exists)
  • realtime.subscriptions.private_channel (no symbols list — cannot confirm implementation exists)
  • realtime.subscriptions.broadcast_self (no symbols list — cannot confirm implementation exists)
  • realtime.subscriptions.broadcast_ack (no symbols list — cannot confirm implementation exists)
  • realtime.subscriptions.broadcast_replay (no symbols list — cannot confirm implementation exists)
  • realtime.presence.track (no symbols list — cannot confirm implementation exists)
  • realtime.presence.untrack (no symbols list — cannot confirm implementation exists)
  • realtime.presence.presence_key (no symbols list — cannot confirm implementation exists)
  • realtime.configuration.custom_websocket_transport (no symbols list — cannot confirm implementation exists)
  • realtime.configuration.reconnect_backoff (no symbols list — cannot confirm implementation exists)
  • realtime.configuration.heartbeat_interval (no symbols list — cannot confirm implementation exists)
  • realtime.configuration.access_token_callback (no symbols list — cannot confirm implementation exists)
  • realtime.configuration.deferred_disconnect (no symbols list — cannot confirm implementation exists)
  • realtime.configuration.custom_logger (no symbols list — cannot confirm implementation exists)
  • realtime.configuration.binary_protocol (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.get_bucket (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.list_file_buckets (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.update_bucket (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.delete_file_bucket (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.empty_bucket (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.access_bucket (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.upload (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.download (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.move (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.copy (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.remove (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.create_signed_url (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.create_signed_urls (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.create_signed_upload_url (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.upload_with_signed_url (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.update_file (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.file_exists (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.file_info (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.list_files_paginated (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.copy_cross_bucket (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.move_cross_bucket (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.upload_with_metadata (no symbols list — cannot confirm implementation exists)
  • storage.file_buckets.url_cache_nonce (no symbols list — cannot confirm implementation exists)

These may have been renamed, removed, or never registered. Please update the capability matrix.
See: https://github.com/supabase/sdk/blob/main/docs/capability-matrix.md

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Sources/HTTPRuntime/HTTPError.swift`:
- Around line 11-18: Update the associated error values in HTTPError cases
transport, decoding, and unexpectedResponse.underlyingError to use
Sendable-constrained error existentials, preserving their existing case names
and optionality while ensuring HTTPError satisfies strict-concurrency Sendable
requirements.

In `@Sources/HTTPRuntime/MultipartFormData.swift`:
- Around line 100-118: Update buildToTempFile() to explicitly set owner-only
POSIX permissions on tempFile immediately after FileManager.default.createFile
succeeds and before opening or uploading it, rather than relying on the process
umask. Preserve the existing cleanup and error-handling behavior, propagating or
mapping any permission-setting failure consistently with the method’s throws
contract.

In `@Sources/HTTPRuntime/URLSessionTransport.swift`:
- Around line 67-80: Update stream(_:) and its related streaming request path to
explicitly handle HTTPBody.file instead of allowing makeURLRequest to send an
empty body. Support file-backed uploads through the streaming implementation, or
validate and reject file bodies with an HTTPError before session.data(for:)
transmits the request; preserve existing behavior for non-file bodies.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2f39776d-4ce5-4d6a-958f-e4671e492c7d

📥 Commits

Reviewing files that changed from the base of the PR and between 003e58d and d6b039b.

⛔ Files ignored due to path filters (1)
  • Package.resolved is excluded by !**/Package.resolved
📒 Files selected for processing (26)
  • .gitignore
  • Package.swift
  • Sources/HTTPRuntime/HTTPError.swift
  • Sources/HTTPRuntime/HTTPMethod.swift
  • Sources/HTTPRuntime/HTTPRequest.swift
  • Sources/HTTPRuntime/HTTPResponse.swift
  • Sources/HTTPRuntime/HTTPTransport.swift
  • Sources/HTTPRuntime/JSONCoding.swift
  • Sources/HTTPRuntime/JSONValue.swift
  • Sources/HTTPRuntime/MultipartFormData.swift
  • Sources/HTTPRuntime/PathEncoding.swift
  • Sources/HTTPRuntime/TransferProgress.swift
  • Sources/HTTPRuntime/URLSessionTransport.swift
  • Sources/HTTPRuntimeTestHelpers/AssertHTTPRequests.swift
  • Sources/HTTPRuntimeTestHelpers/CurlCommand.swift
  • Sources/HTTPRuntimeTestHelpers/HTTPStub.swift
  • Sources/HTTPRuntimeTestHelpers/HTTPStubBody.swift
  • Sources/HTTPRuntimeTestHelpers/HTTPTransportStub.swift
  • Supabase.xcworkspace/xcshareddata/xcschemes/Supabase.xcscheme
  • Tests/HTTPRuntimeTestHelpersTests/AssertHTTPRequestsTests.swift
  • Tests/HTTPRuntimeTestHelpersTests/CurlCommandTests.swift
  • Tests/HTTPRuntimeTestHelpersTests/HTTPStubTests.swift
  • Tests/HTTPRuntimeTestHelpersTests/HTTPStubTraitTests.swift
  • Tests/HTTPRuntimeTestHelpersTests/HTTPTransportStubTests.swift
  • Tests/HTTPRuntimeTests/HTTPRuntimeTests.swift
  • dictionary.txt
💤 Files with no reviewable changes (1)
  • .gitignore

Comment thread Sources/HTTPRuntime/HTTPError.swift
Comment thread Sources/HTTPRuntime/MultipartFormData.swift
Comment thread Sources/HTTPRuntime/URLSessionTransport.swift
@coveralls

coveralls commented Jul 27, 2026

Copy link
Copy Markdown

Coverage Report for CI Build 30343991994

Coverage increased (+0.2%) to 84.036%

Details

  • Coverage increased (+0.2%) from the base build.
  • Patch coverage: No coverable lines changed in this PR.
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 9941
Covered Lines: 8354
Line Coverage: 84.04%
Coverage Strength: 40.67 hits per line

💛 - Coveralls

grdsdev added a commit that referenced this pull request Jul 28, 2026
Adds storage.vectors.{createBucket,getBucket,listBuckets,deleteBucket}
for Supabase Storage's alpha "vector buckets" feature, mirroring
supabase-js's supabase.storage.vectors client. Indexes and vector data
operations (put/get/query/delete vectors) are out of scope for this
pass.

The vector bucket paths/schemas are merged into openapi/storage.json
from the real docs:export output of supabase/storage's
claude/reverent-ramanujan-32755f branch (supabase/storage#1215), which
adds response schemas for these 4 endpoints (previously only errors
were documented). Sources/Storage/Generated is regenerated from that
spec via tools/openapi-codegen.

Since the generated StorageBackendAPI.Client and its models are
module-internal by convention, a new StorageVectorsClient wraps it with
a public API: VectorBucket/ListVectorBucketsResponse replace the
internal generated schemas, and the internal ErrorSchema is translated
to the existing public StorageError. StorageSessionTransport bridges
StorageClientConfiguration's StorageHTTPSession onto HTTPRuntime's
HTTPTransport, so the generated client goes through the same session
(auth headers, test stubbing) as the rest of Storage.

The whole surface is gated behind @_spi(Experimental), matching the
precedent set by Auth's WebAuthn support, since this is an alpha
feature that may change in a breaking way before general availability.

Built on #1121/#1099 (the isolated HTTPRuntime target and
openapi-codegen tool) rather than main.
grdsdev and others added 3 commits July 28, 2026 05:33
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
…ping them

makeURLRequest only copies .data bodies into httpBody; .file bodies were
silently discarded, sending an empty body instead of the file's contents.
@grdsdev grdsdev changed the title feat(runtime): isolate HTTPRuntime target refactor(runtime): isolate HTTPRuntime target Jul 28, 2026
swift-format wraps the multi-line guard condition differently than the
version used locally; add "posix" to the dictionary for .posixPermissions.
@grdsdev
grdsdev merged commit a4703d5 into main Jul 28, 2026
30 checks passed
@grdsdev
grdsdev deleted the claude/httpruntime-target-085a05 branch July 28, 2026 10:16
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.

4 participants