Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions apps/docs/content/guides/api/rest/generating-types.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/content/guides/storage/buckets/fundamentals.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -33,6 +34,7 @@ const FEATURE_PREVIEW_KEY_TO_CONTENT: {
[key: string]: ReactNode
} = {
[LOCAL_STORAGE_KEYS.UI_PREVIEW_BRANCHING_2_0]: <Branching2Preview />,
[LOCAL_STORAGE_KEYS.UI_PREVIEW_PG_DELTA_DIFF]: <PgDeltaDiffPreview />,
[LOCAL_STORAGE_KEYS.UI_PREVIEW_ADVISOR_RULES]: <AdvisorRulesPreview />,
[LOCAL_STORAGE_KEYS.UI_PREVIEW_API_SIDE_PANEL]: <APISidePanelPreview />,
[LOCAL_STORAGE_KEYS.UI_PREVIEW_CLS]: <CLSPreview />,
Expand Down
Original file line number Diff line number Diff line change
@@ -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 (
<div>
<p className="text-sm text-foreground-light mb-4">
Use the <InlineLink href={PG_DELTA_REPO_URL}>pg-delta</InlineLink> 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.
</p>
<div className="my-6">
<p className="text-sm text-foreground mb-2 font-medium">Please note:</p>
<ul className="list-disc pl-6 text-sm text-foreground-light space-y-1">
<li>pg-delta is in alpha; behavior may change.</li>
<li>
Generated migrations may contain errors. Review each migration carefully before
executing it.
</li>
</ul>
</div>
<div className="space-y-2 !mt-4">
<p className="text-sm">Enabling this preview will:</p>
<ul className="list-disc pl-6 text-sm text-foreground-light space-y-1">
<li>Use pg-delta to compute schema diffs when comparing branches, instead of migra</li>
</ul>
</div>
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 [
{
Expand Down Expand Up @@ -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',
Expand Down
Original file line number Diff line number Diff line change
@@ -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'

Expand All @@ -19,7 +19,26 @@ export const DatabaseDiffPanel = ({
error,
currentBranchRef,
}: DatabaseDiffPanelProps) => {
if (isLoading) return <Skeleton className="h-64" />
if (isLoading) {
return (
<div className="flex flex-1 min-h-0 flex-col">
<div className="flex flex-1 min-h-[400px] flex-col rounded-md border border-border bg-surface-100">
<div className="flex shrink-0 items-center gap-2 border-b border-border px-4 py-3">
<Loader2
size={16}
strokeWidth={1.5}
className="animate-spin text-foreground-muted"
aria-hidden
/>
<span className="text-sm text-foreground-light">Loading database diff…</span>
</div>
<div className="min-h-0 flex-1 p-4">
<Skeleton className="h-full w-full rounded" />
</div>
</div>
</div>
)
}

if (error)
return (
Expand All @@ -45,8 +64,8 @@ export const DatabaseDiffPanel = ({
}

return (
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 py-3">
<Card className="flex flex-1 min-h-0 flex-col">
<CardHeader className="flex shrink-0 flex-row items-center justify-between space-y-0 py-3">
<CardTitle>
<Link
href={`/project/${currentBranchRef}/database/schema`}
Expand Down Expand Up @@ -88,13 +107,15 @@ export const DatabaseDiffPanel = ({
Download as migration
</Button>
</CardHeader>
<CardContent className="p-0 h-96">
<DiffEditor
language="sql"
original=""
modified={diffContent}
options={{ readOnly: true }}
/>
<CardContent className="flex min-h-0 flex-1 flex-col p-0">
<div className="min-h-0 flex-1">
<DiffEditor
language="sql"
original=""
modified={diffContent}
options={{ readOnly: true }}
/>
</div>
</CardContent>
</Card>
)
Expand Down
16 changes: 11 additions & 5 deletions apps/studio/data/branches/branch-diff-query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,22 @@ export type BranchDiffVariables = {
branchRef: string
projectRef: string
includedSchemas?: string
pgdelta?: boolean
}

export async function getBranchDiff({
branchRef,
includedSchemas,
}: Pick<BranchDiffVariables, 'branchRef' | 'includedSchemas'>) {
pgdelta,
}: Pick<BranchDiffVariables, 'branchRef' | 'includedSchemas' | 'pgdelta'>) {
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',
Expand All @@ -41,15 +47,15 @@ export async function getBranchDiff({
type BranchDiffData = Awaited<ReturnType<typeof getBranchDiff>>

export const useBranchDiffQuery = (
{ branchRef, projectRef, includedSchemas }: BranchDiffVariables,
{ branchRef, projectRef, includedSchemas, pgdelta }: BranchDiffVariables,
{
enabled = true,
...options
}: Omit<UseCustomQueryOptions<BranchDiffData, ResponseError>, 'queryKey' | 'queryFn'> = {}
) =>
useQuery<BranchDiffData, ResponseError>({
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,
})
9 changes: 7 additions & 2 deletions apps/studio/data/branches/branch-merge-mutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 2 additions & 2 deletions apps/studio/data/branches/keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
4 changes: 4 additions & 0 deletions apps/studio/hooks/branches/useBranchMergeDiff.ts
Original file line number Diff line number Diff line change
@@ -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'
Expand Down Expand Up @@ -51,6 +52,8 @@ export const useBranchMergeDiff = ({
parentBranchConnectionString,
currentBranchCreatedAt,
}: UseBranchMergeDiffProps): BranchMergeDiffResult => {
const pgDeltaDiffEnabled = useIsPgDeltaDiffEnabled()

// Get database diff
const {
data: diffContent,
Expand All @@ -62,6 +65,7 @@ export const useBranchMergeDiff = ({
{
branchRef: currentBranchRef || '',
projectRef: parentProjectRef || '',
pgdelta: pgDeltaDiffEnabled,
},
{
enabled: !!currentBranchRef && !!parentProjectRef,
Expand Down
31 changes: 18 additions & 13 deletions apps/studio/pages/project/[ref]/merge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,15 @@ import {
NavMenu,
NavMenuItem,
} from 'ui'
import { useIsPgDeltaDiffEnabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext'
import { ConfirmationModal } from 'ui-patterns/Dialogs/ConfirmationModal'

const MergePage: NextPageWithLayout = () => {
const router = useRouter()
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)
Expand Down Expand Up @@ -297,6 +299,7 @@ const MergePage: NextPageWithLayout = () => {
branchProjectRef: ref,
baseProjectRef: parentProjectRef,
migration_version: undefined,
pgdelta: pgDeltaDiffEnabled,
})
}

Expand Down Expand Up @@ -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"
>
<div className="border-b">
<ScaffoldContainer size="full">
Expand Down Expand Up @@ -570,18 +573,20 @@ const MergePage: NextPageWithLayout = () => {
</NavMenu>
</ScaffoldContainer>
</div>
<ScaffoldContainer size="full" className="pt-6 pb-12">
{currentTab === 'database' ? (
<DatabaseDiffPanel
diffContent={diffContent}
isLoading={isDatabaseDiffLoading || isDatabaseDiffRefetching}
error={diffError}
showRefreshButton={true}
currentBranchRef={ref}
/>
) : (
<EdgeFunctionsDiffPanel diffResults={edgeFunctionsDiff} currentBranchRef={ref} />
)}
<ScaffoldContainer size="full" className="flex min-h-0 flex-1 flex-col pt-6 pb-12">
<div className="flex min-h-0 flex-1 flex-col">
{currentTab === 'database' ? (
<DatabaseDiffPanel
diffContent={diffContent}
isLoading={isDatabaseDiffLoading || isDatabaseDiffRefetching}
error={diffError}
showRefreshButton={true}
currentBranchRef={ref}
/>
) : (
<EdgeFunctionsDiffPanel diffResults={edgeFunctionsDiff} currentBranchRef={ref} />
)}
</div>
</ScaffoldContainer>

<ConfirmationModal
Expand Down
1 change: 1 addition & 0 deletions packages/api-types/types/api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5008,6 +5008,7 @@ export interface operations {
parameters: {
query?: {
included_schemas?: string
pgdelta?: string
}
header?: never
path: {
Expand Down
1 change: 1 addition & 0 deletions packages/common/constants/local-storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export const LOCAL_STORAGE_KEYS = {
UI_PREVIEW_ADVISOR_RULES: 'supabase-ui-advisor-rules',
UI_PREVIEW_QUEUE_OPERATIONS: 'supabase-ui-queue-operations',
UI_PREVIEW_TABLE_FILTER_BAR: 'supabase-ui-table-filter-bar',
UI_PREVIEW_PG_DELTA_DIFF: 'supabase-ui-pg-delta-diff',

NEW_LAYOUT_NOTICE_ACKNOWLEDGED: 'new-layout-notice-acknowledge',
TABS_INTERFACE_ACKNOWLEDGED: 'tabs-interface-acknowledge',
Expand Down
Loading