From e1b51dff8131aaf95acba6eefbdda100bdbf665f Mon Sep 17 00:00:00 2001 From: Chris Praas Date: Thu, 26 Feb 2026 12:20:29 +0100 Subject: [PATCH 1/3] added CLI example for generating types with self-hosted instance Docs Update. Added a example for generating types with self-hosted instance. Co-authored-by: Chris Chinchilla --- apps/docs/content/guides/api/rest/generating-types.mdx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/apps/docs/content/guides/api/rest/generating-types.mdx b/apps/docs/content/guides/api/rest/generating-types.mdx index 3f10c9dee37bd..c728c698795b4 100644 --- a/apps/docs/content/guides/api/rest/generating-types.mdx +++ b/apps/docs/content/guides/api/rest/generating-types.mdx @@ -46,6 +46,12 @@ or in case of local development: npx supabase gen types typescript --local > database.types.ts ``` +or in case of a self-hosted instance (see [Accessing Postgres](/docs/guides/self-hosting/docker#accessing-postgres) for more information): + +```bash +npx supabase gen types typescript --db-url postgres://postgres.[POOLER_TENANT_ID]:[POSTGRES_PASSWORD]@[your-domain-or-ip]:5432/postgres --schema public > database.types.ts +``` + These types are generated from your database schema. Given a table `public.movies`, the generated types will look like: ```sql From dcc57036741221c5aba58c5c9d1559a8270cf4f1 Mon Sep 17 00:00:00 2001 From: Andrew Valleteau Date: Thu, 26 Feb 2026 15:28:13 +0100 Subject: [PATCH 2/3] feat(branching): add-pg-delta-diff-for-branching (#42952) Allow to use the `pg-delta` capability for merge requests diffing. Feature flag it behind an auto opt-in flag. Must be merged after: https://github.com/supabase/platform/pull/29776 Screenshot 2026-02-17 at 16 50 38 Also updated the loading + final state of the diff view to: 1. Take all the height available - From: Screenshot 2026-02-16 at 20
46 15 - To: Screenshot 2026-02-16 at 20
57 26 2. Show a proper loading state rather than just a plain grey skeleton - From: Screenshot 2026-02-20 at 15
02 51 - To: Screenshot 2026-02-20 at 15 05 46 --- .../FeaturePreview/FeaturePreviewContext.tsx | 8 +++- .../FeaturePreview/FeaturePreviewModal.tsx | 2 + .../App/FeaturePreview/PgDeltaDiffPreview.tsx | 32 ++++++++++++++ .../App/FeaturePreview/useFeaturePreviews.ts | 11 +++++ .../BranchManagement/DatabaseDiffPanel.tsx | 43 ++++++++++++++----- .../studio/data/branches/branch-diff-query.ts | 16 ++++--- .../data/branches/branch-merge-mutation.ts | 9 +++- apps/studio/data/branches/keys.ts | 4 +- .../hooks/branches/useBranchMergeDiff.ts | 4 ++ apps/studio/pages/project/[ref]/merge.tsx | 31 +++++++------ packages/api-types/types/api.d.ts | 1 + packages/common/constants/local-storage.ts | 1 + 12 files changed, 128 insertions(+), 34 deletions(-) create mode 100644 apps/studio/components/interfaces/App/FeaturePreview/PgDeltaDiffPreview.tsx diff --git a/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewContext.tsx b/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewContext.tsx index 043ee9cd303fa..c63dbd112e99c 100644 --- a/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewContext.tsx +++ b/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewContext.tsx @@ -4,12 +4,12 @@ import { noop } from 'lodash' import { useQueryState } from 'nuqs' import { createContext, - PropsWithChildren, useCallback, useContext, useEffect, useMemo, useState, + type PropsWithChildren, } from 'react' import { useFeaturePreviews } from './useFeaturePreviews' @@ -97,6 +97,12 @@ export const useIsBranching2Enabled = () => { return gitlessBranchingEnabled && flags[LOCAL_STORAGE_KEYS.UI_PREVIEW_BRANCHING_2_0] } +export const useIsPgDeltaDiffEnabled = () => { + const { flags } = useFeaturePreviewContext() + const pgDeltaDiffEnabled = useFlag('pgdeltaDiff') + return pgDeltaDiffEnabled && flags[LOCAL_STORAGE_KEYS.UI_PREVIEW_PG_DELTA_DIFF] +} + export const useIsAdvisorRulesEnabled = () => { const { flags } = useFeaturePreviewContext() const advisorRulesEnabled = useFlag('advisorRules') diff --git a/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewModal.tsx b/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewModal.tsx index cbf5eb934fe4c..106f6ea8d1559 100644 --- a/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewModal.tsx +++ b/apps/studio/components/interfaces/App/FeaturePreview/FeaturePreviewModal.tsx @@ -24,6 +24,7 @@ import { APISidePanelPreview } from './APISidePanelPreview' import { Branching2Preview } from './Branching2Preview' import { CLSPreview } from './CLSPreview' import { useFeaturePreviewContext, useFeaturePreviewModal } from './FeaturePreviewContext' +import { PgDeltaDiffPreview } from './PgDeltaDiffPreview' import { QueueOperationsPreview } from './QueueOperationsPreview' import { TableFilterBarPreview } from './TableFilterBarPreview' import { UnifiedLogsPreview } from './UnifiedLogsPreview' @@ -33,6 +34,7 @@ const FEATURE_PREVIEW_KEY_TO_CONTENT: { [key: string]: ReactNode } = { [LOCAL_STORAGE_KEYS.UI_PREVIEW_BRANCHING_2_0]: , + [LOCAL_STORAGE_KEYS.UI_PREVIEW_PG_DELTA_DIFF]: , [LOCAL_STORAGE_KEYS.UI_PREVIEW_ADVISOR_RULES]: , [LOCAL_STORAGE_KEYS.UI_PREVIEW_API_SIDE_PANEL]: , [LOCAL_STORAGE_KEYS.UI_PREVIEW_CLS]: , diff --git a/apps/studio/components/interfaces/App/FeaturePreview/PgDeltaDiffPreview.tsx b/apps/studio/components/interfaces/App/FeaturePreview/PgDeltaDiffPreview.tsx new file mode 100644 index 0000000000000..10d3743388671 --- /dev/null +++ b/apps/studio/components/interfaces/App/FeaturePreview/PgDeltaDiffPreview.tsx @@ -0,0 +1,32 @@ +import { InlineLink } from 'components/ui/InlineLink' + +const PG_DELTA_REPO_URL = 'https://github.com/supabase/pg-toolbelt' + +export const PgDeltaDiffPreview = () => { + return ( +
+

+ Use the pg-delta project to generate + schema diffs instead of migra when creating migrations from branch comparisons. pg-delta is + in alpha and is designed to better handle RLS (Row Level Security) and other schema + constructs. +

+
+

Please note:

+
    +
  • pg-delta is in alpha; behavior may change.
  • +
  • + Generated migrations may contain errors. Review each migration carefully before + executing it. +
  • +
+
+
+

Enabling this preview will:

+
    +
  • Use pg-delta to compute schema diffs when comparing branches, instead of migra
  • +
+
+
+ ) +} diff --git a/apps/studio/components/interfaces/App/FeaturePreview/useFeaturePreviews.ts b/apps/studio/components/interfaces/App/FeaturePreview/useFeaturePreviews.ts index f16028a0ac4ab..ce54a339df146 100644 --- a/apps/studio/components/interfaces/App/FeaturePreview/useFeaturePreviews.ts +++ b/apps/studio/components/interfaces/App/FeaturePreview/useFeaturePreviews.ts @@ -18,6 +18,7 @@ export const useFeaturePreviews = (): FeaturePreview[] => { const advisorRulesEnabled = useFlag('advisorRules') const isUnifiedLogsPreviewAvailable = useFlag('unifiedLogs') const tableEditorNewFilterBar = useFlag('tableEditorNewFilterBar') + const pgDeltaDiffEnabled = useFlag('pgdeltaDiff') return [ { @@ -47,6 +48,16 @@ export const useFeaturePreviews = (): FeaturePreview[] => { isPlatformOnly: true, isDefaultOptIn: false, }, + + { + key: LOCAL_STORAGE_KEYS.UI_PREVIEW_PG_DELTA_DIFF, + name: 'PG Delta Diff', + discussionsUrl: undefined, + isNew: true, + isPlatformOnly: true, + isDefaultOptIn: true, + enabled: pgDeltaDiffEnabled, + }, { key: LOCAL_STORAGE_KEYS.UI_PREVIEW_API_SIDE_PANEL, name: 'Project API documentation', diff --git a/apps/studio/components/interfaces/BranchManagement/DatabaseDiffPanel.tsx b/apps/studio/components/interfaces/BranchManagement/DatabaseDiffPanel.tsx index d4162cbe5a629..9b85ce3dca8d9 100644 --- a/apps/studio/components/interfaces/BranchManagement/DatabaseDiffPanel.tsx +++ b/apps/studio/components/interfaces/BranchManagement/DatabaseDiffPanel.tsx @@ -1,4 +1,4 @@ -import { CircleAlert, Database, Download, Wind } from 'lucide-react' +import { CircleAlert, Database, Download, Loader2, Wind } from 'lucide-react' import Link from 'next/link' import { toast } from 'sonner' @@ -19,7 +19,26 @@ export const DatabaseDiffPanel = ({ error, currentBranchRef, }: DatabaseDiffPanelProps) => { - if (isLoading) return + if (isLoading) { + return ( +
+
+
+ + Loading database diff… +
+
+ +
+
+
+ ) + } if (error) return ( @@ -45,8 +64,8 @@ export const DatabaseDiffPanel = ({ } return ( - - + + - - + +
+ +
) diff --git a/apps/studio/data/branches/branch-diff-query.ts b/apps/studio/data/branches/branch-diff-query.ts index bec96019640a8..14f26c8a5d8ba 100644 --- a/apps/studio/data/branches/branch-diff-query.ts +++ b/apps/studio/data/branches/branch-diff-query.ts @@ -9,16 +9,22 @@ export type BranchDiffVariables = { branchRef: string projectRef: string includedSchemas?: string + pgdelta?: boolean } export async function getBranchDiff({ branchRef, includedSchemas, -}: Pick) { + pgdelta, +}: Pick) { + const query: { included_schemas?: string; pgdelta?: string } = {} + if (includedSchemas) query.included_schemas = includedSchemas + if (pgdelta === true) query.pgdelta = 'true' + const { data: diffData, error } = await get('/v1/branches/{branch_id_or_ref}/diff', { params: { path: { branch_id_or_ref: branchRef }, - query: includedSchemas ? { included_schemas: includedSchemas } : undefined, + query: Object.keys(query).length > 0 ? query : undefined, }, headers: { Accept: 'text/plain', @@ -41,15 +47,15 @@ export async function getBranchDiff({ type BranchDiffData = Awaited> export const useBranchDiffQuery = ( - { branchRef, projectRef, includedSchemas }: BranchDiffVariables, + { branchRef, projectRef, includedSchemas, pgdelta }: BranchDiffVariables, { enabled = true, ...options }: Omit, 'queryKey' | 'queryFn'> = {} ) => useQuery({ - queryKey: branchKeys.diff(projectRef, branchRef), - queryFn: () => getBranchDiff({ branchRef, includedSchemas }), + queryKey: branchKeys.diff(projectRef, branchRef, pgdelta), + queryFn: () => getBranchDiff({ branchRef, includedSchemas, pgdelta }), enabled: IS_PLATFORM && enabled && Boolean(branchRef), ...options, }) diff --git a/apps/studio/data/branches/branch-merge-mutation.ts b/apps/studio/data/branches/branch-merge-mutation.ts index 9155bf4146438..105b4845ce3ef 100644 --- a/apps/studio/data/branches/branch-merge-mutation.ts +++ b/apps/studio/data/branches/branch-merge-mutation.ts @@ -11,11 +11,16 @@ export type BranchMergeVariables = { branchProjectRef: string baseProjectRef: string migration_version?: string + pgdelta?: boolean } -export async function mergeBranch({ branchProjectRef, migration_version }: BranchMergeVariables) { +export async function mergeBranch({ + branchProjectRef, + migration_version, + pgdelta, +}: BranchMergeVariables) { // Step 1: Get the diff output from the branch - const diffContent = await getBranchDiff({ branchRef: branchProjectRef }) + const diffContent = await getBranchDiff({ branchRef: branchProjectRef, pgdelta }) let migrationCreated = false diff --git a/apps/studio/data/branches/keys.ts b/apps/studio/data/branches/keys.ts index 91950e8fa8381..1272479f1525f 100644 --- a/apps/studio/data/branches/keys.ts +++ b/apps/studio/data/branches/keys.ts @@ -2,6 +2,6 @@ export const branchKeys = { list: (projectRef: string | undefined) => ['projects', projectRef, 'branches'] as const, detail: (projectRef: string | undefined, branchRef: string | undefined) => ['projects', projectRef, 'branches', branchRef] as const, - diff: (projectRef: string | undefined, branchRef: string | undefined) => - ['projects', projectRef, 'branch', branchRef, 'diff'] as const, + diff: (projectRef: string | undefined, branchRef: string | undefined, pgdelta?: boolean) => + ['projects', projectRef, 'branch', branchRef, 'diff', pgdelta] as const, } diff --git a/apps/studio/hooks/branches/useBranchMergeDiff.ts b/apps/studio/hooks/branches/useBranchMergeDiff.ts index ec7deb6f7c22b..4fc167c40d59f 100644 --- a/apps/studio/hooks/branches/useBranchMergeDiff.ts +++ b/apps/studio/hooks/branches/useBranchMergeDiff.ts @@ -1,3 +1,4 @@ +import { useIsPgDeltaDiffEnabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext' import { useBranchDiffQuery } from 'data/branches/branch-diff-query' import { useMigrationsQuery } from 'data/database/migrations-query' import { useMemo } from 'react' @@ -51,6 +52,8 @@ export const useBranchMergeDiff = ({ parentBranchConnectionString, currentBranchCreatedAt, }: UseBranchMergeDiffProps): BranchMergeDiffResult => { + const pgDeltaDiffEnabled = useIsPgDeltaDiffEnabled() + // Get database diff const { data: diffContent, @@ -62,6 +65,7 @@ export const useBranchMergeDiff = ({ { branchRef: currentBranchRef || '', projectRef: parentProjectRef || '', + pgdelta: pgDeltaDiffEnabled, }, { enabled: !!currentBranchRef && !!parentProjectRef, diff --git a/apps/studio/pages/project/[ref]/merge.tsx b/apps/studio/pages/project/[ref]/merge.tsx index 556a26813210c..6cf6338395698 100644 --- a/apps/studio/pages/project/[ref]/merge.tsx +++ b/apps/studio/pages/project/[ref]/merge.tsx @@ -40,6 +40,7 @@ import { NavMenu, NavMenuItem, } from 'ui' +import { useIsPgDeltaDiffEnabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext' import { ConfirmationModal } from 'ui-patterns/Dialogs/ConfirmationModal' const MergePage: NextPageWithLayout = () => { @@ -47,6 +48,7 @@ const MergePage: NextPageWithLayout = () => { const { ref, workflow_run_id: currentWorkflowRunId } = useParams() const { data: project } = useSelectedProjectQuery() const { data: selectedOrg } = useSelectedOrganizationQuery() + const pgDeltaDiffEnabled = useIsPgDeltaDiffEnabled() const [isSubmitting, setIsSubmitting] = useState(false) const [workflowFinalStatus, setWorkflowFinalStatus] = useState<'SUCCESS' | 'FAILED' | null>(null) @@ -297,6 +299,7 @@ const MergePage: NextPageWithLayout = () => { branchProjectRef: ref, baseProjectRef: parentProjectRef, migration_version: undefined, + pgdelta: pgDeltaDiffEnabled, }) } @@ -483,7 +486,7 @@ const MergePage: NextPageWithLayout = () => { breadcrumbs={breadcrumbs} primaryActions={primaryActions} size="full" - className="border-b-0 pb-0" + className="h-full border-b-0 pb-0" >
@@ -570,18 +573,20 @@ const MergePage: NextPageWithLayout = () => {
- - {currentTab === 'database' ? ( - - ) : ( - - )} + +
+ {currentTab === 'database' ? ( + + ) : ( + + )} +
Date: Fri, 27 Feb 2026 00:27:45 +0900 Subject: [PATCH 3/3] =?UTF-8?q?Update=20a=20typo=20in=20the=20apps/docs/co?= =?UTF-8?q?ntent/guides/storage/buckets=20by=20fixi=E2=80=A6=20(#43130)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …ng 'a authorization' to 'an authorization''' Fixed a minor grammatical error in `apps/docs/content/guides/storage/buckets` where "a authorization" was incorrectly used instead of "an authorization". ## 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? It is a typo fix in the docs ## What is the current behavior? There are no issues concerning the performance. Just a minor grammar mistake ## What is the new behavior? Feel free to include screenshots if it includes visual changes. Screenshot 2026-02-24 at 20 42 00 Add any other context or screenshots. --- apps/docs/content/guides/storage/buckets/fundamentals.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/docs/content/guides/storage/buckets/fundamentals.mdx b/apps/docs/content/guides/storage/buckets/fundamentals.mdx index 72e27f0339f58..1a1ff75fb2439 100644 --- a/apps/docs/content/guides/storage/buckets/fundamentals.mdx +++ b/apps/docs/content/guides/storage/buckets/fundamentals.mdx @@ -17,7 +17,7 @@ When a bucket is set to **Private** all operations are subject to access control The only ways to download assets within a private bucket is to: -- Use the [download method](/docs/reference/javascript/storage-from-download) by providing a authorization header containing your user's JWT. The RLS policy you create on the `storage.objects` table will use this user to determine if they have access. +- Use the [download method](/docs/reference/javascript/storage-from-download) by providing an authorization header containing your user's JWT. The RLS policy you create on the `storage.objects` table will use this user to determine if they have access. - Create a signed URL with the [`createSignedUrl` method](/docs/reference/javascript/storage-from-createsignedurl) that can be accessed for a limited time. #### Example use cases: