mirror of
https://github.com/supabase/supabase.git
synced 2026-09-06 18:11:51 +08:00
## What kind of change does this PR introduce? Bug fix for the Vercel Deploy Button → Studio handoff. ## What is the current behavior? Vercel sometimes opens our install popup with `source=marketplace` while still sending Deploy Button params (`currentProjectId`, `external-id`). We trust `source` alone, so users are routed to choose-project (connect) instead of create — which is why create never gets reached in the Deploy Button flow. ## What is the new behavior? - When both Deploy Button signals (`currentProjectId` + `externalId`) are present, route to create even if Vercel sent `source=marketplace` / `external` - Hide Skip (and related empty-state copy) on choose-project when those signals are present, so Deploy Button users can't continue without linking ## Additional context Stacked on #48230. Test plan: - [ ] Unit tests for `resolveVercelInstallSource` / `hasVercelDeployButtonSignals` pass - [ ] Deploy Button flow with mislabeled `source=marketplace` + both params → lands on create after org install/continue - [ ] Genuine marketplace install (no `currentProjectId`/`external-id`) → still lands on choose-project with Skip available - [ ] If choose-project is opened with both Deploy Button params, Skip is hidden <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Improved Vercel installation handling for Deploy Button workflows, ensuring the correct setup path is selected. - Added clearer project-connection guidance when no projects are available (including conditional skip copy). - **Bug Fixes** - Prevented Deploy Button installations from incorrectly offering a skip option. - Preserved the skip-and-connect-later guidance for other Vercel installation flows. - Improved recognition of Deploy Button installations even when the reported Vercel source differs. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
98 lines
2.3 KiB
TypeScript
98 lines
2.3 KiB
TypeScript
export function getErrorMessage(error: unknown): string | undefined {
|
|
if (error instanceof Error) return error.message
|
|
if (
|
|
typeof error === 'object' &&
|
|
error !== null &&
|
|
'message' in error &&
|
|
typeof (error as { message: unknown }).message === 'string'
|
|
) {
|
|
return (error as { message: string }).message
|
|
}
|
|
return undefined
|
|
}
|
|
|
|
export type VercelInstallSource = 'deploy-button' | 'marketplace' | 'external'
|
|
|
|
/**
|
|
* Vercel sometimes sends source=marketplace with Deploy Button params
|
|
* (currentProjectId + external-id). Treat that as deploy-button for routing.
|
|
*/
|
|
export function hasVercelDeployButtonSignals({
|
|
currentProjectId,
|
|
externalId,
|
|
}: {
|
|
currentProjectId?: string
|
|
externalId?: string
|
|
}): boolean {
|
|
return Boolean(currentProjectId && externalId)
|
|
}
|
|
|
|
export function resolveVercelInstallSource({
|
|
source,
|
|
currentProjectId,
|
|
externalId,
|
|
}: {
|
|
source: string | undefined
|
|
currentProjectId?: string
|
|
externalId?: string
|
|
}): VercelInstallSource | undefined {
|
|
if (hasVercelDeployButtonSignals({ currentProjectId, externalId })) {
|
|
return 'deploy-button'
|
|
}
|
|
|
|
switch (source) {
|
|
case 'deploy-button':
|
|
case 'marketplace':
|
|
case 'external':
|
|
return source
|
|
default:
|
|
return undefined
|
|
}
|
|
}
|
|
|
|
type BuildVercelInstallRouteQueryArgs = {
|
|
source?: VercelInstallSource
|
|
organizationSlug?: string
|
|
configurationId?: string
|
|
currentProjectId?: string
|
|
externalId?: string
|
|
next?: string
|
|
}
|
|
|
|
function removeUndefinedValues(query: Record<string, string | undefined>) {
|
|
return Object.fromEntries(
|
|
Object.entries(query).filter((entry): entry is [string, string] => entry[1] !== undefined)
|
|
)
|
|
}
|
|
|
|
export function buildVercelInstallRouteQuery({
|
|
source,
|
|
organizationSlug,
|
|
configurationId,
|
|
currentProjectId,
|
|
externalId,
|
|
next,
|
|
}: BuildVercelInstallRouteQueryArgs) {
|
|
switch (source) {
|
|
case 'deploy-button':
|
|
return removeUndefinedValues({
|
|
organizationSlug,
|
|
currentProjectId,
|
|
externalId,
|
|
next,
|
|
})
|
|
case 'marketplace':
|
|
case 'external':
|
|
// Keep Deploy Button ids when present so choose-project → create can seed + link.
|
|
return removeUndefinedValues({
|
|
organizationSlug,
|
|
configurationId,
|
|
currentProjectId,
|
|
externalId,
|
|
next,
|
|
})
|
|
default:
|
|
return removeUndefinedValues({ organizationSlug })
|
|
}
|
|
}
|