feat!: rename the gotrue package to supabase_auth - #1697
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughThe PR renames the Dart authentication package from ChangesSupabase Auth package rename
Estimated code review effort: 4 (Complex) | ~60 minutes Mergeability Score: ⚪ Minimal · up to This PR renames the authentication package and public API for the next major version; the migration guidance and compatibility details are included, and no actionable merge-blocking risk remains after normal checks and review. Sequence Diagram(s)sequenceDiagram
participant SupabaseClient
participant AuthClient
participant AuthFetch
participant SupabaseAuthService
SupabaseClient->>AuthClient: initialize authentication client
AuthClient->>AuthFetch: build and send AuthRequestOptions
AuthFetch->>SupabaseAuthService: issue authentication request
SupabaseAuthService-->>AuthFetch: return authentication response
AuthFetch-->>AuthClient: resolve response
AuthClient-->>SupabaseClient: expose AuthClient through auth getter
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (3)
packages/supabase_auth/lib/src/types/custom_oauth_provider.dart (1)
12-15: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win
fromStringthrowsStateErrorfor unknown server values.
firstWherehas noorElse.CustomOAuthProvider.fromJsoncallsfromStringon the rawprovider_typefield for every admin API response (line 187). If the server introduces a new provider type,listProvidersandgetProviderthrow a bareStateErrorinstead of anAuthException. Callers that catchAuthExceptiondo not handle it.Throw a typed error, or add an explicit unknown value.
Based on learnings: "Applies to packages/{gotrue,postgrest,realtime_client,storage_client}/lib/**/*.dart : Preserve each package's established exception hierarchy and error-handling behavior, including retry logic where applicable."
♻️ Proposed fix to raise a typed error
static CustomProviderType fromString(String value) { - return CustomProviderType.values.firstWhere((e) => e.name == value); + return CustomProviderType.values.firstWhere( + (e) => e.name == value, + orElse: () => throw FormatException( + 'Unknown custom provider type: $value', + ), + ); }🤖 Prompt for 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. In `@packages/supabase_auth/lib/src/types/custom_oauth_provider.dart` around lines 12 - 15, Update CustomProviderType.fromString to handle unknown provider values without allowing firstWhere to emit a raw StateError. Raise the package’s established AuthException type, or return an explicit unknown enum value, so CustomOAuthProvider.fromJson and its listProviders/getProvider callers preserve the expected typed error-handling behavior.Source: Learnings
packages/supabase_auth/CHANGELOG.md (1)
1-3: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd a changelog entry for the package rename.
The changelog starts at
## 2.27.1, which is the lastgotruerelease. It contains no entry for the rename tosupabase_author for theGoTrue*→Auth*symbol renames. A user who reads only this file sees no record of the breaking change. Add an unreleased or v3 section that states the new package name, the discontinuedgotruepackage, and the renamed public types.Based on learnings: "Update package changelogs if making notable changes" and "Any change that breaks the public API adds its own section to
MIGRATION.mdin the same pull request, under the major version it will ship in".🤖 Prompt for 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. In `@packages/supabase_auth/CHANGELOG.md` around lines 1 - 3, Add an unreleased or v3 section before the existing 2.27.1 entry in the package changelog documenting the rename to supabase_auth, discontinuation of the gotrue package, and public GoTrue* to Auth* type renames; also add the corresponding breaking-change guidance under the shipping major version in MIGRATION.md.Source: Learnings
packages/supabase_auth/test/mocks/otp_mock_client.dart (1)
190-290: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueDeduplicate the two phone response builders.
_handlePhoneSignupand_handlePhoneSignInWithPasswordproduce the same payload. The only difference isuser_metadata, which signup fills fromrequestBody?['data']. Extract one builder that takes the metadata map. This keeps the two mock routes in sync when the response shape changes.♻️ Proposed shared builder
- StreamedResponse _handlePhoneSignup(Map<String, dynamic>? requestBody) { - final now = DateTime.now().toIso8601String(); - ... - } - - StreamedResponse _handlePhoneSignInWithPassword( - Map<String, dynamic>? requestBody, - ) { - final now = DateTime.now().toIso8601String(); - ... - } + StreamedResponse _handlePhoneSignup(Map<String, dynamic>? requestBody) { + return _phoneSessionResponse( + requestBody, + userMetadata: requestBody?['data'] ?? {}, + ); + } + + StreamedResponse _handlePhoneSignInWithPassword( + Map<String, dynamic>? requestBody, + ) { + return _phoneSessionResponse(requestBody, userMetadata: {}); + }🤖 Prompt for 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. In `@packages/supabase_auth/test/mocks/otp_mock_client.dart` around lines 190 - 290, Deduplicate the payload construction used by _handlePhoneSignup and _handlePhoneSignInWithPassword by extracting a shared response builder that accepts the user metadata map. Have signup pass requestBody?['data'] with the existing empty-map fallback, and sign-in pass an empty map, while preserving the current response fields and route behavior.
🤖 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 `@MIGRATION.md`:
- Around line 17-22: Update the `gotrue` package status in the migration
documentation to use future tense, indicating discontinuation will occur with
the v3 release rather than implying it has already happened. Keep the existing
package rename and release context unchanged.
In `@packages/supabase_auth/pubspec.yaml`:
- Around line 1-5: Update the package version in pubspec.yaml from 2.27.1 to
3.0.0 so the release publishes supabase_auth as the v3 package.
In `@packages/supabase_auth/test/client_test.dart`:
- Line 516: Wrap the expected OAuth URL in the test assertion by splitting
adjacent string literals so the line stays within 80 characters, while
preserving the exact expected URL value.
In `@packages/supabase_auth/test/provider_test.dart`:
- Line 51: Wrap the changed OAuth URL assertion in the provider test so every
line, including indentation, stays within 80 characters. Split the expected URL
literal or reuse a local prefix without changing the asserted value, then run
dart format.
---
Nitpick comments:
In `@packages/supabase_auth/CHANGELOG.md`:
- Around line 1-3: Add an unreleased or v3 section before the existing 2.27.1
entry in the package changelog documenting the rename to supabase_auth,
discontinuation of the gotrue package, and public GoTrue* to Auth* type renames;
also add the corresponding breaking-change guidance under the shipping major
version in MIGRATION.md.
In `@packages/supabase_auth/lib/src/types/custom_oauth_provider.dart`:
- Around line 12-15: Update CustomProviderType.fromString to handle unknown
provider values without allowing firstWhere to emit a raw StateError. Raise the
package’s established AuthException type, or return an explicit unknown enum
value, so CustomOAuthProvider.fromJson and its listProviders/getProvider callers
preserve the expected typed error-handling behavior.
In `@packages/supabase_auth/test/mocks/otp_mock_client.dart`:
- Around line 190-290: Deduplicate the payload construction used by
_handlePhoneSignup and _handlePhoneSignInWithPassword by extracting a shared
response builder that accepts the user metadata map. Have signup pass
requestBody?['data'] with the existing empty-map fallback, and sign-in pass an
empty map, while preserving the current response fields and route behavior.
🪄 Autofix
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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 77bfc6b7-5c99-43f9-aa61-e02d50172aef
📒 Files selected for processing (102)
.github/ISSUE_TEMPLATE/bug_report.yml.github/workflows/label-issues.yml.github/workflows/release-pana.yml.github/workflows/test.ymlAGENTS.mdMIGRATION.mdREADME.mdpackages/supabase/lib/src/supabase_client.dartpackages/supabase/lib/src/supabase_client_options.dartpackages/supabase/lib/supabase.dartpackages/supabase/pubspec.yamlpackages/supabase_auth/CHANGELOG.mdpackages/supabase_auth/LICENSEpackages/supabase_auth/README.mdpackages/supabase_auth/analysis_options.yamlpackages/supabase_auth/example/README.mdpackages/supabase_auth/example/main.dartpackages/supabase_auth/lib/src/auth_admin_api.dartpackages/supabase_auth/lib/src/auth_admin_custom_providers_api.dartpackages/supabase_auth/lib/src/auth_admin_mfa_api.dartpackages/supabase_auth/lib/src/auth_admin_oauth_api.dartpackages/supabase_auth/lib/src/auth_admin_passkey_api.dartpackages/supabase_auth/lib/src/auth_client.dartpackages/supabase_auth/lib/src/auth_mfa_api.dartpackages/supabase_auth/lib/src/auth_oauth_api.dartpackages/supabase_auth/lib/src/auth_passkey_api.dartpackages/supabase_auth/lib/src/broadcast_stub.dartpackages/supabase_auth/lib/src/broadcast_web.dartpackages/supabase_auth/lib/src/constants.dartpackages/supabase_auth/lib/src/fetch.dartpackages/supabase_auth/lib/src/helper.dartpackages/supabase_auth/lib/src/types/auth_async_storage.dartpackages/supabase_auth/lib/src/types/auth_exception.dartpackages/supabase_auth/lib/src/types/auth_response.dartpackages/supabase_auth/lib/src/types/auth_state.dartpackages/supabase_auth/lib/src/types/custom_oauth_provider.dartpackages/supabase_auth/lib/src/types/error_code.dartpackages/supabase_auth/lib/src/types/fetch_options.dartpackages/supabase_auth/lib/src/types/jwt.dartpackages/supabase_auth/lib/src/types/mfa.dartpackages/supabase_auth/lib/src/types/passkey.dartpackages/supabase_auth/lib/src/types/session.dartpackages/supabase_auth/lib/src/types/sign_out_reason.dartpackages/supabase_auth/lib/src/types/types.dartpackages/supabase_auth/lib/src/types/user.dartpackages/supabase_auth/lib/src/types/user_attributes.dartpackages/supabase_auth/lib/src/version.dartpackages/supabase_auth/lib/supabase_auth.dartpackages/supabase_auth/pubspec.yamlpackages/supabase_auth/test/admin_delete_user_test.dartpackages/supabase_auth/test/admin_list_users_test.dartpackages/supabase_auth/test/admin_test.dartpackages/supabase_auth/test/client_test.dartpackages/supabase_auth/test/custom_http_client.dartpackages/supabase_auth/test/custom_oauth_provider_test.dartpackages/supabase_auth/test/custom_providers_test.dartpackages/supabase_auth/test/fetch_test.dartpackages/supabase_auth/test/get_claims_test.dartpackages/supabase_auth/test/get_session_test.dartpackages/supabase_auth/test/header_isolation_test.dartpackages/supabase_auth/test/jwk_test.dartpackages/supabase_auth/test/mfa_challenge_mock_test.dartpackages/supabase_auth/test/mfa_enroll_test.dartpackages/supabase_auth/test/mocks/otp_mock_client.dartpackages/supabase_auth/test/mocks/passkey_mock_client.dartpackages/supabase_auth/test/mocks/web3_mock_client.dartpackages/supabase_auth/test/otp_mock_test.dartpackages/supabase_auth/test/passkey_test.dartpackages/supabase_auth/test/provider_test.dartpackages/supabase_auth/test/refresh_token_race_test.dartpackages/supabase_auth/test/src/auth_admin_custom_providers_api_test.dartpackages/supabase_auth/test/src/auth_admin_mfa_api_test.dartpackages/supabase_auth/test/src/auth_admin_oauth_api_test.dartpackages/supabase_auth/test/src/auth_mfa_api_test.dartpackages/supabase_auth/test/src/auth_oauth_api_test.dartpackages/supabase_auth/test/src/broadcast_web_test.dartpackages/supabase_auth/test/src/constants_test.dartpackages/supabase_auth/test/src/helper_test.dartpackages/supabase_auth/test/src/set_session_test.dartpackages/supabase_auth/test/src/token_refresh_race_test.dartpackages/supabase_auth/test/src/types/auth_exception_test.dartpackages/supabase_auth/test/src/types/mfa_test.dartpackages/supabase_auth/test/src/types/passkey_test.dartpackages/supabase_auth/test/src/types/session_test.dartpackages/supabase_auth/test/src/types/user_attributes_test.dartpackages/supabase_auth/test/src/types/user_test.dartpackages/supabase_auth/test/utils.dartpackages/supabase_auth/test/web3_auth_integration_test.dartpackages/supabase_auth/test/web3_auth_test.dartpackages/supabase_common/README.mdpackages/supabase_flutter/README.mdpackages/supabase_flutter/lib/src/flutter_auth_client_options.dartpackages/supabase_flutter/lib/src/local_storage.dartpackages/supabase_flutter/lib/src/supabase.dartpackages/supabase_flutter/lib/src/supabase_auth.dartpackages/supabase_flutter/lib/src/supabase_passkey.dartpackages/supabase_flutter/lib/supabase_flutter.dartpackages/supabase_flutter/test/local_storage_migration_test.dartpackages/supabase_flutter/test/storage_test.dartpackages/supabase_flutter/test/widget_test_stubs.dartpubspec.yamlsdk-compliance.yaml
BREAKING CHANGE: The auth client is published as supabase_auth instead of gotrue, and its library entrypoint is supabase_auth.dart. The types that carried the old name use the Auth prefix the rest of the package already uses: GoTrueClient is now AuthClient, GoTrueAdminApi is now AuthAdminApi, GotrueAsyncStorage is now AuthAsyncStorage, and so on for the remaining admin, MFA, OAuth and passkey API classes.
The renamed package has no history on pub.dev, so its first release has to be cut by hand instead of by the versioning workflow. 3.0.0-dev.1 continues the 2.27.1 line the package had as gotrue and matches the -dev preid the v2 prereleases used.
1fae5da to
f752c38
Compare
The guide is for people upgrading this SDK, so what auth-js, supabase-js and supabase-py ship is beside the point. Also phrases the pub.dev discontinuation as something that happens when v3 ships rather than something already done, and wraps the OAuth URL in client_test.dart to stay inside 80 columns.
## What Hotfix for the `gotrue` 2.27.x line, backporting the Wasm `Session.fromJson` crash fix from #1716. The base is `release/gotrue-2.27.x`, a maintenance branch cut at the `gotrue-v2.27.1` tag. It cannot target `main`, because `main` has since renamed the package to `supabase_auth` (#1697) and renamed the public API (#1712), so a PR against `main` would read as reverting everything merged since the tag. Resolves #1687 for the 2.x line. ## The bug `Session.fromJson` cast `json['expires_in']` straight to `int?`. That map does not always come from `jsonDecode`. `GoTrueClient._mayStartBroadcastChannel` also feeds it payloads that crossed the JavaScript interop boundary through `dartify()` in `broadcast_web.dart`, where every JavaScript number arrives as a `double`. Under `dart2js` this was invisible, because Dart `int` and `double` share a JavaScript `Number` at runtime, so `3600.0 as int?` succeeded. Under `dart2wasm` they are distinct runtime types and the cast throws: ``` TypeError: type 'double' is not a subtype of type 'int?' in type cast ``` The `json.decode(json.encode(dataMap))` round trip in `broadcast_web.dart` does not rescue this: `3600.0` encodes to `"3600.0"` and decodes back to a `double`. Because the throw happened inside the `BroadcastChannel` message listener, outside the setup `try`/`catch`, the rest of the listener was skipped. No `_saveSession` or `_removeSession` ran, and `notifyAllSubscribers` never fired, so receiving tabs silently failed to synchronize login, logout, and token refresh. ## The fix `expires_in` is now parsed as `(json['expires_in'] as num?)?.toInt()`, which accepts `int`, `double`, and `null`. `JwtPayload.fromJson` (`exp`, `nbf`, `iat`) and `OAuthClientListResponse.fromJson` (`nextPage`, `lastPage`, `total`) get the same treatment for their numeric fields. I traced the rest of the reachable surface. `dartify()` is called in exactly one place in the repository, and the only types built from that data are `Session`, `User`, `UserIdentity`, and `Factor`. `User.fromJson` has no numeric fields, its timestamps are ISO 8601 strings, so after this change nothing reachable from the interop boundary casts to `int`. Everything else in the workspace decodes from a string through `dart:convert`, where integer literals stay `int` on every backend. ## Pipeline fixes The tag this branch is frozen at no longer builds against the current toolchain, so the second commit carries three unrelated fixes needed to get a green run. All three were verified to be pre-existing drift rather than fallout from this change, by comparing against #1717, an equivalent change on `main` whose run passed minutes apart. - Flutter stable now ships AGP 9, which rejects the example app's old Gradle DSL. The example's Gradle configuration is ported from `main` (AGP 8.13.1 to 9.1.0, Gradle 8.13 to 9.3.1, Kotlin 2.1.20 to 2.4.0). The example is `publish_to: none`, so nothing published changes. - `dart analyze --fatal-infos` now reports `use_super_parameters` on `SupabaseStorageClient`. `main` resolved this as part of the fetch layer refactor in #1647, which gave `StorageBucketApi` a stored client field. At this tag the superclass stores nothing, so the local field is still needed and the lint is suppressed instead of backporting that refactor. - The compliance workflow validates against `supabase/sdk@main`, whose canonical capability identifiers keep moving, so a branch frozen at an old release can never satisfy them. Its `pull_request` trigger is now scoped to pull requests that target `main`. ## Release notes `melos version` on this branch proposes `gotrue` 2.27.2, plus `supabase` 2.16.1 and `supabase_flutter` 2.17.2 as dependency cascades. Those cascades are required, not incidental: the published `supabase` 2.16.0 pins `gotrue: 2.27.1` exactly and `supabase_flutter` 2.17.1 pins `supabase: 2.16.0` exactly, so publishing `gotrue` alone would reach nobody using the higher level packages. Note that `release-tag.yml` only triggers on pushes to `main`, so merging the version pull request into this maintenance branch will not create the tags. They need to be pushed manually, or that workflow needs a `workflow_dispatch` trigger, before `release-publish.yml` can run against `gotrue-v2.27.2`. ## Testing - `dart pub get` resolves the workspace cleanly. - `dart analyze lib test` in `packages/gotrue`: no issues. - `dart analyze --fatal-infos packages/storage_client`: no issues. - `dart test test/src/types/session_test.dart test/src/helper_test.dart`: 57 passing, including two new tests covering a `double` `expires_in` and `double` `exp`, `nbf`, and `iat`. - `dart format`: clean. - The Android build is verified by CI only, it was not built locally.
What
Renames the auth client package from
gotruetosupabase_auth, its library entrypoint fromgotrue.darttosupabase_auth.dart, and the public types that carried the old name.The service this package talks to has been called Supabase Auth for years, and
gotrueis a name users no longer recognize. The other clients already moved:supabase-pyshipssupabase_authandsupabase-jsships@supabase/auth-js.Class renames
The old names are replaced with the
Authprefix the rest of the package already uses (AuthException,AuthResponse,AuthState,AuthClientOptions), which is also whatauth-jsprefers.GoTrueClientAuthClientGoTrueAdminApiAuthAdminApiGoTrueAdminCustomProvidersApiAuthAdminCustomProvidersApiGoTrueAdminMFAApiAuthAdminMFAApiGoTrueAdminOAuthApiAuthAdminOAuthApiGoTrueAdminPasskeyApiAuthAdminPasskeyApiGoTrueMFAApiAuthMFAApiGoTrueOAuthApiAuthOAuthApiGoTruePasskeyApiAuthPasskeyApiGotrueAsyncStorageAuthAsyncStorageSharedPreferencesGotrueAsyncStorageSharedPreferencesAuthAsyncStorageThe two
supabase_flutterextensions on the auth client follow:GoTrueClientSignInProviderbecomesAuthClientSignInProvider,GoTrueClientPasskeybecomesAuthClientPasskey.Other changes
packages/gotruemoved topackages/supabase_auth, withname: supabase_authin the pubspec and the repository link updated. Source files named after the old package are renamed to match their classes, for examplesrc/gotrue_client.darttosrc/auth_client.dart.supabasedepends onsupabase_authinstead ofgotrue.supabase_flutterreaches it transitively, so neither package's own dependency list gains an entry.supabase_flutter/lib/src/flutter_go_true_client_options.dartis renamed toflutter_auth_client_options.dart. The class inside was alreadyFlutterAuthClientOptions.SupabaseClienthad collided under the new naming, so the traced client handed toAuthClientis now_authApiHttpClient, distinct from the_authHttpClientthat injects the JWT into the other service clients.GoTrue-prefixed symbol entries insdk-compliance.yamlare updated. No capability statuses change, this is a rename only.pubspec.yaml, the test/pana workflow package lists and coverage carryforward, the issue-form library dropdown, the issue label mapping, READMEs,AGENTS.mdandMIGRATION.mdall use the new name. The label mapping keeps the oldgotruekey so existing reports still land on theauthlabel.MIGRATION.mdgains a v2 to v3 section with the dependency rename, the import rename and the full class rename table.Deliberately unchanged
X-Client-Infoheader still reportsgotrue-dart.auth-jslikewise still sendsgotrue-js, and changing it would break continuity in server-side telemetry.gotrue_meta_securityfield in captcha payloads is a server wire contract.supabase/config.toml,seed.sqland the20240101000002_gotrue_reset.sqlmigration refer to the actual auth server and its schema.supabase/gotruedocker image name in the test workflow's image-cache grep.Test env keys
The auth test suite reads optional
.envoverrides. Each one now accepts aSUPABASE_AUTH_-prefixed key and still honours the oldGOTRUE_key, so existing local.envfiles keep working:SUPABASE_AUTH_URLGOTRUE_URLSUPABASE_AUTH_TOKENGOTRUE_TOKENSUPABASE_AUTH_SERVICE_ROLE_TOKENGOTRUE_SERVICE_ROLE_TOKENThe URL lookup moved into a
getAuthUrl(env)helper intest/utils.dart, next to the existing token helpers, instead of being repeated in ten test files.Version
The package is set to
3.0.0-dev.1by hand rather than by the versioning workflow, because the first release under a new name has to be published manually before pub.dev knows the package.3.0.0continues the2.27.1line the package had asgotrue, anddevis both the preid the v2 prereleases used (gotrue-v2.0.0-dev.1) and melos' default, so the rest of the packages line up on3.0.0-dev.Nwhen the v3 prerelease is cut.supabase's pin on the auth client moves with it.Follow-up outside this repo
Publishing
supabase_authand markinggotrueas discontinued on pub.dev, pointing at the new name, has to happen at release time.Testing
dart analyzeclean across the workspace.dart test -j 1passes inpackages/supabase_auth(458 tests) andpackages/supabase(134 tests) against the local Supabase stack.flutter testpasses inpackages/supabase_flutter(76 tests).dart format -l 80 --set-exit-if-changedreports no changes.supabase/sdkcompliance checks pass locally:validate-compliance,check-drift(no stale registrations from the renames) andcheck-api-symbolsagainst anorigin/mainbase extraction (every renamed symbol is registered under its new name).Note on merge order
This is rebased on
mainand overlaps with #1696 (thesupabasetosupabase_dartrename) in the workflow package lists, the issue templates,AGENTS.mdand theMIGRATION.mdinsertion point. Whichever merges second needs a conflict pass.Resolves #1695
Part of #1278
SDK-1467
Summary by CodeRabbit