mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 17:35:10 +03:00
fix(studio): add @supabase/ssr to Connect Sheet install step (#44694)
The Connect Sheet install step only listed `@supabase/supabase-js`, but the generated code for Next.js (app router) and Remix imports from `@supabase/ssr` – so users following the steps immediately hit import errors. **Added:** - `EXTRA_PACKAGES` map in `connect.schema.ts` – frameworks declare additional packages on top of the base library install, keyed by `framework/variant` for granularity (e.g. `nextjs/app` gets `@supabase/ssr`, `nextjs/pages` does not) - Install content component appends extras automatically - Step title pluralises to "Install packages" when extras are present - Tests for extra packages, variant-specific install commands, and step titles **Changed:** - Next.js steps now branch on `frameworkVariant` so app router and pages router can have different install steps - Remix gets an explicit entry in the step tree (previously fell through to DEFAULT) ## To test - Open Connect Sheet → Framework → Next.js → App Router - Install step should say "Install packages" and show `npm install @supabase/supabase-js @supabase/ssr` - Switch to Pages Router - Install step should say "Install package" and show `npm install @supabase/supabase-js` - Switch to Remix - Install step should say "Install packages" and show `npm install @supabase/supabase-js @supabase/ssr` - Other frameworks (Vue, SvelteKit, etc.) should be unchanged <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **New Features** * Enhanced package installation guidance to include framework-specific additional packages (e.g., @supabase/ssr for Next.js App Router and Remix). * Installation step labels now accurately reflect the number of packages being installed. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
This commit is contained in:
1 parent
4f90833ed9
commit
ed09fbc6ad
3 files changed
+128
-14
No files matched your search
@@ -1,7 +1,7 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { resolveSteps } from './connect.resolver'
|
||||
import { connectSchema, INSTALL_COMMANDS } from './connect.schema'
|
||||
import { connectSchema, EXTRA_PACKAGES, INSTALL_COMMANDS } from './connect.schema'
|
||||
import type { ConnectState } from './Connect.types'
|
||||
|
||||
// ============================================================================
|
||||
@@ -150,6 +150,20 @@ describe('connect.schema:INSTALL_COMMANDS', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('connect.schema:EXTRA_PACKAGES', () => {
|
||||
test('should have @supabase/ssr as extra package for nextjs app router with supabasejs', () => {
|
||||
expect(EXTRA_PACKAGES.supabasejs?.['nextjs/app']).toContain('@supabase/ssr')
|
||||
})
|
||||
|
||||
test('should not have extra packages for nextjs pages router', () => {
|
||||
expect(EXTRA_PACKAGES.supabasejs?.['nextjs/pages']).toBeUndefined()
|
||||
})
|
||||
|
||||
test('should have @supabase/ssr as extra package for remix with supabasejs', () => {
|
||||
expect(EXTRA_PACKAGES.supabasejs?.remix).toContain('@supabase/ssr')
|
||||
})
|
||||
})
|
||||
|
||||
// ============================================================================
|
||||
// Steps Resolution Integration Tests
|
||||
// ============================================================================
|
||||
@@ -165,6 +179,48 @@ describe('connect.schema:steps resolution', () => {
|
||||
expect(steps.find((s) => s.id === 'install-skills')).toBeDefined()
|
||||
})
|
||||
|
||||
test('should use "Install packages" title for nextjs app router', () => {
|
||||
const state: ConnectState = {
|
||||
mode: 'framework',
|
||||
framework: 'nextjs',
|
||||
frameworkVariant: 'app',
|
||||
frameworkUi: false,
|
||||
}
|
||||
const steps = resolveSteps(connectSchema, state)
|
||||
const installStep = steps.find((s) => s.id === 'install')
|
||||
|
||||
expect(installStep?.title).toBe('Install packages')
|
||||
})
|
||||
|
||||
test('should use "Install package" title for nextjs pages router', () => {
|
||||
const state: ConnectState = {
|
||||
mode: 'framework',
|
||||
framework: 'nextjs',
|
||||
frameworkVariant: 'pages',
|
||||
frameworkUi: false,
|
||||
}
|
||||
const steps = resolveSteps(connectSchema, state)
|
||||
const installStep = steps.find((s) => s.id === 'install')
|
||||
|
||||
expect(installStep?.title).toBe('Install package')
|
||||
})
|
||||
|
||||
test('should use "Install packages" title for remix install step', () => {
|
||||
const state: ConnectState = { mode: 'framework', framework: 'remix' }
|
||||
const steps = resolveSteps(connectSchema, state)
|
||||
const installStep = steps.find((s) => s.id === 'install')
|
||||
|
||||
expect(installStep?.title).toBe('Install packages')
|
||||
})
|
||||
|
||||
test('should use "Install package" title for frameworks without extra packages', () => {
|
||||
const state: ConnectState = { mode: 'framework', framework: 'vuejs' }
|
||||
const steps = resolveSteps(connectSchema, state)
|
||||
const installStep = steps.find((s) => s.id === 'install')
|
||||
|
||||
expect(installStep?.title).toBe('Install package')
|
||||
})
|
||||
|
||||
test('should resolve shadcn steps for nextjs with frameworkUi true', () => {
|
||||
const state: ConnectState = { mode: 'framework', framework: 'nextjs', frameworkUi: true }
|
||||
const steps = resolveSteps(connectSchema, state)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { ConnectSchema, StepDefinition } from './Connect.types'
|
||||
|
||||
/**
|
||||
* Install commands for different packages
|
||||
* Base install commands for each library.
|
||||
*/
|
||||
export const INSTALL_COMMANDS: Record<string, string> = {
|
||||
supabasejs: 'npm install @supabase/supabase-js',
|
||||
@@ -12,6 +12,19 @@ export const INSTALL_COMMANDS: Record<string, string> = {
|
||||
supabasekt: 'implementation("io.github.jan-tennert.supabase:supabase-kt:VERSION")',
|
||||
}
|
||||
|
||||
/**
|
||||
* Extra packages required by specific frameworks on top of the base library.
|
||||
* Keyed by library, then by framework (or framework/variant for more specificity).
|
||||
* The install step checks the most specific key first (e.g. "nextjs/app"),
|
||||
* then falls back to the framework key (e.g. "nextjs").
|
||||
*/
|
||||
export const EXTRA_PACKAGES: Record<string, Record<string, string[]>> = {
|
||||
supabasejs: {
|
||||
'nextjs/app': ['@supabase/ssr'],
|
||||
remix: ['@supabase/ssr'],
|
||||
},
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Step Definitions (reusable)
|
||||
// All content paths use template syntax: {{stateKey}} is replaced with state values
|
||||
@@ -24,6 +37,13 @@ const frameworkInstallStep: StepDefinition = {
|
||||
content: 'steps/install',
|
||||
}
|
||||
|
||||
const frameworkInstallPackagesStep: StepDefinition = {
|
||||
id: 'install',
|
||||
title: 'Install packages',
|
||||
description: 'Run this command to install the required dependencies.',
|
||||
content: 'steps/install',
|
||||
}
|
||||
|
||||
const frameworkConfigureStep: StepDefinition = {
|
||||
id: 'configure',
|
||||
title: 'Add files',
|
||||
@@ -307,15 +327,35 @@ export const connectSchema: ConnectSchema = {
|
||||
framework: {
|
||||
framework: {
|
||||
nextjs: {
|
||||
frameworkUi: {
|
||||
true: [
|
||||
frameworkInstallStep,
|
||||
frameworkShadcnStep,
|
||||
frameworkShadcnEnvStep,
|
||||
frameworkShadcnExploreStep,
|
||||
skillsInstallStep,
|
||||
],
|
||||
DEFAULT: [frameworkInstallStep, frameworkNextJsFilesStep, skillsInstallStep],
|
||||
frameworkVariant: {
|
||||
app: {
|
||||
frameworkUi: {
|
||||
true: [
|
||||
frameworkInstallPackagesStep,
|
||||
frameworkShadcnStep,
|
||||
frameworkShadcnEnvStep,
|
||||
frameworkShadcnExploreStep,
|
||||
skillsInstallStep,
|
||||
],
|
||||
DEFAULT: [
|
||||
frameworkInstallPackagesStep,
|
||||
frameworkNextJsFilesStep,
|
||||
skillsInstallStep,
|
||||
],
|
||||
},
|
||||
},
|
||||
DEFAULT: {
|
||||
frameworkUi: {
|
||||
true: [
|
||||
frameworkInstallStep,
|
||||
frameworkShadcnStep,
|
||||
frameworkShadcnEnvStep,
|
||||
frameworkShadcnExploreStep,
|
||||
skillsInstallStep,
|
||||
],
|
||||
DEFAULT: [frameworkInstallStep, frameworkNextJsFilesStep, skillsInstallStep],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
react: {
|
||||
@@ -330,6 +370,7 @@ export const connectSchema: ConnectSchema = {
|
||||
DEFAULT: [frameworkInstallStep, frameworkReactFilesStep, skillsInstallStep],
|
||||
},
|
||||
},
|
||||
remix: [frameworkInstallPackagesStep, frameworkConfigureStep, skillsInstallStep],
|
||||
DEFAULT: [frameworkInstallStep, frameworkConfigureStep, skillsInstallStep],
|
||||
},
|
||||
},
|
||||
|
||||
@@ -2,19 +2,36 @@ import { Copy } from 'lucide-react'
|
||||
import { useMemo, useState } from 'react'
|
||||
import { Button, copyToClipboard } from 'ui'
|
||||
|
||||
import { INSTALL_COMMANDS } from '@/components/interfaces/ConnectSheet/connect.schema'
|
||||
import {
|
||||
EXTRA_PACKAGES,
|
||||
INSTALL_COMMANDS,
|
||||
} from '@/components/interfaces/ConnectSheet/connect.schema'
|
||||
import type { StepContentProps } from '@/components/interfaces/ConnectSheet/Connect.types'
|
||||
import { resolveFrameworkLibraryKey } from '@/components/interfaces/ConnectSheet/Connect.utils'
|
||||
|
||||
/**
|
||||
* Gets the install command for the current framework selection.
|
||||
* Appends any framework-specific extra packages from EXTRA_PACKAGES,
|
||||
* checking the most specific key first (framework/variant), then framework-only.
|
||||
*/
|
||||
function getInstallCommand(state: StepContentProps['state']): string | null {
|
||||
const libraryKey = resolveFrameworkLibraryKey(state)
|
||||
if (!libraryKey || !INSTALL_COMMANDS[libraryKey]) return null
|
||||
|
||||
if (libraryKey && INSTALL_COMMANDS[libraryKey]) return INSTALL_COMMANDS[libraryKey]
|
||||
let command = INSTALL_COMMANDS[libraryKey]
|
||||
|
||||
return null
|
||||
const { framework, frameworkVariant } = state
|
||||
if (framework) {
|
||||
const extraMap = EXTRA_PACKAGES[libraryKey]
|
||||
const extras =
|
||||
(frameworkVariant && extraMap?.[`${framework}/${frameworkVariant}`]) ||
|
||||
extraMap?.[String(framework)]
|
||||
if (extras?.length) {
|
||||
command += ' ' + extras.join(' ')
|
||||
}
|
||||
}
|
||||
|
||||
return command
|
||||
}
|
||||
|
||||
function InstallContent({ state }: StepContentProps) {
|
||||
|
||||
Reference in new issue
Block a user