## Problem
In order to update to react 19, we need to update several dependencies
## Solution
- migrate to the `radix` umbrella package to ease upgrade
- update some dependencies
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Consolidated Radix UI usage to a single unified package across apps
and packages, updated package manifests and workspace catalog entries.
No user-facing behavior, visuals, or public APIs changed.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Documentation**
* CLI-first quickstart rewritten: Docker/local runtime required,
explicit create/enter directory steps.
* Updated starter function template and optional VSCode runtime note.
* Guidance to secure endpoints at creation with an auth flag.
* Streamlined local testing and curl examples to use 127.0.0.1 and
apikey header with publishable keys.
* Simplified deployment to a single deploy command; notes API-deploy
fallback.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
## What kind of change does this PR introduce?
docs update
## What is the current behavior?
Functions default secrets page doesn't mention new api keys secrets
## What is the new behavior?
Adding the new api keys secrets
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Documentation
* Updated Edge Functions secrets guide with newly documented environment
variables including `SUPABASE_DB_URL`, `SUPABASE_PUBLISHABLE_KEYS`, and
`SUPABASE_SECRET_KEYS` with usage guidance.
* Reorganized secrets documentation for improved clarity.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
missing a filter on org slug in org-level audit logs, causing events to
be matched to the first org in the array.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Fixed organization label display in audit logs to correctly show the
organization associated with each log entry.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
Feature — wires up three new advisor lints landed in splinter, and
updates the self-hosted SQL bundle for the existing
`pg_graphql_anon_table_exposed` lint to track splinter's correctness
fixes. Companion to `supabase/splinter` #160 (already merged) and #162
(test fix in flight).
## What is the current behavior?
Splinter's `main` now exposes four lints in the pg_graphql / SECURITY
DEFINER family:
- `pg_graphql_anon_table_exposed` (0026, existing) — wired into Studio
in #45253; SQL in `packages/pg-meta` is the original version that uses
`has_table_privilege` and the relkind set `('r','p','v','m')`.
- `pg_graphql_authenticated_table_exposed` (0027, new) — paired check
against the `authenticated` role. Studio renders any new finding without
a `lintInfoMap` entry as a row with no icon, no title mapping, and no
"Fix" CTA. Self-hosted users do not see the lint at all because
`packages/pg-meta` does not include it.
- `anon_security_definer_function_executable` (0028, new) — `SECURITY
DEFINER` function executable by `anon`. Same Studio + self-hosted gaps
as 0027.
- `authenticated_security_definer_function_executable` (0029, new) —
same against `authenticated`.
Splinter has also updated 0026 itself (PR #160) in two ways that need to
flow into the self-hosted SQL bundle:
1. **`relkind` filter:** `('r','p','v','m')` → `('r','v','m','f')`.
Drops partitioned table roots (pg_graphql does not expose them; their
leaf partitions are still covered as `'r'`) and adds foreign tables,
which pg_graphql does expose.
2. **Privilege predicate:** `has_table_privilege(role, oid, 'SELECT')` →
`EXISTS` over `pg_attribute` calling `has_column_privilege`. Catches
column-level grants such as `GRANT SELECT (col) ON t TO anon`, which
pg_graphql's introspection exposes but `has_table_privilege` missed.
Cloud projects auto-fetch `splinter.sql` via the platform mgmt-api's
`getLintSql` (1-hour cache TTL), so they pick up #160's lint and SQL
changes independently of this PR. This PR is about the Studio display
mapping and the self-hosted SQL bundle.
## What is the new behavior?
Two minimal additions, mirroring the integration shape of #45253.
### `apps/studio/components/interfaces/Linter/Linter.utils.tsx`
Three new entries appended to `lintInfoMap`:
- `pg_graphql_authenticated_table_exposed` — `Eye` icon (paired with the
existing `pg_graphql_anon_table_exposed` entry); link points to the
Table Editor scoped to `metadata.schema` + `metadata.name`; `linkText:
'View object'`; `category: 'security'`.
- `anon_security_definer_function_executable` — `Unlock` icon (signals
"this thing is callable when it shouldn't be"); link points to the
Database Functions browser scoped to `metadata.schema` +
`metadata.name`; `linkText: 'View function'`; `category: 'security'`.
- `authenticated_security_definer_function_executable` — same as 0028
against `authenticated`.
Each entry's `docsLink` points at the splinter-hosted lint doc.
### `packages/pg-meta/src/sql/studio/advisor/lints.ts`
The existing `pg_graphql_anon_table_exposed` SQL block is updated in
place to match the new splinter version: new `relkind` set, `case`
statement for `'f'`, and the `EXISTS` over `pg_attribute` privilege
check. Three new `union all` blocks are appended for 0027/0028/0029. The
function lints (0028/0029) include the `pgrst.db_schemas` filter
(mirroring lint `0023_sensitive_columns_exposed`) so findings are scoped
to schemas PostgREST actually exposes; the self-hosted query wrapper
already sets the GUC when `exposedSchemas` is passed
(`enrichLintsQuery`).
## Coverage of the four exposure paths
| Role | Tables/views/MVs/foreign tables | SECURITY DEFINER functions |
|------|---------|----------|
| `anon` | 0026 (existing, updated) | 0028 (new) |
| `authenticated` | 0027 (new) | 0029 (new) |
The 0026/0027 pair covers `pg_graphql` introspection visibility; the
0028/0029 pair covers RLS bypass via privileged function execution
through `/rest/v1/rpc` (and `/graphql/v1` for compatible return types).
Each lint's doc cross-references its sibling so an operator hitting one
is steered toward the others.
## Verification
- `cd packages/pg-meta && npx tsc --noEmit` — clean.
- `cd apps/studio && npx tsc --noEmit` — clean for the changed file.
(Other unrelated TS errors exist in the working tree but are
pre-existing and not introduced by this PR.)
- `cd apps/studio && npx eslint
components/interfaces/Linter/Linter.utils.tsx` — clean.
## Files
- `apps/studio/components/interfaces/Linter/Linter.utils.tsx` — adds
three `lintInfoMap` entries (0027, 0028, 0029).
- `packages/pg-meta/src/sql/studio/advisor/lints.ts` — updates the 0026
SQL block to match splinter's correctness fixes, appends 0027/0028/0029
SQL blocks.
## Related
- supabase/splinter#160 — adds 0027/0028/0029 and rewrites 0026
(merged).
- supabase/splinter#162 — fixes test setup for 0028/0029 (in flight;
does not affect the SQL shipped here).
- supabase/supabase#45253 — original 0026 Studio integration.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added security linting to detect authenticated-table exposure and
executable SECURITY DEFINER functions.
* Added signed-in visibility checks alongside anonymous checks.
* **Bug Fixes / Improvements**
* Improved relation type handling for accurate table/foreign/partition
classification.
* Switched to column-level privilege analysis for visibility.
* Improved entity naming shown in lints (includes function argument
display).
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Danny White <3104761+dnywh@users.noreply.github.com>
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
Feature — wires up the new advisor lint `pg_graphql_anon_table_exposed`
so it renders properly in Studio and ships with
self-hosted Supabase. The lint itself was added to splinter in
supabase/splinter#158 (already merged).
## What is the current behavior?
Splinter's `main` exposes lint `0026_pg_graphql_anon_table_exposed`,
which detects tables, views, and materialized views
whose schema is visible through the public `/graphql/v1` introspection
endpoint when the `anon` role has `SELECT` on them.
The hosted advisor (mgmt-api) auto-fetches `splinter.sql` from
raw.githubusercontent.com, so the lint will start firing on
cloud projects, but:
- Studio has no `lintInfoMap` entry for it, so the row renders without
an icon, title mapping, "Fix" CTA, or category
classification.
- Self-hosted Supabase ships with a vendored copy of the lint SQL in
`packages/pg-meta`; without an update there, self-hosted
users never see the lint at all.
## What is the new behavior?
Two minimal additions:
- **`apps/studio/components/interfaces/Linter/Linter.utils.tsx`** — adds
a `lintInfoMap` entry for
`pg_graphql_anon_table_exposed`: title `"pg_graphql Anon Role Exposes
Objects in Introspection"`, `Eye` icon, `security`
category, `"View object"` CTA pointing at the table editor scoped by
`metadata.schema` and `metadata.name`, docs link to the
splinter docs page.
- **`packages/pg-meta/src/sql/studio/advisor/lints.ts`** — vendors the
lint's SQL block into `getLintsSQL()` so self-hosted
deployments include it. Follows the file's documented copy-paste
convention from splinter: every backtick inside SQL string
literals is escaped (`` ` `` → `` \` ``), and the hardcoded docs URL is
replaced with `${literal(\`${docsUrl}/...\`)}`.
No changes to the OpenAPI surface, no changes to the `LINT_TYPES`
literal union (auto-generated; matches the precedent of how
lints 0023–0025 were added — Studio's `LintInfo.name` is typed as
`string`, not the strict enum).
## Additional context
- Splinter PR (merged): https://github.com/supabase/splinter/pull/158
- Splinter lint source:
https://github.com/supabase/splinter/blob/main/lints/0026_pg_graphql_anon_table_exposed.sql
- Splinter docs page:
https://github.com/supabase/splinter/blob/main/docs/0026_pg_graphql_anon_table_exposed.md
- The hosted advisor flow that fetches splinter.sql automatically lives
in the platform mgmt-api (`getLintSql` in
`advisors-utils.ts`), with a 1-hour cache TTL — cloud projects will pick
up the new lint independently of this PR; this PR is
about the Studio display mapping and the self-hosted SQL bundle.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added a new security linter check that identifies tables and views
exposed to anonymous GraphQL access, with warnings and remediation
guidance to help resolve the issue.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary
Adds a reusable `TaxDisclaimer` component ("Prices shown do not include
applicable taxes.") and places it on surfaces where users see a price
before confirming a billable action.
## Where it appears
- **Disk resize review
dialog** — `DiskManagementReviewAndSubmitDialog` (below the before/after
price comparison)
- **Add-on side panels** — PITR, Custom Domain, IPv4 (below the price
options)
- **Log drain destination form** — stacked under "See full pricing
breakdown here" in the footer
- **SMS MFA confirmation modal** — below the $75/$10 billing copy
- **Read replica pricing dialog** — at the end of the cost breakdown
- **Create branch modal** — below the disk/compute cost estimates
## Test plan
- [ ] Open disk/compute resize review dialog — disclaimer appears below
the before/after panel
- [ ] Open each add-on side panel (PITR / Custom Domain / IPv4) —
disclaimer appears below the price options
- [ ] Open log drain destination sheet — disclaimer stacks under the
pricing breakdown link in the footer
- [ ] Trigger SMS MFA confirmation — disclaimer appears below the
billing copy
- [ ] Open read replica pricing dialog ("Learn more" from deploy
replica) — disclaimer at the bottom
- [ ] Open create branch modal — disclaimer appears after the compute
cost block
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added tax disclaimers across multiple billing and pricing interfaces
throughout the platform. Users will now see notices regarding applicable
taxes displayed in various authentication settings, branch creation
workflows, database disk management dialogs, database replica pricing
screens, log drain configuration panels, custom domain settings, IPv4
address configuration, and Point-in-Time Recovery options.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Problem
When creating a new paid organization, if the backend rejects the
request (e.g. invalid tax ID, invalid billing address, name conflict,
rate-limit), the Stripe payment UI was torn down and remounted empty.
## Solution
- Remove `resetPaymentMethod()` from the org-create mutation's
`onError`. Server-side validation failures don't consume or invalidate
the Stripe payment method, so there's no reason to tear down the
Elements.
- Collapse the paid-plan submit flow so that `createPaymentMethod()` is
called on every attempt (not just the first). This materializes a fresh
`PaymentMethod` from whatever is currently in the Stripe Elements -
correctly capturing edits the user made between attempts (including card
number changes), and guaranteeing the latest address/tax ID are sent.
## Test plan
- [ ] Go to `/new`, pick **Pro**, fill a valid card (`4242 4242 4242
4242`) and address, tick "I'm purchasing as a business", select a tax ID
type and enter an **invalid** tax ID value → submit
- [ ] Confirm: error toast appears, card number + address fields + tax
ID selector + tax ID value remain populated, loading state clears
- [ ] Correct the tax ID and resubmit → confirm the network request
contains the **corrected** `tax_id` (not `undefined`) and succeeds
- [ ] Regression: create a Free org still works
- [ ] Regression: a 3DS failure on a paid org still resets the payment
method (that path goes through `PaymentConfirmation.onError`,
unchanged). Use card `4000002760003184`
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved payment method handling during organization creation for paid
plans. The system now consistently attempts to create payment methods
and properly handles failures. Payment information is preserved on
errors, providing a more reliable organization setup experience.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Problem
We want to reduce the code we ship and maintain.
## Solution
Migrate old `<Checkbox />` usage to the new Shadcn component.
There's one visual change: no more green background or outline.
## Screenshots
### On `apps/www`
Before:
<img width="1095" height="772" alt="image"
src="https://github.com/user-attachments/assets/b14a0477-d8ac-4ae5-a1c3-63657609e4e5"
/>
After:
<img width="1085" height="766" alt="image"
src="https://github.com/user-attachments/assets/f4c2156c-38e1-4834-b013-e39b8c3dd76e"
/>
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* Unified checkbox appearance and behavior across the app for consistent
toggles, labels, and interactions.
* **Bug Fixes**
* Fixed selection issues including shift-select edge cases and
click-propagation in lists; added ARIA labels for improved
accessibility.
* **Chores**
* Removed legacy checkbox implementation, associated styles, tests, and
deprecated theme entries.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Problem
#45218 removed the PITR duration input label: _Choose the duration of
recovery_
## Solution
Restore it
## Screenshots
Before:
<img width="1534" height="1130" alt="image"
src="https://github.com/user-attachments/assets/f1f7fc5b-0fba-4356-b6d6-9bffcaa211bd"
/>
After:
<img width="760" height="734" alt="image"
src="https://github.com/user-attachments/assets/5df7a986-9c3b-48a3-84d7-4de151dd7f5f"
/>
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Style**
* Improved accessibility of the PITR (Point-In-Time Recovery) settings
control by adding proper label association for the recovery-duration
selection option.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Documentation**
* Corrected internal documentation links across auth guides (Custom
Access Token Hooks), database hit-rate guides (Disk IO / compute
anchors), functions deployment (Dashboard quickstart), and product
security (Realtime authorization) for proper targets and path
formatting.
* Updated Storage page doc links for analytics and vector introductions.
* Updated Database page “Supabase ETL” docs link to the replication
guide.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary
- Removes the legacy Table Editor filter bar and its
`supabase-ui-table-filter-bar` feature-preview flag (opt-out rate
~0.13%, no plans to keep supporting it).
- Merges `HeaderNew` into `Header`, consolidates `useTableFilterNew`
into `useTableFilter`, and adds
`useOptionalTableEditorTableStateSnapshot` so `useTableFilter` can
safely fall back to URL params when called outside the table-editor
provider (e.g. from the sidebar).
- Drops the associated preview modal entry, screenshot, and local
storage key.
Based on the closed PR https://github.com/supabase/supabase/pull/44867.
Closes
[FE-3071](https://linear.app/supabase/issue/FE-3071/remove-old-table-editor-filter-bar).
## Test plan
- [x] `pnpm --filter=studio typecheck` passes
- [x] `pnpm --filter=studio lint` passes
- [x] Open the Table Editor, confirm the new filter bar renders and
filters apply/clear correctly
- [x] Apply filters, reload the page — filters persist via URL params
- [x] Delete a column that has an active filter — filter is removed
cleanly
- [x] Right-click a cell — "Filter by value" still appears for simple
values
- [x] Select rows — row-selection header (copy / export / delete) still
works
- [x] Foreign Row Selector still renders (`FilterPopoverPrimitive`
retained for this usage)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Table filter bar is now permanently available (no longer gated behind
preview feature).
* **Improvements**
* Reorganized table header layout with improved filter UI placement and
styling.
* Streamlined and unified filter behavior across the grid for more
consistent operation.
* Simplified insert row/column functionality with clearer permission
handling.
* **Refactor**
* Consolidated filter system by removing redundant implementations and
feature flags.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Documentation**
* Updated SDK initialization examples to reflect current authentication
patterns across multiple Supabase integration guides
* Enhanced security documentation with expanded guidance on protecting
sensitive credentials like secrets and service role keys in frontend and
Edge Function environments
* Clarified Row-Level Security access patterns and data availability
considerations when using publishable keys
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: fadymak <dev@fadymak.com>
Closes#45184.
## Summary
`ErroredTableDetails.tsx` links the `no_retry` branch to the support
form with the Postgres error message (`state.reason`) dropped into the
`error` query parameter raw:
```tsx
href={`/support?projectRef=${projectRef}&category=dashboard_bug&subject=Database%20replication%20error&error=${state.reason}`}
```
Error strings routinely contain `&`, `#`, `=`, or newlines. Any of these
break the URL and leave the support form with a truncated or
misattributed value. Wrap with `encodeURIComponent`, matching the
pattern already used in `PipelineStatus.tsx:39-42` for the
replication-logs URL. Null-coalesce to `''` so the link is still
well-formed if `state.reason` is absent.
## Test plan
- [ ] Trigger a replication error whose message contains `&` / `#` /
newlines, open the support link, verify the full error text reaches the
form.
- [ ] Normal error string. URL is unchanged beyond standard URL
encoding.
Co-authored-by: Ali Waseem <waseema393@gmail.com>
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
Fix broken links on self-hosting docs.
## Additional context
<img width="763" height="441" alt="Screenshot_2026-04-23_11-45-37"
src="https://github.com/user-attachments/assets/11479aff-f517-421d-8bcd-ef60b97faec3"
/>
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Bug Fixes
* Fixed edit links in self-hosting configuration documentation guides
for Analytics, Auth, Realtime, and Storage features to ensure they point
to the correct source files.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## What kind of change does this PR introduce?
Feature.
## What is the current behaviour?
Keyboard shortcuts can be discovered piecemeal through command palette
entries, tooltips, and preferences, but there is no universal shortcut
reference surface.
## What is the new behaviour?
Adds a global `Mod+/` shortcut and command palette action to open a
keyboard shortcuts reference sheet. The sheet renders registered
shortcuts grouped from general dashboard actions through navigation and
more specific surfaces.
| Preview |
| --- |
| <img width="820" height="928" alt="CleanShot 2026-04-24 at 11 27
51@2x"
src="https://github.com/user-attachments/assets/8ceb4a35-7adc-474b-8702-5c08a4219d25"
/> |
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added a comprehensive keyboard shortcuts reference sheet that displays
all available shortcuts organized into logical categories.
* New keyboard shortcut Mod+/ (Cmd+/ on Mac) opens the reference sheet
instantly from anywhere within the application.
* Shortcuts are displayed with their formatted keyboard combinations,
with multi-step sequences clearly separated for easy reference and
discovery.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
When unified logs are in "live" mode, we inserted a bar into the list
that got pushed down with new logs appearing. Doesn't seem to add much
value and our live mode button is visibly green when switched on.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* Removed live-updating row functionality from UnifiedLogs component.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## TL;DR
another parsing issue & updated prev tests to validate this aswell :P
## ex
<table>
<tr>
<td><strong>Before</strong></td>
<td><strong>After</strong></td>
</tr>
<tr>
<td>
<img width="325" height="108" alt="Before"
src="https://github.com/user-attachments/assets/f5583e2e-e0d5-439c-a05a-8120959250ca"
/>
</td>
<td>
<img width="363" height="119" alt="After"
src="https://github.com/user-attachments/assets/7e65a578-acb9-4b90-863c-d3b52411ca7b"
/>
</td>
</tr>
</table>
## ref:
- closes https://github.com/supabase/supabase/issues/45186
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Tests**
* Expanded cron job parsing tests to verify correct handling of
SQL-escaped single quotes in HTTP headers and request bodies.
* **Bug Fixes**
* Fixed cron HTTP request generation and parsing so URLs, headers, and
POST bodies with escaped quotes are preserved and unescaped correctly
when building and reading cron jobs.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Problem
The AI icon in the new filter bar renders but no longer animates when an
AI filter is generating. This regressed after #44906 upgraded
`framer-motion` from `^11.0.3` to `^11.18.2`.
## Cause
The outer rotation transition in `AiIconAnimation` mixed tween props
(`duration`, `ease`) with spring physics (`type: 'spring'`, `stiffness`,
`damping`):
```tsx
transition={{
duration: 2,
repeat: loading ? Infinity : 0,
ease: 'circInOut',
type: 'spring',
stiffness: 60,
damping: 10,
}}
```
`framer-motion@11.0.3` tolerated this combination and produced a
continuous rotation. `11.18.x` resolves it strictly as a physics spring
— `duration`/`ease` are dropped, the spring settles at 360°, and
`repeat: Infinity` no longer produces a visible continuous spin. The
icon ends up looking static.
## Fix
Drop the spring config and keep a simple linear repeating tween — the
original intent was a continuous rotation loader, not a bouncy settle.
## Test plan
- [x] Open a table in the Table Editor, type an AI prompt into the
filter bar, submit it, and confirm the icon rotates continuously while
the mutation is pending.
- [x] Confirm the inner circle's scale pulse is still present and
synced.
- [x] Confirm no regressions in other usages of `AiIconAnimation` (e.g.
AI Assistant).
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Style**
* Refined AI icon animation: continuous rotation during loading, subtle
pulsing (scale) while loading, and enhanced hover interactions with
gentle rotation and scale.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Danny White <3104761+dnywh@users.noreply.github.com>
## Problem
We used to have a `_Shadcn_` suffix for all the shadcn form components
because we also had `formik` form components.
This is not needed anymore.
## Solution
- Remove the suffix
- Update all usages
### Summary
This PR updates the logic to include `prepaid_credits_balance` while
showing the existing customer balance.
This changes the credit balance shown in:
- Billing Settings > Credit Balance
- Credit code redemption modal
The displayed amount now reflects the total credit balance across
prepaid credits and the customer balance.
### Testing
- Open an org billing page with prepaid credits and verify Credit
Balance includes both sources.
- Open the credit redemption modal and verify Current Balance matches
the combined credit amount.
- Verify an org with only customer balance still shows the same credit
amount as before.
- Verify an org with only prepaid credits balance and no customer
balance now shows credits correctly.
- Verify an org with no credits shows 0.00 and does not show /credits.
- Verify an org where net balance is debt still shows a negative amount
without the /credits suffix.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Improvements**
* Credit balance display now includes purchased and prorated credits for
a complete account view.
* Credit redemption and current-balance screens now show combined credit
totals (prepaid + existing) for clearer availability.
* UI descriptive text clarified to explain how credits are applied and
how charges occur once credits are exhausted.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
Bug fix
## What is the current behavior?
The apps/learn and apps/ui-library applications fail to start in
development mode (pnpm dev) and during production builds. This is caused
by a conflict between Next.js 16, which enables Turbopack by default,
and the Contentlayer plugin, which injects a custom Webpack
configuration.
Error: ⨯ ERROR: This build is using Turbopack, with a webpack config and
no turbopack config.
## What is the new behavior?
This PR adds the required turbopack configuration block to the
next.config.mjs files for both apps/learn and apps/ui-library.
It explicitly enables Turbopack while providing the raw-loader rules for
*.md files. This ensures that Contentlayer can correctly process
Markdown content under Turbopack.
Reference: This fix follows the established pattern used in the Design
System
[#39890](https://github.com/supabase/supabase/pull/39890/changes#diff-07283a8ef455ee1c6769cb991039300209d540dd727e3434b070d03075ced551)
and Studio to handle the Contentlayer/Turbopack conflict.
<img width="1429" height="856" alt="image"
src="https://github.com/user-attachments/assets/253ad0da-6420-441b-874c-3394b21b9ae5"
/>
---
## Additional context
Verified that `pnpm dev` starts successfully for both apps after the
change.
Verified that `pnpm build` completes successfully using the Turbopack
engine.
<img width="1429" height="856" alt="image"
src="https://github.com/user-attachments/assets/11efbd5c-57c5-425a-baca-f0198d0e7d91"
/>
<img width="1429" height="856" alt="image"
src="https://github.com/user-attachments/assets/17ec4f25-c19e-4f6b-bcc6-d898b7b20815"
/>
System: macOS | Node: v24.13.1 | Next.js: 16.2.3
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Release Notes
* **Chores**
* Updated build configuration to optimize Markdown file processing in
the application build system across multiple packages.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
# Changes
## Removed unused themes
- Deleted `concept-two.css` (unused) and `dark-combined.css` which was
identical to `dark.css`
- Removed the alias `deep-dark` to `dark` theme since it was unused
## Removed Figma token transform scripts
- Deleted the entire `internals/transform/` directory (~700 lines of JS)
— these scripts transformed Figma tokens into Tailwind variables but are
no longer needed
- Deleted `internals/tokens/cleanse-css-for-tailwind.js` and
`extract-design-tokens.js`
- Removed related dependencies from `package.json`
## Removed other unused files
- Deleted `shadcn.css` (unused)
- Deleted `tailwind-theming.md` (outdated doc),
https://supabase.com/design-system/docs/color-usage is a better resource
## Refactoring
- Extracted the `motion-safe-transition` Tailwind plugin into its own
file (`packages/config/tailwind-plugins/motion-safe-transition.js`)
- Renamed the tailwind class generation script for clarity
- Added stub `tailwind.config.js` files in packages that were missing
them, so VSCode IntelliSense works in those workspaces
- Updated `packages/ui/README.md` to reflect current usage patterns
(imports, styling conventions) instead of outdated Figma tokens workflow
# Testing
- Check all apps whether they have the correct themes with the correct
colors
[Linear
task](https://linear.app/supabase/issue/FE-3059/clean-up-unused-ui-build-artifacts-themes-and-figma-token-scripts)
Proposed mitigation, the obvious tradeoff is that clearing the cache
will make compilation slower on subsequent dev server starts, but more
consistent.
Various people have been observing `next-server` use up to ~34 GB
memory. I've observed 12.59 GB memory, with ~1.5k `postcss` processes:
```
ps aux | grep postcss | grep -v grep | wc -l
1526
```
Going down to 3 `postcss` process and 4.71 GB memory after clearing
cache:
```
ps aux | grep postcss | grep -v grep | wc -l
3
```
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Development infrastructure: adds an automated pre-development step
that clears the local dev cache before starting the development server
by introducing a new lifecycle hook and supporting cleanup script;
purely maintenance-oriented with no user-facing changes or functional
impact.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
Fix incorrect pre-fills
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved formatting of upgrade failure details sent through support
communications to use standard text representation instead of
URL-encoded formatting.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Before:
<img width="3784" height="2094" alt="image"
src="https://github.com/user-attachments/assets/c03b52f3-1033-40ec-974d-25d275d6bf6a"
/>
After:
<img width="2088" height="1768" alt="image"
src="https://github.com/user-attachments/assets/f7dedd36-24ac-40e5-87b4-0cb0ecb74c00"
/>
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Style**
* Updated styling for course titles and chapter text displays to enhance
visual clarity and ensure consistent presentation across the learning
experience. Improved readability through refined text formatting and
color treatment.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## What kind of change does this PR introduce?
Docs update and UI copy improvement.
## What is the current behavior?
The GitHub integration working directory helper uses an inline tooltip
for examples. In the form layout, the tooltip alignment and inline code
wrapping can make the helper harder to scan.
The integration settings pages also mix markdown-rendered copy with JSX
copy, duplicate the integration cover image helper, and use slightly
different heading, spacing, and button copy patterns across GitHub,
Vercel, and AWS PrivateLink.
## What is the new behavior?
The GitHub working directory field now keeps the helper copy concise and
links to a dedicated docs section with examples for repository root and
nested `supabase/` directories.
The integration settings sections now use a more consistent JSX
structure and copy treatment across GitHub, Vercel, and AWS PrivateLink,
including shared cover imagery and matching explanatory section
hierarchy.
| Before | After |
| --- | --- |
| <img width="1838" height="696" alt="CleanShot 2026-04-24 at 14 35
32@2x"
src="https://github.com/user-attachments/assets/f9843018-fbf5-4c18-a0c3-1842b665f3fd"
/> | <img width="1842" height="700" alt="CleanShot 2026-04-24 at 14 30
21@2x-64E8726E-0B89-4C5A-8A47-CE1AA24F3D1A"
src="https://github.com/user-attachments/assets/bb017464-2b43-4dfe-94b8-a586aedea318"
/> |
| <img width="1884" height="1432" alt="CleanShot 2026-04-24 at 14 40
19@2x"
src="https://github.com/user-attachments/assets/b34e4573-cd7c-4588-83a0-0e1941019552"
/> | <img width="1844" height="1424" alt="CleanShot 2026-04-24 at 14 39
02@2x"
src="https://github.com/user-attachments/assets/4f82b01c-cb27-4f01-b2da-76b7f6e298a5"
/> |
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Documentation**
* Clarified GitHub integration setup: provide a Working directory value,
how to compute it from the repo root (including "." for root), examples,
and updated “initialize” spelling.
* **Refactor**
* Simplified integration form descriptions (tooltips → inline text +
Learn more link).
* Reworked GitHub and Vercel integration content to use consistent
headings, layout, and shared image handling.
* Reorganized integration settings rendering for clearer UI states.
* **Style**
* Minor copy, casing, and button text/spacing adjustments.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## What kind of change does this PR introduce?
AGENTS.md update.
## What is the current behavior?
None of the below are specified in AGENTS.md.
## What is the new behavior?
- Specify U.S. English in code. This is necessary as many of us use
British English or equivalent, and this can creep into code
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Added/updated contribution documentation to specify that all
repository text should use U.S. English for consistency.
---
**Note:** This change updates internal documentation conventions only
and does not affect end-user functionality.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Adds a "Supabase AI may not always produce correct answers. Double check
responses." disclaimer to the AI assistant chat panel.
<img width="1472" height="678" alt="image"
src="https://github.com/user-attachments/assets/ad53a371-f9c5-4c40-aec5-5a3be435fadf"
/>
Closes AI-645
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added a disclaimer message in the AI Assistant panel informing users
that AI-generated answers may be incorrect and should be verified before
use.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
Wording change
## What is the current behavior?
Please link any relevant issues here.
## What is the new behavior?
Just provides an example of what to include
## Additional context
Add any other context or screenshots.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Documentation**
* Clarified the "Working directory" guidance in GitHub Integration
settings: must be a relative path to the directory that contains the
supabase/ folder (not the supabase folder itself). Added an
example-driven tooltip and updated the placeholder to "." to reflect the
expected format and reduce confusion. This improves clarity and prevents
setup errors for repository-based workflows.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
## Problem
Cookie banner keeps re-prompting GDPR users who denied consent or made a
partial opt-out via Privacy Settings — they can't get rid of it.
Reported by Christian Gedde-Dahl (Front SU-362240, mygame.no) and a
Supabase support engineer independently.
The March fix for FE-2648 handled the accept case — users got their
banner dismissal stomped when GTM's Usercentrics integration migrated
localStorage from `uc_settings` to `ucData`/`ucString`. But that fix
only recognized uniformly-accepted `ucData`, so any other shape
(deny-all, essentials-plus-some-tracking, partial opt-out via the
Privacy Settings modal) fell through and was treated as "no prior
decision." Banner re-prompts on every page load.
Christian's and his colleague's `ucData.consent.services` showed 13
services accepted (essentials + functional) and 4 tracking services
denied — the shape you get from toggling off the Marketing category in
Privacy Settings. Our detection ignored it.
## Changes
- `detectPriorConsent` now returns a discriminated union — `null`, `{
kind: 'uniform-accept' }`, or `{ kind: 'decisions'; decisions }` — so we
restore per-service state faithfully instead of flattening to deny-all.
- Parse `uc_settings` for the fast cross-app nav case. The old fallback
treated `uc_user_interaction === "true"` as uniform-accept, which
silently upgraded deny users (GDPR violation waiting to happen). Now the
flag is just a gate confirming the user actually interacted, and we read
real decisions from `uc_settings.services[]`.
- Extracted the post-init orchestration from `initUserCentrics` into
exported `applyPriorDecisionToSDK(UC, initialUIValues, priorDecision)`
so it's unit-testable without mocking the dynamic SDK import.
- Added a coverage cross-check: if the Usercentrics ruleset has a
non-essential service that isn't in the user's stored decisions, force a
re-prompt rather than silently defaulting the new service. Essentials
are skipped because the SDK forces them on regardless.
- Everything fails closed on partial `ucData` / `uc_settings`
corruption. Cherry-picking the valid subset would bias toward
over-consent, which is the worst-direction bias in this domain.
## Testing
27 unit tests covering `detectPriorConsent` parsing (both `ucData` and
`uc_settings` paths, fail-closed on malformed or partially-corrupt
blobs, combined scenarios) and `applyPriorDecisionToSDK` orchestration
(uniform accept, decisions with full coverage, uncovered-non-essential
compliance guard, essentials-only negative control, null fallthrough,
SDK-already-consented passthrough).
Can't fully repro on staging — CSP blocks GTM on preview, so the
`ucData` migration never fires. Same limitation as the original FE-2648
fix. Will verify in production post-merge by asking Christian to reload
and watching support ticket volume.
Reviewed twice by Codex with a full iteration between passes; final pass
found no functional blockers.
GROWTH-790
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Fail-closed validation for stored consent data: malformed, partial, or
missing entries now yield null and avoid unsafe restoration.
* Improved precedence and fallback so corrupt prior data won’t
incorrectly restore consent.
* **Refactor**
* Consent detection now returns richer prior-decision results (uniform
accept, per-service decisions, or null).
* Applying prior decisions to the SDK uses stricter coverage checks
before restoring per-service consent.
* **Tests**
* Expanded tests covering varied stored-consent shapes, gating rules,
precedence, recovery, and SDK application behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
### Summary
Mirrors the tax-ID-clearing behavior already present in
`NewPaymentMethodElement` (used by `AddPaymentMethodForm`) over to
`BillingCustomerDataForm`. When a user changes their billing country,
the previously selected tax ID (type, value, name) is now cleared so a
stale tax ID from the previous country doesn't silently persist under
the new one.
### Test plan
- [x] Open **Organization Settings → Billing → Billing Address** for an
org with a saved billing address + tax ID
- [x] Verify the saved tax ID is shown on initial load (not cleared)
- [x] Change the country in the address element to a different country
- [x] Verify the tax ID combobox resets to "Select tax ID" and the tax
ID value input disappears
- [x] Change the country back to the original country → tax ID still
cleared (does not re-populate)
- [x] Pick a new tax ID for the new country, enter a value, save →
confirm it persists
- [x] Reload the page → saved tax ID shows correctly and is not cleared
on mount
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Tax ID fields in organization billing settings are now automatically
cleared when the billing address country is changed, preventing
country-specific tax ID mismatches.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
chore
## What is the current behavior?
New project dialog defaults to AWS Revamped provider on staging.
## What is the new behavior?
New project dialog defaults to AWS provider on staging.
## Additional context
N/A
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Standardized the default cloud provider to AWS across all environments
(staging/preview included), ensuring consistent infrastructure
selection.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
Feature
## What is the current behavior?
When sending organization invites to multiple emails at once, the
invitations API is called once for each email passed, passing a single
email address in the `email` field.
## What is the new behavior?
A single request is used when sending multiple organization invites at
once, by using the new `emails` field.
## Additional context
This builds further on https://github.com/supabase/supabase/pull/42637⚠️ Note: I'd like to merge this after getting the API changes in first:
https://github.com/supabase/platform/pull/31561
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Bulk invite: paste comma-separated emails (parsed, trimmed,
deduplicated, lowercased) and send as a single batched request; inputs
are categorized into new, already-invited, and existing members.
* SSO and project scope options included in invite payloads.
* **Bug Fixes / API**
* Invitation endpoint now accepts multiple emails; resend uses
multi-email format. Invalid addresses are blocked, existing members are
skipped with error toasts, and overall success is reported with the
dialog closing after invite.
* **Tests**
* Added unit and UI tests covering parsing, categorization, payload
building, validation limits, and invite flows.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Danny White <3104761+dnywh@users.noreply.github.com>
## Summary
Fixes
[FE-3060](https://linear.app/supabase/issue/FE-3060/modshiftc-modshiftm-shortcuts-suppressed-when-a-table-editor-cell-is).
`Mod+Shift+C` (Copy as CSV) and `Mod+Shift+M` (Copy as Markdown) — and
any other Meta/Ctrl/Escape shortcut registered via `useShortcut` without
an explicit `ignoreInputs` — stopped firing when focus landed on a
`react-data-grid` cell in the table editor (or any other
input/contenteditable).
## Fix
In `apps/studio/state/shortcuts/useShortcut.tsx`, only include
`ignoreInputs` in the options object when it's actually set, so
TanStack's register-time default sticks across re-renders.
Updated the `ignoreInputs resolution` test to assert that the key is
omitted (rather than passed as `undefined`) when neither caller nor
registry set it.
## Test plan
- [x] SQL editor results: `Cmd+Shift+C`, `Cmd+Shift+M`, `Cmd+Shift+J`,
`Cmd+Shift+D` still fire
- [x] `Mod+ArrowUp` / `Mod+ArrowDown` / `Mod+ArrowLeft` /
`Mod+ArrowRight` inside a focused cell editor still blocked (registry
sets `ignoreInputs: true`)
- [x] Unit tests: `pnpm vitest run state/shortcuts/useShortcut.test.tsx`
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Fixed keyboard shortcut handling to properly respect the hotkey
library's default configuration values when custom options are not
explicitly specified.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES
## What kind of change does this PR introduce?
Bug fix and small marketing UI update.
## What is the current behavior?
The 2025 State of Startups page advertises `/state-of-startups` in its
metadata, which can cause Google to prefer the 2026 page for 2025
queries. The 2026 registration page also does not link users or crawlers
back to the 2025 report, and the workspace diff includes an RSS feed
refresh.
## What is the new behavior?
The 2025 page now self-canonicalizes to `/state-of-startups-2025`, the
2026 page has explicit canonical/Open Graph metadata for
`/state-of-startups`, and the registration page now includes a prominent
CTA linking to the 2025 report. This PR also includes the current
`rss.xml` update present in the workspace diff.
## Additional context
No local build or preview was run in this workspace.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Added a call-to-action section on the registration page linking to the
State of Startups 2025 report.
- **Chores**
- Improved SEO metadata for State of Startups pages to enhance search
visibility and social media sharing.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary
- Removes the UI guard in `RestoreToNewProject.tsx` that blocked
projects cloned from another cloned project from being restored to a new
project
- The API now supports a ConfigCat feature flag (`INDATA-559`) to allow
specific customers to clone clones, so the client-side restriction is no
longer needed
- Removes the unused `IS_CLONED_PROJECT` constant alongside the block
## Test plan
- [ ] Verify a cloned project can now reach the restore-to-new-project
UI without hitting the "cannot be restored" admonition
- [ ] Verify non-cloned projects are unaffected
- [ ] Verify the feature flag at the API level correctly gates access
for customers without the flag enabled
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Removed unnecessary warning message that displayed during database
restoration when restoring a cloned or previously restored project to a
new project.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.
YES/
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Documentation**
* Updated Vercel Marketplace integration documentation with revised
environment variable references. The guide now contains accurate
information about the credentials required when connecting Supabase
projects through Vercel's marketplace. This update ensures users have
the correct configuration details for seamless project integration and
proper synchronization of their environment settings.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## What kind of change does this PR introduce?
Documentation fix
## What is the current behavior?
Several docs pages use "Javascript" and "Typescript" (lowercase 's')
instead of the official camelCase names:
1. **client-libs.mdx**: "Javascript/Typescript" in the official
libraries table
2. **creating-routes.mdx**: "Javascript" as a tab label
3. **page.tsx** (docs home): "Javascript" as a client library card title
4. **MainSkeleton.tsx**: "Javascript Reference v1.0" and "Javascript
Reference v2.0" in sidebar navigation
## What is the new behavior?
All corrected to "JavaScript" and "TypeScript" (capital S).
## Additional context
The official names are "JavaScript" and "TypeScript" per their
respective specifications and branding guidelines.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Documentation**
* Corrected capitalization of language names in API guides, updating
"Javascript" to "JavaScript" and "Javascript/Typescript" to
"JavaScript/TypeScript" for consistency.
* **Style**
* Updated display labels for JavaScript in navigation menus and UI tabs
to use proper terminology and capitalization.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: Chris Chinchilla <chris.ward@supabase.io>
## Summary
Closes
[FE-3056](https://linear.app/supabase/issue/FE-3056/add-unit-tests-for-new-shortcut-primitives).
Backfills unit coverage for the shortcut primitives added in the recent
keyboard-shortcut overhaul — these shipped with no tests.
- **`state/shortcuts/formatShortcut.test.ts`** (16 tests) —
`hotkeyToKeys`: `Mod → Meta` mapping (case-sensitive, substring-safe),
single/multi-modifier combos, named keys, punctuation, edge cases.
- **`state/shortcuts/useShortcut.test.tsx`** (26 tests) — mocks
`useHotkeySequence`, `useRegisterCommands`, and `useIsShortcutEnabled`
to unit-test: sequence/callback wiring (single-step + multi-step
G-chords), full option-resolution priority (caller → registry →
fallback) for `enabled` / `timeout` / `ignoreInputs`, global-preference
AND gating, command-menu registration across all four enable
permutations, stable action identity, stale-closure protection via
`useLatest`, and badge rendering with/without the "then" separator.
- **`components/ui/Shortcut.test.tsx`** (12 tests) — mocks `useShortcut`
and `ShortcutTooltip` to verify prop forwarding (including rerender
behavior), tooltip positioning props, unset-prop hygiene, and the
`asChild` pass-through contract (clicks on the child do not fire
`onTrigger`).
54 tests total, all passing.
## Test plan
- [x] `pnpm --filter studio test state/shortcuts/formatShortcut.test.ts
state/shortcuts/useShortcut.test.tsx components/ui/Shortcut.test.tsx`
- [x] `tsc --noEmit` clean across the three test files
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Tests**
* Added comprehensive test coverage for the Shortcut component,
verifying rendering, hook integration, and tooltip behavior.
* Added test suite for hotkey key formatting, covering plain keys, named
keys, modifiers, and edge cases.
* Added test suite for the useShortcut hook, validating hotkey
sequences, enablement logic, command menu integration, and callback
handling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<img width="3504" height="2226" alt="cleanshot_2026-02-09_at_08 54 44_2x
(1)"
src="https://github.com/user-attachments/assets/967f2dab-09a7-4c46-9849-0e9f524fba70"
/>
When enabling GitHub integration for a project that already has a
connection, the create-connection API returns "already exists" error
while the branch settings update succeeds, causing both an error and
success toast to stack. Handle this by suppressing the error toast for
"already exists" so only the branch success toast is shown.
Fixes DEVWF-1128
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved error handling for GitHub connection creation. Suppresses
redundant error notifications when a connection already exists and
displays clearer error messages for other failures.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
- Add tax preview to the credit top-up flow by integrating the new `POST
/organizations/{slug}/billing/credits/preview` endpoint
- Show a price breakdown (credit amount, tax line item, total) in the
top-up dialog before the user confirms payment
- Handle all three `tax_status` states: show tax when `calculated`, hide
the line when `not_applicable`, show an inline warning when `failed`
## Behavior
- Preview fires as soon as a valid amount (300–2000) is entered; address
and tax ID are optional and refine the estimate
- Amount and address changes are debounced at 1s to avoid excessive API
calls
## Test plan
- [ ] Open credit top-up dialog - verify preview appears with default
$300 amount
- [ ] Change amount within 300–2000 - verify preview updates after
debounce
- [ ] Enter amount outside range (e.g. 100 or 3000) - verify preview
hides and validation error shows
- [ ] Add a new payment method with a billing address in a taxed region
- verify tax line item appears
- [ ] Add a new payment method with no tax jurisdiction - verify no tax
line, just total
- [ ] Complete a top-up - verify the charge goes through and dialog
closes
<img width="571" height="551" alt="image"
src="https://github.com/user-attachments/assets/d3357752-f913-4a4a-b84a-f78e2f457c7b"
/>
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Credit top-up preview with charge breakdown (credit, tax or tax note,
total).
* Onboarding survey endpoint and ISO 27001 certificate availability for
organizations.
* **Updates**
* Improved top-up UX: debounced address/tax inputs, enforced min/max
amount validation, preview-driven form state, and submit disabled while
preview is loading/stale.
* API docs wording changed to “temporary access configuration.”
<!-- end of auto-generated comment: release notes by coderabbit.ai -->