Use relative paths in File editor and support existing entrypoint, import map settings (#34553)

* fix: add jsr:@std/path module

* fix: use relative paths for files in editor

* Smol fix

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
This commit is contained in:
Lakshan Perera
2025-03-31 18:23:12 +11:00
committed by GitHub
parent b9b748391d
commit a66278b811
8 changed files with 175 additions and 149 deletions

1
.npmrc
View File

@@ -1,2 +1,3 @@
engine-strict=true
update-notifier=false
@jsr:registry=https://npm.jsr.io

View File

@@ -64,7 +64,6 @@ const EdgeFunctionDetailsLayout = ({
})
const name = selectedFunction?.name || ''
const cliCommand = `supabase functions download ${functionSlug}`
const breadcrumbItems = [
{

View File

@@ -64,7 +64,7 @@ export const useEdgeFunctionDeployMutation = ({
async onSuccess(data, variables, context) {
const { projectRef, slug } = variables
await Promise.all([
queryClient.invalidateQueries(edgeFunctionsKeys.list(projectRef)),
queryClient.invalidateQueries(edgeFunctionsKeys.detail(projectRef, slug)),
queryClient.invalidateQueries(edgeFunctionsKeys.body(projectRef, slug)),
])
await onSuccess?.(data, variables, context)

View File

@@ -1,7 +1,7 @@
export const edgeFunctionsKeys = {
list: (projectRef: string | undefined) => ['projects', projectRef, 'edge-functions'] as const,
detail: (projectRef: string | undefined, slug: string | undefined) =>
['projects', projectRef, 'edge-function', slug] as const,
['projects', projectRef, 'edge-function', slug, 'detail'] as const,
body: (projectRef: string | undefined, slug: string | undefined) =>
['projects', projectRef, 'edge-function', slug, 'body'] as const,
}

View File

@@ -4,28 +4,7 @@ import path from 'path'
function url2path(url: string) {
try {
// Parse the URL
const parsedUrl = new URL(url)
// Get the pathname and split it
const pathParts = parsedUrl.pathname.split('/').filter(Boolean)
// For user function paths like "user_fn_ukekbxwcwofeosgskskm_66727868-6415-49d7-b518-2a057c8377cb_1/data.json"
// Just return the filename (data.json)
if (pathParts.length > 0) {
// Check if it's a user function path with UUID
if (pathParts[0].startsWith('user_fn_')) {
// Get just the filename (last part)
return pathParts[pathParts.length - 1]
}
// If it starts with 'tmp/' or similar, remove that prefix
if (pathParts[0] === 'tmp' || pathParts[0] === 'deno') {
// Get just the filename (last part)
return pathParts[pathParts.length - 1]
}
}
// Otherwise, return the full path without leading/trailing slashes
return pathParts.join('/')
return new URL(url).pathname
} catch (error) {
// If URL parsing fails, fallback to extracting just the filename
console.warn('Failed to parse URL:', url)

View File

@@ -40,6 +40,7 @@
"@next/bundle-analyzer": "^14.2.3",
"@number-flow/react": "^0.3.2",
"@sentry/nextjs": "^8.52.1",
"@std/path": "npm:@jsr/std__path@^1.0.8",
"@stripe/react-stripe-js": "^3.1.1",
"@stripe/stripe-js": "^5.5.0",
"@supabase/auth-js": "catalog:",

View File

@@ -1,3 +1,4 @@
import { common, dirname, relative } from '@std/path/posix'
import { AlertCircle, CornerDownLeft, Loader2 } from 'lucide-react'
import { useRouter } from 'next/router'
import { useEffect, useState } from 'react'
@@ -54,12 +55,33 @@ const CodePage = () => {
if (isDeploying || !ref || !functionSlug || !selectedFunction || files.length === 0) return
try {
const parsedEntrypointPath =
selectedFunction.entrypoint_path?.replace(/\/tmp\/user_fn_[^/]+\//, '') || 'index.ts'
const existingFile = files.find((file) => file.name === parsedEntrypointPath) ||
files.find((file) => file.name.endsWith('.ts') || file.name.endsWith('.js')) || {
name: 'index.ts',
const newEntrypointPath = selectedFunction.entrypoint_path?.split('/').pop()
const newImportMapPath = selectedFunction.import_map_path?.split('/').pop()
const fallbackEntrypointPath = () => {
// when there's no matching entrypoint path is set,
// we use few heuristics to find an entrypoint file
// 1. If the function has only a single TS / JS file, if so set it as entrypoint
const jsFiles = files.filter(({ name }) => name.endsWith('.js') || name.endsWith('.ts'))
if (jsFiles.length === 1) {
return jsFiles[0].name
} else if (jsFiles.length) {
// 2. If function has a `index` or `main` file use it as the entrypoint
const regex = /^.*?(index|main).*$/i
const matchingFile = jsFiles.find(({ name }) => regex.test(name))
// 3. if no valid index / main file found, we set the entrypoint expliclty to first JS file
return matchingFile ? matchingFile.name : jsFiles[0].name
} else {
// no potential entrypoint files found, this will most likely result in an error on deploy
return 'index.ts'
}
}
const fallbackImportMapPath = () => {
// try to find a deno.json or import_map.json file
const regex = /^.*?(deno|import_map).json*$/i
return files.find(({ name }) => regex.test(name))?.name
}
await deployFunction({
projectRef: ref,
@@ -67,8 +89,12 @@ const CodePage = () => {
metadata: {
name: selectedFunction.name,
verify_jwt: selectedFunction.verify_jwt,
entrypoint_path: existingFile.name,
import_map_path: selectedFunction.import_map_path,
entrypoint_path: files.some(({ name }) => name === newEntrypointPath)
? (newEntrypointPath as string)
: fallbackEntrypointPath(),
import_map_path: files.some(({ name }) => name === newImportMapPath)
? newImportMapPath
: fallbackImportMapPath(),
},
files: files.map(({ name, content }) => ({ name, content })),
})
@@ -79,42 +105,17 @@ const CodePage = () => {
}
}
const renderContent = () => {
if (isLoadingFiles) {
return (
<div className="flex flex-col items-center justify-center h-full bg-surface-200">
<LogoLoader />
</div>
)
function getBasePath(entrypoint: string | undefined): string {
if (!entrypoint) {
return '/'
}
if (isErrorLoadingFiles) {
return (
<div className="flex flex-col items-center justify-center h-full bg-surface-200">
<div className="flex flex-col items-center text-center gap-2 max-w-md">
<AlertCircle size={24} strokeWidth={1.5} className="text-amber-900" />
<h3 className="text-md mt-4">Failed to load function code</h3>
<p className="text-sm text-foreground-light">
{filesError?.message ||
'There was an error loading the function code. The format may be invalid or the function may be corrupted.'}
</p>
</div>
</div>
)
try {
return dirname(new URL(entrypoint).pathname)
} catch (e) {
console.error('failed to parse entrypoint', entrypoint)
return '/'
}
return (
<FileExplorerAndEditor
files={files}
onFilesChange={setFiles}
aiEndpoint={`${BASE_PATH}/api/ai/edge-function/complete`}
aiMetadata={{
projectRef: project?.ref,
connectionString: project?.connectionString,
includeSchemaMetadata,
}}
/>
)
}
// TODO (Saxon): Remove this once the flag is fully launched
@@ -126,49 +127,105 @@ const CodePage = () => {
useEffect(() => {
// Set files from API response when available
if (functionFiles) {
setFiles(
functionFiles.map((file, index: number) => ({
id: index + 1,
name: file.name,
content: file.content,
selected: index === 0,
}))
)
if (selectedFunction?.entrypoint_path && functionFiles) {
const base_path = getBasePath(selectedFunction?.entrypoint_path)
const filesWithRelPath = functionFiles
// ignore empty filesq
.filter((file: { name: string; content: string }) => !!file.content.length)
// set file paths relative to entrypoint
.map((file: { name: string; content: string }) => {
try {
// if the current file and base path doesn't share a common path,
// return unmodified file
const common_path = common([base_path, file.name])
if (common_path === '' || common_path === '/tmp/') {
return file
}
file.name = relative(base_path, file.name)
return file
} catch (e) {
console.error(e)
// return unmodified file
return file
}
})
setFiles((prev) => {
return filesWithRelPath.map((file: { name: string; content: string }, index: number) => {
const prevState = prev.find((x) => x.name === file.name)
return {
id: index + 1,
name: file.name,
content: file.content,
selected: prevState?.selected ?? index === 0,
}
})
})
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [functionFiles])
return (
<div className="flex flex-col h-full">
{renderContent()}
{!isErrorLoadingFiles && (
<div className="flex items-center bg-background-muted justify-end p-4 border-t bg-surface-100 shrink-0">
<Button
loading={isDeploying}
size="medium"
disabled={files.length === 0 || isLoadingFiles}
onClick={() => {
onUpdate()
sendEvent({
action: 'edge_function_deploy_updates_button_clicked',
groups: { project: ref ?? 'Unknown', organization: org?.slug ?? 'Unknown' },
})
}}
iconRight={
isDeploying ? (
<Loader2 className="animate-spin" size={10} strokeWidth={1.5} />
) : (
<div className="flex items-center space-x-1">
<CornerDownLeft size={10} strokeWidth={1.5} />
</div>
)
}
>
Deploy updates
</Button>
{isLoadingFiles && (
<div className="flex flex-col items-center justify-center h-full bg-surface-200">
<LogoLoader />
</div>
)}
{isErrorLoadingFiles && (
<div className="flex flex-col items-center justify-center h-full bg-surface-200">
<div className="flex flex-col items-center text-center gap-2 max-w-md">
<AlertCircle size={24} strokeWidth={1.5} className="text-amber-900" />
<h3 className="text-md mt-4">Failed to load function code</h3>
<p className="text-sm text-foreground-light">
{filesError?.message ||
'There was an error loading the function code. The format may be invalid or the function may be corrupted.'}
</p>
</div>
</div>
)}
{isSuccessLoadingFiles && (
<>
<FileExplorerAndEditor
files={files}
onFilesChange={setFiles}
aiEndpoint={`${BASE_PATH}/api/ai/edge-function/complete`}
aiMetadata={{
projectRef: project?.ref,
connectionString: project?.connectionString,
includeSchemaMetadata,
}}
/>
<div className="flex items-center bg-background-muted justify-end p-4 border-t bg-surface-100 shrink-0">
<Button
loading={isDeploying}
size="medium"
disabled={files.length === 0 || isLoadingFiles}
onClick={() => {
onUpdate()
sendEvent({
action: 'edge_function_deploy_updates_button_clicked',
groups: { project: ref ?? 'Unknown', organization: org?.slug ?? 'Unknown' },
})
}}
iconRight={
isDeploying ? (
<Loader2 className="animate-spin" size={10} strokeWidth={1.5} />
) : (
<div className="flex items-center space-x-1">
<CornerDownLeft size={10} strokeWidth={1.5} />
</div>
)
}
>
Deploy updates
</Button>
</div>
</>
)}
</div>
)
}

85
pnpm-lock.yaml generated
View File

@@ -88,10 +88,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)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.72.0)
version: 14.2.26(@babel/core@7.24.7(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.72.0)
next-contentlayer2:
specifier: 0.4.6
version: 0.4.6(contentlayer2@0.4.6(esbuild@0.25.1)(markdown-wasm@1.2.0)(supports-color@8.1.1))(esbuild@0.25.1)(markdown-wasm@1.2.0)(next@14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.72.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(supports-color@8.1.1)
version: 0.4.6(contentlayer2@0.4.6(esbuild@0.25.1)(markdown-wasm@1.2.0)(supports-color@8.1.1))(esbuild@0.25.1)(markdown-wasm@1.2.0)(next@14.2.26(@babel/core@7.24.7(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.72.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(supports-color@8.1.1)
next-themes:
specifier: ^0.3.0
version: 0.3.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
@@ -580,6 +580,9 @@ importers:
'@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@14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.72.0))(react@18.2.0)(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'
'@stripe/react-stripe-js':
specifier: ^3.1.1
version: 3.1.1(@stripe/stripe-js@5.5.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
@@ -1039,10 +1042,10 @@ importers:
version: 0.436.0(react@18.2.0)
next:
specifier: 'catalog:'
version: 14.2.26(@babel/core@7.24.7(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.72.0)
version: 14.2.26(@babel/core@7.26.10(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.72.0)
next-contentlayer2:
specifier: 0.4.6
version: 0.4.6(contentlayer2@0.4.6(esbuild@0.25.1)(markdown-wasm@1.2.0)(supports-color@8.1.1))(esbuild@0.25.1)(markdown-wasm@1.2.0)(next@14.2.26(@babel/core@7.24.7(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.72.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(supports-color@8.1.1)
version: 0.4.6(contentlayer2@0.4.6(esbuild@0.25.1)(markdown-wasm@1.2.0)(supports-color@8.1.1))(esbuild@0.25.1)(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)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.72.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(supports-color@8.1.1)
next-themes:
specifier: ^0.3.0
version: 0.3.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
@@ -1528,7 +1531,7 @@ importers:
version: 0.7.12
'@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.2.0(react@18.2.0))(react@18.2.0)(sass@1.72.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
version: 2.6.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)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.72.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
api-types:
specifier: workspace:*
version: link:../api-types
@@ -1870,7 +1873,7 @@ importers:
version: 3.6.1
'@testing-library/jest-dom':
specifier: ^6.1.3
version: 6.4.6(@jest/globals@29.7.0(supports-color@8.1.1))(@types/jest@29.5.5)(jest@29.7.0(@types/node@20.12.11)(supports-color@8.1.1)(ts-node@10.9.2(@types/node@20.12.11)(typescript@5.5.2)))(vitest@3.0.4)
version: 6.4.6(@jest/globals@29.7.0(supports-color@8.1.1))(@types/jest@29.5.5)(jest@29.7.0(@types/node@20.12.11)(supports-color@8.1.1))(vitest@3.0.4)
'@testing-library/react':
specifier: ^14.0.0
version: 14.0.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
@@ -2045,7 +2048,7 @@ importers:
version: 10.1.0
'@testing-library/jest-dom':
specifier: ^6.4.6
version: 6.4.6(@jest/globals@29.7.0(supports-color@8.1.1))(@types/jest@29.5.5)(jest@29.7.0(@types/node@20.12.11)(supports-color@8.1.1)(ts-node@10.9.2(@types/node@20.12.11)(typescript@5.5.2)))(vitest@3.0.4)
version: 6.4.6(@jest/globals@29.7.0(supports-color@8.1.1))(@types/jest@29.5.5)(jest@29.7.0(@types/node@20.12.11)(supports-color@8.1.1))(vitest@3.0.4)
'@testing-library/react':
specifier: ^16.0.0
version: 16.0.0(@testing-library/dom@10.1.0)(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
@@ -3603,6 +3606,9 @@ packages:
peerDependencies:
tslib: '2'
'@jsr/std__path@1.0.8':
resolution: {integrity: sha512-eNBGlh/8ZVkMxtFH4bwIzlAeKoHYk5in4wrBZhi20zMdOiuX4QozP4+19mIXBT2lzHDjhuVLyECbhFeR304iDg==, tarball: https://npm.jsr.io/~/11/@jsr/std__path/1.0.8.tgz}
'@kwsites/file-exists@1.1.1':
resolution: {integrity: sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==}
@@ -8753,6 +8759,7 @@ packages:
resolution: {integrity: sha512-t0q23FIpvHDTtnORW+bDJziGsal5uh9RJTJ1fyH8drd4lICOoXhJ5pLMUZ5C0VQei6dNmwTzzoTRgMkO9JgHEQ==}
peerDependencies:
eslint: '>= 5'
bundledDependencies: []
eslint-plugin-import@2.29.1:
resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==}
@@ -17019,6 +17026,8 @@ snapshots:
dependencies:
tslib: 2.8.1
'@jsr/std__path@1.0.8': {}
'@kwsites/file-exists@1.1.1(supports-color@8.1.1)':
dependencies:
debug: 4.4.0(supports-color@8.1.1)
@@ -20541,6 +20550,22 @@ snapshots:
pretty-format: 27.5.1
'@testing-library/jest-dom@6.4.6(@jest/globals@29.7.0(supports-color@8.1.1))(@types/jest@29.5.5)(jest@29.7.0(@types/node@20.12.11)(supports-color@8.1.1)(ts-node@10.9.2(@types/node@20.12.11)(typescript@5.5.2)))(vitest@3.0.4)':
dependencies:
'@adobe/css-tools': 4.4.0
'@babel/runtime': 7.24.7
aria-query: 5.3.0
chalk: 3.0.0
css.escape: 1.5.1
dom-accessibility-api: 0.6.3
lodash: 4.17.21
redent: 3.0.0
optionalDependencies:
'@jest/globals': 29.7.0(supports-color@8.1.1)
'@types/jest': 29.5.5
jest: 29.7.0(@types/node@20.12.11)(supports-color@8.1.1)(ts-node@10.9.2(@types/node@20.12.11)(typescript@5.5.2))
vitest: 3.0.4(@types/node@20.12.11)(@vitest/ui@3.0.4)(jiti@2.4.2)(jsdom@20.0.3(supports-color@8.1.1))(msw@2.4.11(typescript@5.5.2))(sass@1.72.0)(supports-color@8.1.1)(terser@5.39.0)(tsx@4.19.3)(yaml@2.4.5)
'@testing-library/jest-dom@6.4.6(@jest/globals@29.7.0(supports-color@8.1.1))(@types/jest@29.5.5)(jest@29.7.0(@types/node@20.12.11)(supports-color@8.1.1))(vitest@3.0.4)':
dependencies:
'@adobe/css-tools': 4.4.0
'@babel/runtime': 7.24.7
@@ -21192,14 +21217,6 @@ snapshots:
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
'@vercel/flags@2.6.0(next@14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.72.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
jose: 5.2.1
optionalDependencies:
next: 14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.72.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
'@vercel/nft@0.29.2(encoding@0.1.13)(rollup@4.37.0)(supports-color@8.1.1)':
dependencies:
'@mapbox/node-pre-gyp': 2.0.0(encoding@0.1.13)(supports-color@8.1.1)
@@ -27378,12 +27395,12 @@ snapshots:
- markdown-wasm
- supports-color
next-contentlayer2@0.4.6(contentlayer2@0.4.6(esbuild@0.25.1)(markdown-wasm@1.2.0)(supports-color@8.1.1))(esbuild@0.25.1)(markdown-wasm@1.2.0)(next@14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.72.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(supports-color@8.1.1):
next-contentlayer2@0.4.6(contentlayer2@0.4.6(esbuild@0.25.1)(markdown-wasm@1.2.0)(supports-color@8.1.1))(esbuild@0.25.1)(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)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.72.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(supports-color@8.1.1):
dependencies:
'@contentlayer2/core': 0.4.3(esbuild@0.25.1)(markdown-wasm@1.2.0)(supports-color@8.1.1)
'@contentlayer2/utils': 0.4.3
contentlayer2: 0.4.6(esbuild@0.25.1)(markdown-wasm@1.2.0)(supports-color@8.1.1)
next: 14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.72.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)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.72.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
transitivePeerDependencies:
@@ -27397,7 +27414,7 @@ snapshots:
'@contentlayer2/core': 0.5.3(esbuild@0.25.1)(markdown-wasm@1.2.0)(supports-color@8.1.1)
'@contentlayer2/utils': 0.5.3
contentlayer2: 0.5.3(esbuild@0.25.1)(markdown-wasm@1.2.0)(supports-color@8.1.1)
next: 14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.72.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)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.72.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
transitivePeerDependencies:
@@ -27428,7 +27445,7 @@ snapshots:
next-seo@6.5.0(next@14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.72.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0):
dependencies:
next: 14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.72.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)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.72.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
@@ -27493,34 +27510,6 @@ snapshots:
- '@babel/core'
- babel-plugin-macros
next@14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.72.0):
dependencies:
'@next/env': 14.2.26
'@swc/helpers': 0.5.5
busboy: 1.6.0
caniuse-lite: 1.0.30001695
graceful-fs: 4.2.11
postcss: 8.4.31
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
styled-jsx: 5.1.1(@babel/core@7.26.10(supports-color@8.1.1))(react@18.2.0)
optionalDependencies:
'@next/swc-darwin-arm64': 14.2.26
'@next/swc-darwin-x64': 14.2.26
'@next/swc-linux-arm64-gnu': 14.2.26
'@next/swc-linux-arm64-musl': 14.2.26
'@next/swc-linux-x64-gnu': 14.2.26
'@next/swc-linux-x64-musl': 14.2.26
'@next/swc-win32-arm64-msvc': 14.2.26
'@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
sass: 1.72.0
transitivePeerDependencies:
- '@babel/core'
- babel-plugin-macros
nice-try@1.0.5: {}
nitropack@2.11.7(@electric-sql/pglite@0.2.15)(encoding@0.1.13)(supports-color@8.1.1)(typescript@5.5.2):
@@ -27811,7 +27800,7 @@ snapshots:
nuqs@1.19.1(next@14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.72.0)):
dependencies:
mitt: 3.0.1
next: 14.2.26(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.72.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)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.72.0)
nuqs@2.4.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)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.72.0))(react-router@7.4.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react@18.2.0):
dependencies: