Skip to content

chore: register the remaining public API in the capability matrix - #1673

Open
spydon wants to merge 3 commits into
chore/mark-internal-apifrom
chore/register-remaining-symbols
Open

chore: register the remaining public API in the capability matrix#1673
spydon wants to merge 3 commits into
chore/mark-internal-apifrom
chore/register-remaining-symbols

Conversation

@spydon

@spydon spydon commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Stacked on #1671. Closes the backfill that #1670 and #1671 flagged: capability-matrix coverage of the Dart public API goes from 49% to 100%.

before after
Symbols reported as public API 1831 1774
Registered 899 1766
Unregistered 930 0

How the 881 unregistered symbols were placed

26 are entry points the matrix was missing outright. These go in symbols, so the drift check now verifies them:

Feature Entry point
auth.session.update_user GoTrueClient.updateUser
auth.session.get_session / get_user GoTrueClient.currentSession / currentUser
auth.sign_in.sign_in_with_oauth GoTrueClient.getOAuthSignInUrl, GoTrueClientSignInProvider.signInWithOAuth
auth.sign_in.sign_in_with_sso GoTrueClientSignInProvider.signInWithSSO
auth.identities.link_identity GoTrueClientSignInProvider.linkIdentity
auth.passkey.* GoTruePasskeyApi.start/verifyRegistration, start/verifyAuthentication
database.query.from_table / rpc / schema_selection SupabaseClient.from / rpc / schema
database.using_modifiers.explain PostgrestTransformBuilder.explain
realtime.subscriptions.postgres_changes RealtimeChannel.onPostgresChanges, onSystemEvents
realtime.client.* SupabaseClient.channel, getChannels, removeChannel, removeAllChannels, RealtimeClient.disconnect
storage.file_buckets.create_signed_url StorageFileApi.createSignedUrl
client.* GoTrueClient.getSessionFromUrl, recoverSession, setInitialSession

Several of these features previously listed only an option or enum as their evidence. storage.file_buckets.create_signed_url claimed DownloadBehavior; database.using_modifiers.explain claimed ExplainFormat; auth.session.update_user claimed UserAttributes.currentPassword. The method that actually implements the capability was unregistered in each case.

500 go in a feature's supporting_symbols, where the type maps onto one capability: the MFA response types to their operations, Jwt*/JWK*/DecodedJwt to get_claims, FileObjectV2 to file_info, SignedUrl* to create_signed_urls, the presence payloads to subscribe_presence, and so on.

355 go in the top-level supporting_symbols list. Four kinds:

  • Shared domain modelsSession, User, AuthResponse, Bucket, OAuthClient, Factor. Accepted or returned by many features at once, so no single feature id is a truthful home.
  • Exception hierarchiesAuthException, PostgrestException, FunctionException, RealtimeSubscribeException and subclasses. Thrown rather than passed, so reachable from no signature.
  • Client and sub-API handlesSupabaseClient, GoTrueClient, RealtimeClient, GoTrueAdminApi and the accessors returning them gate whole areas; their operations are attributed individually.
  • Surface with no canonical id — see the last section.

26 symbols left the scan instead of entering the matrix

#1671's script only matched class-like declarations, so top-level functions and variables slipped through. Now @internal:

  • realtime_client/src/transformers.dart: convertCell, convertColumn, convertChangeData, toArray, toBoolean, toDouble, toInt, toJson, toTimestampString, noop, httpEndpointURL, getEnrichedPayload, getPayloadRecords
  • conditional-import platform shims: accessToken, hasAccessToken, persistSession, removePersistedSession, disposePreviousClient, markClientToDispose, supabaseFlutterClientToDispose, getBroadcastChannel, createWebSocketClient
  • passkeyRegisterRequestFromOptions, passkeyAuthenticateRequestFromOptions, maxShift, defaultHeaders

ChannelFilter joins them, and this one is worth a second look: it is hidden from realtime_client's public library, so ChannelFilter.select could never have been drift-verified evidence for realtime.subscriptions.postgres_changes. RealtimeChannel.onPostgresChanges replaces it.

Two paths cannot carry the annotation, so .sdk-parse-ignore excludes them:

  • packages/*/example/ — each package ships its own example app, and the extractor treats it as a package of its own because it has a pubspec.yaml. MyApp, MyWidget and main were counted as SDK public API. examples/ was already excluded for exactly this reason.
  • packages/*/lib/src/version.dart — the release tooling rewrites it wholesale (echo "const version = '$version';" > ...), so an annotation would not survive a release.

One behaviour-visible change

realtime_client.dart changes from export 'src/transformers.dart' hide getEnrichedPayload, getPayloadRecords to show PostgresColumn, PostgresType. The 13 payload-conversion helpers above were public only by accident of that hide list, and the analyzer requires it: @internal on an exported member is invalid_export_of_internal_element. The show form also stops the next helper added to that file from leaking.

This removes public API. It is not API anyone should be calling (toInt, noop, convertCell), and v3 is already removing dead public surface, but it is the one item here that is not purely additive.

Also declared: storage.errors.error_codes

The validator reported it undeclared, and StorageException.error already carries the machine-readable service code the capability describes. Declared as implemented, which also gives StorageException a real home instead of the shared bucket.

Gaps this surfaced

Public API with no canonical capability id, currently parked in the top-level list. Each is a candidate for a new id in supabase/sdk:

  1. Client construction and disposalSupabase.initialize, Supabase.instance, Supabase.client, isInitialized, and dispose on every client. client.* has no lifecycle group at all.
  2. User-facing passkey managementGoTruePasskeyApi.list, delete, update. The matrix has auth.passkey_admin.list_passkeys and delete_passkey for the admin API, but nothing for a user managing their own.
  3. Realtime streams as a database capabilitySupabaseQueryBuilder.stream and SupabaseStreamBuilder. The stream filters and modifiers are registered under database.using_filters.* and using_modifiers.*, but stream() itself is not a capability.
  4. Storage retry configurationStorageClientOptions.retryAttempts and StorageRetryController. database.configuration.auto_retry exists; there is no storage equivalent.
  5. realtime.subscriptions.postgres_changes_multiple_filters is the one remaining undeclared feature, and Dart implements it (onPostgresChanges(filters: [...])). Declaring it needs RealtimeChannel.onPostgresChanges registered against two features, so it is left out here rather than adding a duplicate registration.

Two more judgement calls worth flagging:

  • RealtimeClient exposes transport internalssendBuffer, stateChangeCallbacks, pendingHeartbeatRef, makeRef, ref, push, heartbeatTimer, reconnectTimer, and RealtimeChannel.canPush/trigger. Registered here because they are genuinely exported, but they read like @internal candidates for a future breaking change.
  • yet_another_json_isolate contributes 13 symbols with no Supabase capability behind them. Registered in the top-level list; it could instead be excluded from the scan the way supabase_common is.

Test plan

  • dart analyze packages/: No issues found. This is the real gate for invalid_internal_annotation, invalid_use_of_internal_member and invalid_export_of_internal_element.
  • Compliance validator: OK — compliance file is valid.
  • check-drift: ✅ No capability matrix drift detected.
  • check-api-symbols against chore: mark non-public declarations @internal #1671 as base: ✅ All new public API symbols are covered in the capability matrix. Nothing registered was removed, and nothing new is uncovered.
  • Uncovered symbol count recomputed from a fresh extraction: 0.
  • Checked for symbols registered in more than one place: 9, all pre-existing and deliberate (one method serving two capabilities, e.g. StorageFileApi.move for move and move_cross_bucket). This change adds none.
  • dart format packages/: 0 changed.
  • Tests, all passing: gotrue 471, realtime_client 205, postgrest 196, supabase 134, storage_client 210, supabase_flutter 65, functions_client 48. postgrest needs -j 1; run in parallel its test files race on the shared database reset helper, which varies the failure count run to run on unmodified code.

Brings capability-matrix coverage of the Dart public API from 49% to 100%.

The 881 unregistered symbols split three ways:

- 500 are attributed to the capability they support, and 26 are entry points
  the matrix was missing outright (GoTrueClient.updateUser, SupabaseClient.from,
  RealtimeChannel.onPostgresChanges, StorageFileApi.createSignedUrl, ...).
- 355 go in the top-level supporting_symbols list: shared domain models, the
  exception hierarchies, the client handles that gate whole areas, and surface
  the canonical registry has no id for.
- 26 are not public API at all and leave the scan instead of entering the
  matrix. #1671's script only matched class-like declarations, so top-level
  functions and variables were missed: the realtime transformers, the
  conditional-import platform shims, and the passkey option mappers are now
  @internal. ChannelFilter joins them; it is hidden from realtime_client's
  public library, so it could not serve as evidence for postgres changes, and
  RealtimeChannel.onPostgresChanges replaces it there.

Two paths cannot carry the annotation and are excluded by .sdk-parse-ignore
instead: each package's own example app, which the extractor treats as a
package because it has a pubspec.yaml, and version.dart, which the release
tooling rewrites wholesale.

Also declares storage.errors.error_codes, which StorageException.error already
implements.
@spydon
spydon requested a review from a team as a code owner August 7, 2026 15:07
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: b7b2b985-16d7-48e3-a722-416eace02a01

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

Copilot AI 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.

Pull request overview

This PR completes the backfill of the capability matrix (sdk-compliance.yaml) so that the Dart SDK’s extracted public API symbols are fully accounted for, and it tightens a small amount of accidentally-exported surface by marking helper declarations @internal and narrowing exports.

Changes:

  • Expanded sdk-compliance.yaml to register the remaining public API symbols (including missing entry points and supporting types) and added a new storage.errors.error_codes feature.
  • Marked various top-level helpers / shims as @internal so they no longer count as SDK public API symbols.
  • Narrowed realtime_client exports of transformers.dart from hide ... to show PostgresColumn, PostgresType to prevent future accidental leakage.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
sdk-compliance.yaml Registers remaining public API symbols into capability matrix features/supporting symbols.
packages/supabase_flutter/lib/src/passkey/passkey_options_mapper.dart Marks passkey options mapping helpers @internal.
packages/supabase_flutter/lib/src/local_storage_web.dart Marks web local storage helpers @internal.
packages/supabase_flutter/lib/src/local_storage_stub.dart Marks stub local storage helpers @internal.
packages/supabase_flutter/lib/src/hot_restart_cleanup_web.dart Marks hot-restart cleanup hooks @internal for web.
packages/supabase_flutter/lib/src/hot_restart_cleanup_stub.dart Marks hot-restart cleanup hooks @internal for stub.
packages/realtime_client/lib/src/websocket/websocket_web.dart Marks createWebSocketClient @internal for web implementation.
packages/realtime_client/lib/src/websocket/websocket_stub.dart Marks createWebSocketClient @internal for stub implementation.
packages/realtime_client/lib/src/websocket/websocket_io.dart Marks createWebSocketClient @internal for IO implementation.
packages/realtime_client/lib/src/types.dart Marks ChannelFilter @internal (no longer treated as SDK public API evidence).
packages/realtime_client/lib/src/transformers.dart Marks transformer helpers @internal (keeps only intended public types).
packages/realtime_client/lib/src/retry_timer.dart Marks maxShift @internal.
packages/realtime_client/lib/realtime_client.dart Narrows exports of transformers to only PostgresColumn and PostgresType.
packages/postgrest/lib/src/constants.dart Marks defaultHeaders @internal.
packages/gotrue/lib/src/broadcast_web.dart Marks getBroadcastChannel @internal for web implementation.
packages/gotrue/lib/src/broadcast_stub.dart Marks getBroadcastChannel @internal for stub implementation.
.sdk-parse-ignore Excludes per-package examples and rewritten version.dart from API extraction.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/supabase_flutter/lib/src/local_storage_web.dart
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.

2 participants