E2E Testing Setup Consolidation (#35080)
* add new e2e folder * add local supabase and confitional storage * fix e2e selfhosted * update actions * add correct e2e folder * fix e2e actions * fix action project ids * fix permissions * fix script * fix playwright install * playwright root * pnpm i * fix api rul * add env docs * update run script * only install deps for e2e * use same dep * only install deps for tests * upd lockfile * use official vercel integration * use vercel cli * remove old folder * fix script * rm filter * rename e2e studio package * fix install browsers * add polling for vercel build * use vercel-preview-url package * undo actions * rename ci env to ci * chore:add rls check and make playwright test less flakey (#35348) * update ci action * fix paths * fix browser install * run ci against staging * try caching builds * fix envs * fix env check * fix sign in * fix sign in url * fix envs and url * fix caching * fix race condition in sign in page * fix race condition in sign in page * add check to see if being redirected * fix caching, check IS_PLATFORM var * log is_platform * try vercel build * fix vercel project id * fix path * add temp vercel.json file * fix paths * undo project id stuff * rm cwd * fix path * fix paths again * fix path * fix base url * try different fix * fix config base url * fix base studio url issues * retain video on fails * Update e2e/studio/README.md Co-authored-by: Copple <10214025+kiwicopple@users.noreply.github.com> * Update e2e/studio/README.md Co-authored-by: Copple <10214025+kiwicopple@users.noreply.github.com> * fix env file naming * undo caching * rm old tests folder * fix readme scripts * rm vercel deploy for now, just run build locally * fix url * fix build script * fix is_platform * fix stuck studio start * fix env vars * retain network and logs on fail for better debugging * add apiurl env * back to vercel * disable catpcha * fix test * update environment configuration to remove default URLs for CI and streamline API base URL handling * fix typeerr * fix urls in home.spec * fix urls in logs.spec * fix urls in sqleditor spec * fix table editor spec * add tourl util * use staging api in ci * re add base url env var * fix url in projects page * fix url in sql editor spec * fix sign in not waiting for cookies omfg * fix env var name * fix sql-editor test * simplify table removal * add opt out telemetry step * fix logs tests * fix table editor spec * remove flaky steps from table editor tests * use vercel deployment events instead of build * add studio check * fix condition * debug event * rm if * trigger deploy * undo ac * make opt out button step optional, some envs dont hav eit * use testid for sql run button * use id instaed of timestamp in logs tests * empty * rm retries * up glbal timeout * chore: fix failing sql-editor playwright test (#35767) * chore: fix failing sql-editor playwright test * chore: minor fixes * Chore/update playwright config (#35826) chore: update playwright config * rm supabase project from e2e tests * refactor and simplify environments * fix sql editor test * fix ci env vars * fix * fix on windows * update readme * add playwright install script to readme * rm turbopack trace flag * npm to pnpm for scripts * delete ivan lines --------- Co-authored-by: Michael Ong <minghao_3728@hotmail.com> Co-authored-by: Copple <10214025+kiwicopple@users.noreply.github.com>
This commit is contained in:
55
.github/workflows/studio-e2e-tests.yml
vendored
55
.github/workflows/studio-e2e-tests.yml
vendored
@@ -5,14 +5,14 @@ on:
|
||||
paths:
|
||||
- 'packages/pg-meta/**/*'
|
||||
- 'apps/studio/**'
|
||||
- 'tests/studio-tests/**'
|
||||
- 'e2e/studio/**'
|
||||
- 'pnpm-lock.yaml'
|
||||
pull_request:
|
||||
branches: [master]
|
||||
paths:
|
||||
- 'packages/pg-meta/**/*'
|
||||
- 'apps/studio/**'
|
||||
- 'tests/studio-tests/**'
|
||||
- 'e2e/studio/**'
|
||||
- 'pnpm-lock.yaml'
|
||||
|
||||
# Cancel old builds on new commit for same workflow + branch/PR
|
||||
@@ -27,6 +27,18 @@ jobs:
|
||||
test:
|
||||
timeout-minutes: 60
|
||||
runs-on: ubuntu-latest
|
||||
# Make the job non-blocking
|
||||
continue-on-error: true
|
||||
|
||||
env:
|
||||
EMAIL: ${{ secrets.CI_EMAIL }}
|
||||
PASSWORD: ${{ secrets.CI_PASSWORD }}
|
||||
PROJECT_REF: ${{ secrets.CI_PROJECT_REF }}
|
||||
NEXT_PUBLIC_IS_PLATFORM: true
|
||||
NEXT_PUBLIC_API_URL: https://api.supabase.green
|
||||
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
|
||||
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_STUDIO_HOSTED_PROJECT_ID }}
|
||||
NEXT_PUBLIC_HCAPTCHA_SITE_KEY: 10000000-ffff-ffff-ffff-000000000001
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@@ -39,20 +51,41 @@ jobs:
|
||||
with:
|
||||
node-version-file: '.nvmrc'
|
||||
cache: 'pnpm'
|
||||
- uses: supabase/setup-cli@v1
|
||||
with:
|
||||
version: latest
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm i
|
||||
|
||||
- name: Install Vercel CLI
|
||||
run: pnpm add --global vercel@latest
|
||||
|
||||
- name: Pull Vercel Environment Information (Preview)
|
||||
run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}
|
||||
|
||||
- name: Build Project Artifacts for Vercel
|
||||
run: vercel build --token=${{ secrets.VERCEL_TOKEN }}
|
||||
|
||||
- name: Deploy Project to Vercel and Get URL
|
||||
id: deploy_vercel
|
||||
run: |
|
||||
DEPLOY_URL=$(vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }})
|
||||
echo "Vercel Preview URL: $DEPLOY_URL"
|
||||
echo "DEPLOY_URL=$DEPLOY_URL" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Install Playwright Browsers
|
||||
run: pnpm -C tests/studio-tests exec playwright install --with-deps
|
||||
run: pnpm -C e2e/studio exec playwright install --with-deps
|
||||
|
||||
- name: Run Playwright tests
|
||||
run: pnpm test:e2e:studio-local
|
||||
# mark the action as succeeded even if the tests failed. This is temporarily until we make the tests more stable.
|
||||
# continue-on-error: true
|
||||
id: playwright
|
||||
env:
|
||||
AUTHENTICATION: true
|
||||
STUDIO_URL: ${{ steps.deploy_vercel.outputs.DEPLOY_URL }}/dashboard
|
||||
run: pnpm e2e
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: playwright-report
|
||||
path: tests/studio-tests/playwright-report/
|
||||
name: playwright-artifacts
|
||||
path: |
|
||||
e2e/studio/playwright-report/
|
||||
e2e/studio/test-results/
|
||||
retention-days: 7
|
||||
|
||||
@@ -29,6 +29,7 @@ export const SqlRunButton = ({
|
||||
disabled={isDisabled}
|
||||
type="primary"
|
||||
size="tiny"
|
||||
data-testid="sql-run-button"
|
||||
iconRight={
|
||||
isExecuting ? (
|
||||
<Loader2 className="animate-spin" size={10} strokeWidth={1.5} />
|
||||
|
||||
@@ -184,12 +184,7 @@ const DefaultPreviewSelectionRenderer = ({ log }: { log: PreviewLogData }) => {
|
||||
)}
|
||||
{log?.status && <PropertyRow key={'status'} keyName={'status'} value={log.status} />}
|
||||
{log?.timestamp && (
|
||||
<PropertyRow
|
||||
dataTestId="log-selection-timestamp"
|
||||
key={'timestamp'}
|
||||
keyName={'timestamp'}
|
||||
value={log.timestamp}
|
||||
/>
|
||||
<PropertyRow key={'timestamp'} keyName={'timestamp'} value={log.timestamp} />
|
||||
)}
|
||||
{Object.entries(rest).map(([key, value]) => {
|
||||
return <PropertyRow key={key} keyName={key} value={value} />
|
||||
|
||||
@@ -23,13 +23,15 @@ const LogsLayout = ({ title, children }: PropsWithChildren<LogsLayoutProps>) =>
|
||||
const router = useRouter()
|
||||
const [_, setLastLogsPage] = useLocalStorageQuery(
|
||||
LOCAL_STORAGE_KEYS.LAST_VISITED_LOGS_PAGE,
|
||||
router.pathname.split('/logs/')[1]
|
||||
router.pathname.split('/logs/')[1] || ''
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (router.pathname.includes('/logs/')) {
|
||||
const path = router.pathname.split('/logs/')[1]
|
||||
setLastLogsPage(path)
|
||||
if (path) {
|
||||
setLastLogsPage(path)
|
||||
}
|
||||
}
|
||||
}, [router, setLastLogsPage])
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ test('mock is working', async () => {
|
||||
To render a component that uses Nuqs with some predefined query parameters, you can use `customRender` with the `nuqs` prop.
|
||||
|
||||
```ts
|
||||
|
||||
customRender(<MyComponent />, {
|
||||
nuqs: {
|
||||
searchParams: {
|
||||
|
||||
14
e2e/studio/.env.local.example
Normal file
14
e2e/studio/.env.local.example
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
# 1. Copy and paste this file and rename it to .env.local
|
||||
|
||||
# 2. Set the STUDIO_URL and API_URL you want the e2e tests to run against
|
||||
|
||||
STUDIO_URL=https://supabase.com/dashboard
|
||||
API_URL=https://api.supabase.com
|
||||
AUTHENTICATION=true
|
||||
|
||||
# 3. *Optional* If the environment requires auth, set AUTHENTICATION to true, auth credentials, and PROJECT_REF
|
||||
|
||||
EMAIL=
|
||||
PASSWORD=
|
||||
PROJECT_REF=
|
||||
143
e2e/studio/README.md
Normal file
143
e2e/studio/README.md
Normal file
@@ -0,0 +1,143 @@
|
||||
# Supabase Studio E2E Tests
|
||||
|
||||
## Set up
|
||||
|
||||
```bash
|
||||
cp .env.local.example .env.local
|
||||
```
|
||||
|
||||
Edit the `.env.local` file with your credentials and environment.
|
||||
|
||||
### Install the playwright browser
|
||||
|
||||
```bash
|
||||
pnpm exec playwright install
|
||||
```
|
||||
|
||||
## Environments
|
||||
|
||||
### Staging
|
||||
|
||||
```bash
|
||||
STUDIO_URL=https://supabase.green/dashboard
|
||||
API_URL=https://api.supabase.green
|
||||
AUTHENTICATION=true
|
||||
EMAIL=your@email.com
|
||||
PASSWORD=yourpassword
|
||||
PROJECT_REF=yourprojectref
|
||||
```
|
||||
|
||||
### CLI (NO AUTH)
|
||||
|
||||
You'll need to run the CLI locally.
|
||||
|
||||
```bash
|
||||
STUDIO_URL=http://localhost:54323
|
||||
API_URL=http://localhost:54323/api
|
||||
AUTHENTICATION=false
|
||||
```
|
||||
|
||||
### CLI Development (NO AUTH)
|
||||
|
||||
You'll need to run Studio in development mode with `IS_PLATFORM=false`
|
||||
|
||||
```bash
|
||||
STUDIO_URL=http://localhost:8082/
|
||||
API_URL=http://localhost:8082/api
|
||||
AUTHENTICATION=false
|
||||
```
|
||||
|
||||
### Hosted Development
|
||||
|
||||
You'll need to run Studio in development mode with `IS_PLATFORM=true`
|
||||
|
||||
```bash
|
||||
STUDIO_URL=http://localhost:8082/
|
||||
API_URL=http://localhost:8080/api
|
||||
AUTHENTICATION=true
|
||||
EMAIL=your@email.com
|
||||
PASSWORD=yourpassword
|
||||
PROJECT_REF=yourprojectref
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Running the tests
|
||||
|
||||
Check the `package.json` for the available commands and environments.
|
||||
|
||||
#### Example:
|
||||
|
||||
```bash
|
||||
pnpm run e2e
|
||||
```
|
||||
|
||||
With Playwright UI:
|
||||
|
||||
```bash
|
||||
pnpm run e2e -- --ui
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tips for development
|
||||
|
||||
- Read [Playwright Best Practices](https://playwright.dev/docs/best-practices)
|
||||
- Use `pnpm run e2e -- --ui` to get the playwright UI.
|
||||
- Add the tests in `examples/examples.ts` to Cursor as context.
|
||||
- Add messages to expect statements to make them easier to debug.
|
||||
|
||||
Example:
|
||||
|
||||
```ts
|
||||
await expect(page.getByRole('heading', { name: 'Logs & Analytics' }), {
|
||||
message: 'Logs heading should be visible',
|
||||
}).toBeVisible()
|
||||
```
|
||||
|
||||
- Use the test utility instead of playwrights test.
|
||||
|
||||
```ts
|
||||
import { test } from '../utils/test'
|
||||
```
|
||||
|
||||
- Use the PWDEBUG environment variable to debug the tests.
|
||||
|
||||
```bash
|
||||
PWDEBUG=1 pnpm run e2e -- --ui
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Organization
|
||||
|
||||
Name the folders based on the feature you are testing.
|
||||
|
||||
```bash
|
||||
e2e/studio/logs/
|
||||
e2e/studio/sql-editor/
|
||||
e2e/studio/storage/
|
||||
e2e/studio/auth/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## What should I test?
|
||||
|
||||
- Can the feature be navigated to?
|
||||
- Does the feature load correctly?
|
||||
- Can you do the actions (filtering, sorting, opening dialogs, etc)?
|
||||
|
||||
---
|
||||
|
||||
## API Mocks
|
||||
|
||||
Read here: https://playwright.dev/docs/mock#mock-api-requests
|
||||
|
||||
Example:
|
||||
|
||||
```ts
|
||||
await page.route(`*/**/logs.all*`, async (route) => {
|
||||
await route.fulfill({ body: JSON.stringify(mockAPILogs) })
|
||||
})
|
||||
```
|
||||
12
e2e/studio/env.config.ts
Normal file
12
e2e/studio/env.config.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import path from 'path'
|
||||
|
||||
export const env = {
|
||||
STUDIO_URL: process.env.STUDIO_URL,
|
||||
API_URL: process.env.API_URL || 'https://api.supabase.green',
|
||||
AUTHENTICATION: process.env.AUTHENTICATION,
|
||||
EMAIL: process.env.EMAIL,
|
||||
PASSWORD: process.env.PASSWORD,
|
||||
PROJECT_REF: process.env.PROJECT_REF || 'default',
|
||||
}
|
||||
|
||||
export const STORAGE_STATE_PATH = path.join(__dirname, './playwright/.auth/user.json')
|
||||
79
e2e/studio/examples/examples.ts
Normal file
79
e2e/studio/examples/examples.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import { expect } from '@playwright/test'
|
||||
import { isEnv } from '../env.config'
|
||||
import { test } from '../utils/test'
|
||||
|
||||
/**
|
||||
* * Example tests for Studio.
|
||||
* Tips:
|
||||
* - Use the test utility instead of playwrights test.
|
||||
* import { test } from '../utils/test'
|
||||
* - Use the isEnv utility to check the environment.
|
||||
* import { isEnv } from '../env.config'
|
||||
* - Make tests easy to debug by adding enough expect() statements.
|
||||
*/
|
||||
|
||||
/**
|
||||
* * Test that is skipped in self-hosted environment
|
||||
*/
|
||||
test('Loads the page 1', async ({ page }) => {
|
||||
if (isEnv('selfhosted')) return
|
||||
|
||||
await page.goto('https://www.supabase.com')
|
||||
await expect(
|
||||
page.getByRole('heading', { name: 'Build in a weekend Scale to millions' })
|
||||
).toBeVisible()
|
||||
})
|
||||
|
||||
/**
|
||||
* * Test that only runs in staging and production environments
|
||||
*/
|
||||
test('Loads the page 2', async ({ page }) => {
|
||||
if (!isEnv(['staging', 'production'])) return
|
||||
|
||||
await page.goto('https://www.supabase.com')
|
||||
await expect(
|
||||
page.getByRole('heading', { name: 'Build in a weekend Scale to millions' })
|
||||
).toBeVisible()
|
||||
})
|
||||
|
||||
/**
|
||||
* * Test that navigates to a project by ref
|
||||
* Make sure to set up the project in the `.env.local` file.
|
||||
*/
|
||||
test('Navigates to a project by ref', async ({ page, ref }) => {
|
||||
await page.goto(`${process.env.BASE_URL}/project/${ref}`)
|
||||
await expect(page.getByRole('heading', { name: 'Project Home' })).toBeVisible()
|
||||
})
|
||||
|
||||
/**
|
||||
* * Test that mocks some API calls
|
||||
*/
|
||||
|
||||
const mockRes = {
|
||||
data: [
|
||||
{
|
||||
id: 1,
|
||||
name: 'John Doe',
|
||||
email: 'john.doe@example.com',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: 'Jane Doe',
|
||||
email: 'jane.doe@example.com',
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
test.beforeEach(async ({ context }) => {
|
||||
context.route('*/**/users*', async (route, request) => {
|
||||
await route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify(mockRes),
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test('Mocks some API calls', async ({ page }) => {
|
||||
// ... Run some code that depends on that API call
|
||||
})
|
||||
155
e2e/studio/features/_global.setup.ts
Normal file
155
e2e/studio/features/_global.setup.ts
Normal file
@@ -0,0 +1,155 @@
|
||||
import { expect, test as setup } from '@playwright/test'
|
||||
import dotenv from 'dotenv'
|
||||
import path from 'path'
|
||||
import { env, STORAGE_STATE_PATH } from '../env.config'
|
||||
|
||||
/**
|
||||
* Run any setup tasks for the tests.
|
||||
* Catch errors and show useful messages.
|
||||
*/
|
||||
|
||||
dotenv.config({
|
||||
path: path.resolve(__dirname, '..', '.env.local'),
|
||||
override: true,
|
||||
})
|
||||
|
||||
const IS_PLATFORM = process.env.IS_PLATFORM
|
||||
|
||||
const envHasAuth = env.AUTHENTICATION
|
||||
|
||||
setup('Global Setup', async ({ page }) => {
|
||||
console.log(`\n 🧪 Setting up test environment.
|
||||
- Studio URL: ${env.STUDIO_URL}
|
||||
- API URL: ${env.API_URL}
|
||||
- Auth: ${envHasAuth ? 'enabled' : 'disabled'}
|
||||
- Is Platform: ${IS_PLATFORM}
|
||||
`)
|
||||
|
||||
/**
|
||||
* Studio Check
|
||||
*/
|
||||
|
||||
const studioUrl = env.STUDIO_URL
|
||||
const apiUrl = env.API_URL
|
||||
|
||||
await page.goto(studioUrl).catch((err) => {
|
||||
console.error(
|
||||
`\n 🚨 Setup Error
|
||||
Studio is not available at: ${studioUrl}
|
||||
|
||||
Please ensure:
|
||||
1. Studio is running in the expected URL
|
||||
2. You have proper network access
|
||||
`
|
||||
)
|
||||
throw err
|
||||
})
|
||||
|
||||
console.log(`\n ✅ Studio is running at ${studioUrl}`)
|
||||
|
||||
/**
|
||||
* API Check
|
||||
*/
|
||||
|
||||
await fetch(apiUrl).catch((err) => {
|
||||
console.error(`\n 🚨 Setup Error
|
||||
API is not available at: ${apiUrl}
|
||||
|
||||
Please ensure:
|
||||
1. API is running in the expected URL
|
||||
2. You have proper network access
|
||||
|
||||
To start API locally, run:
|
||||
npm run dev:api`)
|
||||
throw new Error('API is not available')
|
||||
})
|
||||
|
||||
console.log(`\n ✅ API is running at ${apiUrl}`)
|
||||
|
||||
/**
|
||||
* Only run authentication if the environment requires it
|
||||
*/
|
||||
if (!env.AUTHENTICATION) {
|
||||
console.log(`\n 🔑 Skipping authentication for ${env.STUDIO_URL}`)
|
||||
return
|
||||
} else {
|
||||
if (!env.EMAIL || !env.PASSWORD || !env.PROJECT_REF) {
|
||||
console.error(`Missing environment variables. Check README.md for more information.`)
|
||||
throw new Error('Missing environment variables')
|
||||
}
|
||||
}
|
||||
|
||||
const signInUrl = `${studioUrl}/sign-in`
|
||||
console.log(`\n 🔑 Navigating to sign in page: ${signInUrl}`)
|
||||
|
||||
await page.goto(signInUrl, { waitUntil: 'networkidle' })
|
||||
await page.waitForLoadState('domcontentloaded')
|
||||
await page.waitForLoadState('networkidle')
|
||||
|
||||
// Check if we're still on the sign-in page
|
||||
const currentUrl = page.url()
|
||||
console.log(`\n 📍 Current URL: ${currentUrl}`)
|
||||
|
||||
if (!currentUrl.includes('/sign-in')) {
|
||||
console.log('\n ⚠️ Redirected away from sign-in page. Checking if already authenticated...')
|
||||
|
||||
// Check if we're already on the projects page
|
||||
if (currentUrl.includes('/projects')) {
|
||||
console.log('\n ✅ Already authenticated, proceeding with tests')
|
||||
await page.context().storageState({ path: STORAGE_STATE_PATH })
|
||||
return
|
||||
}
|
||||
|
||||
// If we're redirected somewhere else, try to navigate back to sign-in
|
||||
console.log('\n 🔄 Attempting to navigate back to sign-in page')
|
||||
await page.goto(signInUrl, { waitUntil: 'networkidle' })
|
||||
await page.waitForLoadState('domcontentloaded')
|
||||
await page.waitForLoadState('networkidle')
|
||||
|
||||
// Check URL again after second attempt
|
||||
const secondAttemptUrl = page.url()
|
||||
if (!secondAttemptUrl.includes('/sign-in')) {
|
||||
throw new Error(`Failed to reach sign-in page. Current URL: ${secondAttemptUrl}`)
|
||||
}
|
||||
}
|
||||
|
||||
const auth = {
|
||||
email: env.EMAIL,
|
||||
password: env.PASSWORD,
|
||||
projectRef: env.PROJECT_REF,
|
||||
}
|
||||
|
||||
expect(auth).toBeDefined()
|
||||
expect(auth.email).toBeDefined()
|
||||
expect(auth.password).toBeDefined()
|
||||
expect(auth.projectRef).toBeDefined()
|
||||
|
||||
// Wait for form elements with increased timeout
|
||||
const emailInput = page.getByLabel('Email')
|
||||
const passwordInput = page.getByLabel('Password')
|
||||
const signInButton = page.getByRole('button', { name: 'Sign In' })
|
||||
|
||||
// if found click opt out on telemetry
|
||||
const optOutButton = page.getByRole('button', { name: 'Opt out' })
|
||||
if ((await optOutButton.count()) > 0) {
|
||||
await optOutButton.click()
|
||||
}
|
||||
|
||||
// Debug element states
|
||||
console.log('\n 🔍 Checking form elements:')
|
||||
console.log(`Email input exists: ${(await emailInput.count()) > 0}`)
|
||||
console.log(`Password input exists: ${(await passwordInput.count()) > 0}`)
|
||||
console.log(`Sign in button exists: ${(await signInButton.count()) > 0}`)
|
||||
|
||||
await emailInput.waitFor({ state: 'visible', timeout: 15000 })
|
||||
await passwordInput.waitFor({ state: 'visible', timeout: 15000 })
|
||||
await signInButton.waitFor({ state: 'visible', timeout: 15000 })
|
||||
|
||||
await emailInput.fill(auth.email ?? '')
|
||||
await passwordInput.fill(auth.password ?? '')
|
||||
await signInButton.click()
|
||||
|
||||
await page.waitForURL('**/organizations')
|
||||
|
||||
await page.context().storageState({ path: STORAGE_STATE_PATH })
|
||||
})
|
||||
12
e2e/studio/features/home.spec.ts
Normal file
12
e2e/studio/features/home.spec.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { expect } from '@playwright/test'
|
||||
import { test } from '../utils/test'
|
||||
import { toUrl } from '../utils/to-url'
|
||||
|
||||
test.describe('Project', async () => {
|
||||
test('Can navigate to project home page', async ({ page, ref }) => {
|
||||
console.log(page.url())
|
||||
await page.goto(toUrl(`/project/${ref}`))
|
||||
|
||||
await expect(page.getByRole('button', { name: 'Project Status' })).toBeVisible()
|
||||
})
|
||||
})
|
||||
90
e2e/studio/features/logs.spec.ts
Normal file
90
e2e/studio/features/logs.spec.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
import { expect } from '@playwright/test'
|
||||
import { test } from '../utils/test'
|
||||
import { toUrl } from '../utils/to-url'
|
||||
const LOGS_PAGES = [
|
||||
{ label: 'API Gateway', route: 'edge-logs' },
|
||||
{ label: 'Postgres', route: 'postgres-logs' },
|
||||
]
|
||||
|
||||
const mockAPILogs = {
|
||||
error: null,
|
||||
result: [
|
||||
{
|
||||
id: 'uuid-1',
|
||||
timestamp: 1713200000000, // 15 Apr 18:53:20"
|
||||
event_message: 'Random event message: uuid-1',
|
||||
count: 123,
|
||||
ok_count: 123,
|
||||
error_count: 0,
|
||||
warning_count: 20,
|
||||
metadata: {
|
||||
foo: 'bar',
|
||||
request: {
|
||||
url: 'https://example.com',
|
||||
},
|
||||
response: {
|
||||
status: 200,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
test.beforeEach(async ({ context }) => {
|
||||
context.route(/.*logs\.all.*/, async (route) => {
|
||||
await route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify(mockAPILogs),
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
test.describe('Logs', () => {
|
||||
for (const logPage of LOGS_PAGES) {
|
||||
test(`${logPage.label} logs page`, async ({ page, ref }) => {
|
||||
/**
|
||||
* Navigates to Logs
|
||||
*/
|
||||
await page.goto(toUrl(`/project/${ref}/logs/${logPage.route}`))
|
||||
|
||||
await expect(page.getByRole('heading', { name: 'Logs & Analytics' }), {
|
||||
message: 'Logs & Analytics heading should be visible',
|
||||
}).toBeVisible()
|
||||
|
||||
/**
|
||||
* Shows the logs table
|
||||
*/
|
||||
|
||||
const logsTable = page.getByRole('table')
|
||||
|
||||
await expect(logsTable, {
|
||||
message: 'Logs table should be visible',
|
||||
}).toBeVisible({ timeout: 20000 })
|
||||
|
||||
/**
|
||||
* Shows the logs data without errors
|
||||
*/
|
||||
await expect(page.getByText(mockAPILogs.result[0].event_message), {
|
||||
message: 'Logs data should be visible',
|
||||
}).toBeVisible()
|
||||
|
||||
/**
|
||||
* Can select and view log details
|
||||
*/
|
||||
const gridcells = page.getByText('Random event message')
|
||||
await gridcells.click()
|
||||
|
||||
const tabPanel = page.getByTestId('log-selection')
|
||||
await expect(tabPanel).toBeVisible()
|
||||
|
||||
// Assert known fixed values instead of extracting text
|
||||
await expect(tabPanel, {
|
||||
message: 'Log selection should be visible',
|
||||
}).toContainText('Random event message: uuid-1')
|
||||
await expect(tabPanel.getByTestId('log-selection-id'), {
|
||||
message: 'Log selection ID should be visible',
|
||||
}).toContainText('uuid-1')
|
||||
})
|
||||
}
|
||||
})
|
||||
36
e2e/studio/features/sql-editor.spec.ts
Normal file
36
e2e/studio/features/sql-editor.spec.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { expect } from '@playwright/test'
|
||||
import { test } from '../utils/test'
|
||||
import { toUrl } from '../utils/to-url'
|
||||
import { env } from '../env.config'
|
||||
|
||||
test.describe('SQL Editor', () => {
|
||||
test('should check if SQL editor can run simple commands', async ({ page }) => {
|
||||
await page.goto(toUrl(`/project/${env.PROJECT_REF}/sql`))
|
||||
|
||||
const editor = page.getByRole('code').nth(0)
|
||||
|
||||
// write some sql in the editor
|
||||
// This has to be done since the editor is not editable (input, textarea, etc.)
|
||||
await editor.click()
|
||||
await editor.click()
|
||||
await page.keyboard.press('ControlOrMeta+KeyA')
|
||||
await page.keyboard.type(`select 'hello world';`)
|
||||
|
||||
await page.getByRole('button', { name: /^Run( CTRL)?$/, exact: false }).click()
|
||||
|
||||
// Should say "Running..."
|
||||
await expect(page.getByText('Running...')).toBeVisible()
|
||||
|
||||
// Wait until Running... is not visible
|
||||
await expect(page.getByText('Running...')).not.toBeVisible()
|
||||
|
||||
// clear the editor
|
||||
await editor.click()
|
||||
await page.keyboard.press('ControlOrMeta+KeyA')
|
||||
await page.keyboard.press('Backspace')
|
||||
|
||||
// verify the result
|
||||
const result = page.getByRole('gridcell', { name: 'hello world' })
|
||||
await expect(result).toBeVisible()
|
||||
})
|
||||
})
|
||||
210
e2e/studio/features/table-editor.spec.ts
Normal file
210
e2e/studio/features/table-editor.spec.ts
Normal file
@@ -0,0 +1,210 @@
|
||||
import { expect, Page } from '@playwright/test'
|
||||
import { test } from '../utils/test'
|
||||
import { toUrl } from '../utils/to-url'
|
||||
|
||||
// Helper to generate a random table name
|
||||
const getRandomTableName = () => `pw-test-${Math.floor(Math.random() * 10000)}`
|
||||
|
||||
const getSelectors = (tableName: string) => ({
|
||||
tableButton: (page) => page.getByRole('button', { name: `View ${tableName}` }),
|
||||
newTableBtn: (page) => page.getByRole('button', { name: 'New table', exact: true }),
|
||||
tableNameInput: (page) => page.getByTestId('table-name-input'),
|
||||
createdAtExtraOptions: (page) => page.getByTestId('created_at-extra-options'),
|
||||
addColumnBtn: (page) => page.getByRole('button', { name: 'Add column' }),
|
||||
columnNameInput: (page) => page.getByRole('textbox', { name: 'column_name' }),
|
||||
chooseColumnType: (page) => page.locator('button').filter({ hasText: 'Choose a column type...' }),
|
||||
signedIntOption: (page) => page.getByText('Signed two-byte integer'),
|
||||
defaultValueField: (page) => page.getByTestId('defaultValueColumn-default-value'),
|
||||
saveBtn: (page) => page.getByRole('button', { name: 'Save' }),
|
||||
definitionTab: (page) => page.getByText('definition', { exact: true }),
|
||||
viewLines: (page) => page.locator('div.view-lines'),
|
||||
insertRowBtn: (page) => page.getByTestId('table-editor-insert-new-row'),
|
||||
insertModal: (page) => page.getByText('Insert a new row into'),
|
||||
defaultValueInput: (page) => page.getByTestId('defaultValueColumn-input'),
|
||||
actionBarSaveRow: (page) => page.getByTestId('action-bar-save-row'),
|
||||
grid: (page) => page.getByRole('grid'),
|
||||
row: (page) => page.getByRole('row'),
|
||||
sortBtn: (page) => page.getByRole('button', { name: 'Sort', exact: true }),
|
||||
pickSortColumnBtn: (page) => page.getByTestId('table-editor-pick-column-to-sort-button'),
|
||||
sortColumnOption: (page) =>
|
||||
page.getByLabel('Pick a column to sort by').getByText('defaultValueColumn'),
|
||||
applySortingBtn: (page) => page.getByRole('button', { name: 'Apply sorting' }),
|
||||
sortedByRuleBtn: (page) => page.getByRole('button', { name: 'Sorted by 1 rule' }),
|
||||
filterBtn: (page) => page.getByRole('button', { name: 'Filter', exact: true }),
|
||||
addFilterBtn: (page) => page.getByRole('button', { name: 'Add filter' }),
|
||||
columnPickerBtn: (page) => page.getByRole('button', { name: 'id' }),
|
||||
filterColumnOption: (page) => page.getByLabel('id').getByText('defaultValueColumn'),
|
||||
filterInput: (page) => page.getByPlaceholder('Enter a value'),
|
||||
applyFilterBtn: (page) => page.getByRole('button', { name: 'Apply filter' }),
|
||||
viewTableLabel: (page) => page.getByLabel(`View ${tableName}`, { exact: true }),
|
||||
deleteTableBtn: (page) => page.getByText('Delete table'),
|
||||
confirmDeleteBtn: (page) => page.getByRole('button', { name: 'Delete' }),
|
||||
rlsCheckbox: (page) => page.getByLabel('Enable Row Level Security ('),
|
||||
rlsConfirmBtn: (page) => page.getByRole('button', { name: 'Confirm' }),
|
||||
deleteTableToast: (page) => page.getByText('Successfully deleted table "'),
|
||||
})
|
||||
|
||||
test.describe('Table Editor', () => {
|
||||
let page: Page
|
||||
let tableName: string
|
||||
|
||||
test.beforeAll(async ({ browser, ref }) => {
|
||||
test.setTimeout(60000)
|
||||
|
||||
/**
|
||||
* Create a new table for the tests
|
||||
*/
|
||||
page = await browser.newPage()
|
||||
|
||||
await page.goto(toUrl(`/project/${ref}/editor`))
|
||||
|
||||
tableName = getRandomTableName()
|
||||
const s = getSelectors(tableName)
|
||||
|
||||
await s.newTableBtn(page).click()
|
||||
await s.tableNameInput(page).fill(tableName)
|
||||
|
||||
await s.createdAtExtraOptions(page).click()
|
||||
await page.getByText('Is Nullable').click()
|
||||
await s.createdAtExtraOptions(page).click({ force: true })
|
||||
|
||||
await s.addColumnBtn(page).click()
|
||||
await s.columnNameInput(page).fill('defaultValueColumn')
|
||||
await s.chooseColumnType(page).click()
|
||||
await s.signedIntOption(page).click()
|
||||
await s.defaultValueField(page).click()
|
||||
await s.defaultValueField(page).fill('2')
|
||||
|
||||
await s.saveBtn(page).click()
|
||||
|
||||
// wait till we see the success toast
|
||||
// Text: Table tableName is good to go!
|
||||
|
||||
await expect(
|
||||
page.getByText(`Table ${tableName} is good to go!`),
|
||||
'Success toast should be visible after table creation'
|
||||
).toBeVisible({
|
||||
timeout: 50000,
|
||||
})
|
||||
|
||||
await expect(
|
||||
page.getByRole('button', { name: `View ${tableName}` }),
|
||||
'Table should be visible after creation'
|
||||
).toBeVisible()
|
||||
})
|
||||
|
||||
test.afterAll(async () => {
|
||||
test.setTimeout(60000)
|
||||
/**
|
||||
* Delete the table after the tests are done
|
||||
*/
|
||||
const s = getSelectors(tableName)
|
||||
|
||||
const exists = (await s.tableButton(page).count()) > 0
|
||||
if (!exists) return
|
||||
|
||||
await s.viewTableLabel(page).click()
|
||||
await s.viewTableLabel(page).getByRole('button').nth(1).click()
|
||||
await s.deleteTableBtn(page).click()
|
||||
await s.confirmDeleteBtn(page).click()
|
||||
await expect(
|
||||
s.deleteTableToast(page),
|
||||
'Delete confirmation toast should be visible'
|
||||
).toBeVisible()
|
||||
})
|
||||
|
||||
test('should perform all table operations sequentially', async ({ ref }) => {
|
||||
const s = getSelectors(tableName)
|
||||
test.setTimeout(60000)
|
||||
|
||||
// 1. View table definition
|
||||
await page.evaluate(() => document.querySelector('.ReactQueryDevtools')?.remove())
|
||||
await s.definitionTab(page).click()
|
||||
await expect(
|
||||
s.viewLines(page),
|
||||
'Table definition should contain the correct SQL'
|
||||
).toContainText(
|
||||
`CREATE TABLE public.${tableName} ( id bigint GENERATED BY DEFAULT AS IDENTITY NOT NULL, created_at timestamp with time zone NULL DEFAULT now(), "defaultValueColumn" smallint NULL DEFAULT '2'::smallint, CONSTRAINT ${tableName}_pkey PRIMARY KEY (id)) TABLESPACE pg_default;`
|
||||
)
|
||||
|
||||
// 2. Insert test data
|
||||
await page.getByRole('button', { name: `View ${tableName}` }).click()
|
||||
await s.insertRowBtn(page).click()
|
||||
await s.insertModal(page).click()
|
||||
await s.defaultValueInput(page).fill('100')
|
||||
await s.actionBarSaveRow(page).click()
|
||||
|
||||
await page.getByRole('button', { name: `View ${tableName}` }).click()
|
||||
await s.insertRowBtn(page).click()
|
||||
await s.insertModal(page).click()
|
||||
await s.defaultValueInput(page).fill('4')
|
||||
await s.actionBarSaveRow(page).click()
|
||||
|
||||
// Wait for the grid to be visible and data to be loaded
|
||||
await expect(s.grid(page), 'Grid should be visible after inserting data').toBeVisible()
|
||||
|
||||
// 3. Sort rows
|
||||
await s.sortBtn(page).click()
|
||||
await s.pickSortColumnBtn(page).click()
|
||||
await s.sortColumnOption(page).click()
|
||||
await s.applySortingBtn(page).click()
|
||||
await page.keyboard.down('Escape')
|
||||
|
||||
// Wait for sorting to complete
|
||||
await page.waitForResponse((response) => response.url().includes(`pg-meta/${ref}/query`))
|
||||
|
||||
// give it a second to rerender
|
||||
await page.waitForTimeout(1000)
|
||||
|
||||
const defaultValueCells = page.getByRole('gridcell')
|
||||
|
||||
const thirdGridCell = defaultValueCells.nth(3)
|
||||
const thirdGridCellText = await thirdGridCell.textContent()
|
||||
expect(thirdGridCellText, 'Third grid cell should contain the value "4"').toEqual('4')
|
||||
|
||||
// 4. Filter rows
|
||||
await s.filterBtn(page).click()
|
||||
await s.addFilterBtn(page).click()
|
||||
await s.columnPickerBtn(page).click()
|
||||
await s.filterColumnOption(page).click()
|
||||
await s.filterInput(page).fill('4')
|
||||
await s.applyFilterBtn(page).click()
|
||||
await page.keyboard.down('Escape')
|
||||
|
||||
await expect(
|
||||
s.grid(page).getByRole('gridcell', { name: '4', exact: true }),
|
||||
'Filtered value "4" should be visible'
|
||||
).toBeVisible()
|
||||
await expect(
|
||||
s.grid(page).getByText('100'),
|
||||
'Filtered value "100" should not be visible'
|
||||
).not.toBeVisible()
|
||||
|
||||
// 5. Check auth schema
|
||||
await page.getByTestId('schema-selector').click()
|
||||
await page.getByRole('option', { name: 'auth' }).click()
|
||||
|
||||
// Wait for the tables list to be visible
|
||||
await expect(
|
||||
page.getByTestId('tables-list'),
|
||||
'Tables list should be visible in auth schema'
|
||||
).toBeVisible()
|
||||
|
||||
// search for users
|
||||
await page.getByRole('textbox', { name: 'Search tables...' }).fill('users')
|
||||
|
||||
// Try to find the users table directly
|
||||
const usersTable = page.getByRole('button', { name: 'View users' })
|
||||
await expect(usersTable, 'Users table should be visible in auth schema').toBeVisible()
|
||||
|
||||
// go back to public schema
|
||||
await page.getByTestId('schema-selector').click()
|
||||
await page.getByRole('option', { name: 'public', exact: true }).click()
|
||||
|
||||
// wait for the tables list to be visible
|
||||
await expect(
|
||||
page.getByTestId('tables-list'),
|
||||
'Tables list should be visible in public schema'
|
||||
).toBeVisible()
|
||||
})
|
||||
})
|
||||
16
e2e/studio/package.json
Normal file
16
e2e/studio/package.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "e2e-studio",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"e2e": "playwright test"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"description": "",
|
||||
"dependencies": {
|
||||
"dotenv": "^16.5.0",
|
||||
"@playwright/test": "^1.52.0"
|
||||
}
|
||||
}
|
||||
45
e2e/studio/playwright.config.ts
Normal file
45
e2e/studio/playwright.config.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { defineConfig } from '@playwright/test'
|
||||
import { env, STORAGE_STATE_PATH } from './env.config'
|
||||
import dotenv from 'dotenv'
|
||||
import path from 'path'
|
||||
|
||||
dotenv.config({ path: path.resolve(__dirname, '.env.local') })
|
||||
|
||||
const IS_CI = !!process.env.CI
|
||||
|
||||
export default defineConfig({
|
||||
timeout: 60 * 1000,
|
||||
testDir: './features',
|
||||
testMatch: /.*\.spec\.ts/,
|
||||
forbidOnly: IS_CI,
|
||||
retries: 3,
|
||||
use: {
|
||||
baseURL: env.STUDIO_URL,
|
||||
screenshot: 'off',
|
||||
video: 'retain-on-failure',
|
||||
headless: IS_CI,
|
||||
trace: 'retain-on-failure',
|
||||
},
|
||||
projects: [
|
||||
{
|
||||
name: 'setup',
|
||||
testMatch: /.*\.setup\.ts/,
|
||||
},
|
||||
{
|
||||
name: 'Features',
|
||||
testDir: './features',
|
||||
testMatch: /.*\.spec\.ts/,
|
||||
dependencies: ['setup'],
|
||||
use: {
|
||||
browserName: 'chromium',
|
||||
screenshot: 'off',
|
||||
storageState: STORAGE_STATE_PATH,
|
||||
},
|
||||
},
|
||||
],
|
||||
reporter: [
|
||||
['list'],
|
||||
['html', { open: 'never' }],
|
||||
['json', { outputFile: 'test-results/test-results.json' }],
|
||||
],
|
||||
})
|
||||
7
e2e/studio/tsconfig.json
Normal file
7
e2e/studio/tsconfig.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"jsx": "react",
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true
|
||||
}
|
||||
}
|
||||
11
e2e/studio/utils/dismiss-toast.ts
Normal file
11
e2e/studio/utils/dismiss-toast.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Page } from '@playwright/test'
|
||||
|
||||
export const dismissToast = async (page: Page) => {
|
||||
await page
|
||||
.locator('li.toast')
|
||||
.getByRole('button', { name: 'Opt out' })
|
||||
.waitFor({ state: 'visible' })
|
||||
await page.locator('li.toast').getByRole('button', { name: 'Opt out' }).click()
|
||||
}
|
||||
|
||||
export const toKebabCase = (str: string) => str.replace(/([A-Z])/g, '-$1').toLowerCase()
|
||||
21
e2e/studio/utils/test.ts
Normal file
21
e2e/studio/utils/test.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { test as base } from '@playwright/test'
|
||||
import dotenv from 'dotenv'
|
||||
import path from 'path'
|
||||
import { env } from '../env.config'
|
||||
|
||||
dotenv.config({
|
||||
path: path.resolve(__dirname, '../.env.local'),
|
||||
override: true,
|
||||
})
|
||||
|
||||
export interface TestOptions {
|
||||
env: string
|
||||
ref: string
|
||||
apiUrl: string
|
||||
}
|
||||
|
||||
export const test = base.extend<TestOptions>({
|
||||
env: env.STUDIO_URL,
|
||||
ref: env.PROJECT_REF,
|
||||
apiUrl: env.API_URL,
|
||||
})
|
||||
5
e2e/studio/utils/to-url.ts
Normal file
5
e2e/studio/utils/to-url.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { env } from '../env.config'
|
||||
|
||||
export function toUrl(path: `/${string}`) {
|
||||
return `${env.STUDIO_URL}${path}`
|
||||
}
|
||||
13
package.json
13
package.json
@@ -29,8 +29,17 @@
|
||||
"test:ui-patterns": "turbo run test --filter=ui-patterns",
|
||||
"test:studio": "turbo run test --filter=studio",
|
||||
"test:studio:watch": "turbo run test --filter=studio -- watch",
|
||||
"test:e2e:studio-local": "pnpm --prefix tests/studio-tests run test:local",
|
||||
"test:e2e:studio-staging": "pnpm --prefix tests/studio-tests run test:staging",
|
||||
|
||||
"e2e": "pnpm --prefix e2e/studio run e2e",
|
||||
"e2e:dev-hosted": "pnpm --prefix e2e/studio run e2e:dev-hosted",
|
||||
"e2e:dev-selfhosted": "pnpm --prefix e2e/studio run e2e:dev-selfhosted",
|
||||
"e2e:selfhosted": "pnpm --prefix e2e/studio run e2e:selfhosted",
|
||||
"e2e:staging": "pnpm --prefix e2e/studio run e2e:staging",
|
||||
"e2e:prod": "pnpm --prefix e2e/studio run e2e:prod",
|
||||
"e2e:ci": "pnpm --prefix e2e/studio run e2e:ci",
|
||||
"e2e:supabase:start": "pnpm --prefix e2e/studio run supabase:start",
|
||||
"e2e:supabase:stop": "pnpm --prefix e2e/studio run supabase:stop",
|
||||
|
||||
"perf:kong": "ab -t 5 -c 20 -T application/json http://localhost:8000/",
|
||||
"perf:meta": "ab -t 5 -c 20 -T application/json http://localhost:5555/tables",
|
||||
"generate:types": "supabase gen types typescript --local > ./supabase/functions/common/database-types.ts",
|
||||
|
||||
222
pnpm-lock.yaml
generated
222
pnpm-lock.yaml
generated
@@ -91,28 +91,28 @@ importers:
|
||||
version: 3.40.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@payloadcms/next':
|
||||
specifier: 3.33.0
|
||||
version: 3.33.0(@types/react@18.3.3)(graphql@16.10.0)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
|
||||
version: 3.33.0(@types/react@18.3.3)(graphql@16.10.0)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
|
||||
'@payloadcms/payload-cloud':
|
||||
specifier: 3.33.0
|
||||
version: 3.33.0(encoding@0.1.13)(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))
|
||||
'@payloadcms/plugin-form-builder':
|
||||
specifier: 3.33.0
|
||||
version: 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
|
||||
version: 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
|
||||
'@payloadcms/plugin-nested-docs':
|
||||
specifier: 3.33.0
|
||||
version: 3.33.0(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))
|
||||
'@payloadcms/plugin-seo':
|
||||
specifier: 3.33.0
|
||||
version: 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
|
||||
version: 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
|
||||
'@payloadcms/richtext-lexical':
|
||||
specifier: 3.33.0
|
||||
version: 3.33.0(@faceless-ui/modal@3.0.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@faceless-ui/scroll-info@2.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@payloadcms/next@3.33.0(@types/react@18.3.3)(graphql@16.10.0)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3))(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)(yjs@13.6.27)
|
||||
version: 3.33.0(@faceless-ui/modal@3.0.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@faceless-ui/scroll-info@2.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@payloadcms/next@3.33.0(@types/react@18.3.3)(graphql@16.10.0)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3))(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)(yjs@13.6.27)
|
||||
'@payloadcms/storage-s3':
|
||||
specifier: 3.33.0
|
||||
version: 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
|
||||
version: 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
|
||||
'@payloadcms/ui':
|
||||
specifier: 3.33.0
|
||||
version: 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
|
||||
version: 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
|
||||
common:
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/common
|
||||
@@ -130,7 +130,7 @@ importers:
|
||||
version: 16.10.0
|
||||
next:
|
||||
specifier: ~15.3.0
|
||||
version: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
version: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
payload:
|
||||
specifier: 3.33.0
|
||||
version: 3.33.0(graphql@16.10.0)(typescript@5.7.3)
|
||||
@@ -182,10 +182,10 @@ importers:
|
||||
version: 1.2.0
|
||||
next:
|
||||
specifier: 'catalog:'
|
||||
version: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
version: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
next-contentlayer2:
|
||||
specifier: 0.4.6
|
||||
version: 0.4.6(contentlayer2@0.4.6(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1))(esbuild@0.25.2)(markdown-wasm@1.2.0)(next@14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)
|
||||
version: 0.4.6(contentlayer2@0.4.6(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1))(esbuild@0.25.2)(markdown-wasm@1.2.0)(next@14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)
|
||||
next-themes:
|
||||
specifier: ^0.3.0
|
||||
version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
@@ -327,7 +327,7 @@ importers:
|
||||
version: 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@sentry/nextjs':
|
||||
specifier: ^9.15.0
|
||||
version: 9.15.0(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0)(supports-color@8.1.1))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)(supports-color@8.1.1)(webpack@5.94.0)
|
||||
version: 9.15.0(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0)(supports-color@8.1.1))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)(supports-color@8.1.1)(webpack@5.94.0)
|
||||
'@supabase/supabase-js':
|
||||
specifier: 'catalog:'
|
||||
version: 2.49.3
|
||||
@@ -435,7 +435,7 @@ importers:
|
||||
version: 1.0.1
|
||||
next:
|
||||
specifier: 15.3.1
|
||||
version: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
version: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
next-mdx-remote:
|
||||
specifier: ^4.4.1
|
||||
version: 4.4.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)
|
||||
@@ -447,7 +447,7 @@ importers:
|
||||
version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
nuqs:
|
||||
specifier: ^1.19.1
|
||||
version: 1.19.1(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))
|
||||
version: 1.19.1(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))
|
||||
openai:
|
||||
specifier: ^4.20.1
|
||||
version: 4.71.1(encoding@0.1.13)(zod@3.23.8)
|
||||
@@ -700,7 +700,7 @@ importers:
|
||||
version: 0.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@sentry/nextjs':
|
||||
specifier: ^8.52.1
|
||||
version: 8.52.1(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.56.0(@opentelemetry/api@1.9.0)(supports-color@8.1.1))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)(supports-color@8.1.1)(webpack@5.94.0)
|
||||
version: 8.52.1(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.56.0(@opentelemetry/api@1.9.0)(supports-color@8.1.1))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)(supports-color@8.1.1)(webpack@5.94.0)
|
||||
'@std/path':
|
||||
specifier: npm:@jsr/std__path@^1.0.8
|
||||
version: '@jsr/std__path@1.0.8'
|
||||
@@ -739,7 +739,7 @@ importers:
|
||||
version: 2.4.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@vercel/flags':
|
||||
specifier: ^2.6.0
|
||||
version: 2.6.0(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
version: 2.6.0(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@vitejs/plugin-react':
|
||||
specifier: ^4.3.4
|
||||
version: 4.3.4(supports-color@8.1.1)(vite@6.2.6(@types/node@20.12.11)(jiti@2.4.2)(sass@1.77.4)(terser@5.39.0)(tsx@4.19.3)(yaml@2.4.5))
|
||||
@@ -826,13 +826,13 @@ importers:
|
||||
version: 0.52.2
|
||||
next:
|
||||
specifier: ~15.3.0
|
||||
version: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
version: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
next-themes:
|
||||
specifier: ^0.3.0
|
||||
version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
nuqs:
|
||||
specifier: ^2.4.1
|
||||
version: 2.4.1(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-router@7.5.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
|
||||
version: 2.4.1(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-router@7.5.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
|
||||
openai:
|
||||
specifier: ^4.20.1
|
||||
version: 4.71.1(encoding@0.1.13)(zod@3.23.8)
|
||||
@@ -1085,7 +1085,7 @@ importers:
|
||||
version: 2.4.11(typescript@5.5.2)
|
||||
next-router-mock:
|
||||
specifier: ^0.9.13
|
||||
version: 0.9.13(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)
|
||||
version: 0.9.13(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)
|
||||
postcss:
|
||||
specifier: ^8.5.3
|
||||
version: 8.5.3
|
||||
@@ -1172,10 +1172,10 @@ importers:
|
||||
version: 0.436.0(react@18.3.1)
|
||||
next:
|
||||
specifier: 'catalog:'
|
||||
version: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
version: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
next-contentlayer2:
|
||||
specifier: 0.4.6
|
||||
version: 0.4.6(contentlayer2@0.4.6(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1))(esbuild@0.25.2)(markdown-wasm@1.2.0)(next@14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)
|
||||
version: 0.4.6(contentlayer2@0.4.6(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1))(esbuild@0.25.2)(markdown-wasm@1.2.0)(next@14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)
|
||||
next-themes:
|
||||
specifier: ^0.3.0
|
||||
version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
@@ -1407,16 +1407,16 @@ importers:
|
||||
version: 1.2.0
|
||||
next:
|
||||
specifier: 'catalog:'
|
||||
version: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
version: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
next-contentlayer2:
|
||||
specifier: 0.5.3
|
||||
version: 0.5.3(contentlayer2@0.5.3(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1))(esbuild@0.25.2)(markdown-wasm@1.2.0)(next@14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)
|
||||
version: 0.5.3(contentlayer2@0.5.3(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1))(esbuild@0.25.2)(markdown-wasm@1.2.0)(next@14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)
|
||||
next-mdx-remote:
|
||||
specifier: ^4.4.1
|
||||
version: 4.4.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)
|
||||
next-seo:
|
||||
specifier: ^6.5.0
|
||||
version: 6.5.0(next@14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
version: 6.5.0(next@14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
next-themes:
|
||||
specifier: ^0.3.0
|
||||
version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
@@ -1551,6 +1551,15 @@ importers:
|
||||
specifier: ^3.22.4
|
||||
version: 3.23.8
|
||||
|
||||
e2e/studio:
|
||||
dependencies:
|
||||
'@playwright/test':
|
||||
specifier: ^1.52.0
|
||||
version: 1.52.0
|
||||
dotenv:
|
||||
specifier: ^16.5.0
|
||||
version: 16.5.0
|
||||
|
||||
packages/ai-commands:
|
||||
dependencies:
|
||||
'@serafin/schema-builder':
|
||||
@@ -1661,7 +1670,7 @@ importers:
|
||||
version: 4.42.0
|
||||
'@vercel/flags':
|
||||
specifier: ^2.6.0
|
||||
version: 2.6.0(next@14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
version: 2.6.0(next@14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
api-types:
|
||||
specifier: workspace:*
|
||||
version: link:../api-types
|
||||
@@ -1676,7 +1685,7 @@ importers:
|
||||
version: 4.17.21
|
||||
next:
|
||||
specifier: 'catalog:'
|
||||
version: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
version: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
next-themes:
|
||||
specifier: ^0.3.0
|
||||
version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
@@ -1954,7 +1963,7 @@ importers:
|
||||
version: 0.436.0(react@18.3.1)
|
||||
next:
|
||||
specifier: 'catalog:'
|
||||
version: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
version: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
next-themes:
|
||||
specifier: ^0.3.0
|
||||
version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
@@ -2123,7 +2132,7 @@ importers:
|
||||
version: 0.52.2
|
||||
next:
|
||||
specifier: '*'
|
||||
version: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
version: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
next-themes:
|
||||
specifier: '*'
|
||||
version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
@@ -2232,7 +2241,7 @@ importers:
|
||||
version: link:../api-types
|
||||
next-router-mock:
|
||||
specifier: ^0.9.13
|
||||
version: 0.9.13(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)
|
||||
version: 0.9.13(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)
|
||||
tsx:
|
||||
specifier: ^4.19.3
|
||||
version: 4.19.3
|
||||
@@ -2252,18 +2261,6 @@ importers:
|
||||
specifier: ^3.0.5
|
||||
version: 3.0.9(@types/node@20.12.11)(jiti@2.4.2)(jsdom@20.0.3(supports-color@8.1.1))(msw@2.7.3(@types/node@20.12.11)(typescript@5.5.2))(sass@1.77.4)(supports-color@8.1.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.4.5)
|
||||
|
||||
tests/studio-tests:
|
||||
devDependencies:
|
||||
'@playwright/test':
|
||||
specifier: ^1.49.0
|
||||
version: 1.49.1
|
||||
dotenv:
|
||||
specifier: ^16.4.7
|
||||
version: 16.4.7
|
||||
lodash:
|
||||
specifier: ^4.17.21
|
||||
version: 4.17.21
|
||||
|
||||
packages:
|
||||
|
||||
'@aashutoshrathi/word-wrap@1.2.6':
|
||||
@@ -5816,8 +5813,8 @@ packages:
|
||||
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
'@playwright/test@1.49.1':
|
||||
resolution: {integrity: sha512-Ky+BVzPz8pL6PQxHqNRW1k3mIyv933LML7HktS8uik0bUXNCdPhoS/kLihiO1tMf/egaJb4IutXd7UywvXEW+g==}
|
||||
'@playwright/test@1.52.0':
|
||||
resolution: {integrity: sha512-uh6W7sb55hl7D6vsAeA+V2p5JnlAqzhqFyF0VcJkKZXkgnFcVG9PziERRHQfPLfNGx1C292a4JqbWzhR8L4R1g==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
@@ -10858,6 +10855,10 @@ packages:
|
||||
resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
dotenv@16.5.0:
|
||||
resolution: {integrity: sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
dotty@0.1.2:
|
||||
resolution: {integrity: sha512-V0EWmKeH3DEhMwAZ+8ZB2Ao4OK6p++Z0hsDtZq3N0+0ZMVqkzrcEGROvOnZpLnvBg5PTNG23JEDLAm64gPaotQ==}
|
||||
|
||||
@@ -14907,13 +14908,13 @@ packages:
|
||||
pkg-types@2.1.0:
|
||||
resolution: {integrity: sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==}
|
||||
|
||||
playwright-core@1.49.1:
|
||||
resolution: {integrity: sha512-BzmpVcs4kE2CH15rWfzpjzVGhWERJfmnXmniSyKeRZUs9Ws65m+RGIi7mjJK/euCegfn3i7jvqWeWyHe9y3Vgg==}
|
||||
playwright-core@1.52.0:
|
||||
resolution: {integrity: sha512-l2osTgLXSMeuLZOML9qYODUQoPPnUsKsb5/P6LJ2e6uPKXUdPK5WYhN4z03G+YNbWmGDY4YENauNu4ZKczreHg==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
playwright@1.49.1:
|
||||
resolution: {integrity: sha512-VYL8zLoNTBxVOrJBbDuRgDWa3i+mfQgDTrL8Ah9QXZ7ax4Dsj0MSq5bYgytRnDVVe+njoKnfsYkH3HzqVj5UZA==}
|
||||
playwright@1.52.0:
|
||||
resolution: {integrity: sha512-JAwMNMBlxJ2oD1kce4KPtMkDeKGHQstdpFPcPH3maElAXon/QZeTvtsfXmTMRyO9TslfoYOXkSsvao2nE1ilTw==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
|
||||
@@ -17508,11 +17509,6 @@ packages:
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||
|
||||
use-sync-external-store@1.4.0:
|
||||
resolution: {integrity: sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==}
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
|
||||
use-sync-external-store@1.5.0:
|
||||
resolution: {integrity: sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==}
|
||||
peerDependencies:
|
||||
@@ -20300,8 +20296,8 @@ snapshots:
|
||||
|
||||
'@fastify/ajv-compiler@3.6.0':
|
||||
dependencies:
|
||||
ajv: 8.17.1
|
||||
ajv-formats: 2.1.1(ajv@8.17.1)
|
||||
ajv: 8.12.0
|
||||
ajv-formats: 2.1.1(ajv@8.12.0)
|
||||
fast-uri: 2.4.0
|
||||
|
||||
'@fastify/busboy@3.1.1': {}
|
||||
@@ -22825,12 +22821,12 @@ snapshots:
|
||||
|
||||
'@payloadcms/live-preview@3.40.0': {}
|
||||
|
||||
'@payloadcms/next@3.33.0(@types/react@18.3.3)(graphql@16.10.0)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)':
|
||||
'@payloadcms/next@3.33.0(@types/react@18.3.3)(graphql@16.10.0)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)':
|
||||
dependencies:
|
||||
'@dnd-kit/core': 6.0.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@payloadcms/graphql': 3.33.0(graphql@16.10.0)(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(typescript@5.7.3)
|
||||
'@payloadcms/translations': 3.33.0
|
||||
'@payloadcms/ui': 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
|
||||
'@payloadcms/ui': 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
|
||||
busboy: 1.6.0
|
||||
dequal: 2.0.3
|
||||
file-type: 19.3.0
|
||||
@@ -22838,7 +22834,7 @@ snapshots:
|
||||
graphql-http: 1.22.4(graphql@16.10.0)
|
||||
graphql-playground-html: 1.6.30
|
||||
http-status: 2.1.0
|
||||
next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
path-to-regexp: 6.3.0
|
||||
payload: 3.33.0(graphql@16.10.0)(typescript@5.7.3)
|
||||
qs-esm: 7.0.2
|
||||
@@ -22867,9 +22863,9 @@ snapshots:
|
||||
- aws-crt
|
||||
- encoding
|
||||
|
||||
'@payloadcms/plugin-cloud-storage@3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)':
|
||||
'@payloadcms/plugin-cloud-storage@3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)':
|
||||
dependencies:
|
||||
'@payloadcms/ui': 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
|
||||
'@payloadcms/ui': 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
|
||||
find-node-modules: 2.1.3
|
||||
payload: 3.33.0(graphql@16.10.0)(typescript@5.7.3)
|
||||
range-parser: 1.2.1
|
||||
@@ -22882,9 +22878,9 @@ snapshots:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
'@payloadcms/plugin-form-builder@3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)':
|
||||
'@payloadcms/plugin-form-builder@3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)':
|
||||
dependencies:
|
||||
'@payloadcms/ui': 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
|
||||
'@payloadcms/ui': 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
|
||||
escape-html: 1.0.3
|
||||
payload: 3.33.0(graphql@16.10.0)(typescript@5.7.3)
|
||||
react: 18.3.1
|
||||
@@ -22900,10 +22896,10 @@ snapshots:
|
||||
dependencies:
|
||||
payload: 3.33.0(graphql@16.10.0)(typescript@5.7.3)
|
||||
|
||||
'@payloadcms/plugin-seo@3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)':
|
||||
'@payloadcms/plugin-seo@3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)':
|
||||
dependencies:
|
||||
'@payloadcms/translations': 3.33.0
|
||||
'@payloadcms/ui': 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
|
||||
'@payloadcms/ui': 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
|
||||
payload: 3.33.0(graphql@16.10.0)(typescript@5.7.3)
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
@@ -22914,7 +22910,7 @@ snapshots:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
'@payloadcms/richtext-lexical@3.33.0(@faceless-ui/modal@3.0.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@faceless-ui/scroll-info@2.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@payloadcms/next@3.33.0(@types/react@18.3.3)(graphql@16.10.0)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3))(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)(yjs@13.6.27)':
|
||||
'@payloadcms/richtext-lexical@3.33.0(@faceless-ui/modal@3.0.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@faceless-ui/scroll-info@2.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@payloadcms/next@3.33.0(@types/react@18.3.3)(graphql@16.10.0)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3))(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)(yjs@13.6.27)':
|
||||
dependencies:
|
||||
'@faceless-ui/modal': 3.0.0-beta.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@faceless-ui/scroll-info': 2.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
@@ -22928,9 +22924,9 @@ snapshots:
|
||||
'@lexical/selection': 0.28.0
|
||||
'@lexical/table': 0.28.0
|
||||
'@lexical/utils': 0.28.0
|
||||
'@payloadcms/next': 3.33.0(@types/react@18.3.3)(graphql@16.10.0)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
|
||||
'@payloadcms/next': 3.33.0(@types/react@18.3.3)(graphql@16.10.0)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
|
||||
'@payloadcms/translations': 3.33.0
|
||||
'@payloadcms/ui': 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
|
||||
'@payloadcms/ui': 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
|
||||
'@types/uuid': 10.0.0
|
||||
acorn: 8.12.1
|
||||
bson-objectid: 2.0.4
|
||||
@@ -22956,12 +22952,12 @@ snapshots:
|
||||
- typescript
|
||||
- yjs
|
||||
|
||||
'@payloadcms/storage-s3@3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)':
|
||||
'@payloadcms/storage-s3@3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)':
|
||||
dependencies:
|
||||
'@aws-sdk/client-s3': 3.821.0
|
||||
'@aws-sdk/lib-storage': 3.821.0(@aws-sdk/client-s3@3.821.0)
|
||||
'@aws-sdk/s3-request-presigner': 3.821.0
|
||||
'@payloadcms/plugin-cloud-storage': 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
|
||||
'@payloadcms/plugin-cloud-storage': 3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)
|
||||
payload: 3.33.0(graphql@16.10.0)(typescript@5.7.3)
|
||||
transitivePeerDependencies:
|
||||
- '@types/react'
|
||||
@@ -22977,7 +22973,7 @@ snapshots:
|
||||
dependencies:
|
||||
date-fns: 4.1.0
|
||||
|
||||
'@payloadcms/ui@3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)':
|
||||
'@payloadcms/ui@3.33.0(@types/react@18.3.3)(monaco-editor@0.52.2)(next@15.3.1(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(payload@3.33.0(graphql@16.10.0)(typescript@5.7.3))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1)(typescript@5.7.3)':
|
||||
dependencies:
|
||||
'@date-fns/tz': 1.2.0
|
||||
'@dnd-kit/core': 6.0.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
@@ -22991,7 +22987,7 @@ snapshots:
|
||||
date-fns: 4.1.0
|
||||
dequal: 2.0.3
|
||||
md5: 2.3.0
|
||||
next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
object-to-formdata: 4.5.1
|
||||
payload: 3.33.0(graphql@16.10.0)(typescript@5.7.3)
|
||||
qs-esm: 7.0.2
|
||||
@@ -23016,9 +23012,9 @@ snapshots:
|
||||
'@pkgjs/parseargs@0.11.0':
|
||||
optional: true
|
||||
|
||||
'@playwright/test@1.49.1':
|
||||
'@playwright/test@1.52.0':
|
||||
dependencies:
|
||||
playwright: 1.49.1
|
||||
playwright: 1.52.0
|
||||
|
||||
'@polka/url@1.0.0-next.25': {}
|
||||
|
||||
@@ -23727,7 +23723,7 @@ snapshots:
|
||||
|
||||
'@radix-ui/react-popper@1.2.4(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@floating-ui/react-dom': 2.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@floating-ui/react-dom': 2.0.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@radix-ui/react-arrow': 1.1.4(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@radix-ui/react-compose-refs': 1.1.2(@types/react@18.3.3)(react@18.3.1)
|
||||
'@radix-ui/react-context': 1.1.2(@types/react@18.3.3)(react@18.3.1)
|
||||
@@ -24561,7 +24557,7 @@ snapshots:
|
||||
chokidar: 3.6.0
|
||||
colorette: 1.4.0
|
||||
core-js: 3.35.0
|
||||
dotenv: 16.4.7
|
||||
dotenv: 16.5.0
|
||||
form-data: 4.0.2
|
||||
get-port-please: 3.1.2
|
||||
glob: 7.2.3
|
||||
@@ -24943,7 +24939,7 @@ snapshots:
|
||||
'@babel/core': 7.26.10(supports-color@8.1.1)
|
||||
'@sentry/babel-plugin-component-annotate': 2.22.7
|
||||
'@sentry/cli': 2.39.1(encoding@0.1.13)(supports-color@8.1.1)
|
||||
dotenv: 16.4.7
|
||||
dotenv: 16.5.0
|
||||
find-up: 5.0.0
|
||||
glob: 9.3.5
|
||||
magic-string: 0.30.8
|
||||
@@ -25050,7 +25046,7 @@ snapshots:
|
||||
|
||||
'@sentry/core@9.15.0': {}
|
||||
|
||||
'@sentry/nextjs@8.52.1(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.56.0(@opentelemetry/api@1.9.0)(supports-color@8.1.1))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)(supports-color@8.1.1)(webpack@5.94.0)':
|
||||
'@sentry/nextjs@8.52.1(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.56.0(@opentelemetry/api@1.9.0)(supports-color@8.1.1))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)(supports-color@8.1.1)(webpack@5.94.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/semantic-conventions': 1.28.0
|
||||
@@ -25063,7 +25059,7 @@ snapshots:
|
||||
'@sentry/vercel-edge': 8.52.1
|
||||
'@sentry/webpack-plugin': 2.22.7(encoding@0.1.13)(supports-color@8.1.1)(webpack@5.94.0)
|
||||
chalk: 3.0.0
|
||||
next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
resolve: 1.22.8
|
||||
rollup: 3.29.5
|
||||
stacktrace-parser: 0.1.10
|
||||
@@ -25076,7 +25072,7 @@ snapshots:
|
||||
- supports-color
|
||||
- webpack
|
||||
|
||||
'@sentry/nextjs@9.15.0(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0)(supports-color@8.1.1))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)(supports-color@8.1.1)(webpack@5.94.0)':
|
||||
'@sentry/nextjs@9.15.0(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0)(supports-color@8.1.1))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1)(supports-color@8.1.1)(webpack@5.94.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@opentelemetry/semantic-conventions': 1.32.0
|
||||
@@ -25089,7 +25085,7 @@ snapshots:
|
||||
'@sentry/vercel-edge': 9.15.0
|
||||
'@sentry/webpack-plugin': 3.3.1(encoding@0.1.13)(supports-color@8.1.1)(webpack@5.94.0)
|
||||
chalk: 3.0.0
|
||||
next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
resolve: 1.22.8
|
||||
rollup: 4.35.0
|
||||
stacktrace-parser: 0.1.10
|
||||
@@ -26425,7 +26421,7 @@ snapshots:
|
||||
'@tanstack/store': 0.7.0
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
use-sync-external-store: 1.4.0(react@18.3.1)
|
||||
use-sync-external-store: 1.5.0(react@18.3.1)
|
||||
|
||||
'@tanstack/react-virtual@3.13.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
@@ -27298,19 +27294,19 @@ snapshots:
|
||||
lz-string: 1.5.0
|
||||
uuid: 9.0.1
|
||||
|
||||
'@vercel/flags@2.6.0(next@14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
'@vercel/flags@2.6.0(next@14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
jose: 5.2.1
|
||||
optionalDependencies:
|
||||
next: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
next: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
|
||||
'@vercel/flags@2.6.0(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
'@vercel/flags@2.6.0(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
jose: 5.2.1
|
||||
optionalDependencies:
|
||||
next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
|
||||
@@ -27785,9 +27781,9 @@ snapshots:
|
||||
optionalDependencies:
|
||||
ajv: 8.17.1
|
||||
|
||||
ajv-formats@3.0.1(ajv@8.17.1):
|
||||
ajv-formats@3.0.1(ajv@8.12.0):
|
||||
optionalDependencies:
|
||||
ajv: 8.17.1
|
||||
ajv: 8.12.0
|
||||
|
||||
ajv-keywords@3.5.2(ajv@6.12.6):
|
||||
dependencies:
|
||||
@@ -27828,7 +27824,7 @@ snapshots:
|
||||
js-cookie: 2.2.1
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
|
||||
|
||||
animejs@4.0.2: {}
|
||||
|
||||
anser@2.3.2: {}
|
||||
@@ -28254,7 +28250,7 @@ snapshots:
|
||||
chokidar: 4.0.3
|
||||
confbox: 0.1.8
|
||||
defu: 6.1.4
|
||||
dotenv: 16.4.7
|
||||
dotenv: 16.5.0
|
||||
exsolve: 1.0.4
|
||||
giget: 2.0.0
|
||||
jiti: 2.4.2
|
||||
@@ -29290,6 +29286,8 @@ snapshots:
|
||||
|
||||
dotenv@16.4.7: {}
|
||||
|
||||
dotenv@16.5.0: {}
|
||||
|
||||
dotty@0.1.2: {}
|
||||
|
||||
drange@1.1.1: {}
|
||||
@@ -30147,8 +30145,8 @@ snapshots:
|
||||
fast-json-stringify@5.16.1:
|
||||
dependencies:
|
||||
'@fastify/merge-json-schemas': 0.1.1
|
||||
ajv: 8.17.1
|
||||
ajv-formats: 3.0.1(ajv@8.17.1)
|
||||
ajv: 8.12.0
|
||||
ajv-formats: 3.0.1(ajv@8.12.0)
|
||||
fast-deep-equal: 3.1.3
|
||||
fast-uri: 2.4.0
|
||||
json-schema-ref-resolver: 1.0.1
|
||||
@@ -33645,12 +33643,12 @@ snapshots:
|
||||
|
||||
neo-async@2.6.2: {}
|
||||
|
||||
next-contentlayer2@0.4.6(contentlayer2@0.4.6(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1))(esbuild@0.25.2)(markdown-wasm@1.2.0)(next@14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1):
|
||||
next-contentlayer2@0.4.6(contentlayer2@0.4.6(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1))(esbuild@0.25.2)(markdown-wasm@1.2.0)(next@14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1):
|
||||
dependencies:
|
||||
'@contentlayer2/core': 0.4.3(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1)
|
||||
'@contentlayer2/utils': 0.4.3
|
||||
contentlayer2: 0.4.6(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1)
|
||||
next: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
next: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
transitivePeerDependencies:
|
||||
@@ -33659,12 +33657,12 @@ snapshots:
|
||||
- markdown-wasm
|
||||
- supports-color
|
||||
|
||||
next-contentlayer2@0.5.3(contentlayer2@0.5.3(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1))(esbuild@0.25.2)(markdown-wasm@1.2.0)(next@14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1):
|
||||
next-contentlayer2@0.5.3(contentlayer2@0.5.3(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1))(esbuild@0.25.2)(markdown-wasm@1.2.0)(next@14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(supports-color@8.1.1):
|
||||
dependencies:
|
||||
'@contentlayer2/core': 0.5.3(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1)
|
||||
'@contentlayer2/utils': 0.5.3
|
||||
contentlayer2: 0.5.3(esbuild@0.25.2)(markdown-wasm@1.2.0)(supports-color@8.1.1)
|
||||
next: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
next: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
transitivePeerDependencies:
|
||||
@@ -33688,14 +33686,14 @@ snapshots:
|
||||
dependencies:
|
||||
js-yaml-loader: 1.2.2
|
||||
|
||||
next-router-mock@0.9.13(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1):
|
||||
next-router-mock@0.9.13(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1):
|
||||
dependencies:
|
||||
next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
react: 18.3.1
|
||||
|
||||
next-seo@6.5.0(next@14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
|
||||
next-seo@6.5.0(next@14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
|
||||
dependencies:
|
||||
next: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
next: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
|
||||
@@ -33706,7 +33704,7 @@ snapshots:
|
||||
|
||||
next-tick@1.1.0: {}
|
||||
|
||||
next@14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4):
|
||||
next@14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4):
|
||||
dependencies:
|
||||
'@next/env': 14.2.26
|
||||
'@swc/helpers': 0.5.5
|
||||
@@ -33728,13 +33726,13 @@ snapshots:
|
||||
'@next/swc-win32-ia32-msvc': 14.2.26
|
||||
'@next/swc-win32-x64-msvc': 14.2.26
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@playwright/test': 1.49.1
|
||||
'@playwright/test': 1.52.0
|
||||
sass: 1.77.4
|
||||
transitivePeerDependencies:
|
||||
- '@babel/core'
|
||||
- babel-plugin-macros
|
||||
|
||||
next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4):
|
||||
next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4):
|
||||
dependencies:
|
||||
'@next/env': 15.3.1
|
||||
'@swc/counter': 0.1.3
|
||||
@@ -33755,7 +33753,7 @@ snapshots:
|
||||
'@next/swc-win32-arm64-msvc': 15.3.1
|
||||
'@next/swc-win32-x64-msvc': 15.3.1
|
||||
'@opentelemetry/api': 1.9.0
|
||||
'@playwright/test': 1.49.1
|
||||
'@playwright/test': 1.52.0
|
||||
sass: 1.77.4
|
||||
sharp: 0.34.1
|
||||
transitivePeerDependencies:
|
||||
@@ -34053,17 +34051,17 @@ snapshots:
|
||||
|
||||
number-flow@0.3.7: {}
|
||||
|
||||
nuqs@1.19.1(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)):
|
||||
nuqs@1.19.1(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)):
|
||||
dependencies:
|
||||
mitt: 3.0.1
|
||||
next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
|
||||
nuqs@2.4.1(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-router@7.5.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1):
|
||||
nuqs@2.4.1(next@15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react-router@7.5.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1):
|
||||
dependencies:
|
||||
mitt: 3.0.1
|
||||
react: 18.3.1
|
||||
optionalDependencies:
|
||||
next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
next: 15.3.1(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4)
|
||||
react-router: 7.5.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
|
||||
nwsapi@2.2.20:
|
||||
@@ -34514,7 +34512,7 @@ snapshots:
|
||||
|
||||
periscopic@3.1.0:
|
||||
dependencies:
|
||||
'@types/estree': 1.0.5
|
||||
'@types/estree': 1.0.7
|
||||
estree-walker: 3.0.3
|
||||
is-reference: 3.0.3
|
||||
|
||||
@@ -34712,11 +34710,11 @@ snapshots:
|
||||
exsolve: 1.0.4
|
||||
pathe: 2.0.3
|
||||
|
||||
playwright-core@1.49.1: {}
|
||||
playwright-core@1.52.0: {}
|
||||
|
||||
playwright@1.49.1:
|
||||
playwright@1.52.0:
|
||||
dependencies:
|
||||
playwright-core: 1.49.1
|
||||
playwright-core: 1.52.0
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.2
|
||||
|
||||
@@ -36628,7 +36626,7 @@ snapshots:
|
||||
static-browser-server@1.0.3:
|
||||
dependencies:
|
||||
'@open-draft/deferred-promise': 2.2.0
|
||||
dotenv: 16.4.7
|
||||
dotenv: 16.5.0
|
||||
mime-db: 1.53.0
|
||||
outvariant: 1.4.3
|
||||
|
||||
@@ -36935,7 +36933,7 @@ snapshots:
|
||||
dependencies:
|
||||
client-only: 0.0.1
|
||||
react: 18.3.1
|
||||
use-sync-external-store: 1.4.0(react@18.3.1)
|
||||
use-sync-external-store: 1.5.0(react@18.3.1)
|
||||
|
||||
swrev@4.0.0: {}
|
||||
|
||||
@@ -37874,10 +37872,6 @@ snapshots:
|
||||
dependencies:
|
||||
react: 18.3.1
|
||||
|
||||
use-sync-external-store@1.4.0(react@18.3.1):
|
||||
dependencies:
|
||||
react: 18.3.1
|
||||
|
||||
use-sync-external-store@1.5.0(react@18.3.1):
|
||||
dependencies:
|
||||
react: 18.3.1
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
packages:
|
||||
- 'apps/*'
|
||||
- 'packages/*'
|
||||
- 'tests/*'
|
||||
- 'e2e/*'
|
||||
|
||||
catalog:
|
||||
'@types/node': ^20.0.0
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
EMAIL=
|
||||
PASSWORD=
|
||||
PROJECT_REF=
|
||||
@@ -1,48 +0,0 @@
|
||||
# Studio E2E Tests
|
||||
|
||||
In an effort to make the local + hosted studio more stable, we've added tests which test features which are commonly used in local
|
||||
development. Built with [Playwright](https://playwright.dev/docs/intro).
|
||||
|
||||
## How to run tests
|
||||
|
||||
Before running the tests, make sure you've done the following:
|
||||
|
||||
- Run `npm install` in the root folder of this repo
|
||||
- `docker` or `orbstack` is currently running
|
||||
- `supabase` CLI is already [installed](https://github.com/supabase/cli?tab=readme-ov-file#install-the-cli)
|
||||
- no other supabase local environment is running (infrastructure environment is ok)
|
||||
|
||||
You can run the tests by running `npm run test` in this folder.
|
||||
|
||||
When you run the command, it includes:
|
||||
|
||||
1. Setting up the local environment using the `supabase` CLI
|
||||
2. Extracting the environment variables and saving them into a `.env.test` file in the studio app
|
||||
3. Running the `studio` app in dev mode (`npm run dev`)
|
||||
4. Running the tests
|
||||
5. Stopping the `studio` app and the local environment
|
||||
|
||||
If the environment does't stop for some reason, you'll see `supabase start is already running` on the next run. In this
|
||||
case, just run `supabase stop` between test runs.
|
||||
|
||||
## How to write tests
|
||||
|
||||
Playwright has a nice [Codegen tool](https://playwright.dev/docs/codegen-intro#running-codegen) which you can use to
|
||||
record your actions:
|
||||
|
||||
```bash
|
||||
pnpm codegen:setup
|
||||
# in a separate terminal
|
||||
pnpm codegen
|
||||
```
|
||||
|
||||
## How to debug/fix tests
|
||||
|
||||
If you've run the tests locally and you want to see the results, Playwright has a [UI mode](https://playwright.dev/docs/test-ui-mode)
|
||||
which you can use to run and replay specific tests:
|
||||
|
||||
```bash
|
||||
pnpm test -- --ui
|
||||
```
|
||||
|
||||
It will also record any failing tests when running `npm run test` in this folder.
|
||||
@@ -1,25 +0,0 @@
|
||||
import { test as base } from '@playwright/test'
|
||||
import dotenv from 'dotenv'
|
||||
import path from 'path'
|
||||
|
||||
dotenv.config({
|
||||
path: path.resolve(__dirname, process.env.ENV === 'staging' ? '../.env.staging' : ''),
|
||||
override: true,
|
||||
})
|
||||
|
||||
export interface TestOptions {
|
||||
env: string
|
||||
ref: string
|
||||
apiUrl: string
|
||||
}
|
||||
|
||||
export const test = base.extend<TestOptions>({
|
||||
env: process.env.ENV,
|
||||
ref: process.env.PROJECT_REF,
|
||||
apiUrl:
|
||||
process.env.ENV === 'local'
|
||||
? 'http://localhost:8082/api'
|
||||
: process.env.ENV === 'staging'
|
||||
? 'https://api.supabase.green'
|
||||
: '',
|
||||
})
|
||||
@@ -1,37 +0,0 @@
|
||||
const fs = require('fs')
|
||||
const generatedEnv = require('./keys.json')
|
||||
|
||||
/**
|
||||
* This script takes the API keys from the local environment, merges them with some predefined variables and saves them
|
||||
* to a env.test file in the studio app. This is needed to prepare the studio so that it can be run with the local
|
||||
* environment as the backend.
|
||||
*/
|
||||
|
||||
const defaultEnv = {
|
||||
// POSTGRES_PASSWORD: 'postgres',
|
||||
// NEXT_ANALYTICS_BACKEND_PROVIDER: 'postgres',
|
||||
// SUPABASE_REST_URL: 'http://127.0.0.1:54321/rest/v1/',
|
||||
// NEXT_PUBLIC_ENABLE_LOGS: 'false',
|
||||
// NEXT_PUBLIC_IS_PLATFORM: 'false',
|
||||
SUPABASE_ANON_KEY: '$ANON_KEY',
|
||||
SUPABASE_SERVICE_KEY: '$SERVICE_ROLE_KEY',
|
||||
SUPABASE_URL: '$API_URL',
|
||||
STUDIO_PG_META_URL: '$API_URL/pg',
|
||||
SUPABASE_PUBLIC_URL: '$API_URL',
|
||||
SENTRY_IGNORE_API_RESOLUTION_ERROR: '1',
|
||||
LOGFLARE_URL: 'http://localhost:54329',
|
||||
LOGFLARE_API_KEY: 'api-key',
|
||||
NEXT_PUBLIC_SITE_URL: 'http://localhost:8082',
|
||||
NEXT_PUBLIC_GOTRUE_URL: '$SUPABASE_PUBLIC_URL/auth/v1',
|
||||
NEXT_PUBLIC_HCAPTCHA_SITE_KEY: '10000000-ffff-ffff-ffff-000000000001',
|
||||
NEXT_PUBLIC_NODE_ENV: 'test',
|
||||
}
|
||||
|
||||
const environment = { ...generatedEnv, ...defaultEnv }
|
||||
|
||||
fs.writeFileSync(
|
||||
'../../apps/studio/.env.test',
|
||||
Object.keys(environment)
|
||||
.map((key) => `${key}=${environment[key]}`)
|
||||
.join('\n')
|
||||
)
|
||||
@@ -1,25 +0,0 @@
|
||||
{
|
||||
"name": "studio-tests",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
"env:setup": "supabase start -x studio && supabase status --output json > keys.json && node generate-local-env.js",
|
||||
"pretest:local": "pnpm env:setup",
|
||||
"test:local": "pnpm env:setup && export ENV=local && export PROJECT_REF=default && playwright test",
|
||||
"posttest:local": "supabase stop --no-backup",
|
||||
"test:staging": "export ENV=staging && playwright test",
|
||||
"codegen:setup": "pnpm env:setup && NODE_ENV=test pnpm --prefix ../../apps/studio dev",
|
||||
"codegen": "playwright codegen http://localhost:8082/project/default",
|
||||
"clean": "rimraf node_modules"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.49.0",
|
||||
"lodash": "^4.17.21",
|
||||
"dotenv": "^16.4.7"
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
import { defineConfig, devices } from '@playwright/test'
|
||||
|
||||
// See https://playwright.dev/docs/test-configuration.
|
||||
|
||||
export default defineConfig({
|
||||
fullyParallel: true,
|
||||
forbidOnly: !!process.env.CI,
|
||||
retries: process.env.CI ? 2 : 0,
|
||||
workers: process.env.CI ? 1 : undefined,
|
||||
timeout: 20000,
|
||||
reporter: 'html',
|
||||
use: {
|
||||
baseURL:
|
||||
process.env.ENV === 'local'
|
||||
? 'http://localhost:8082'
|
||||
: process.env.ENV === 'staging'
|
||||
? 'https://supabase.green/dashboard/'
|
||||
: '',
|
||||
trace: 'on-first-retry',
|
||||
video: 'retain-on-failure',
|
||||
launchOptions: {
|
||||
env: {
|
||||
NODE_ENV:
|
||||
process.env.ENV === 'local' ? 'test' : process.env.ENV === 'staging' ? 'staging' : '',
|
||||
},
|
||||
},
|
||||
},
|
||||
projects: [
|
||||
...(process.env.ENV !== 'local'
|
||||
? [
|
||||
{
|
||||
name: 'Authentication setup',
|
||||
testDir: './tests',
|
||||
testMatch: /.*\.setup\.ts/,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
{
|
||||
name: 'Common Functionality',
|
||||
use: {
|
||||
...devices['Desktop Chrome'],
|
||||
...(process.env.ENV !== 'local' ? { storageState: 'playwright/.auth/user.json' } : {}),
|
||||
viewport: { width: 1366, height: 768 },
|
||||
},
|
||||
testDir: './tests/common-functionality',
|
||||
dependencies: process.env.ENV !== 'local' ? ['Authentication setup'] : undefined,
|
||||
},
|
||||
...(process.env.ENV !== 'local'
|
||||
? [
|
||||
{
|
||||
name: 'Production Functionality',
|
||||
use: {
|
||||
...devices['Desktop Chrome'],
|
||||
storageState: 'playwright/.auth/user.json',
|
||||
viewport: { width: 1366, height: 768 },
|
||||
},
|
||||
testDir: './tests/production-functionality',
|
||||
dependencies: ['Authentication setup'],
|
||||
},
|
||||
]
|
||||
: []),
|
||||
],
|
||||
/* Run your local dev server before starting the tests */
|
||||
webServer:
|
||||
process.env.ENV === 'local'
|
||||
? {
|
||||
// using npm run dev instead of turbo because turbo doesn't stop the server after a test (doesn't handle SIGTERM).
|
||||
command: 'pnpm dev',
|
||||
cwd: '../../apps/studio',
|
||||
url: 'http://localhost:8082',
|
||||
reuseExistingServer: !process.env.CI,
|
||||
env: { NODE_ENV: 'test' },
|
||||
}
|
||||
: undefined,
|
||||
})
|
||||
4
tests/studio-tests/supabase/.gitignore
vendored
4
tests/studio-tests/supabase/.gitignore
vendored
@@ -1,4 +0,0 @@
|
||||
# Supabase
|
||||
.branches
|
||||
.temp
|
||||
.env
|
||||
@@ -1,159 +0,0 @@
|
||||
# A string used to distinguish different Supabase projects on the same host. Defaults to the
|
||||
# working directory name when running `supabase init`.
|
||||
project_id = "local-studio-tests"
|
||||
|
||||
[api]
|
||||
enabled = true
|
||||
# Port to use for the API URL.
|
||||
port = 54321
|
||||
# Schemas to expose in your API. Tables, views and stored procedures in this schema will get API
|
||||
# endpoints. public and storage are always included.
|
||||
schemas = ["public", "storage", "graphql_public"]
|
||||
# Extra schemas to add to the search_path of every request. public is always included.
|
||||
extra_search_path = ["public", "extensions"]
|
||||
# The maximum number of rows returns from a view, table, or stored procedure. Limits payload size
|
||||
# for accidental or malicious requests.
|
||||
max_rows = 1000
|
||||
|
||||
[db]
|
||||
# Port to use for the local database URL.
|
||||
port = 54322
|
||||
# Port used by db diff command to initialize the shadow database.
|
||||
shadow_port = 54320
|
||||
# The database major version to use. This has to be the same as your remote database's. Run `SHOW
|
||||
# server_version;` on the remote database to check.
|
||||
major_version = 15
|
||||
|
||||
[db.pooler]
|
||||
enabled = false
|
||||
# Port to use for the local connection pooler.
|
||||
port = 54329
|
||||
# Specifies when a server connection can be reused by other clients.
|
||||
# Configure one of the supported pooler modes: `transaction`, `session`.
|
||||
pool_mode = "transaction"
|
||||
# How many server connections to allow per user/database pair.
|
||||
default_pool_size = 20
|
||||
# Maximum number of client connections allowed.
|
||||
max_client_conn = 100
|
||||
|
||||
[realtime]
|
||||
enabled = true
|
||||
# Bind realtime via either IPv4 or IPv6. (default: IPv6)
|
||||
# ip_version = "IPv6"
|
||||
# The maximum length in bytes of HTTP request headers. (default: 4096)
|
||||
# max_header_length = 4096
|
||||
|
||||
[studio]
|
||||
enabled = true
|
||||
# Port to use for Supabase Studio.
|
||||
port = 54323
|
||||
# External URL of the API server that frontend connects to.
|
||||
api_url = "http://127.0.0.1"
|
||||
|
||||
# Email testing server. Emails sent with the local dev setup are not actually sent - rather, they
|
||||
# are monitored, and you can view the emails that would have been sent from the web interface.
|
||||
[inbucket]
|
||||
enabled = true
|
||||
# Port to use for the email testing server web interface.
|
||||
port = 54324
|
||||
# Uncomment to expose additional ports for testing user applications that send emails.
|
||||
# smtp_port = 54325
|
||||
# pop3_port = 54326
|
||||
|
||||
[storage]
|
||||
enabled = true
|
||||
# The maximum file size allowed (e.g. "5MB", "500KB").
|
||||
file_size_limit = "50MiB"
|
||||
|
||||
[auth]
|
||||
enabled = true
|
||||
# The base URL of your website. Used as an allow-list for redirects and for constructing URLs used
|
||||
# in emails.
|
||||
site_url = "http://127.0.0.1:3000"
|
||||
# A list of *exact* URLs that auth providers are permitted to redirect to post authentication.
|
||||
additional_redirect_urls = ["https://127.0.0.1:3000"]
|
||||
# How long tokens are valid for, in seconds. Defaults to 3600 (1 hour), maximum 604,800 (1 week).
|
||||
jwt_expiry = 3600
|
||||
# If disabled, the refresh token will never expire.
|
||||
enable_refresh_token_rotation = true
|
||||
# Allows refresh tokens to be reused after expiry, up to the specified interval in seconds.
|
||||
# Requires enable_refresh_token_rotation = true.
|
||||
refresh_token_reuse_interval = 10
|
||||
# Allow/disallow new user signups to your project.
|
||||
enable_signup = true
|
||||
# Allow/disallow testing manual linking of accounts
|
||||
# enable_manual_linking = false
|
||||
|
||||
[auth.email]
|
||||
# Allow/disallow new user signups via email to your project.
|
||||
enable_signup = true
|
||||
# If enabled, a user will be required to confirm any email change on both the old, and new email
|
||||
# addresses. If disabled, only the new email is required to confirm.
|
||||
double_confirm_changes = true
|
||||
# If enabled, users need to confirm their email address before signing in.
|
||||
enable_confirmations = false
|
||||
|
||||
# Uncomment to customize email template
|
||||
# [auth.email.template.invite]
|
||||
# subject = "You have been invited"
|
||||
# content_path = "./supabase/templates/invite.html"
|
||||
|
||||
[auth.sms]
|
||||
# Allow/disallow new user signups via SMS to your project.
|
||||
enable_signup = true
|
||||
# If enabled, users need to confirm their phone number before signing in.
|
||||
enable_confirmations = false
|
||||
# Template for sending OTP to users
|
||||
# template = "Your code is {{ .Code }} ."
|
||||
|
||||
# Use pre-defined map of phone number to OTP for testing.
|
||||
[auth.sms.test_otp]
|
||||
# 4152127777 = "123456"
|
||||
|
||||
# This hook runs before a token is issued and allows you to add additional claims based on the authentication method used.
|
||||
# [auth.hook.custom_access_token]
|
||||
# enabled = true
|
||||
# uri = "pg-functions://<database>/<schema>/<hook_name>"
|
||||
|
||||
|
||||
# Configure one of the supported SMS providers: `twilio`, `twilio_verify`, `messagebird`, `textlocal`, `vonage`.
|
||||
[auth.sms.twilio]
|
||||
enabled = false
|
||||
account_sid = ""
|
||||
message_service_sid = ""
|
||||
# DO NOT commit your Twilio auth token to git. Use environment variable substitution instead:
|
||||
auth_token = "env(SUPABASE_AUTH_SMS_TWILIO_AUTH_TOKEN)"
|
||||
|
||||
# Use an external OAuth provider. The full list of providers are: `apple`, `azure`, `bitbucket`,
|
||||
# `discord`, `facebook`, `github`, `gitlab`, `google`, `keycloak`, `linkedin_oidc`, `notion`, `twitch`,
|
||||
# `twitter`, `slack`, `spotify`, `workos`, `zoom`.
|
||||
[auth.external.apple]
|
||||
enabled = false
|
||||
client_id = ""
|
||||
# DO NOT commit your OAuth provider secret to git. Use environment variable substitution instead:
|
||||
secret = "env(SUPABASE_AUTH_EXTERNAL_APPLE_SECRET)"
|
||||
# Overrides the default auth redirectUrl.
|
||||
redirect_uri = ""
|
||||
# Overrides the default auth provider URL. Used to support self-hosted gitlab, single-tenant Azure,
|
||||
# or any other third-party OIDC providers.
|
||||
url = ""
|
||||
|
||||
[analytics]
|
||||
enabled = true
|
||||
port = 54329
|
||||
vector_port = 54328
|
||||
# Configure one of the supported backends: `postgres`, `bigquery`.
|
||||
backend = "postgres"
|
||||
|
||||
# Experimental features may be deprecated any time
|
||||
# [experimental]
|
||||
# Configures Postgres storage engine to use OrioleDB (S3)
|
||||
# orioledb_version = ""
|
||||
# Configures S3 bucket URL, eg. <bucket_name>.s3-<region>.amazonaws.com
|
||||
# s3_host = "env(S3_HOST)"
|
||||
# Configures S3 bucket region, eg. us-east-1
|
||||
# s3_region = "env(S3_REGION)"
|
||||
# Configures AWS_ACCESS_KEY_ID for S3 bucket
|
||||
# s3_access_key = "env(S3_ACCESS_KEY)"
|
||||
# Configures AWS_SECRET_ACCESS_KEY for S3 bucket
|
||||
# s3_secret_key = "env(S3_SECRET_KEY)"
|
||||
@@ -1,21 +0,0 @@
|
||||
import { test as setup } from '@playwright/test'
|
||||
import dotenv from 'dotenv'
|
||||
import path from 'path'
|
||||
|
||||
dotenv.config({
|
||||
path: path.resolve(__dirname, process.env.ENV === 'staging' ? '../.env.staging' : ''),
|
||||
override: true,
|
||||
})
|
||||
const authFile = path.join(__dirname, '../playwright/.auth/user.json')
|
||||
|
||||
setup('Authenticate', async ({ page }) => {
|
||||
await page.goto('./sign-in')
|
||||
await page.getByLabel('Email').fill(process.env.EMAIL ?? '')
|
||||
await page.getByLabel('Password').fill(process.env.PASSWORD ?? '')
|
||||
await page.getByRole('button', { name: 'Sign In' }).click()
|
||||
|
||||
await page.pause()
|
||||
|
||||
await page.waitForURL('./projects')
|
||||
await page.context().storageState({ path: authFile })
|
||||
})
|
||||
@@ -1,13 +0,0 @@
|
||||
import { expect } from '@playwright/test'
|
||||
import { test } from '../../base'
|
||||
|
||||
test.describe('Project', async () => {
|
||||
test('Can navigate to project home page', async ({ page, env, ref }) => {
|
||||
await page.goto(`./project/${ref}`)
|
||||
await expect(
|
||||
page.getByRole('heading', {
|
||||
name: env === 'local' ? 'Welcome to your project' : 'Playwright Test',
|
||||
})
|
||||
).toBeVisible({ timeout: 10000 })
|
||||
})
|
||||
})
|
||||
@@ -1,110 +0,0 @@
|
||||
import { expect } from '@playwright/test'
|
||||
import { test } from '../../base'
|
||||
|
||||
const LOGS_PAGES = [
|
||||
{ label: 'API Gateway', route: 'edge-logs' },
|
||||
{ label: 'Postgres', route: 'postgres-logs' },
|
||||
{ label: 'PostgREST', route: 'postgrest-logs' },
|
||||
]
|
||||
|
||||
test.describe('Logs', async () => {
|
||||
test.describe.configure({ retries: 5 })
|
||||
for (const logPage of LOGS_PAGES) {
|
||||
test.describe(`${logPage.label} logs page`, () => {
|
||||
test('can navigate to logs page', async ({ page, ref }) => {
|
||||
await page.goto(`./project/${ref}`)
|
||||
await page.locator('a', { hasText: 'Logs' }).click({ timeout: 10000 })
|
||||
await expect(page.getByRole('heading', { name: 'Logs & Analytics' })).toBeVisible()
|
||||
|
||||
// Click anywhere on the screen to close the sidebar
|
||||
await page.click('body')
|
||||
|
||||
await page
|
||||
.getByRole('link', { name: logPage.label, exact: true })
|
||||
.click()
|
||||
.catch((e) => {
|
||||
console.log('🔴 Error clicking', logPage, e)
|
||||
throw e
|
||||
})
|
||||
|
||||
// Wait for and verify the logs table is present
|
||||
const logsTable = page.getByRole('table')
|
||||
await expect(logsTable).toBeVisible({
|
||||
timeout: 20000,
|
||||
})
|
||||
})
|
||||
|
||||
test('shows logs data without errors', async ({ page, ref, apiUrl }) => {
|
||||
// Navigate to page first
|
||||
await page.goto(`./project/${ref}/logs/${logPage.route}`)
|
||||
|
||||
await page.waitForResponse((response) =>
|
||||
response
|
||||
.url()
|
||||
.includes(
|
||||
`${apiUrl}/platform/projects/${ref}/analytics/endpoints/logs.all?project=${ref}`
|
||||
)
|
||||
)
|
||||
|
||||
// Wait a bit and check for errors with a longer timeout
|
||||
const error = page.getByText('Error fetching logs')
|
||||
await expect(error).not.toBeVisible({ timeout: 10000 })
|
||||
|
||||
const emptyState = page.getByText('No results found')
|
||||
if (await emptyState.isVisible()) {
|
||||
// Empty state, no need to check further
|
||||
} else {
|
||||
// Check if the logs table has any rows
|
||||
const gridcells = page.getByRole('gridcell')
|
||||
await expect(gridcells.first()).toBeVisible({ timeout: 20000 })
|
||||
}
|
||||
})
|
||||
|
||||
test('can select and view log details', async ({ page, ref, apiUrl }) => {
|
||||
// Navigate to page first
|
||||
await page.goto(`./project/${ref}/logs/${logPage.route}`)
|
||||
|
||||
await page.waitForResponse((response) =>
|
||||
response
|
||||
.url()
|
||||
.includes(
|
||||
`${apiUrl}/platform/projects/${ref}/analytics/endpoints/logs.all?project=${ref}`
|
||||
)
|
||||
)
|
||||
|
||||
const emptyState = page.getByText('No results found')
|
||||
if (await emptyState.isVisible()) {
|
||||
// Empty state, no need to check further
|
||||
} else {
|
||||
// Check if the logs table has any rows
|
||||
const gridcells = page.getByRole('gridcell')
|
||||
|
||||
// Click first row and verify details
|
||||
await gridcells.first().click()
|
||||
const tabPanel = page.getByTestId('log-selection')
|
||||
await page.waitForResponse((response) =>
|
||||
response
|
||||
.url()
|
||||
.includes(
|
||||
`${apiUrl}/platform/projects/${ref}/analytics/endpoints/logs.all?project=${ref}`
|
||||
)
|
||||
)
|
||||
await expect(tabPanel).toBeVisible()
|
||||
|
||||
const selectionPanelTimestamp = tabPanel.getByTestId('log-selection-timestamp')
|
||||
await expect(selectionPanelTimestamp).toBeVisible()
|
||||
|
||||
const rawTimestamp = await selectionPanelTimestamp.textContent()
|
||||
const timestamp = rawTimestamp?.replace('timestamp', '')
|
||||
const rowText = await gridcells.first().textContent()
|
||||
expect(rowText).toContain(timestamp)
|
||||
|
||||
// Click second row and verify different content
|
||||
await gridcells.nth(1).click()
|
||||
const tabPanelText2 = await tabPanel.textContent()
|
||||
expect(tabPanelText2).not.toBe(rowText)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -1,168 +0,0 @@
|
||||
import { Page, expect } from '@playwright/test'
|
||||
import { kebabCase } from 'lodash'
|
||||
import { test } from '../../base'
|
||||
|
||||
const dismissToast = async (page: Page) => {
|
||||
await page
|
||||
.locator('li.toast')
|
||||
.getByRole('button', { name: 'Opt out' })
|
||||
.waitFor({ state: 'visible' })
|
||||
await page.locator('li.toast').getByRole('button', { name: 'Opt out' }).click()
|
||||
}
|
||||
|
||||
test.describe('Table Editor', () => {
|
||||
test.beforeEach(async ({ page, env, ref, apiUrl }) => {
|
||||
const tableResponsePromise = page.waitForResponse(
|
||||
`${apiUrl}/platform/pg-meta/${ref}/query?key=entity-types-public-0`,
|
||||
{ timeout: 0 }
|
||||
)
|
||||
await page.goto(`./project/${ref}/editor`)
|
||||
if (env !== 'local') await dismissToast(page)
|
||||
await tableResponsePromise
|
||||
})
|
||||
|
||||
test('should create a new table, view its definition, add new rows, sort and filter', async ({
|
||||
page,
|
||||
ref,
|
||||
apiUrl,
|
||||
}, testInfo) => {
|
||||
const tableName = `${kebabCase(testInfo.title).slice(0, 24)}-${testInfo.retry}-${Math.floor(Math.random() * 10000)}`
|
||||
|
||||
// The page has been loaded with the table data, we can now interact with the page
|
||||
await page.getByRole('button', { name: 'New table', exact: true }).click()
|
||||
|
||||
await page.getByTestId('table-name-input').waitFor({ state: 'visible' })
|
||||
await page.getByTestId('table-name-input').click()
|
||||
await page.getByTestId('table-name-input').fill(tableName)
|
||||
|
||||
// make the built-in created_at column nullable
|
||||
await page.getByTestId('created_at-extra-options').click()
|
||||
await page.getByText('Is Nullable').click()
|
||||
// the force option is needed because the button is obscured by the popover but we just want to close the popover.
|
||||
await page.getByTestId('created_at-extra-options').click({ force: true })
|
||||
|
||||
// add a new column and add default value
|
||||
await page.getByRole('button', { name: 'Add column' }).click()
|
||||
await page.getByRole('textbox', { name: 'column_name' }).click()
|
||||
await page.getByRole('textbox', { name: 'column_name' }).fill('defaultValueColumn')
|
||||
await page.locator('button').filter({ hasText: 'Choose a column type...' }).click()
|
||||
await page.getByText('Signed two-byte integer').click()
|
||||
await page.getByTestId('defaultValueColumn-default-value').click()
|
||||
await page.getByTestId('defaultValueColumn-default-value').fill('2')
|
||||
|
||||
await page.getByRole('button', { name: 'Save' }).waitFor({ state: 'visible' })
|
||||
await page.getByRole('button', { name: 'Save' }).click()
|
||||
|
||||
// hide React Query DevTools if present
|
||||
await page.evaluate(() => {
|
||||
const devtools = document.querySelector('.ReactQueryDevtools')
|
||||
if (devtools) {
|
||||
devtools.remove()
|
||||
}
|
||||
})
|
||||
|
||||
// view its definition
|
||||
await page.getByText('definition').click()
|
||||
await expect(page.locator('div.view-lines')).toContainText(
|
||||
`CREATE TABLE public.${tableName} ( id bigint GENERATED BY DEFAULT AS IDENTITY NOT NULL, created_at timestamp with time zone NULL DEFAULT now(), \"defaultValueColumn\" smallint NULL DEFAULT '2'::smallint, CONSTRAINT ${tableName}_pkey PRIMARY KEY (id)) TABLESPACE pg_default;`
|
||||
)
|
||||
|
||||
// add a new row
|
||||
await page.getByRole('button', { name: tableName }).click()
|
||||
await page.getByTestId('table-editor-insert-new-row').click()
|
||||
await page.getByText('Insert a new row into').click()
|
||||
await page.getByTestId('defaultValueColumn-input').click()
|
||||
await page.getByTestId('defaultValueColumn-input').fill('100')
|
||||
await page.getByTestId('action-bar-save-row').click()
|
||||
|
||||
// add a second row
|
||||
await page.getByRole('button', { name: tableName }).click()
|
||||
await page.getByTestId('table-editor-insert-new-row').click()
|
||||
await page.getByText('Insert a new row into').click()
|
||||
// the default value should be '100' for defaultValueColumn
|
||||
await page.getByTestId('action-bar-save-row').click()
|
||||
|
||||
// Wait for both rows to be visible in the grid
|
||||
await page.waitForResponse((response) =>
|
||||
response.url().includes(`${apiUrl}/platform/pg-meta/${ref}/query`)
|
||||
)
|
||||
await expect(page.getByRole('grid')).toContainText('2')
|
||||
await expect(page.getByRole('grid')).toContainText('100')
|
||||
|
||||
// Make sure we can see both rows in the grid before sorting
|
||||
const rows = page.getByRole('row')
|
||||
await expect(rows).toHaveCount(3) // header row + 2 data rows
|
||||
|
||||
// sort by the a column
|
||||
await page.getByRole('button', { name: 'Sort' }).click()
|
||||
await page.getByTestId('table-editor-pick-column-to-sort-button').click()
|
||||
await page.getByLabel('Pick a column to sort by').getByText('defaultValueColumn').click()
|
||||
await page.getByRole('button', { name: 'Apply sorting' }).click()
|
||||
|
||||
// Close the sorting dialog
|
||||
await page.keyboard.down('Escape')
|
||||
|
||||
// expect the row to be sorted by defaultValueColumn. They're inserted in the order 100, 2
|
||||
await expect(rows.nth(1)).toContainText('2')
|
||||
await expect(rows.nth(2)).toContainText('100')
|
||||
// remove the sorting
|
||||
await page.getByRole('button', { name: 'Sorted by 1 rule' }).click()
|
||||
await page.getByRole('dialog').getByRole('button').nth(1).click()
|
||||
|
||||
// filter by a column
|
||||
await page.getByRole('button', { name: 'Filter' }).click()
|
||||
await page.getByRole('button', { name: 'Add filter' }).click()
|
||||
await page.getByRole('button', { name: 'id' }).click()
|
||||
await page.getByLabel('id').getByText('defaultValueColumn').click()
|
||||
await page.getByPlaceholder('Enter a value').click()
|
||||
await page.getByPlaceholder('Enter a value').fill('2')
|
||||
await page.getByRole('button', { name: 'Apply filter' }).click()
|
||||
|
||||
// Close the filter dialog
|
||||
await page.keyboard.down('Escape')
|
||||
|
||||
await expect(page.getByRole('grid')).toContainText('2')
|
||||
await expect(page.getByRole('grid')).not.toContainText('100')
|
||||
|
||||
// Delete the table as clean up
|
||||
await page.getByLabel(`View ${tableName}`).click()
|
||||
await page.getByLabel(`View ${tableName}`).getByRole('button').nth(1).click()
|
||||
await page.getByText('Delete table').click()
|
||||
await page.getByRole('button', { name: 'Delete' }).click()
|
||||
await page.waitForResponse((response) =>
|
||||
response.url().includes(`${apiUrl}/platform/pg-meta/${ref}/tables`)
|
||||
)
|
||||
})
|
||||
|
||||
test('should check the auth schema', async ({ page }) => {
|
||||
await page.getByTestId('schema-selector').click()
|
||||
await page.getByRole('option', { name: 'auth' }).click()
|
||||
|
||||
// extract the tables names from the sidebar
|
||||
const tables = await page
|
||||
.getByTestId('tables-list')
|
||||
.innerText()
|
||||
.then((text) => text.split('\n'))
|
||||
|
||||
// expect the tables list to contain the following tables (additional tables may be present)
|
||||
expect(tables).toEqual(
|
||||
expect.arrayContaining([
|
||||
'audit_log_entries',
|
||||
'flow_state',
|
||||
'identities',
|
||||
'instances',
|
||||
'mfa_amr_claims',
|
||||
'mfa_challenges',
|
||||
'mfa_factors',
|
||||
'refresh_tokens',
|
||||
'saml_providers',
|
||||
'saml_relay_states',
|
||||
'schema_migrations',
|
||||
'sessions',
|
||||
'sso_domains',
|
||||
'sso_providers',
|
||||
'users',
|
||||
])
|
||||
)
|
||||
})
|
||||
})
|
||||
@@ -1,11 +0,0 @@
|
||||
import { expect } from '@playwright/test'
|
||||
import { test } from '../../base'
|
||||
|
||||
// [Joshen] This file is redundant, so once we start putting in production specific spec tests, can remove this
|
||||
|
||||
test.describe('Example', async () => {
|
||||
test('Can navigate to project home page', async ({ page, ref }) => {
|
||||
await page.goto(`./project/${ref}`)
|
||||
await expect(page.getByRole('heading', { name: 'Playwright Test' })).toBeVisible()
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user