From 0bf5ca584dd037c885641f1e92ad66a491e57228 Mon Sep 17 00:00:00 2001 From: Guilherme Souza Date: Tue, 4 Aug 2026 14:37:14 -0300 Subject: [PATCH] docs: Update Swift/Kotlin postgrest specs and Swift Web3 sign-in (#48291) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Cross-referenced recent commits across all 6 SDK repos (supabase-js, supabase-flutter, supabase-py, supabase-swift, supabase-kt, supabase-csharp) against `apps/docs/spec/` and `apps/docs/content/guides/`. Most recent commits were CI/chore/release/patch-fix noise; the following genuine feature gaps were found and fixed. ## Changes analyzed - **supabase-swift**: `dryRun()`, `notIn()`, `maybeSingle()` (PR supabase/supabase-swift#1114) and `signInWithWeb3()` (PR supabase/supabase-swift#1138) - **supabase-kt**: `dryRun()`, `notIn()`, `maybeSingle()` (PR supabase-community/supabase-kt#1365) ## Documentation updates - `apps/docs/spec/supabase_swift_v2.yml` — added `notin`, `dry-run`, `maybe-single` filter/modifier entries and a `sign-in-with-web3` auth entry (Web3/Ethereum/Solana sign-in was already documented for JS and Dart, missing for Swift) - `apps/docs/spec/supabase_kt_v3.yml` — added `notin`, `maybe-single`, `dry-run` entries - `apps/docs/spec/common-client-libs-sections.json` — registered nav entries for the two brand-new cross-SDK ids (`notin`, `dry-run`); `sign-in-with-web3` was already registered ## Explicitly out of scope - **Kotlin `custom_claims_allowlist`** (added to `CustomOAuthProvider`/`CustomProviderBuilder` in supabase-kt) — skipped. The Kotlin spec has no admin custom-OAuth-provider section documented at all yet (create/list/get/update/delete), so adding just this one field would require authoring a whole new, currently-undocumented admin API section from scratch — too large/risky to guess correctly in this pass. Flagging for a follow-up. - Dart's recently-shipped storage features (vector buckets, analytics/Iceberg buckets, `purgeCache`, `downloadStream`, `listPaginated`) were checked and are already fully documented in `supabase_dart_v2.yml`. - Swift/Kotlin lacking Storage vector-bucket/analytics-bucket docs — out of scope, those SDKs didn't ship that feature in this commit range (Dart-only so far). ## Test plan - [x] `python3 -c "import yaml; yaml.safe_load(open(...))"` — both edited YAML specs parse cleanly - [x] `python3 -c "import json; json.load(open(...))"` — nav JSON parses cleanly - [ ] Visual check of the rendered reference pages for `notIn`/`dryRun`/`maybeSingle`/`signInWithWeb3` on Swift and Kotlin reference docs --- 🤖 Generated with [Claude Code](https://claude.com/claude-code) ## Summary by CodeRabbit * **Documentation** * Added documentation for `notIn()` query filtering across supported Kotlin and Swift query operations. * Documented `maybeSingle()` for safely handling zero-or-one query results without raising a single-row error. * Added guidance for `dryRun()` mutations, including rollback behavior and returned results. * Added Swift authentication documentation for Web3 sign-in with Ethereum and Solana credentials. Co-authored-by: Claude Sonnet 5 --- .../spec/common-client-libs-sections.json | 16 +++ apps/docs/spec/supabase_kt_v3.yml | 91 +++++++++++++++++ apps/docs/spec/supabase_swift_v2.yml | 99 +++++++++++++++++++ 3 files changed, 206 insertions(+) diff --git a/apps/docs/spec/common-client-libs-sections.json b/apps/docs/spec/common-client-libs-sections.json index b6574b10733..4e06787fd8b 100644 --- a/apps/docs/spec/common-client-libs-sections.json +++ b/apps/docs/spec/common-client-libs-sections.json @@ -189,6 +189,14 @@ "parent": "filters", "type": "function" }, + { + "id": "notin", + "title": "Column is not in an array", + "slug": "notin", + "product": "database", + "parent": "filters", + "type": "function" + }, { "id": "contains", "title": "Column contains every element in a value", @@ -399,6 +407,14 @@ "product": "database", "parent": "modifiers", "type": "function" + }, + { + "id": "dry-run", + "title": "Test a mutation without committing it", + "slug": "dryrun", + "product": "database", + "parent": "modifiers", + "type": "function" } ] } diff --git a/apps/docs/spec/supabase_kt_v3.yml b/apps/docs/spec/supabase_kt_v3.yml index 90c7ab5cf1a..be7d643535d 100644 --- a/apps/docs/spec/supabase_kt_v3.yml +++ b/apps/docs/spec/supabase_kt_v3.yml @@ -1633,6 +1633,34 @@ functions: } ``` + - id: notin + title: notIn() + description: | + Finds all rows whose value on the stated `column` is not found on the specified `values`. The negation of `in_()`. + params: + - name: column + isOptional: false + type: String + description: The column to filter on. + - name: values + isOptional: false + type: List + description: The values to exclude. + examples: + - id: with-select + name: With `select()` + isSpotlight: true + code: | + ```kotlin + supabase.from("cities").select(columns = Columns.list("name")) { + filter { + City::name notIn listOf("Hobbiton", "Edoras") + //or + notIn("name", listOf("Hobbiton", "Edoras")) + } + } + ``` + - id: contains title: contains() description: | @@ -2776,6 +2804,69 @@ functions: hideCodeBlock: true isSpotlight: true + - id: maybe-single + title: maybeSingle() + $ref: '@supabase/postgrest-js.PostgrestTransformBuilder.maybeSingle' + examples: + - id: with-select + name: With `select()` + isSpotlight: true + code: | + ```kotlin + val result = supabase.from("characters").select(Columns.list("name")) { + limit(1) + maybeSingle() + } + ``` + data: + sql: | + ```sql + create table + characters (id int8 primary key, name text); + + insert into + characters (id, name) + values + (1, 'Luke'), + (2, 'Leia'), + (3, 'Han'); + ``` + response: | + ```json + { + "data": { + "name": "Luke" + }, + "status": 200, + "statusText": "OK" + } + ``` + hideCodeBlock: true + + - id: dry-run + title: dryRun() + description: | + Executes the mutation but rolls back the transaction instead of committing it, so no changes are persisted. + notes: | + - The mutation runs and its result (including side effects such as triggers) is returned in the response, but the transaction is rolled back afterward. + - Useful for testing mutations without touching real data. + - Requires PostgREST's `db-tx-end` setting to allow client-controlled transaction rollback. + examples: + - id: with-update + name: With `update()` + isSpotlight: true + code: | + ```kotlin + val toUpdate = City(name = "Mordor") + supabase.from("cities").update(toUpdate) { + filter { + City::name eq "Gondor" + } + dryRun() + } + // Row is not actually updated in the database. + ``` + - id: csv $ref: '@supabase/postgrest-js.PostgrestTransformBuilder.csv' title: csv() diff --git a/apps/docs/spec/supabase_swift_v2.yml b/apps/docs/spec/supabase_swift_v2.yml index 3c56ac8bc68..56e8d168e36 100644 --- a/apps/docs/spec/supabase_swift_v2.yml +++ b/apps/docs/spec/supabase_swift_v2.yml @@ -699,6 +699,44 @@ functions: // Open the URL using your preferred method to complete sign-in process. UIApplication.shared.open(url) ``` + - id: sign-in-with-web3 + title: 'signInWithWeb3()' + description: | + Signs in a user via a signed Sign in with Ethereum (EIP-4361) or Sign in with Solana message. + notes: | + - Supports Ethereum (Sign-In with Ethereum) and Solana (Sign-In with Solana), both of which derive from the [EIP-4361](https://eips.ethereum.org/EIPS/eip-4361) standard. + - Your app is responsible for building the message and obtaining the signature from the user's wallet (e.g. via a WalletConnect session or native wallet SDK) before calling this method. + - For `Web3Chain.ethereum` the signature is a `0x`-prefixed hex encoded string. For `Web3Chain.solana` it is a base64 encoded string. + examples: + - id: sign-in-with-ethereum + name: Sign in with an Ethereum wallet + isSpotlight: true + description: | + Sign the EIP-4361 message with the user's Ethereum wallet, then pass the message and its hex encoded signature. + code: | + ```swift + let session = try await supabase.auth.signInWithWeb3( + credentials: Web3Credentials( + chain: .ethereum, + message: siweMessage, + signature: signatureHex + ) + ) + ``` + - id: sign-in-with-solana + name: Sign in with a Solana wallet + description: | + Sign the message with the user's Solana wallet, then pass the message and its base64 encoded signature. + code: | + ```swift + let session = try await supabase.auth.signInWithWeb3( + credentials: Web3Credentials( + chain: .solana, + message: siwsMessage, + signature: signatureBase64 + ) + ) + ``` - id: sign-in-with-passkey title: 'signInWithPasskey()' notes: | @@ -3731,6 +3769,21 @@ functions: .in("name", values: ["Rio de Janeiro", "San Francisco"]) ``` + - id: notin + title: notIn() + description: | + Match only rows where `column` is not included in the `values` array. The negation of `in()`. + examples: + - id: with-select + name: With `select()` + code: | + ```swift + try await supabase + .from("cities") + .select("name, country_id") + .notIn("name", values: ["Rio de Janeiro", "San Francisco"]) + ``` + - id: contains title: contains() description: | @@ -4295,6 +4348,30 @@ functions: description: | Ensure that the RPC call affects at most 10 rows. Useful for limiting the impact of functions. + - id: dry-run + title: dryRun() + description: | + Executes the mutation but rolls back the transaction instead of committing it, so no changes are persisted. + notes: | + - The mutation runs and its result (including side effects such as triggers) is returned in the response, but the transaction is rolled back afterward. + - Useful for testing mutations without touching real data. + - Requires PostgREST's `db-tx-end` setting to allow client-controlled transaction rollback. + examples: + - id: with-update + name: With `update()` + isSpotlight: true + code: | + ```swift + try await supabase + .from("todos") + .update(["done": true]) + .eq("id", value: 1) + .select() + .dryRun() + .execute() + // Row is not actually updated in the database. + ``` + - id: single title: single() description: | @@ -4336,6 +4413,28 @@ functions: ``` hideCodeBlock: true isSpotlight: true + + - id: maybe-single + title: maybeSingle() + description: | + Like `single()`, this sets the `application/vnd.pgrst.object+json` accept header so the server enforces a single result. Unlike `single()`, when the query does not match exactly one row the resulting `PGRST116` error is not thrown — the response `value` is `nil` instead. + notes: | + - PostgREST returns `PGRST116` both when zero rows match and when more than one row matches. `maybeSingle()` returns `nil` for either case; use `single()` for the strict variant that always throws when the query does not match exactly one row. + examples: + - id: with-select + name: With `select()` + isSpotlight: true + code: | + ```swift + let todo: Todo? = try await supabase + .from("todos") + .select() + .eq("id", value: 42) + .maybeSingle() + .execute() + .value + ``` + - id: csv title: csv() examples: