Skip to content

refactor(storage)!: share one SortDirection enum across the packages - #1752

Merged
spydon merged 2 commits into
mainfrom
session/scheming-wren-pkvw
Aug 21, 2026
Merged

refactor(storage)!: share one SortDirection enum across the packages#1752
spydon merged 2 commits into
mainfrom
session/scheming-wren-pkvw

Conversation

@spydon

@spydon spydon commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

What

StorageFileApi.list() took its sort direction as a String:

SortBy(column: 'created_at', order: 'desc')

Nothing validated that string, so order: 'ascending' or order: 'DESC' compiled fine and only
surfaced as a 400 from the storage server.

While fixing that, the same asc/desc direction turned out to be modelled three times over:

Enum Package Used by
BucketSortOrder supabase_storage ListBucketsOptions.sortOrder
FileSortOrder supabase_storage FileSort.order (listPaginated)
SortDirection iceberg SortField.direction

All three had identical ascending('asc') / descending('desc') values.

Change

One SortDirection in supabase_common, re-exported from iceberg and supabase_storage (and so
from supabase and supabase_flutter):

enum SortDirection {
  ascending('asc'),
  descending('desc');

  const SortDirection(this.value);

  /// The value sent to and received from the API.
  final String value;

  static SortDirection fromValue(String value) =>
      values.firstWhere((direction) => direction.value == value);
}

SortBy.order is now that enum, non-nullable and defaulting to SortDirection.ascending:

const SortBy({
  this.column = 'name',
  this.order = SortDirection.ascending,
});

column stays a String? with its 'name' default, since list() accepts any column of a
FileObject while FileSortColumn only covers the three the paginated endpoint sorts by.
supabase-swift made the same SortBy change in its storage v3 rewrite
(supabase/supabase-swift#987).

SortDirection is the name that survives rather than SortOrder, because package:iceberg
already has a public SortOrder class (the Iceberg spec's sort-order object, with orderId and
fields) that supabase_storage re-exports, so a SortOrder enum would make the name ambiguous
for consumers.

The wire format is untouched: every serializer still emits asc / desc.

Breaking changes

  • BucketSortOrder and FileSortOrder are gone; use SortDirection, whose values are identical
  • SortBy(order: 'desc') becomes SortBy(order: SortDirection.descending)
  • SortBy(order: null) no longer compiles; leave order out to sort ascending

iceberg callers are unaffected: SortDirection keeps its name and is still exported from
package:iceberg/iceberg.dart.

Documented in MIGRATION.md. The default-filling behavior from #1490 is preserved: a partial
SortBy still sends both keys, and order can no longer be null at all.

Query ordering keeps its bool

PostgrestTransformBuilder.order() and SupabaseStreamBuilder.order() deliberately keep
ascending: bool rather than taking a SortDirection. They build the asc / desc string
internally, so there was never an invalid value a caller could pass, and the bool matches
supabase-js ({ ascending: false }) and supabase-swift, which keeps shared docs and cross-SDK
examples portable. v3 already changed that call once by flipping the ascending default, so an
enum would make users touch the same line twice for no safety gain.

Compliance matrix

BucketSortOrder and FileSortOrder are removed from the storage features. SortDirection was
already registered in the shared supporting_symbols block for iceberg, which is the right home
for it now that no single capability owns it. .sdk-parse-ignore gains an exception for
sort_direction.dart, alongside the existing one for retry_options.dart, since both are
supabase_common sources the clients re-export as user facing API.

Tests

  • SortBy.toMap covers the null column fallback and the enum serialization
  • The list sortBy defaults group passes the enum, and its explicit-null case narrowed to column
    since order cannot be null anymore

dart test passes for supabase_storage (203), iceberg (30) and supabase_common (109), and
dart analyze is clean across packages and examples.

Closes #1491
Closes SDK-1549

`SearchOptions.sortBy` took its sort direction as a `String`, so an
invalid value only surfaced as a 400 from the storage server.
`SortBy.order` is now the `FileSortOrder` enum that `listPaginated`
already used, non-nullable and defaulting to `FileSortOrder.ascending`.

`column` stays a `String`, since `list()` accepts any column of a
`FileObject`.

Closes SDK-1549
@spydon
spydon requested a review from a team as a code owner August 21, 2026 08:43
@coderabbitai

coderabbitai Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@spydon, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 13 minutes

Limit details: You’ve used all 4 included reviews currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

Wait for the limit to reset, then comment @coderabbitai review or push new commits to the PR.

An organization admin can change what happens after included review limits in Billing.

How do review limits work?

CodeRabbit enforces per-developer PR review limits within each organization.

For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 0aff76db-b169-4bc6-be6e-0afe57dda915

📥 Commits

Reviewing files that changed from the base of the PR and between 7942c37 and 502f327.

📒 Files selected for processing (13)
  • .sdk-parse-ignore
  • MIGRATION.md
  • examples/storage_transforms/lib/storage_repository.dart
  • packages/iceberg/lib/iceberg.dart
  • packages/iceberg/lib/src/iceberg_types.dart
  • packages/supabase_common/lib/src/sort_direction.dart
  • packages/supabase_common/lib/supabase_common.dart
  • packages/supabase_storage/lib/src/types.dart
  • packages/supabase_storage/lib/supabase_storage.dart
  • packages/supabase_storage/test/basic_test.dart
  • packages/supabase_storage/test/client_test.dart
  • packages/supabase_storage/test/types_test.dart
  • sdk-compliance.yaml

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.

`BucketSortOrder` and `FileSortOrder` in supabase_storage and
`SortDirection` in iceberg all described the same ascending or descending
direction. They are now one `SortDirection` in supabase_common,
re-exported from the clients that use it.

`FileSortOrder` was only introduced in the previous commit, so the
storage list sort direction lands as `SortDirection` from the start.

Closes SDK-1549
@spydon spydon changed the title feat(storage)!: take the list sort direction as an enum refactor(storage)!: share one SortDirection enum across the packages Aug 21, 2026
@spydon
spydon merged commit 38396ed into main Aug 21, 2026
48 checks passed
@spydon
spydon deleted the session/scheming-wren-pkvw branch August 21, 2026 09:56
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.

order should be an enum instead of a string

2 participants