mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 01:15:03 +03:00
chore(studio): move the TanStack Start deploy onto Nitro (#50030)
Moves the Studio TanStack Start build off the hand-rolled Vercel setup (an `api/server.js` function shim, rewrites in `vercel.ts`, a custom `?dpl=` skew-protection Vite plugin, and `scripts/serve.js` for self-hosted) and onto Nitro, which TanStack Start documents as its deployment path. Documents are served from the static SPA shell on the CDN; only `/api/*` and `/_serverFn/*` invoke the function. **Removed:** - `api/server.js`, `scripts/serve.js`, `scripts/smoke-server.mjs` - The `skewProtectionDpl` Vite plugin, `renderBuiltUrl`, and the `vite:preloadError` reload backstop in `router.tsx` (TanStack Router already reloads once on a failed lazy import) - Rewrites, `functions`, `outputDirectory`, and `cleanUrls` from `vercel.ts` (redirects and headers stay) - `magic-string` and `@jridgewell/remapping` devDependencies, the `preview` script **Added:** - `nitro` plugin in `vite.config.ts`. Preset is auto-detected: `.vercel/output` on Vercel, a self-contained node server in `.output` everywhere else. `vercel.immutableStaticFiles` puts hashed chunks under `/_vercel/immutable/` so tabs opened before a redeploy keep loading their chunks; `functions.maxDuration: 300` carries over the old function timeout - `scripts/vercel-spa-routes.ts`: Nitro module that rewrites the generated Build Output routes (documents -> `_shell.html`, allow-list -> `__server`, missing chunk -> 404, base-path prefixes), with a unit test - `server.ts`: TanStack Start server entry that initializes Sentry before the route tree loads and wraps the handler with `wrapFetchWithSentry` **Changed:** - `start:tanstack` runs `.output/server/index.mjs` directly with Node's `--env-file-if-exists` for the `.env` cascade. Node doesn't expand `$VAR` references, so `scripts/generateLocalEnv.js` now writes literal values into `.env.test` - Dockerfile's TanStack stage copies `.output` instead of running `pnpm deploy`; the `server.js` shim loads `.env` and imports the Nitro server - `NEXT_PUBLIC_BASE_PATH` (the platform's `/dashboard`) only sets the router basepath; Vite's `base` stays at the root so chunks can use the immutable store. The routes module emits prefixed rules for `/dashboard/api/*` and `/dashboard/_serverFn/*` and rewrites `public/` files requested under the prefix back to the root - Self-hosted security headers come from a Nitro `routeRules` entry; on Vercel they stay in `vercel.ts` - `tslib` is inlined for the build only: Nitro's dev runner has no interop for its CJS wrapper - Monaco's worker chunks follow the client assets dir so they land in the immutable store too Verified on the `studio-staging` preview (`STUDIO_FRAMEWORK=tanstack` is scoped to this branch there): documents come back as the static shell, `/dashboard/api/*` hits the function, `public/` files resolve under the prefix, a missing immutable chunk 404s. Across two deployments of this branch, the older deployment's chunks still load from the immutable store and requests carrying its `__vdpl` cookie are answered by that deployment. Self-hosted path covered by the TanStack E2E job and the Docker build job. ## To test - On the `studio-staging` preview: `/dashboard/project/<ref>` should show `content-disposition: inline; filename="_shell.html"` and a single-region `x-vercel-id`; `/dashboard/api/get-utc-time` a two-region id - Sign in and click through a few pages, including one that opens Monaco (SQL editor) so the worker chunks load - After the next deploy, a tab left open on the previous one should still navigate (lazy chunks) and call the API without errors - Self-hosted: `STUDIO_FRAMEWORK=tanstack pnpm --filter studio build && pnpm --filter studio start`, then check `/api/platform/profile` and that responses carry the security headers <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Production TanStack deployments now run on Nitro’s self-contained server output. * Vercel routing serves static pages first while directing API and server-function requests appropriately. * Server-function requests can include deployment identification for consistent handling. * Local environment generation now writes resolved configuration values. * **Bug Fixes** * Improved handling of missing static assets and SPA fallback routing. * Server-side error monitoring now captures request errors in the new runtime. * **Refactor** * Replaced the legacy production server and smoke-test workflow with Nitro-based startup. * Removed automatic reload handling for stale client assets. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
This commit is contained in:
1 parent
0db2667819
commit
3bac7165bd
23 files changed
+750
-846
No files matched your search
@@ -1,3 +1,5 @@
|
||||
# Default for the TanStack server (`pnpm start`); shell env and later env files override it.
|
||||
PORT=8082
|
||||
STUDIO_PG_META_URL=http://localhost:8000/pg
|
||||
POSTGRES_PASSWORD=your-super-secret-and-long-postgres-password
|
||||
|
||||
|
||||
+13
-35
@@ -71,42 +71,20 @@ RUN mkdir -p /srv && \
|
||||
cp -a apps/studio/.next/static /srv/apps/studio/.next/static && \
|
||||
cp -a apps/studio/public /srv/apps/studio/public
|
||||
|
||||
# Compile TanStack Start (Vite)
|
||||
# Compile TanStack Start (Vite + Nitro)
|
||||
FROM dev AS build-tanstack
|
||||
# build:tanstack = vite build --mode production, then a smoke test that
|
||||
# boots the server bundle so module-scope crashes fail the image build.
|
||||
RUN NODE_OPTIONS=--max-old-space-size=4096 pnpm --filter studio run build:tanstack
|
||||
|
||||
# Assemble the runtime tree at /srv. Unlike Next's standalone output, the
|
||||
# Vite SSR bundle externalizes studio's dependencies and resolves them from
|
||||
# node_modules at request time, so the tree is a prod-only `pnpm deploy` of
|
||||
# studio (node_modules + manifest) plus the built dist/ and the runtime
|
||||
# scripts. `scripts/serve.js` is the HTTP server (the same entry
|
||||
# start:tanstack uses); the server.js shim gives the production stage a
|
||||
# single CMD that works for both frameworks. `.env` is kept because
|
||||
# serve.js loads it as the base of the runtime env cascade (container env
|
||||
# vars always win over file values).
|
||||
#
|
||||
# --ignore-scripts: pnpm 11 hard-errors (ERR_PNPM_IGNORED_BUILDS) on
|
||||
# dependency build scripts without an allowBuilds entry, and deploy turns
|
||||
# the workspace packages into file: deps whose `only-allow pnpm` preinstall
|
||||
# guards trip it. No lifecycle script is needed here anyway: the tree is
|
||||
# fully prebuilt, and nothing in studio's prod graph is approved to build
|
||||
# (allowBuilds only permits node-pty and supabase, both dev-only).
|
||||
RUN pnpm --filter studio deploy --prod --legacy --ignore-scripts /srv/apps/studio && \
|
||||
cd /srv/apps/studio && \
|
||||
find . -mindepth 1 -maxdepth 1 \
|
||||
! -name node_modules ! -name package.json ! -name scripts \
|
||||
! -name instrument.server.mjs ! -name .env \
|
||||
-exec rm -rf {} + && \
|
||||
cp -a /app/apps/studio/dist ./dist && \
|
||||
printf "import('./scripts/serve.js')\n" > server.js
|
||||
|
||||
# Boot the pruned tree exactly the way the container will run it, so a
|
||||
# dependency that's runtime-imported but missing from `dependencies`
|
||||
# (present only in devDependencies) fails the build here instead of
|
||||
# 500ing the deployed container.
|
||||
RUN cd /srv/apps/studio && node scripts/smoke-server.mjs
|
||||
# Assemble the runtime tree at /srv. Nitro's node-server output is
|
||||
# self-contained (`.output/server` bundles the app with its traced
|
||||
# dependencies, `.output/public` holds the client assets), so no node_modules
|
||||
# install is needed. The server.js shim loads `.env` (container env vars win)
|
||||
# and gives the production stage one CMD for both frameworks; package.json is
|
||||
# copied so the shim runs as ESM.
|
||||
RUN mkdir -p /srv/apps/studio && \
|
||||
cp -a apps/studio/.output /srv/apps/studio/.output && \
|
||||
cp apps/studio/package.json apps/studio/.env /srv/apps/studio/ && \
|
||||
printf "process.loadEnvFile(new URL('.env', import.meta.url))\nawait import('./.output/server/index.mjs')\n" > /srv/apps/studio/server.js
|
||||
|
||||
# Alias whichever framework build was selected so the production stage can
|
||||
# COPY from a single stage name. BuildKit only builds the selected branch.
|
||||
@@ -115,8 +93,8 @@ FROM build-${STUDIO_FRAMEWORK} AS build
|
||||
# Copy only compiled code and dependencies
|
||||
FROM base AS production
|
||||
COPY --from=build /srv ./
|
||||
# serve.js (TanStack) defaults to port 8082; pin both servers to the port
|
||||
# the healthcheck and compose files expect. Next's server.js reads PORT too.
|
||||
# Both servers read PORT (the TanStack `start` script defaults it to 8082);
|
||||
# pin it to the port the healthcheck and compose files expect.
|
||||
ENV PORT=3000
|
||||
EXPOSE 3000
|
||||
ENTRYPOINT ["docker-entrypoint.sh"]
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
// STUDIO_FRAMEWORK gates whether this function actually serves the TanStack
|
||||
// SSR handler. Vercel auto-detects every file under /api as a Function
|
||||
// regardless of the framework preset (vercel.com/docs/functions), so we
|
||||
// can't keep this file from being deployed in the Next.js prod build — we
|
||||
// just make it inert when the env var is unset.
|
||||
const isTanstack = process.env.STUDIO_FRAMEWORK === 'tanstack'
|
||||
|
||||
// Computed path keeps `dist/server/server.js` out of Vercel's function
|
||||
// bundler's static analysis. In the Next.js prod deploy the `dist/` tree
|
||||
// doesn't exist, but Vercel still bundles this file because it lives under
|
||||
// `api/`. With the .join() the bundler treats the import as runtime-only
|
||||
// and the missing dist/ isn't a build error. In TanStack mode the SSR
|
||||
// bundle is shipped into the function via the `functions['api/server.js']
|
||||
// .includeFiles` config in vercel.ts.
|
||||
const tanstackEntry = ['..', 'dist', 'server', 'server.js'].join('/')
|
||||
|
||||
// Initialize server-side Sentry BEFORE the handler module is imported, so its
|
||||
// instrumentation is in place when route modules evaluate. Gated to TanStack
|
||||
// (the Next deploy uses instrumentation.ts / sentry.server.config.ts instead).
|
||||
// Vercel functions can't use a `--import` startup flag, so we import the
|
||||
// instrument module here at boot. Vercel provides env vars via process.env.
|
||||
// A Sentry boot failure must never take the API down — mirror scripts/serve.js
|
||||
// and fall back to the identity wrapper if init or the SDK import throws.
|
||||
let wrapFetchWithSentry = (fetchHandler) => fetchHandler
|
||||
if (isTanstack) {
|
||||
try {
|
||||
await import('../instrument.server.mjs')
|
||||
} catch (err) {
|
||||
console.warn('[api/server] Sentry server init skipped:', err?.message ?? err)
|
||||
}
|
||||
;({ wrapFetchWithSentry } = await import('@sentry/tanstackstart-react').catch(() => ({
|
||||
wrapFetchWithSentry: (fetchHandler) => fetchHandler,
|
||||
})))
|
||||
}
|
||||
|
||||
const rawHandler = isTanstack
|
||||
? (await import(tanstackEntry)).default
|
||||
: { fetch: () => new Response('Not Found', { status: 404 }) }
|
||||
|
||||
// Wrap the fetch handler so request-scoped errors (including those swallowed
|
||||
// into a 500 downstream) are captured with request context.
|
||||
const handler = isTanstack
|
||||
? { ...rawHandler, fetch: wrapFetchWithSentry(rawHandler.fetch.bind(rawHandler)) }
|
||||
: rawHandler
|
||||
|
||||
// Vercel's Web API handler convention: export an object with `fetch(request)`.
|
||||
// TanStack's server build is already shaped that way — default-export it
|
||||
// verbatim and Vercel hands us a real Web Request.
|
||||
// eslint-disable-next-line no-restricted-exports
|
||||
export default handler
|
||||
@@ -5,12 +5,10 @@ import { BASE_PATH } from '@/lib/constants'
|
||||
import type { ResponseError, UseCustomQueryOptions } from '@/types'
|
||||
|
||||
export async function getDeploymentCommit() {
|
||||
// Deliberately unpinned: API fetches never carry the `?dpl=` skew-protection
|
||||
// pin — only built asset URLs do (TanStack, see skewProtectionDpl in
|
||||
// vite.config.ts) — so Vercel's edge routes this to the LATEST deployment
|
||||
// and the check can detect a newer version while the session's assets stay
|
||||
// pinned. We keep the basePath URL so it still routes to studio in
|
||||
// production (root `/api/*` there is the marketing site).
|
||||
// Deliberately unpinned: TanStack only adds x-deployment-id to server-function
|
||||
// calls (start.ts), and Nitro's session cookie is disabled. This API request
|
||||
// sees the latest deployment while older assets stay in the immutable store.
|
||||
// Keep the basePath so www routes this request to Studio in production.
|
||||
const response = await fetchHandler(`${BASE_PATH}/api/get-deployment-commit`)
|
||||
return (await response.json()) as { commitSha: string; commitTime: string }
|
||||
}
|
||||
|
||||
@@ -27,9 +27,8 @@ const DeployCheckToast = ({ id }: { id: string | number }) => {
|
||||
<Button
|
||||
variant="primary"
|
||||
onClick={() => {
|
||||
// Document requests carry no skew-protection pin (only built
|
||||
// asset URLs do — see skewProtectionDpl in vite.config.ts), so a
|
||||
// plain reload lands on the latest deployment.
|
||||
// Vercel never pins document navigations to a deployment, so a
|
||||
// plain reload lands on the latest one.
|
||||
router.reload()
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
// Server-side Sentry init for the TanStack Start runtime.
|
||||
// Server-side Sentry init for the TanStack Start runtime. Mirrors
|
||||
// sentry.server.config.ts (Next) with the `@sentry/tanstackstart-react` SDK.
|
||||
// server.ts imports it first so it runs before the route tree evaluates.
|
||||
//
|
||||
// Mirrors sentry.server.config.ts (the Next.js server init) but uses the
|
||||
// unified `@sentry/tanstackstart-react` SDK. Loaded:
|
||||
// - self-hosted / e2e (scripts/serve.js): dynamically imported AFTER the
|
||||
// .env files are read into process.env, so the DSN is available.
|
||||
// - Vercel (api/server.js): imported at module top (gated to TanStack),
|
||||
// Vercel injects env vars into process.env for us.
|
||||
//
|
||||
// Reads process.env at call time (unlike NEXT_PUBLIC_* which the client bundle
|
||||
// inlines at build time), so it must run after env loading on self-hosted.
|
||||
// Reads process.env at call time (NEXT_PUBLIC_* are inlined at build time
|
||||
// instead), so env files must be loaded before the server boots self-hosted.
|
||||
|
||||
import * as Sentry from '@sentry/tanstackstart-react'
|
||||
|
||||
|
||||
@@ -9,14 +9,12 @@
|
||||
"dev": "node scripts/dispatch.js dev",
|
||||
"build": "node scripts/dispatch.js build",
|
||||
"start": "node scripts/dispatch.js start",
|
||||
"preview": "vite preview --mode ${MODE:-production} --port 8082",
|
||||
"dev:next": "next dev -p ${STUDIO_PORT:-8082}",
|
||||
"build:next": "next build && if [ \"$SKIP_ASSET_UPLOAD\" != \"1\" ]; then ./../../scripts/upload-static-assets.sh; fi",
|
||||
"start:next": "next start -p 8082",
|
||||
"dev:tanstack": "NODE_OPTIONS=--max-old-space-size=8192 vite dev --port ${STUDIO_PORT:-8082}",
|
||||
"build:tanstack": "vite build --mode ${MODE:-production} && pnpm smoke:tanstack",
|
||||
"smoke:tanstack": "node scripts/smoke-server.mjs",
|
||||
"start:tanstack": "node scripts/serve.js",
|
||||
"build:tanstack": "vite build --mode ${MODE:-production}",
|
||||
"start:tanstack": "node --env-file-if-exists=.env --env-file-if-exists=.env.local --env-file-if-exists=.env.${MODE:-production} --env-file-if-exists=.env.${MODE:-production}.local .output/server/index.mjs",
|
||||
"lint": "eslint .",
|
||||
"lint:ratchet": "tsx scripts/ratchet-eslint-rules.ts --rules-file scripts/ratchet-rules.json",
|
||||
"clean": "rimraf .next .turbo tsconfig.tsbuildinfo",
|
||||
@@ -168,7 +166,6 @@
|
||||
"@faker-js/faker": "^9.9.0",
|
||||
"@graphql-codegen/cli": "5.0.5",
|
||||
"@graphql-typed-document-node/core": "^3.2.0",
|
||||
"@jridgewell/remapping": "^2.3.5",
|
||||
"@tailwindcss/postcss": "^4.2.4",
|
||||
"@tailwindcss/vite": "4.2.4",
|
||||
"@tanstack/devtools-vite": "^0.6.0",
|
||||
@@ -205,9 +202,9 @@
|
||||
"graphql-ws": "5.14.1",
|
||||
"import-in-the-middle": "^2.0.0",
|
||||
"jsdom-testing-mocks": "^1.13.1",
|
||||
"magic-string": "^0.30.21",
|
||||
"msw": "^2.3.0",
|
||||
"next-router-mock": "^0.9.13",
|
||||
"nitro": "3.0.260903-beta",
|
||||
"node-mocks-http": "^1.17.2",
|
||||
"postcss": "catalog:",
|
||||
"raw-loader": "^4.0.2",
|
||||
|
||||
@@ -11,37 +11,6 @@ export interface RouterContext {
|
||||
queryClient: QueryClient
|
||||
}
|
||||
|
||||
// Skew protection: every asset URL in the built bundle carries a
|
||||
// `?dpl=<deployment-id>` pin (see skewProtectionDpl in vite.config.ts), so a
|
||||
// long-lived dashboard session keeps loading lazily-imported chunks from the
|
||||
// deployment it was built by instead of 404ing after a redeploy. Backstop: if
|
||||
// a lazily-loaded chunk still 404s — most likely the pinned deployment aged
|
||||
// out of Skew Protection's Maximum Age, so Vercel refuses the `?dpl=` request
|
||||
// — Vite emits `vite:preloadError`. Reload so we land on the latest
|
||||
// deployment, whose asset URLs pin to itself. A short time-window guard
|
||||
// prevents a reload loop if the latest deployment is itself broken.
|
||||
function registerChunkErrorBackstop() {
|
||||
if (typeof window === 'undefined') return
|
||||
window.addEventListener('vite:preloadError', (event) => {
|
||||
const KEY = 'studio:chunk-error-reload-at'
|
||||
let last = 0
|
||||
try {
|
||||
last = Number(sessionStorage.getItem(KEY) || 0)
|
||||
} catch {
|
||||
// sessionStorage unavailable — fall through and attempt a reload anyway.
|
||||
}
|
||||
// Reloaded very recently → likely a loop; let Vite surface the error.
|
||||
if (Date.now() - last < 10_000) return
|
||||
event.preventDefault()
|
||||
try {
|
||||
sessionStorage.setItem(KEY, String(Date.now()))
|
||||
} catch {
|
||||
// ignore — worst case we lose loop protection for this reload.
|
||||
}
|
||||
window.location.reload()
|
||||
})
|
||||
}
|
||||
|
||||
function getContext(): RouterContext {
|
||||
return {
|
||||
queryClient: getQueryClient(),
|
||||
@@ -49,8 +18,6 @@ function getContext(): RouterContext {
|
||||
}
|
||||
|
||||
export function getRouter() {
|
||||
registerChunkErrorBackstop()
|
||||
|
||||
const context = getContext()
|
||||
|
||||
const router = createRouter({
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import { buildSpaRoutes } from '../vercel-spa-routes'
|
||||
|
||||
const IMMUTABLE = '/_vercel/immutable/initial/nitro'
|
||||
const cacheRule = {
|
||||
headers: { 'cache-control': 'public, max-age=31536000, immutable' },
|
||||
src: `${IMMUTABLE}/(.*)`,
|
||||
}
|
||||
const skewCookieRule = {
|
||||
src: '/.*',
|
||||
has: [{ type: 'header', key: 'Sec-Fetch-Dest', value: 'document' }],
|
||||
headers: { 'Set-Cookie': '__vdpl=dpl_123; Path=/; SameSite=Lax; Secure; HttpOnly' },
|
||||
continue: true,
|
||||
}
|
||||
const filesystem = { handle: 'filesystem' }
|
||||
const functionCatchAll = { src: '/(.*)', dest: '/__server' }
|
||||
|
||||
describe('buildSpaRoutes', () => {
|
||||
it('keeps the rules ahead of the filesystem handler and replaces the function catch-all', () => {
|
||||
const routes = buildSpaRoutes(
|
||||
[cacheRule, skewCookieRule, filesystem, functionCatchAll],
|
||||
'/__server',
|
||||
IMMUTABLE
|
||||
)
|
||||
|
||||
expect(routes).toEqual([
|
||||
cacheRule,
|
||||
skewCookieRule,
|
||||
filesystem,
|
||||
{ src: '/_serverFn/(.*)', dest: '/__server' },
|
||||
{ src: '/api/(.*)', dest: '/__server' },
|
||||
{ src: `${IMMUTABLE}/(.*)`, status: 404 },
|
||||
{ src: '/(.*)', dest: '/_shell.html' },
|
||||
])
|
||||
})
|
||||
|
||||
it('adds prefixed rules and a public-file rewrite under a base path', () => {
|
||||
const routes = buildSpaRoutes(
|
||||
[cacheRule, filesystem, functionCatchAll],
|
||||
'/__server',
|
||||
IMMUTABLE,
|
||||
'/dashboard'
|
||||
)
|
||||
|
||||
expect(routes.slice(2)).toEqual([
|
||||
{ src: '/dashboard/_serverFn/(.*)', dest: '/__server' },
|
||||
{ src: '/dashboard/api/(.*)', dest: '/__server' },
|
||||
{ src: '/_serverFn/(.*)', dest: '/__server' },
|
||||
{ src: '/api/(.*)', dest: '/__server' },
|
||||
{ src: `${IMMUTABLE}/(.*)`, status: 404 },
|
||||
{ src: '/dashboard/(.*\\.\\w+)', dest: '/$1' },
|
||||
{ src: '/(.*)', dest: '/_shell.html' },
|
||||
])
|
||||
})
|
||||
|
||||
it('fails loudly when Nitro output changes shape', () => {
|
||||
expect(() => buildSpaRoutes([functionCatchAll], '/__server', '/assets')).toThrow(
|
||||
/no \{ handle: "filesystem" \}/
|
||||
)
|
||||
expect(() => buildSpaRoutes([filesystem], '/__server', '/assets')).toThrow(
|
||||
/catch-all .* was not found/
|
||||
)
|
||||
})
|
||||
|
||||
it.each([
|
||||
[`/dashboard${IMMUTABLE}/old-chunk.js`, `${IMMUTABLE}/old-chunk.js`],
|
||||
[`/dashboard${IMMUTABLE}/editor.worker.js`, `${IMMUTABLE}/editor.worker.js`],
|
||||
[`/dashboard${IMMUTABLE}/styles.css`, `${IMMUTABLE}/styles.css`],
|
||||
['/dashboard/img/logo.svg', '/img/logo.svg'],
|
||||
['/dashboard/api/export.json', '/__server'],
|
||||
['/dashboard/_serverFn/function-id', '/__server'],
|
||||
['/dashboard/project/example/editor', '/_shell.html'],
|
||||
])('routes %s to %s after the filesystem misses', (pathname, destination) => {
|
||||
const routes = buildSpaRoutes(
|
||||
[filesystem, functionCatchAll],
|
||||
'/__server',
|
||||
IMMUTABLE,
|
||||
'/dashboard'
|
||||
)
|
||||
const rule = routes.find(({ src }) => src && new RegExp(`^${src}$`).test(pathname))
|
||||
|
||||
expect(rule?.dest).toBeDefined()
|
||||
expect(pathname.replace(new RegExp(`^${rule!.src}$`), rule!.dest!)).toBe(destination)
|
||||
})
|
||||
})
|
||||
@@ -3,7 +3,7 @@
|
||||
// tanstack-flavoured variant based on STUDIO_FRAMEWORK. We parse the env files
|
||||
// (via the shared scripts/lib/env.js parser) and pull out only
|
||||
// STUDIO_FRAMEWORK — we deliberately don't load the whole file into the
|
||||
// child's process.env, because scripts/serve.js / vite do their own .env
|
||||
// child's process.env, because vite and the start script do their own .env
|
||||
// loading and would otherwise refuse to override the dispatcher-set values,
|
||||
// including NEXT_PUBLIC_IS_PLATFORM which the e2e `.env.test` needs to flip to
|
||||
// `false`.
|
||||
@@ -29,7 +29,7 @@ if (!target) {
|
||||
const studioRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
|
||||
|
||||
// Shell env wins, then `.env.local`, then `.env` — the same precedence
|
||||
// scripts/serve.js and vite use, so STUDIO_FRAMEWORK set in either file is
|
||||
// vite and the start script use, so STUDIO_FRAMEWORK set in either file is
|
||||
// picked up (not just `.env.local`).
|
||||
const fileEnv = readEnvFiles(studioRoot, ['.env', '.env.local'])
|
||||
const studioFramework = process.env.STUDIO_FRAMEWORK ?? fileEnv.STUDIO_FRAMEWORK
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
// Shared .env parsing for the studio build/serve scripts (dispatch.js,
|
||||
// serve.js). We parse the small subset of the dotenv format we actually rely
|
||||
// on — `KEY=value`, an optional `export` prefix, and surrounding single/double
|
||||
// quotes — rather than taking on the `dotenv` dependency for a couple of build
|
||||
// scripts. Crucially, nothing here touches `process.env`: callers decide what
|
||||
// to do with the parsed values, which is what lets dispatch.js read a single
|
||||
// key without leaking the whole file into the child process.
|
||||
//
|
||||
// dispatch.js and serve.js must agree on this format, so it lives here once.
|
||||
// .env parsing for scripts/dispatch.js. We parse the small subset of the
|
||||
// dotenv format we actually rely on — `KEY=value`, an optional `export`
|
||||
// prefix, and surrounding single/double quotes — rather than taking on the
|
||||
// `dotenv` dependency for one build script. Crucially, nothing here touches
|
||||
// `process.env`: callers decide what to do with the parsed values, which is
|
||||
// what lets dispatch.js read a single key without leaking the whole file into
|
||||
// the child process.
|
||||
import { readFileSync } from 'node:fs'
|
||||
import path from 'node:path'
|
||||
|
||||
|
||||
@@ -1,214 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
// Standalone Node HTTP server that hosts the production studio build.
|
||||
//
|
||||
// We export the fetch-handler shape from `dist/server/server.js` because
|
||||
// Vercel consumes it directly (see `apps/studio/api/server.js`). For
|
||||
// self-hosted / e2e, we need an HTTP listener of our own — this is that
|
||||
// listener.
|
||||
//
|
||||
// Responsibilities:
|
||||
// - Load env files in vite preview's order so non-NEXT_PUBLIC_* values
|
||||
// (POSTGRES_PASSWORD, PG_META_CRYPTO_KEY, etc.) are in process.env
|
||||
// at request time. NEXT_PUBLIC_* are already inlined into the bundle
|
||||
// at build time and don't need to be re-loaded.
|
||||
// - Serve static client assets from `dist/client/` directly with the
|
||||
// right MIME types and cache headers.
|
||||
// - Forward everything else to the TanStack Start handler exported
|
||||
// from `dist/server/server.js`.
|
||||
import { createReadStream } from 'node:fs'
|
||||
import { stat } from 'node:fs/promises'
|
||||
import { createServer } from 'node:http'
|
||||
import path from 'node:path'
|
||||
import { Readable } from 'node:stream'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
import { readEnvFiles } from './lib/env.js'
|
||||
|
||||
const studioRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
|
||||
const clientDir = path.join(studioRoot, 'dist/client')
|
||||
const mode = process.env.MODE || 'production'
|
||||
|
||||
const envFiles = ['.env', '.env.local', `.env.${mode}`, `.env.${mode}.local`]
|
||||
const parsed = readEnvFiles(studioRoot, envFiles)
|
||||
// Don't clobber values the shell already provides — match `vite preview`.
|
||||
for (const [k, v] of Object.entries(parsed)) {
|
||||
if (process.env[k] !== undefined) continue
|
||||
process.env[k] = v.replace(
|
||||
/\$\{?([A-Za-z_][A-Za-z0-9_]*)\}?/g,
|
||||
(_, name) => process.env[name] ?? parsed[name] ?? ''
|
||||
)
|
||||
}
|
||||
|
||||
// Initialize server-side Sentry now that .env values are in process.env (the
|
||||
// instrument module reads process.env.NEXT_PUBLIC_SENTRY_DSN at call time).
|
||||
// Imported dynamically here rather than via a `--import` flag so it runs after
|
||||
// the env-loading block above. Non-fatal if the SDK isn't present.
|
||||
try {
|
||||
await import(path.join(studioRoot, 'instrument.server.mjs'))
|
||||
} catch (err) {
|
||||
console.warn('[serve] Sentry server init skipped:', err?.message ?? err)
|
||||
}
|
||||
const { wrapFetchWithSentry } = await import('@sentry/tanstackstart-react').catch(() => ({
|
||||
wrapFetchWithSentry: (fetchHandler) => fetchHandler,
|
||||
}))
|
||||
|
||||
const { default: rawHandler } = await import(path.join(studioRoot, 'dist/server/server.js'))
|
||||
// Wrap so request-scoped errors (incl. ones swallowed into a 500) are captured.
|
||||
const handler = {
|
||||
...rawHandler,
|
||||
fetch: wrapFetchWithSentry(rawHandler.fetch.bind(rawHandler)),
|
||||
}
|
||||
|
||||
const mimeByExt = new Map([
|
||||
['.js', 'application/javascript; charset=utf-8'],
|
||||
['.mjs', 'application/javascript; charset=utf-8'],
|
||||
['.css', 'text/css; charset=utf-8'],
|
||||
['.html', 'text/html; charset=utf-8'],
|
||||
['.json', 'application/json; charset=utf-8'],
|
||||
['.map', 'application/json; charset=utf-8'],
|
||||
['.png', 'image/png'],
|
||||
['.jpg', 'image/jpeg'],
|
||||
['.jpeg', 'image/jpeg'],
|
||||
['.gif', 'image/gif'],
|
||||
['.svg', 'image/svg+xml'],
|
||||
['.ico', 'image/x-icon'],
|
||||
['.woff', 'font/woff'],
|
||||
['.woff2', 'font/woff2'],
|
||||
['.txt', 'text/plain; charset=utf-8'],
|
||||
['.webmanifest', 'application/manifest+json'],
|
||||
])
|
||||
|
||||
// Vite emits hashed filenames (e.g. `index-DB4J79t9.js`) for everything
|
||||
// it bundles. Those are content-addressed so we serve them immutable.
|
||||
const HASHED_RE = /-[A-Za-z0-9_-]{6,}\.[a-z0-9]+$/
|
||||
|
||||
async function serveStatic(req, res) {
|
||||
let pathname
|
||||
try {
|
||||
pathname = new URL(req.url, 'http://localhost').pathname
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
if (pathname === '/' || pathname.endsWith('/')) return false
|
||||
if (pathname.includes('..') || pathname.includes('\\')) return false
|
||||
const filePath = path.join(clientDir, pathname)
|
||||
if (!filePath.startsWith(clientDir + path.sep)) return false
|
||||
|
||||
let st
|
||||
try {
|
||||
st = await stat(filePath)
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
if (!st.isFile()) return false
|
||||
|
||||
res.statusCode = 200
|
||||
res.setHeader(
|
||||
'content-type',
|
||||
mimeByExt.get(path.extname(filePath).toLowerCase()) ?? 'application/octet-stream'
|
||||
)
|
||||
res.setHeader('content-length', String(st.size))
|
||||
res.setHeader(
|
||||
'cache-control',
|
||||
HASHED_RE.test(pathname) ? 'public, max-age=31536000, immutable' : 'no-cache'
|
||||
)
|
||||
await new Promise((resolve, reject) => {
|
||||
const stream = createReadStream(filePath)
|
||||
stream.on('error', reject)
|
||||
stream.on('end', resolve)
|
||||
stream.pipe(res)
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
||||
function toWebRequest(req) {
|
||||
const protocol = req.socket.encrypted ? 'https' : 'http'
|
||||
const url = `${protocol}://${req.headers.host ?? 'localhost'}${req.url}`
|
||||
const headers = new Headers()
|
||||
for (const [k, v] of Object.entries(req.headers)) {
|
||||
if (k.startsWith(':')) continue
|
||||
if (Array.isArray(v)) for (const vv of v) headers.append(k, vv)
|
||||
else if (v !== undefined) headers.set(k, v)
|
||||
}
|
||||
const init = { method: req.method, headers }
|
||||
// Only attach a body for methods that can carry one AND that actually
|
||||
// have body bytes coming. Wrapping `req` in `Readable.toWeb(req)` for
|
||||
// requests where Node has nothing to deliver leaves undici's
|
||||
// `extractBody` looking at an already-consumed stream and throwing
|
||||
// `TypeError: Response body object should not be disturbed or locked`
|
||||
// at the `new Request(...)` call below.
|
||||
const contentLength = Number(req.headers['content-length'] ?? '0')
|
||||
const hasBody =
|
||||
req.method !== 'GET' &&
|
||||
req.method !== 'HEAD' &&
|
||||
(contentLength > 0 || req.headers['transfer-encoding'] === 'chunked')
|
||||
if (hasBody) {
|
||||
init.body = Readable.toWeb(req)
|
||||
init.duplex = 'half'
|
||||
}
|
||||
return new Request(url, init)
|
||||
}
|
||||
|
||||
async function pipeWebResponse(response, res) {
|
||||
res.statusCode = response.status
|
||||
// The Headers iterator collapses duplicate keys, and for `set-cookie` it joins
|
||||
// every cookie into one comma-separated value — which corrupts auth/session
|
||||
// cookies. Pull the cookies out separately via getSetCookie() and set them as
|
||||
// an array so each one becomes its own header.
|
||||
const setCookies =
|
||||
typeof response.headers.getSetCookie === 'function' ? response.headers.getSetCookie() : []
|
||||
for (const [k, v] of response.headers) {
|
||||
if (k.toLowerCase() === 'set-cookie') continue
|
||||
res.setHeader(k, v)
|
||||
}
|
||||
if (setCookies.length > 0) res.setHeader('set-cookie', setCookies)
|
||||
if (!response.body) {
|
||||
res.end()
|
||||
return
|
||||
}
|
||||
// Pipe via Readable.fromWeb so the underlying stream gets proper backpressure
|
||||
// and gets released cleanly. `for await (chunk of response.body)` works in
|
||||
// simple cases but can leave the body in a "disturbed / locked" state when
|
||||
// the handler internally peeks at it — surfacing as
|
||||
// `TypeError: Response body object should not be disturbed or locked` on a
|
||||
// subsequent request.
|
||||
await new Promise((resolve, reject) => {
|
||||
const readable = Readable.fromWeb(response.body)
|
||||
readable.on('error', reject)
|
||||
res.on('error', reject)
|
||||
res.on('close', resolve)
|
||||
res.on('finish', resolve)
|
||||
readable.pipe(res)
|
||||
})
|
||||
}
|
||||
|
||||
// Security headers for the self-hosted server. Mirrors the non-platform branch
|
||||
// of next.config.ts `headers()` (self-hosted is always IS_PLATFORM=false, so the
|
||||
// CSP is just `frame-ancestors 'none'` and there's no HSTS). The platform CSP is
|
||||
// applied at the edge via vercel.ts instead; see security-headers.ts. Set before
|
||||
// any response is written so both the static and handler paths inherit them.
|
||||
const SECURITY_HEADERS = [
|
||||
['X-Frame-Options', 'DENY'],
|
||||
['X-Content-Type-Options', 'nosniff'],
|
||||
['Content-Security-Policy', "frame-ancestors 'none';"],
|
||||
['Referrer-Policy', 'strict-origin-when-cross-origin'],
|
||||
]
|
||||
|
||||
const port = Number(process.env.PORT || 8082)
|
||||
createServer(async (req, res) => {
|
||||
try {
|
||||
for (const [key, value] of SECURITY_HEADERS) res.setHeader(key, value)
|
||||
if (await serveStatic(req, res)) return
|
||||
const response = await handler.fetch(toWebRequest(req))
|
||||
await pipeWebResponse(response, res)
|
||||
} catch (err) {
|
||||
console.error('[serve] request failed:', err)
|
||||
if (!res.headersSent) {
|
||||
res.statusCode = 500
|
||||
res.setHeader('content-type', 'text/plain; charset=utf-8')
|
||||
}
|
||||
res.end('Internal Server Error')
|
||||
}
|
||||
}).listen(port, () => {
|
||||
console.log(`Studio listening on http://localhost:${port} (mode=${mode})`)
|
||||
})
|
||||
@@ -1,73 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
// Post-build smoke test: boot the built TanStack server handler and make a
|
||||
// real request with a platform-like environment, so module-scope boot
|
||||
// crashes fail the BUILD instead of the deployed function at runtime.
|
||||
//
|
||||
// Why this exists: the TanStack server entry eagerly imports the entire route
|
||||
// tree (`loadEntries`), so every route module is evaluated the first time the
|
||||
// single function handler serves a request. A bad top-level side effect in any
|
||||
// one route — e.g. `createClient(process.env.SUPABASE_URL!, ...)` at module
|
||||
// scope, where SUPABASE_URL is unset on platform — throws during that import
|
||||
// and 500s every route, including trivial ones like /api/get-utc-time. Those
|
||||
// failures only showed up at runtime on Vercel; this catches them at build.
|
||||
//
|
||||
// What this catches: anything that throws while the route tree is imported
|
||||
// (the most common class — missing env vars read at module scope).
|
||||
// What this does NOT catch: assets missing from the *Vercel function bundle*
|
||||
// (e.g. libpg-query.wasm). Local node_modules still has those, so booting the
|
||||
// plain `dist/server` build won't surface them — that needs booting the
|
||||
// `vercel build` output. Pass that function's entry as argv[1] to reuse this
|
||||
// script in a deploy-gating CI step.
|
||||
|
||||
import path from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
const studioRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
|
||||
const serverEntry = process.argv[2]
|
||||
? path.resolve(process.argv[2])
|
||||
: path.join(studioRoot, 'dist/server/server.js')
|
||||
|
||||
// Simulate the platform function runtime: these are only set on self-hosted,
|
||||
// so removing them surfaces any route that needs them at module-load time.
|
||||
for (const key of ['SUPABASE_URL', 'SUPABASE_SERVICE_KEY', 'SUPABASE_SERVICE_ROLE_KEY']) {
|
||||
delete process.env[key]
|
||||
}
|
||||
|
||||
const basePath = process.env.NEXT_PUBLIC_BASE_PATH ?? ''
|
||||
|
||||
// A request to any route forces `loadEntries` to import the full route tree,
|
||||
// so a single cheap, dependency-free endpoint is enough to exercise the boot.
|
||||
const ROUTES = ['/api/get-utc-time']
|
||||
|
||||
console.log(`[smoke] booting ${path.relative(studioRoot, serverEntry)}`)
|
||||
const { default: handler } = await import(serverEntry)
|
||||
|
||||
let failed = false
|
||||
for (const route of ROUTES) {
|
||||
const url = `http://localhost${basePath}${route}`
|
||||
try {
|
||||
const res = await handler.fetch(new Request(url))
|
||||
if (res.status >= 500) {
|
||||
failed = true
|
||||
const body = await res.text().catch(() => '')
|
||||
console.error(`[smoke] ✗ ${route} → ${res.status}\n${body.slice(0, 800)}`)
|
||||
} else {
|
||||
console.log(`[smoke] ✓ ${route} → ${res.status}`)
|
||||
}
|
||||
} catch (err) {
|
||||
failed = true
|
||||
console.error(`[smoke] ✗ ${route} threw while booting the server:\n`, err)
|
||||
}
|
||||
}
|
||||
|
||||
if (failed) {
|
||||
console.error(
|
||||
'\n[smoke] FAILED — the server bundle does not boot cleanly. This usually means a\n' +
|
||||
'route module has a top-level side effect (e.g. createClient at module scope with a\n' +
|
||||
'missing env var). Make it lazy so it only runs inside the handler.'
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
console.log('\n[smoke] passed — server boots and routes respond without a 5xx.')
|
||||
process.exit(0)
|
||||
@@ -0,0 +1,97 @@
|
||||
import { readFile, writeFile } from 'node:fs/promises'
|
||||
import { basename, resolve } from 'node:path'
|
||||
import type { NitroModule } from 'nitro/types'
|
||||
|
||||
// Nitro module that makes the Vercel Build Output a static-first SPA: documents
|
||||
// are served from the prerendered shell on the CDN and only server functions
|
||||
// and API routes invoke the function. Nitro's own config sends every
|
||||
// non-static path to the function.
|
||||
//
|
||||
// A module rather than config because `nitro({ hooks: { compiled } })`
|
||||
// REPLACES the vercel preset's `compiled` hook (config.json is never written),
|
||||
// and `vercel.config.routes` is defu-merged: user routes land above Nitro's
|
||||
// `handle: filesystem` while its function catch-all is still appended last.
|
||||
//
|
||||
// Runs before TanStack Start writes `_shell.html`.
|
||||
|
||||
/** Must match `spa.prerender.outputPath` in tanstackStart() (default `/_shell`). */
|
||||
export const SHELL_PATH = '/_shell.html'
|
||||
/** Must match `serverFns.base` in tanstackStart() (default `/_serverFn`). */
|
||||
export const SERVER_FN_BASE = '/_serverFn'
|
||||
/** Directory under `routes/` that holds the server routes. */
|
||||
export const API_PREFIX = '/api'
|
||||
|
||||
type Route = Record<string, unknown> & {
|
||||
src?: string
|
||||
dest?: string
|
||||
handle?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* After `handle: filesystem`: only `/_serverFn/*` and `/api/*` reach the
|
||||
* function, a missing hashed chunk 404s instead of becoming the HTML shell,
|
||||
* and everything else is the shell.
|
||||
*
|
||||
* @param assetsPrefix `/assets`, or `/_vercel/immutable/<salt>/nitro` with
|
||||
* `vercel.immutableStaticFiles`.
|
||||
* @param basePath `NEXT_PUBLIC_BASE_PATH` (e.g. `/dashboard`). Pages, API
|
||||
* routes, server functions and browser asset URLs live under it while the
|
||||
* static files and immutable store stay at the root. Prefixed rules come
|
||||
* first and asset requests under the prefix are rewritten to the root.
|
||||
*/
|
||||
export function buildSpaRoutes(
|
||||
generated: Route[],
|
||||
functionDest: string,
|
||||
assetsPrefix: string,
|
||||
basePath = ''
|
||||
): Route[] {
|
||||
const fsIndex = generated.findIndex((r) => r.handle === 'filesystem')
|
||||
if (fsIndex === -1) {
|
||||
throw new Error('[vercel-spa-routes] generated config has no { handle: "filesystem" }')
|
||||
}
|
||||
const before = generated.slice(0, fsIndex)
|
||||
const after = generated.slice(fsIndex + 1)
|
||||
|
||||
const isFunctionCatchAll = (r: Route) => r.src === '/(.*)' && r.dest === functionDest
|
||||
if (!after.some(isFunctionCatchAll)) {
|
||||
throw new Error(
|
||||
`[vercel-spa-routes] expected Nitro catch-all { src: "/(.*)", dest: "${functionDest}" } was not found`
|
||||
)
|
||||
}
|
||||
const kept = after.filter((r) => !isFunctionCatchAll(r) && r.handle !== 'filesystem')
|
||||
const prefixes = basePath ? [basePath, ''] : ['']
|
||||
|
||||
return [
|
||||
...before,
|
||||
{ handle: 'filesystem' },
|
||||
...kept,
|
||||
...prefixes.flatMap((prefix) => [
|
||||
{ src: `${prefix}${SERVER_FN_BASE}/(.*)`, dest: functionDest },
|
||||
{ src: `${prefix}${API_PREFIX}/(.*)`, dest: functionDest },
|
||||
]),
|
||||
{ src: `${assetsPrefix}/(.*)`, status: 404 },
|
||||
...(basePath ? [{ src: `${basePath}/(.*\\.\\w+)`, dest: '/$1' }] : []),
|
||||
{ src: '/(.*)', dest: SHELL_PATH },
|
||||
]
|
||||
}
|
||||
|
||||
export function vercelSpaRoutes({ basePath = '' }: { basePath?: string } = {}): NitroModule {
|
||||
return {
|
||||
name: 'vercel-spa-routes',
|
||||
setup(nitro) {
|
||||
if (nitro.options.preset !== 'vercel') return
|
||||
nitro.hooks.hook('compiled', async () => {
|
||||
const configPath = resolve(nitro.options.output.dir, 'config.json')
|
||||
const functionDest = `/${basename(nitro.options.output.serverDir).replace(/\.func$/, '')}`
|
||||
const assetsPrefix =
|
||||
'/' + (nitro.options.buildAssetsDir || 'assets').replace(/^\/|\/$/g, '')
|
||||
const config = JSON.parse(await readFile(configPath, 'utf8'))
|
||||
config.routes = buildSpaRoutes(config.routes, functionDest, assetsPrefix, basePath)
|
||||
await writeFile(configPath, JSON.stringify(config, null, 2))
|
||||
nitro.logger.success(
|
||||
`[vercel-spa-routes] documents -> ${SHELL_PATH}, ${basePath}${SERVER_FN_BASE}/* and ${basePath}${API_PREFIX}/* -> ${functionDest}, missing ${assetsPrefix}/* -> 404`
|
||||
)
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
import { getCSP } from './csp'
|
||||
|
||||
// Security response headers for the app. On the Next build these are applied via
|
||||
// `next.config.ts` `headers()`; the TanStack build has no such hook and (on
|
||||
// Vercel) serves a static shell with no server to attach them, so they're
|
||||
// applied through `vercel.ts` (deploy) and `scripts/serve.js` (self-hosted)
|
||||
// instead. Keep this in sync with the `/(.*?)` header block in next.config.ts.
|
||||
// Security response headers. The Next build applies them via next.config.ts
|
||||
// `headers()`; the TanStack build has no such hook, so they're applied through
|
||||
// `vercel.ts` (Vercel) and Nitro `routeRules` in `vite.config.ts`
|
||||
// (self-hosted). Keep in sync with the `/(.*?)` header block in next.config.ts.
|
||||
//
|
||||
// Env-gated exactly like next.config:
|
||||
// - CSP: full `getCSP()` on platform, else just `frame-ancestors 'none'`.
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
// TanStack Start server entry; Nitro bundles it into the server for every
|
||||
// target. Sentry's init must run before the route tree evaluates, so the
|
||||
// instrument module is imported first; `wrapFetchWithSentry` then captures
|
||||
// request-scoped errors, including ones swallowed into a 500 downstream.
|
||||
import './instrument.server.mjs'
|
||||
|
||||
import { wrapFetchWithSentry } from '@sentry/tanstackstart-react'
|
||||
import handler, { createServerEntry, type ServerEntry } from '@tanstack/react-start/server-entry'
|
||||
|
||||
const requestHandler: ServerEntry = wrapFetchWithSentry({
|
||||
fetch(request: Request) {
|
||||
return handler.fetch(request)
|
||||
},
|
||||
})
|
||||
|
||||
// eslint-disable-next-line no-restricted-exports
|
||||
export default createServerEntry(requestHandler)
|
||||
+14
-9
@@ -8,14 +8,11 @@ import { BASE_PATH, IS_PLATFORM } from '@/lib/constants'
|
||||
import { isHostedSupportedApiPath } from '@/lib/hosted-api-allowlist'
|
||||
|
||||
// Self-hosted-only API routes must 404 in platform (hosted) mode. Under the
|
||||
// Next pages router this lives in middleware (proxy.ts), but TanStack Start
|
||||
// has no middleware runtime, so the guard is migrated here as a global
|
||||
// request middleware sharing the same allowlist (lib/hosted-api-allowlist.ts).
|
||||
// On Vercel our `/api/*` (and `/_serverFn/*`) requests are rewritten to the
|
||||
// api/server.js function which runs the Start handler, so createStartHandler
|
||||
// runs this server-side for every API request — even though pages are served
|
||||
// as a static SPA shell. The guard therefore covers all API routes from a
|
||||
// single place.
|
||||
// Next pages router this lives in middleware (proxy.ts); TanStack Start has no
|
||||
// middleware runtime, so it's a global request middleware sharing the same
|
||||
// allowlist (lib/hosted-api-allowlist.ts). On Vercel every `/api/*` request
|
||||
// still reaches the function (pages are a static shell), so this covers all
|
||||
// API routes from one place.
|
||||
|
||||
const platformApiGuard = createMiddleware({ type: 'request' }).server(({ request, next }) => {
|
||||
const { pathname } = new URL(request.url)
|
||||
@@ -34,6 +31,14 @@ const platformApiGuard = createMiddleware({ type: 'request' }).server(({ request
|
||||
return next()
|
||||
})
|
||||
|
||||
// Vercel's standard request pin keeps server functions compatible with the
|
||||
// current tab. Documents and the deployment check stay unpinned, so a reload
|
||||
// gets the latest version. Vite only defines the ID when protection is enabled.
|
||||
const deploymentMiddleware = createMiddleware({ type: 'function' }).client(({ next }) => {
|
||||
const deploymentId = process.env.NEXT_PUBLIC_VERCEL_DEPLOYMENT_ID
|
||||
return next({ headers: deploymentId ? { 'x-deployment-id': deploymentId } : {} })
|
||||
})
|
||||
|
||||
// Sentry's global middlewares go at the FRONT so they wrap the whole request /
|
||||
// server-function lifecycle — including errors that downstream code swallows
|
||||
// into a 500, which the manual `@sentry/nextjs` approach never sees. The SDK's
|
||||
@@ -42,5 +47,5 @@ const platformApiGuard = createMiddleware({ type: 'request' }).server(({ request
|
||||
// explicitly so the instrumentation is visible in source.
|
||||
export const startInstance = createStart(() => ({
|
||||
requestMiddleware: [sentryGlobalRequestMiddleware, platformApiGuard],
|
||||
functionMiddleware: [sentryGlobalFunctionMiddleware],
|
||||
functionMiddleware: [sentryGlobalFunctionMiddleware, deploymentMiddleware],
|
||||
}))
|
||||
+18
-6
@@ -33,6 +33,11 @@
|
||||
"SUPABASE_URL",
|
||||
"VERCEL",
|
||||
"VERCEL_ENV",
|
||||
// Project-level Vercel settings Nitro's vercel preset reads at build
|
||||
// time; they change the emitted routes and asset paths.
|
||||
"VERCEL_SKEW_PROTECTION_ENABLED",
|
||||
"VERCEL_IMMUTABLE_STATIC_FILES_ENABLED",
|
||||
"VERCEL_HASH_SALT",
|
||||
"MAINTENANCE_MODE",
|
||||
// These envs are used in the packages
|
||||
"NEXT_PUBLIC_STORAGE_KEY",
|
||||
@@ -106,12 +111,11 @@
|
||||
// cache when it changes — without this, switching between test and
|
||||
// production builds reuses a stale cached output.
|
||||
"MODE",
|
||||
// Read by scripts/serve.js (the Node host for `pnpm start`).
|
||||
// Declared here so the studio-package turbo env lint rule passes
|
||||
// even though turbo doesn't directly drive `start`.
|
||||
// Read by the Nitro server behind `pnpm start`. Declared so the turbo
|
||||
// env lint rule passes even though turbo doesn't drive `start`.
|
||||
"PORT",
|
||||
// Gates the TanStack vs Next path in api/server.js, vercel.ts,
|
||||
// and scripts/dispatch.js (the dev/build/start dispatcher).
|
||||
// Gates the TanStack vs Next path in vercel.ts and
|
||||
// scripts/dispatch.js (the dev/build/start dispatcher).
|
||||
"STUDIO_FRAMEWORK",
|
||||
// Vite's built-in `import.meta.env.SSR` flag (used in ConnectStepsSection
|
||||
// to gate Vite-only `import.meta.glob`). Not a real process env var
|
||||
@@ -119,6 +123,12 @@
|
||||
"SSR",
|
||||
],
|
||||
"passThroughEnv": [
|
||||
// Vite bakes this into TanStack's server-function request header. Passed
|
||||
// through rather than hashed so Next's same-commit redeploys keep
|
||||
// hitting the turbo cache as before; a TanStack cache hit reuses the
|
||||
// earlier deployment's id, which is the same code and falls back to
|
||||
// latest if that deployment is gone.
|
||||
"VERCEL_DEPLOYMENT_ID",
|
||||
"CURRENT_CLI_VERSION",
|
||||
"VERCEL_GIT_COMMIT_REF",
|
||||
"VERCEL_GIT_COMMIT_SHA",
|
||||
@@ -131,7 +141,9 @@
|
||||
".next/**",
|
||||
"!.next/cache/**",
|
||||
"!.next/dev/**/*",
|
||||
"dist/**",
|
||||
// TanStack Start via Nitro: node server and Vercel Build Output.
|
||||
".output/**",
|
||||
".vercel/output/**",
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
+40
-117
@@ -15,74 +15,39 @@ import { getSecurityHeaders } from './security-headers'
|
||||
// Next.js preset untouched. Vercel reads `vercel.ts` regardless of the
|
||||
// framework preset (per vercel.com/docs/project-configuration —
|
||||
// `vercel.ts`'s `framework` field overrides the dashboard preset), so a
|
||||
// no-op early return is the only way to keep the TanStack rewrites,
|
||||
// `framework: null`, and `outputDirectory: 'dist/client'` below from
|
||||
// clobbering the Next build. Set `STUDIO_FRAMEWORK=tanstack` on the
|
||||
// TanStack Vercel project to opt in.
|
||||
// no-op early return is the only way to keep `framework: null` and the
|
||||
// headers below from clobbering the Next build. Set
|
||||
// `STUDIO_FRAMEWORK=tanstack` on the TanStack Vercel project to opt in.
|
||||
const isTanstack = process.env.STUDIO_FRAMEWORK === 'tanstack'
|
||||
|
||||
// Vite's `base` bakes the prefix into asset URLs but leaves the filesystem
|
||||
// layout at `dist/client/...`. On Vercel we strip the prefix for file lookups
|
||||
// and fall through to the SPA shell. When NEXT_PUBLIC_BASE_PATH is empty
|
||||
// the prefixed rule set is skipped and only the root-level rules fire.
|
||||
// Routing lives in Nitro's Build Output config (`.vercel/output/config.json`,
|
||||
// shaped by scripts/vercel-spa-routes.ts). Vercel applies this file's
|
||||
// `redirects`/`headers` ahead of it, which is also why no `rewrites` belong
|
||||
// here: a catch-all rewrite at this layer swallows the API routes.
|
||||
const basePath = process.env.NEXT_PUBLIC_BASE_PATH ?? ''
|
||||
|
||||
// Build the rewrites + headers for a given prefix ('' for root, or a base
|
||||
// path like '/dashboard'). We run this once for each prefix and concatenate
|
||||
// the results so we don't hand-duplicate every rule.
|
||||
//
|
||||
// Rewrite ordering: API + server-function passthrough first so extensioned
|
||||
// API paths (/api/foo.json) don't get caught by the asset rule. Asset rule
|
||||
// next — strips the basePath prefix so `/dashboard/assets/x.js` maps onto the
|
||||
// `dist/client/assets/x.js` filesystem layout (a no-op identity when
|
||||
// prefix=''). Shell rule LAST, and it deliberately matches only extensionless
|
||||
// paths via a negative lookahead.
|
||||
//
|
||||
// Why the lookahead matters: a request WITH a file extension that doesn't
|
||||
// resolve to a real file — e.g. a hashed chunk from an older deployment after
|
||||
// a redeploy — must fall through to a 404, NOT the HTML shell. A catch-all
|
||||
// `(.*)` shell swallows those misses and returns `text/html`, so the browser
|
||||
// gets HTML for a `.js` request and throws "Failed to load module script …
|
||||
// MIME type text/html" (and, because /assets/* is cached immutable, that HTML
|
||||
// poisons the edge cache under the asset URL). A clean 404 instead lets skew
|
||||
// protection's `?dpl=` routing (baked into asset URLs at build time — see
|
||||
// skewProtectionDpl in vite.config.ts) serve the chunk from the deployment
|
||||
// that still has it, or the client's `vite:preloadError` backstop recover.
|
||||
function routesFor(prefix: string) {
|
||||
return {
|
||||
rewrites: [
|
||||
routes.rewrite(`${prefix}/api/(.*)`, '/api/server'),
|
||||
routes.rewrite(`${prefix}/_serverFn/(.*)`, '/api/server'),
|
||||
routes.rewrite(`${prefix}/(.*\\.\\w+)`, '/$1'),
|
||||
routes.rewrite(`${prefix}/((?!.*\\.\\w+$).*)`, '/_shell'),
|
||||
],
|
||||
headers: [
|
||||
// Security headers for every response. The Next build sets these via
|
||||
// next.config.ts `headers()`; the TanStack build serves a static shell
|
||||
// with no server to attach them, so they live here. Matches next.config's
|
||||
// `/(.*?)` block (CSP, X-Frame-Options, HSTS, etc.).
|
||||
{ source: `${prefix}/(.*)`, headers: getSecurityHeaders() },
|
||||
// Dynamic function responses must not be cached by any shared cache —
|
||||
// handlers can still opt in with their own Cache-Control on the
|
||||
// Response when a response IS safe to cache.
|
||||
routes.cacheControl(`${prefix}/api/(.*)`, { private: true, noStore: true }),
|
||||
routes.cacheControl(`${prefix}/_serverFn/(.*)`, { private: true, noStore: true }),
|
||||
// Hashed bundles under /assets/* are content-addressed — safe to
|
||||
// cache forever.
|
||||
routes.cacheControl(`${prefix}/assets/(.*)`, {
|
||||
public: true,
|
||||
maxAge: '1year',
|
||||
immutable: true,
|
||||
}),
|
||||
// Static images and favicons aren't content-hashed, so they can't be
|
||||
// `immutable`, but they change rarely — mirror next.config's
|
||||
// `cache-control` for these paths (img: max-age=2592000 = 30 days,
|
||||
// favicon: max-age=86400 = 1 day). Prefixed like the other rules so
|
||||
// `/dashboard/img/x.png` gets the header too when a basePath is set.
|
||||
routes.cacheControl(`${prefix}/img/(.*)`, { public: true, maxAge: '30days' }),
|
||||
routes.cacheControl(`${prefix}/favicon/(.*)`, { public: true, maxAge: '1day' }),
|
||||
],
|
||||
}
|
||||
// Headers for a given prefix ('' for root, or a base path like '/dashboard').
|
||||
// Run once per prefix and concatenated so no rule is hand-duplicated.
|
||||
function headersFor(prefix: string) {
|
||||
return [
|
||||
// Security headers for every response. The Next build sets these via
|
||||
// next.config.ts `headers()`; the TanStack build serves a static shell
|
||||
// from the CDN, so they live at the edge. Matches next.config's `/(.*?)`
|
||||
// block (CSP, X-Frame-Options, HSTS, etc.).
|
||||
{ source: `${prefix}/(.*)`, headers: getSecurityHeaders() },
|
||||
// Dynamic function responses must not be cached by any shared cache —
|
||||
// handlers can still opt in with their own Cache-Control on the
|
||||
// Response when a response IS safe to cache.
|
||||
routes.cacheControl(`${prefix}/api/(.*)`, { private: true, noStore: true }),
|
||||
routes.cacheControl(`${prefix}/_serverFn/(.*)`, { private: true, noStore: true }),
|
||||
// Hashed chunks are covered by Nitro (`/_vercel/immutable/*`, immutable).
|
||||
// Static images and favicons aren't content-hashed, so they can't be
|
||||
// `immutable`, but they change rarely — mirror next.config's
|
||||
// `cache-control` for these paths (img: max-age=2592000 = 30 days,
|
||||
// favicon: max-age=86400 = 1 day).
|
||||
routes.cacheControl(`${prefix}/img/(.*)`, { public: true, maxAge: '30days' }),
|
||||
routes.cacheControl(`${prefix}/favicon/(.*)`, { public: true, maxAge: '1day' }),
|
||||
]
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -118,69 +83,27 @@ function buildRedirects(): Redirect[] {
|
||||
}
|
||||
|
||||
function buildTanstackConfig(): VercelConfig {
|
||||
// When a base path is configured, emit both the prefixed and root rule
|
||||
// sets (prefixed first so it wins for explicit /dashboard/* hits, root as
|
||||
// a fallback for bare-domain traffic).
|
||||
const ruleSets = (basePath ? [basePath, ''] : ['']).map(routesFor)
|
||||
|
||||
// Vercel's Flags Explorer probes `/.well-known/vercel/flags` and expects
|
||||
// JSON. next.config.ts proxies it to supabase.com's endpoint and forces
|
||||
// `content-type: application/json`; the TanStack build has no equivalent, so
|
||||
// without these the path falls through to the extensionless catch-all shell
|
||||
// rule and the browser gets HTML. This lives at the domain root (once, NOT
|
||||
// inside routesFor) because next.config's rewrite sets `basePath: false`, so
|
||||
// the path is never basePath-prefixed — well-known URLs are by convention at
|
||||
// the root regardless of the app's basePath. The rewrite must be listed
|
||||
// BEFORE the routesFor rewrites so it wins over the shell catch-all.
|
||||
// `content-type: application/json`; mirror that here. It lives at the domain
|
||||
// root (once, NOT per prefix) because next.config's rewrite sets
|
||||
// `basePath: false` — well-known URLs are at the root regardless of the
|
||||
// app's basePath.
|
||||
const wellKnownFlags = '/.well-known/vercel/flags'
|
||||
|
||||
return {
|
||||
// Nitro's Build Output directory is what gets deployed; no framework
|
||||
// preset should route on top of it.
|
||||
framework: null,
|
||||
outputDirectory: 'dist/client',
|
||||
cleanUrls: true,
|
||||
redirects: buildRedirects(),
|
||||
rewrites: [
|
||||
routes.rewrite(wellKnownFlags, `https://supabase.com${wellKnownFlags}`),
|
||||
...ruleSets.flatMap((r) => r.rewrites),
|
||||
],
|
||||
rewrites: [routes.rewrite(wellKnownFlags, `https://supabase.com${wellKnownFlags}`)],
|
||||
headers: [
|
||||
routes.header(wellKnownFlags, [{ key: 'content-type', value: 'application/json' }]),
|
||||
...ruleSets.flatMap((r) => r.headers),
|
||||
// When a base path is configured, emit both the prefixed and root rule
|
||||
// sets (prefixed first so it wins for explicit /dashboard/* hits, root
|
||||
// as a fallback for bare-domain traffic).
|
||||
...(basePath ? [basePath, ''] : ['']).flatMap(headersFor),
|
||||
],
|
||||
// `api/server.js` imports the TanStack SSR bundle via a computed
|
||||
// path so Vercel's function bundler doesn't try to statically
|
||||
// resolve `dist/server/server.js` during the Next.js prod build
|
||||
// (where `dist/` doesn't exist). `includeFiles` ships the SSR
|
||||
// output into the function bundle for the TanStack build so the
|
||||
// runtime import resolves.
|
||||
functions: {
|
||||
'api/server.js': {
|
||||
// Every API + server-function request is rewritten onto this single
|
||||
// function (see the `/api/*` and `/_serverFn/*` rewrites), so its
|
||||
// timeout must cover the LONGEST per-route `maxDuration` the Next
|
||||
// build declared — otherwise long AI streams and Stripe sync hit the
|
||||
// platform default (~15s) and get killed. Next set these per route via
|
||||
// `export const maxDuration`: generate-attachment-url (120),
|
||||
// ai/code/complete (60), ai/onboarding/design (60), ai/sql/generate-v4
|
||||
// (120), ai/feedback/rate (30), and integrations/stripe-sync (300).
|
||||
// TanStack collapses them into one function, so we take the max: 300s.
|
||||
maxDuration: 300,
|
||||
// Ship the SSR output, plus libpg-query's wasm. libpg-query is
|
||||
// externalized for SSR and loads its `.wasm` relative to its own
|
||||
// dir (`__dirname`) at import time; Vercel's function bundler
|
||||
// doesn't trace that node_modules asset, so co-ship it explicitly
|
||||
// or the server crashes at boot with ENOENT on libpg-query.wasm.
|
||||
//
|
||||
// Target the real pnpm store path (repo-root `.pnpm`, two levels up
|
||||
// from this Root Directory) rather than `node_modules/libpg-query`,
|
||||
// which is a pnpm symlink — Vercel rejects packaging files reached
|
||||
// through symlinked dirs ("invalid deployment package"). The real
|
||||
// path also matches where Node resolves __dirname at runtime
|
||||
// (/var/task/node_modules/.pnpm/libpg-query@.../wasm/...).
|
||||
includeFiles:
|
||||
'{dist/server/**,../../node_modules/.pnpm/libpg-query@*/node_modules/libpg-query/wasm/libpg-query.wasm}',
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+76
-202
@@ -4,15 +4,17 @@ import fs from 'node:fs'
|
||||
import { createRequire } from 'node:module'
|
||||
import path from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import remapping, { type SourceMapInput } from '@jridgewell/remapping'
|
||||
import { sentryTanstackStart } from '@sentry/tanstackstart-react/vite'
|
||||
import tailwindcss from '@tailwindcss/vite'
|
||||
import { devtools } from '@tanstack/devtools-vite'
|
||||
import { tanstackStart } from '@tanstack/react-start/plugin/vite'
|
||||
import viteReact from '@vitejs/plugin-react'
|
||||
import MagicString from 'magic-string'
|
||||
import { nitro } from 'nitro/vite'
|
||||
import { defineConfig, loadEnv, type Plugin } from 'vite'
|
||||
|
||||
import { vercelSpaRoutes } from './scripts/vercel-spa-routes'
|
||||
import { getSecurityHeaders } from './security-headers'
|
||||
|
||||
const rootDir = path.dirname(fileURLToPath(import.meta.url))
|
||||
const compatRoot = path.resolve(rootDir, 'compat/next')
|
||||
|
||||
@@ -269,9 +271,8 @@ function ssrStubGraphiql(): Plugin {
|
||||
// back, ES module live-bindings can be undefined at the point the
|
||||
// chunk that evaluates first tries to use them.
|
||||
//
|
||||
// Cycles are matched by chunk basename prefix (stripping the
|
||||
// `assets/` directory and the `-<hash>.js` suffix), so the allowlist
|
||||
// stays stable across builds even as Rolldown reassigns hashes.
|
||||
// Cycles are matched by chunk basename prefix (directory and `-<hash>.js`
|
||||
// suffix stripped), so the allowlist stays stable across builds.
|
||||
const KNOWN_CHUNK_CYCLES: ReadonlyArray<ReadonlyArray<string>> = [
|
||||
// `ui` ↔ `TreeView` chunk cycle. `cva` lives in the `ui` chunk
|
||||
// (Rolldown pools it there because many ui files use it), TreeView
|
||||
@@ -289,8 +290,8 @@ const KNOWN_CHUNK_CYCLES: ReadonlyArray<ReadonlyArray<string>> = [
|
||||
|
||||
function chunkPrefix(name: string): string {
|
||||
return name
|
||||
.replace(/^assets\//, '')
|
||||
.replace(/-[A-Za-z0-9_-]{6,10}\.js$/, '')
|
||||
.replace(/^.*\//, '')
|
||||
.replace(/-[A-Za-z0-9_-]{6,}\.js$/, '')
|
||||
.replace(/\.js$/, '')
|
||||
}
|
||||
|
||||
@@ -369,155 +370,17 @@ function assertNoChunkCycles(): Plugin {
|
||||
}
|
||||
}
|
||||
|
||||
// Skew protection (vercel.com/docs/skew-protection): bake `?dpl=<deployment
|
||||
// id>` into every asset URL the client bundle can request, so every hashed
|
||||
// chunk resolves against the deployment that referenced it. Vercel's edge
|
||||
// routes any request carrying `?dpl=` to that exact deployment, so a
|
||||
// long-lived dashboard session keeps loading its own deployment's hashed
|
||||
// chunks after a redeploy, while document navigations (which carry no pin)
|
||||
// always land on the latest deployment. If the pinned deployment ages out of
|
||||
// Skew Protection's Maximum Age, Vercel 404s the chunk and the
|
||||
// `vite:preloadError` backstop in router.tsx reloads onto the latest deploy.
|
||||
// API / server-function fetches are deliberately unpinned — that is what
|
||||
// lets use-check-latest-deploy detect newer deploys mid-session.
|
||||
//
|
||||
// Three mechanisms are needed for full coverage:
|
||||
// 1. `experimental.renderBuiltUrl` (in the config below) — asset and
|
||||
// public-file URLs referenced from JS/CSS/HTML, including the
|
||||
// `__vite__mapDeps` preload lists for dynamic imports.
|
||||
// 2. The `generateBundle` hook here — chunk-to-chunk `import`/`from`
|
||||
// specifiers. Rolldown renders these as bare relative paths that
|
||||
// `renderBuiltUrl` never sees (vitejs/vite#13834), and they're what the
|
||||
// browser actually fetches; the preload list alone would just warm a
|
||||
// cache entry under a different URL. Module identity is keyed by URL, so
|
||||
// the rewrite must cover EVERY specifier or a chunk could load twice
|
||||
// (pinned + unpinned) and break singleton module state.
|
||||
// 3. The `buildApp` hook here — `_shell.html` is prerendered by TanStack's
|
||||
// own post-order `buildApp` hook from the router manifest, outside
|
||||
// Vite's asset pipeline, so its <script>/<link> URLs and the embedded
|
||||
// route-preload manifest are patched on disk afterwards. Without this,
|
||||
// the shell's unpinned modulepreload URLs and the pinned import URLs are
|
||||
// different cache keys and the whole entry graph downloads twice.
|
||||
function skewProtectionDpl(opts: { dplSearch: string; assetsUrlPrefix: string }): Plugin {
|
||||
const { dplSearch, assetsUrlPrefix } = opts
|
||||
// Vite bundles `?worker` modules (Monaco's workers via graphiql) with the ROOT
|
||||
// `build.assetsDir`, while Nitro only rewrites the client environment's (to
|
||||
// `_vercel/immutable/<salt>/nitro` on Vercel). Keep the workers in the same
|
||||
// directory so they land in the immutable store too.
|
||||
function workersFollowClientAssetsDir(): Plugin {
|
||||
return {
|
||||
name: 'studio-skew-protection-dpl',
|
||||
name: 'studio-workers-follow-client-assets-dir',
|
||||
apply: 'build',
|
||||
// TanStack's `tanstack-start-core:post-build` plugin is `enforce: 'post'`;
|
||||
// matching it keeps THIS plugin sorted after it (same enforce group,
|
||||
// registration order wins), which the buildApp hook below relies on.
|
||||
enforce: 'post',
|
||||
transform: {
|
||||
handler(code, id) {
|
||||
if (id !== '\0vite/preload-helper.js') return
|
||||
// Vite's preload helper decides stylesheet-vs-modulepreload with
|
||||
// `dep.endsWith(".css")`. The `?dpl=` suffix makes that false for
|
||||
// every CSS dep, so lazy chunks' CSS would be injected as a script
|
||||
// modulepreload — a console MIME error, and the stylesheet never
|
||||
// applies. Make the check query-aware. Hard-fail if the helper's
|
||||
// shape ever changes so a Vite upgrade can't silently regress this.
|
||||
const cssCheck = 'dep.endsWith(".css")'
|
||||
if (!code.includes(cssCheck)) {
|
||||
this.error(
|
||||
`studio-skew-protection-dpl: expected \`${cssCheck}\` in vite's preload helper — ` +
|
||||
`vite changed its preload-helper shape; update this patch to match.`
|
||||
)
|
||||
}
|
||||
return { code: code.replaceAll(cssCheck, '/\\.css(\\?|$)/.test(dep)'), map: null }
|
||||
},
|
||||
},
|
||||
generateBundle: {
|
||||
// `order: 'post'` so this runs AFTER `vite:build-import-analysis`'s
|
||||
// normal-order generateBundle. That hook maps each dynamic-import
|
||||
// specifier back to a bundle key — with no query stripping — to collect
|
||||
// the chunk's CSS/preload deps; a `?dpl` suffix added any earlier makes
|
||||
// the lookup miss and silently drops CSS preloading for lazy chunks.
|
||||
order: 'post',
|
||||
handler(_options, bundle) {
|
||||
// Server chunks import each other via Node's filesystem resolution —
|
||||
// only the browser-facing client build gets the query pin.
|
||||
if (this.environment.name !== 'client') return
|
||||
for (const chunk of Object.values(bundle)) {
|
||||
if (chunk.type !== 'chunk') continue
|
||||
const importees = new Set([...chunk.imports, ...chunk.dynamicImports])
|
||||
if (importees.size === 0) continue
|
||||
const chunkDir = path.posix.dirname(chunk.fileName)
|
||||
let edits: MagicString | undefined
|
||||
for (const importee of importees) {
|
||||
const rel = path.posix.relative(chunkDir, importee)
|
||||
const spec = rel.startsWith('.') ? rel : `./${rel}`
|
||||
// Rolldown quotes static import specifiers with `"` and dynamic
|
||||
// ones with backticks; cover `'` too for safety. Matching the
|
||||
// exact quoted specifier of a known importee (hashed filename)
|
||||
// can't collide with app string literals.
|
||||
for (const quote of ['"', "'", '`']) {
|
||||
const target = `${quote}${spec}${quote}`
|
||||
for (
|
||||
let at = chunk.code.indexOf(target);
|
||||
at !== -1;
|
||||
at = chunk.code.indexOf(target, at + target.length)
|
||||
) {
|
||||
edits ??= new MagicString(chunk.code)
|
||||
edits.appendLeft(at + target.length - 1, dplSearch)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!edits) continue
|
||||
chunk.code = edits.toString()
|
||||
// Recombine the sourcemap so the columns Sentry maps stay accurate
|
||||
// — every insertion shifts the rest of the minified line. Like
|
||||
// vite:build-import-analysis's own generateBundle edits, updating
|
||||
// `chunk.map` isn't enough: the `.js.map` file already exists in
|
||||
// the bundle as an emitted asset by this point, so the combined map
|
||||
// has to be written into that asset too.
|
||||
if (chunk.map) {
|
||||
const editMap = edits.generateMap({ source: chunk.fileName, hires: 'boundary' })
|
||||
const original = chunk.map as unknown as SourceMapInput & {
|
||||
file?: string
|
||||
debugId?: string
|
||||
}
|
||||
const combined = {
|
||||
...remapping([editMap as SourceMapInput, original], () => null),
|
||||
// Preserve fields remapping drops but the toolchain relies on
|
||||
// (`debugId` is how Sentry pairs the uploaded map to the chunk).
|
||||
file: original.file,
|
||||
...(original.debugId && { debugId: original.debugId }),
|
||||
}
|
||||
chunk.map = combined as unknown as typeof chunk.map
|
||||
const mapAsset = bundle[`${chunk.fileName}.map`]
|
||||
if (mapAsset && mapAsset.type === 'asset') {
|
||||
mapAsset.source = JSON.stringify(combined)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
buildApp: {
|
||||
// TanStack's `tanstack-start-core:post-build` prerenders `_shell.html`
|
||||
// in its own post-order buildApp hook. This hook must run after it, so
|
||||
// this plugin must sort after that one: same hook order + same plugin
|
||||
// `enforce` group (see above) + registered after `tanstackStart()` in
|
||||
// the plugins array.
|
||||
order: 'post',
|
||||
async handler(builder) {
|
||||
const clientEnv = builder.environments.client
|
||||
if (!clientEnv) return
|
||||
const outDir = path.resolve(builder.config.root, clientEnv.config.build.outDir)
|
||||
const escapedPrefix = assetsUrlPrefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
||||
// Quoted `/assets/...` URLs: <script src>/<link href> attributes and
|
||||
// the serialized router manifest's preload lists. `[^"'`?]` keeps the
|
||||
// match inside one URL and skips any that already carry a query.
|
||||
const assetUrl = new RegExp(`(["'\`])(${escapedPrefix}[^"'\`?]+)\\1`, 'g')
|
||||
for (const entry of fs.readdirSync(outDir, { recursive: true, withFileTypes: true })) {
|
||||
if (!entry.isFile() || !entry.name.endsWith('.html')) continue
|
||||
const filePath = path.join(entry.parentPath, entry.name)
|
||||
const html = fs.readFileSync(filePath, 'utf-8')
|
||||
const patched = html.replace(assetUrl, (_match, quote, url) => {
|
||||
return `${quote}${url}${dplSearch}${quote}`
|
||||
})
|
||||
if (patched !== html) fs.writeFileSync(filePath, patched)
|
||||
}
|
||||
},
|
||||
configResolved(config) {
|
||||
const clientAssetsDir = config.environments.client?.build.assetsDir
|
||||
if (clientAssetsDir) config.build.assetsDir = clientAssetsDir
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -602,6 +465,13 @@ export default defineConfig(({ command, mode }) => {
|
||||
}
|
||||
}
|
||||
|
||||
// Pin server-function calls to the build that created them, without a
|
||||
// session cookie that also pins document reloads and the update check.
|
||||
publicEnvDefines['process.env.NEXT_PUBLIC_VERCEL_DEPLOYMENT_ID'] =
|
||||
JSON.stringify(
|
||||
env.VERCEL_SKEW_PROTECTION_ENABLED === '1' ? env.VERCEL_DEPLOYMENT_ID : undefined
|
||||
) ?? 'undefined'
|
||||
|
||||
// `MAINTENANCE_MODE` gates the "redirect everything to /maintenance" rule.
|
||||
// It's deliberately unprefixed, and the other two consumers both read it at
|
||||
// BUILD time: `next.config.ts` reads it in `redirects()`, which Next bakes
|
||||
@@ -629,36 +499,19 @@ export default defineConfig(({ command, mode }) => {
|
||||
publicEnvDefines[`process.env.${key}`] ??= 'undefined'
|
||||
}
|
||||
|
||||
// Mirror Next's `basePath` via NEXT_PUBLIC_BASE_PATH. Unlike Next, TanStack
|
||||
// Start has no single knob — the prefix has to be declared in three places
|
||||
// (see BASE_PATH_REDIRECT_GUIDE.md):
|
||||
// - Vite `base` — bakes the prefix into asset URLs in the
|
||||
// built bundle.
|
||||
// - tanstackStart router.basepath — must be passed explicitly. If
|
||||
// omitted, the plugin's internal
|
||||
// `deriveRouterBasepath` derives a value
|
||||
// from `publicBase` and strips both
|
||||
// leading and trailing slashes
|
||||
// (`/dashboard` → `dashboard`), which then
|
||||
// surfaces in `useRouter().basePath`
|
||||
// consumers as relative URLs (e.g.
|
||||
// `${BASE_PATH}/img/...` becomes
|
||||
// `dashboard/img/...` and the browser
|
||||
// resolves it against the current path).
|
||||
// See planning.js:14 in
|
||||
// @tanstack/start-plugin-core.
|
||||
// - createRouter({ basepath }) — runtime navigation prefix; configured
|
||||
// in router.tsx off the same env var
|
||||
// (inlined via `define` above).
|
||||
// Leaving the var empty keeps the app at `/` as today.
|
||||
// Vite's public base keeps asset requests under www's `/dashboard` proxy.
|
||||
// Nitro's baseURL stays `/`: its immutable manifest must use the reserved
|
||||
// root path. vercel-spa-routes rewrites the browser's prefixed asset URLs
|
||||
// to that root path, including assets retained from older deployments.
|
||||
const basePath = env.NEXT_PUBLIC_BASE_PATH || undefined
|
||||
|
||||
// Skew protection — see the skewProtectionDpl comment above. Both are
|
||||
// build-time system env vars on Vercel; unset on local/self-hosted builds,
|
||||
// which disables the whole mechanism.
|
||||
const skewDeploymentId =
|
||||
env.VERCEL_SKEW_PROTECTION_ENABLED === '1' ? env.VERCEL_DEPLOYMENT_ID : undefined
|
||||
const dplSearch = skewDeploymentId ? `?dpl=${encodeURIComponent(skewDeploymentId)}` : ''
|
||||
// Self-hosted responses get next.config.ts's security headers via Nitro
|
||||
// route rules. On Vercel they come from vercel.ts: a `/**` header route in
|
||||
// the Build Output config would stop matching before Nitro's asset and
|
||||
// skew-cookie rules.
|
||||
const securityHeaders = Object.fromEntries(
|
||||
getSecurityHeaders().map(({ key, value }) => [key, value])
|
||||
)
|
||||
|
||||
// Substitutions that have to apply to *both* our app source (via Vite's
|
||||
// `define`) and any pre-bundled dependencies (via esbuild's optimizeDeps).
|
||||
@@ -713,19 +566,6 @@ export default defineConfig(({ command, mode }) => {
|
||||
],
|
||||
},
|
||||
...(basePath && { base: basePath }),
|
||||
// Skew protection part 1 (see skewProtectionDpl above): every asset /
|
||||
// public-file URL rendered into the bundle — CSS url()s, images, worker
|
||||
// URLs, `__vite__mapDeps` preload lists — gets the `?dpl=` pin. Returning
|
||||
// a string opts out of Vite's base handling, so the base path is joined
|
||||
// here. Left unset when the pin is off so Vite keeps its default
|
||||
// base-relative URL rendering.
|
||||
...(dplSearch && {
|
||||
experimental: {
|
||||
renderBuiltUrl(filename: string) {
|
||||
return `${basePath ?? ''}/${filename}${dplSearch}`
|
||||
},
|
||||
},
|
||||
}),
|
||||
optimizeDeps: {
|
||||
// graphiql's Vite worker setup (swapped in for the webpack one by the
|
||||
// `graphiqlViteWorkers` plugin above) imports Monaco's workers with
|
||||
@@ -867,7 +707,16 @@ export default defineConfig(({ command, mode }) => {
|
||||
// above rewrites it to the `@sentry/react`-backed shim before SSR
|
||||
// resolution ever sees the id, and `@sentry/react` ships real ESM
|
||||
// ("import" condition → build/esm), so plain externalization works.
|
||||
noExternal: ['lodash', /^next(\/|$)/, 'tslib', 'react-use', 'awesome-debounce-promise'],
|
||||
// `tslib` is inlined for the BUILD only: Nitro's dev runner has no CJS
|
||||
// interop for the `tslib.js` that its ESM wrapper default-imports, and
|
||||
// every SSR request would 500. Left external in dev, Node loads it.
|
||||
noExternal: [
|
||||
'lodash',
|
||||
/^next(\/|$)/,
|
||||
...(command === 'build' ? ['tslib'] : []),
|
||||
'react-use',
|
||||
'awesome-debounce-promise',
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
nextCompat(),
|
||||
@@ -877,8 +726,39 @@ export default defineConfig(({ command, mode }) => {
|
||||
ssrLodashEs(),
|
||||
umdAmdShortCircuit(),
|
||||
assertNoChunkCycles(),
|
||||
workersFollowClientAssetsDir(),
|
||||
devtools(),
|
||||
tailwindcss(),
|
||||
// Nitro builds and hosts the server for every target: the Vercel
|
||||
// function (`.vercel/output`, preset auto-detected from `VERCEL`) and
|
||||
// the self-hosted node server (`.output`).
|
||||
nitro({
|
||||
// `server.ts` is TanStack Start's SSR entry, not a Nitro entry;
|
||||
// without this Nitro's scan picks it up as both and warns.
|
||||
serverEntry: false,
|
||||
// Nitro bundles dependencies. libpg-query's emscripten glue reads
|
||||
// `__dirname` and loads its `.wasm` from disk, so keep it external
|
||||
// and fully copied (`*`).
|
||||
traceDeps: ['libpg-query*'],
|
||||
vercel: {
|
||||
// Content-addressed chunks under `/_vercel/immutable/`, shared
|
||||
// across deployments, so a tab opened before a redeploy keeps
|
||||
// loading its lazy chunks.
|
||||
immutableStaticFiles: true,
|
||||
// Nitro uses a session-wide __vdpl cookie, which pins reloads too.
|
||||
// Keep Skew Protection ENABLED in the Vercel dashboard: this flag
|
||||
// only disables Nitro's cookie integration, not Vercel's routing.
|
||||
// start.ts pins only server functions using Vercel's request header.
|
||||
skewProtection: false,
|
||||
// One function serves every API route, so the timeout must cover
|
||||
// the longest one (integrations/stripe-sync).
|
||||
functions: { maxDuration: 300 },
|
||||
},
|
||||
// Documents from the static shell; only /api/* and /_serverFn/*
|
||||
// invoke the function.
|
||||
modules: [vercelSpaRoutes({ basePath })],
|
||||
...(!process.env.VERCEL && { routeRules: { '/**': { headers: securityHeaders } } }),
|
||||
}),
|
||||
tanstackStart({
|
||||
srcDirectory: './',
|
||||
spa: {
|
||||
@@ -889,12 +769,6 @@ export default defineConfig(({ command, mode }) => {
|
||||
...(basePath && { router: { basepath: basePath } }),
|
||||
}),
|
||||
viteReact(),
|
||||
// Skew protection parts 2 + 3. Registered after tanstackStart() so the
|
||||
// shell-patching buildApp hook runs after TanStack's prerender — see
|
||||
// the skewProtectionDpl comment.
|
||||
...(dplSearch
|
||||
? [skewProtectionDpl({ dplSearch, assetsUrlPrefix: `${basePath ?? ''}/assets/` })]
|
||||
: []),
|
||||
// Sentry's TanStack Start plugin(s) MUST be last so source maps reflect
|
||||
// every prior transform. `sentryTanstackStart` returns an ARRAY of
|
||||
// plugins (route patterns, source-map upload, middleware auto-wrap), so
|
||||
|
||||
@@ -36,13 +36,6 @@
|
||||
// vite.config.ts (`next/link` -> compat/next/link.tsx), which knip
|
||||
// cannot resolve, so they need to be entries in their own right.
|
||||
"compat/**/*.{ts,tsx}",
|
||||
// Vercel serverless function. Vercel deploys every file under `api/`
|
||||
// as a Function by convention; knip's vercel plugin only contributes
|
||||
// `vercel.ts`, so this one is manual. Listing it also traces its
|
||||
// runtime `import('../instrument.server.mjs')`, which is why
|
||||
// instrument.server.mjs needs no entry of its own even though
|
||||
// scripts/serve.js (its other importer) is ignored below.
|
||||
"api/server.js",
|
||||
],
|
||||
"ignore": [
|
||||
"public/**",
|
||||
|
||||
Generated
+352
-53
@@ -734,13 +734,13 @@ importers:
|
||||
version: 7.2.4(supports-color@8.1.1)
|
||||
'@astrojs/mdx':
|
||||
specifier: ^7.0.7
|
||||
version: 7.0.8(@astrojs/markdown-satteri@0.3.8)(astro@7.2.9(@astrojs/markdown-remark@7.2.4(supports-color@8.1.1))(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.3)(@types/node@22.13.14)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.4.5))(ioredis@5.10.1(supports-color@8.1.1))(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(supports-color@8.1.1)
|
||||
version: 7.0.8(@astrojs/markdown-satteri@0.3.8)(astro@7.2.9(@astrojs/markdown-remark@7.2.4(supports-color@8.1.1))(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.3)(@types/node@22.13.14)(aws4fetch@1.0.20)(db0@0.4.1)(ioredis@5.10.1(supports-color@8.1.1))(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(supports-color@8.1.1)
|
||||
'@astrojs/react':
|
||||
specifier: ^6.0.4
|
||||
version: 6.0.4(@types/node@22.13.14)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(esbuild@0.28.1)(jiti@2.7.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4)(supports-color@8.1.1)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)
|
||||
astro:
|
||||
specifier: ^7.2.6
|
||||
version: 7.2.9(@astrojs/markdown-remark@7.2.4(supports-color@8.1.1))(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.3)(@types/node@22.13.14)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.4.5))(ioredis@5.10.1(supports-color@8.1.1))(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)
|
||||
version: 7.2.9(@astrojs/markdown-remark@7.2.4(supports-color@8.1.1))(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.3)(@types/node@22.13.14)(aws4fetch@1.0.20)(db0@0.4.1)(ioredis@5.10.1(supports-color@8.1.1))(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)
|
||||
lucide-react:
|
||||
specifier: '*'
|
||||
version: 0.436.0(react@19.2.6)
|
||||
@@ -1079,7 +1079,7 @@ importers:
|
||||
version: 1.167.1(@tanstack/query-core@5.101.2)(@tanstack/react-query@5.83.0(react@19.2.6))(@tanstack/react-router@1.170.10(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@tanstack/router-core@1.171.8)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
'@tanstack/react-start':
|
||||
specifier: 'catalog:'
|
||||
version: 1.168.18(esbuild@0.28.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(rolldown@1.2.3)(rollup@4.60.3)(supports-color@8.1.1)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))
|
||||
version: 1.168.18(crossws@0.4.12(srvx@1.0.4))(esbuild@0.28.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(rolldown@1.2.8)(rollup@4.60.3)(supports-color@8.1.1)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))
|
||||
'@tanstack/react-table':
|
||||
specifier: 'catalog:'
|
||||
version: 8.21.3(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
@@ -1330,9 +1330,6 @@ importers:
|
||||
'@graphql-typed-document-node/core':
|
||||
specifier: ^3.2.0
|
||||
version: 3.2.0(graphql@16.11.0)
|
||||
'@jridgewell/remapping':
|
||||
specifier: ^2.3.5
|
||||
version: 2.3.5
|
||||
'@tailwindcss/postcss':
|
||||
specifier: ^4.2.4
|
||||
version: 4.2.4
|
||||
@@ -1441,15 +1438,15 @@ importers:
|
||||
jsdom-testing-mocks:
|
||||
specifier: ^1.13.1
|
||||
version: 1.13.1
|
||||
magic-string:
|
||||
specifier: ^0.30.21
|
||||
version: 0.30.21
|
||||
msw:
|
||||
specifier: ^2.3.0
|
||||
version: 2.11.3(@types/node@22.13.14)(typescript@6.0.2)
|
||||
next-router-mock:
|
||||
specifier: ^0.9.13
|
||||
version: 0.9.13(next@16.3.5(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@22.13.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4))(react@19.2.6)
|
||||
nitro:
|
||||
specifier: 3.0.260903-beta
|
||||
version: 3.0.260903-beta
|
||||
node-mocks-http:
|
||||
specifier: ^1.17.2
|
||||
version: 1.17.2(@types/node@22.13.14)
|
||||
@@ -1645,7 +1642,7 @@ importers:
|
||||
version: 1.170.10(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
'@tanstack/react-start':
|
||||
specifier: 'catalog:'
|
||||
version: 1.168.18(esbuild@0.28.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(rolldown@1.2.3)(rollup@4.60.3)(supports-color@8.1.1)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))
|
||||
version: 1.168.18(crossws@0.4.12(srvx@1.0.4))(esbuild@0.28.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(rolldown@1.2.8)(rollup@4.60.3)(supports-color@8.1.1)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))
|
||||
'@types/common-tags':
|
||||
specifier: ^1.8.4
|
||||
version: 1.8.4
|
||||
@@ -2090,7 +2087,7 @@ importers:
|
||||
version: 0.562.0(vue@3.5.35(typescript@6.0.2))
|
||||
nuxt:
|
||||
specifier: ^4.4.6
|
||||
version: 4.5.2(@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.29.7(supports-color@8.1.1)))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7(supports-color@8.1.1)))(@electric-sql/pglite@0.4.5)(@oxc-project/types@0.143.0)(@parcel/watcher@2.5.6)(@types/node@22.13.14)(@vue/compiler-sfc@3.5.41)(aws4fetch@1.0.20)(cac@6.7.14)(commander@14.0.1)(db0@0.3.4(@electric-sql/pglite@0.4.5))(encoding@0.1.13)(esbuild@0.28.1)(eslint@9.37.0(jiti@2.7.0)(supports-color@8.1.1))(ioredis@5.10.1(supports-color@8.1.1))(lightningcss@1.33.0)(magicast@0.5.4)(oxc-parser@0.143.0)(rolldown@1.2.3)(rollup-plugin-visualizer@7.0.1(rolldown@1.2.3)(rollup@4.60.3))(rollup@4.60.3)(sass@1.77.4)(supports-color@8.1.1)(terser@5.48.0)(tsx@4.22.4)(typescript@6.0.2)(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))(yaml@2.9.0)
|
||||
version: 4.5.2(@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.29.7(supports-color@8.1.1)))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7(supports-color@8.1.1)))(@electric-sql/pglite@0.4.5)(@oxc-project/types@0.149.0)(@parcel/watcher@2.5.6)(@types/node@22.13.14)(@vue/compiler-sfc@3.5.41)(aws4fetch@1.0.20)(cac@6.7.14)(commander@14.0.1)(db0@0.3.4(@electric-sql/pglite@0.4.5))(encoding@0.1.13)(esbuild@0.28.1)(eslint@9.37.0(jiti@2.7.0)(supports-color@8.1.1))(ioredis@5.10.1(supports-color@8.1.1))(lightningcss@1.33.0)(magicast@0.5.4)(oxc-parser@0.143.0)(rolldown@1.2.3)(rollup-plugin-visualizer@7.0.1(rolldown@1.2.8)(rollup@4.60.3))(rollup@4.60.3)(sass@1.77.4)(supports-color@8.1.1)(terser@5.48.0)(tsx@4.22.4)(typescript@6.0.2)(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))(yaml@2.9.0)
|
||||
vue:
|
||||
specifier: ^3.5.35
|
||||
version: 3.5.35(typescript@6.0.2)
|
||||
@@ -5999,6 +5996,9 @@ packages:
|
||||
'@oxc-project/types@0.143.0':
|
||||
resolution: {integrity: sha512-u6JZdLBTLotrNC9Vd6vPssINdzcCzleKAH6EJKImQb7GtYvX5keN2dxkoK44stCc4tffE6QQRtZTXVSzsLUlWA==}
|
||||
|
||||
'@oxc-project/types@0.149.0':
|
||||
resolution: {integrity: sha512-Efcc+iF0j3Bf67YjEqIqWXbX5XddXoK/Mw4K1/JuXwRCZ8N16VR7iT23nlCc9XrveFVh/E5Rqs2StT0V8v9LdA==}
|
||||
|
||||
'@oxc-resolver/binding-android-arm-eabi@11.24.2':
|
||||
resolution: {integrity: sha512-y09e0L0SRI2OA2tUIrjBgoV3eH5hvUKXNkJqXmNo5V2WxIjyC7I7aJfRLMEVpA8yi95f90gFDvO0VMgrDw+vwA==}
|
||||
cpu: [arm]
|
||||
@@ -7109,36 +7109,72 @@ packages:
|
||||
resolution: {integrity: sha512-C7c51Nn4yTxXFKvgh2txJFNweaVcfUPQxwEUFw4aWsCmfiBDJsTSwviIF8EcwjQ6k8bPyMWCl1vw4BdxE569Cg==}
|
||||
engines: {node: '>= 10'}
|
||||
|
||||
'@rolldown/binding-android-arm-eabi@1.2.8':
|
||||
resolution: {integrity: sha512-tN5aztYkKCte4i5SIrrz5yK/HMjEuCqCSCJa418jOV8tZ1cBY3YF2otxB1ktPxzsLA1BeTqwapK0bfjxNvHJVw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm]
|
||||
os: [android]
|
||||
|
||||
'@rolldown/binding-android-arm64@1.2.3':
|
||||
resolution: {integrity: sha512-zrJtHDcaZJ1Fp7xf4hNl+7seH9Cn/N5TwLYkhgXREtBwAd/jaqW3uqeHxpDugJLVICWg4eW44kOQEGJ1r6jCGw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
|
||||
'@rolldown/binding-android-arm64@1.2.8':
|
||||
resolution: {integrity: sha512-dIYTWl9XprMUiQFoc55KUyk/oS8SKYH3zFl0LTR7RT0Xj4hgSVyuJcroH8JUu8RcpF8fTB6E0aOwCkZoYPcDSQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
|
||||
'@rolldown/binding-darwin-arm64@1.2.3':
|
||||
resolution: {integrity: sha512-ieIiibVCp0tX7TLu2cafoNPv8wJyYi01ekXpbf8q2j7F4rGAhhXb/eQh7ge9DRBY78GwmRQtvjZDux7EDbA8kA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@rolldown/binding-darwin-arm64@1.2.8':
|
||||
resolution: {integrity: sha512-PCSDQGXD2IyTEFrcgPyBM8jJuGmrbCMuoIOXdbEGVemruKACXoLQJrb+A45Z0L5t1RQkdfJprAYPkikbh7dzdA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@rolldown/binding-darwin-x64@1.2.3':
|
||||
resolution: {integrity: sha512-Zh9tCon19eDXJoihx0rqKhMUlMYqzwj3aPsSuHmI4RWZh62dWUL+DJN4C5YQya5TcQBJU/Fe8+rY0jhXTQITqA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@rolldown/binding-darwin-x64@1.2.8':
|
||||
resolution: {integrity: sha512-Uk7lRsGhPFHVX/sAUC6D5H9Ol30dFHd6iquokll2th3LpdJ3F5CzQB+7DHn0Ri2mG+U7k2zXiPHDrwZenXhwSA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@rolldown/binding-freebsd-x64@1.2.3':
|
||||
resolution: {integrity: sha512-nGbJWewA1wrXXZiQhjAT5rhibGfns5ZNkDVqxsO6zJ3f3YvpoDNNmGMSbbhLuXKjNScaBJVOAboztAWVespQMg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
|
||||
'@rolldown/binding-freebsd-x64@1.2.8':
|
||||
resolution: {integrity: sha512-DjszaTEVogPqA5bYzsEeqDCQxbcp2fexQwKcRspYji2yzR68fCf+e4fx6kBSRDwX5/brZaHw/hWS9+A/+/w9sQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
|
||||
'@rolldown/binding-linux-arm-gnueabihf@1.2.3':
|
||||
resolution: {integrity: sha512-QNniJr5Kml0kDEB98jiDOJjXNroxIIi0IXIbdYzY26Xt1pVbeP62+KnoIZLwirOymX/0jDk/2gI/bNUv7A7OIw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@rolldown/binding-linux-arm-gnueabihf@1.2.8':
|
||||
resolution: {integrity: sha512-zmwa7FTmdzB6aaEEuuls18H6Ap5JmJPSoPTuXixeJZV6tG40SyLkApQtz1g8ptZtiEKqj9OM0oNLPh1AgvE31Q==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@rolldown/binding-linux-arm64-gnu@1.2.3':
|
||||
resolution: {integrity: sha512-TkqEAcmmvH3I/q4114NB4RVt6241Dao48pF45uLcFGrwAaIn0iITgTAKP/dLjbN0R4buJjGb91+UHSoFmpgIWw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
@@ -7146,6 +7182,13 @@ packages:
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rolldown/binding-linux-arm64-gnu@1.2.8':
|
||||
resolution: {integrity: sha512-KdYQDPHwJVnbFwdTGMgxsI9SqblBlz6STGM+w1We/d5B8OWWidYH0MwkU/uA1wM5fIpO2MkOVxXrNzzuZhw9ew==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rolldown/binding-linux-arm64-musl@1.2.3':
|
||||
resolution: {integrity: sha512-NHqjnxpsndf4MPymxteFAWHHfkTL8HjWh1KB7z23ofZ6QO2euONuxDXjat69dKZRALnGypg8k8SsK8vZJoXv1Q==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
@@ -7153,6 +7196,13 @@ packages:
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rolldown/binding-linux-arm64-musl@1.2.8':
|
||||
resolution: {integrity: sha512-jFJTifHnNPY+yzOoNZQfSIysrVyXzEQPhPnOUjmD1bcQGHH6s7c8cViKWar8YplQImE5N9JRqMCLrM2CdxOrZA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rolldown/binding-linux-ppc64-gnu@1.2.3':
|
||||
resolution: {integrity: sha512-6tbrbwfz5GB9DQ4Jwo6hy9v+vR31xZlvzZ6n5Xut6Hhx5PvrA9q/HsK8KMaYQp063iqZGXwNvZtYNLD7EM/x0w==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
@@ -7160,6 +7210,13 @@ packages:
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rolldown/binding-linux-ppc64-gnu@1.2.8':
|
||||
resolution: {integrity: sha512-FhiOziBDWPBjbcmRzfLyIJnaP7AVMFXT7YCXPjXxj7wKU3vx24RjrCNN/zjvVa+N2vVoHJwCoUBvsrN/DG3zIA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rolldown/binding-linux-s390x-gnu@1.2.3':
|
||||
resolution: {integrity: sha512-oyuXxXmoZHjXC917IAPFAAv4wWAa0cM9afk8nx1+9/jNNOX1uPf8yDA6p7G0RypOfw/X0PQt5IfoquY1um+zSg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
@@ -7167,6 +7224,13 @@ packages:
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rolldown/binding-linux-s390x-gnu@1.2.8':
|
||||
resolution: {integrity: sha512-WnHfADMzOV2Y55wlx1hzzQnar/wDt/VdvWSD99r18Mz9ylNieIGOkRx3UV21h7m/eJvjySYJkO26VvGNFkwsIQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rolldown/binding-linux-x64-gnu@1.2.3':
|
||||
resolution: {integrity: sha512-TytMwF2KVGqP2tgd0I1OY0PAv78dZRAYcF5ssDzjM34SUXCED3uXvSd5+lHoC0bTD6eEdFz7LdQNCO1y0oVk9w==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
@@ -7174,6 +7238,13 @@ packages:
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rolldown/binding-linux-x64-gnu@1.2.8':
|
||||
resolution: {integrity: sha512-H9tRr5ibfXFVLxbPOseVewewFpl28zcEdjRDt2FTUZU7odxP0gEv1ki4/kGmcGOh78oRwZuuQllGLZ9zTJp84g==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rolldown/binding-linux-x64-musl@1.2.3':
|
||||
resolution: {integrity: sha512-/E9m3qstrJFVPoULV25mVQblSNExY2+kBsYe4sy0Tn0yOOgJ8wZbZt3KnRbF/XeU2Gl1STKUQnDNTqhIE5MD4A==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
@@ -7181,24 +7252,49 @@ packages:
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rolldown/binding-linux-x64-musl@1.2.8':
|
||||
resolution: {integrity: sha512-UefiqfM3D6IVNlZ8tSGs9+Ejjud2T+oxO0IHADU45Y+lyEjD2dVFyZHbkfX0LUb5Zugo/oIv1eCO/KVYhgYJYA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rolldown/binding-openharmony-arm64@1.2.3':
|
||||
resolution: {integrity: sha512-Kr0OcsoQI816i6HOl3vFHpd1K0eZyh76zgfj4c1nTyaTsd5r2Mj1lwM4R90y/qaCfmTn9eHy0SKwi98eitRxug==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [openharmony]
|
||||
|
||||
'@rolldown/binding-openharmony-arm64@1.2.8':
|
||||
resolution: {integrity: sha512-637Ke4kWSy6rp9cxQ9gMOXlxPgIw/c1beASV4M//3+9I4uwBVOOl74G+e3zyU3u19U7RkRl/HuewixZ/Z6+Rjg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [openharmony]
|
||||
|
||||
'@rolldown/binding-win32-arm64-msvc@1.2.3':
|
||||
resolution: {integrity: sha512-hOtMwTqnME+/gJcH/PCZ0wn0zPUjiWOgkHpxbSJpfGKMezHltx1S7/k1SitzVa7Ww2cqrDDaFbZEhcJZO8o+Jw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@rolldown/binding-win32-arm64-msvc@1.2.8':
|
||||
resolution: {integrity: sha512-xWBkPOF1Q9k/Gv1nQXnVdLxKu74jXppuOM4Z3mnypVUJJJwLsMl7hNJGRAUJoG8A5MgOI1ACKM+wBFxSJzKy4A==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@rolldown/binding-win32-x64-msvc@1.2.3':
|
||||
resolution: {integrity: sha512-ekcqMMkI2PlhYnfzQnB/cEdYUVVJViWvoUyLrbzgDoi3Snfc1mVBwdnc306ufA5ejy8JSPjT2RlW1nQSjW7efg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@rolldown/binding-win32-x64-msvc@1.2.8':
|
||||
resolution: {integrity: sha512-uz2ZvfgXbxqNwijjjbxrnvALwpyODDcgc1T1N8N3rf/DXKQmaFwmB4LX4yyjggpwN2obdQLb2rgirX5ffCWYng==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@rolldown/pluginutils@1.0.0-rc.3':
|
||||
resolution: {integrity: sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==}
|
||||
|
||||
@@ -10731,6 +10827,14 @@ packages:
|
||||
crossws@0.3.5:
|
||||
resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==}
|
||||
|
||||
crossws@0.4.12:
|
||||
resolution: {integrity: sha512-aypfsr6t0uNvkqaZc6zvBfXzC6pLI0/sIulpkV6RwCVtZqG5ebBzv4weImKK0VNCj91Wl9F5j7p5WU4MNrybng==}
|
||||
peerDependencies:
|
||||
srvx: '>=0.11.5'
|
||||
peerDependenciesMeta:
|
||||
srvx:
|
||||
optional: true
|
||||
|
||||
crypto-js@4.2.0:
|
||||
resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==}
|
||||
deprecated: Active development of CryptoJS has been discontinued. This library is no longer maintained.
|
||||
@@ -11048,6 +11152,9 @@ packages:
|
||||
sqlite3:
|
||||
optional: true
|
||||
|
||||
db0@0.4.1:
|
||||
resolution: {integrity: sha512-6RBY/bSn42UrqATwsiULj2uYFyEykB3XeA/NLIVQeHNXlYV6D4Idxx3/aa6k5Y45Dwzx7sygeLotnqHWSeURYA==}
|
||||
|
||||
dc-browser@1.0.4:
|
||||
resolution: {integrity: sha512-7oEtnzNlcE+hr4OvO3GR6Gndgw8BhW+wKOEwMqSleyY7N29jbAxzyW5BaJl7qBCw+6OIxfMWtY0T+6dxq8RWLw==}
|
||||
|
||||
@@ -11365,6 +11472,10 @@ packages:
|
||||
resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
env-runner@0.2.1:
|
||||
resolution: {integrity: sha512-2iDP2DfheAMMAKeXBggEuFmpSq+1Xs6wQoHba1g65pZFXlC3VHD1O6/tgVzS6GQLv+P2koPKZPKgKhXkigNBdg==}
|
||||
hasBin: true
|
||||
|
||||
err-code@2.0.3:
|
||||
resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==}
|
||||
|
||||
@@ -12531,6 +12642,19 @@ packages:
|
||||
crossws:
|
||||
optional: true
|
||||
|
||||
h3@2.0.1-rc.31:
|
||||
resolution: {integrity: sha512-AG7qZzF99a0BSYoXT3evJgIhwSIUKow7R+hwkLRZS06WJ9nbSb7QXUDgs1ByBjp6svTvl++N/GKA7I9YPz9cQQ==}
|
||||
engines: {node: '>=20.11.1'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
crossws: ^0.4.12
|
||||
ocache: '>=0.3.0'
|
||||
peerDependenciesMeta:
|
||||
crossws:
|
||||
optional: true
|
||||
ocache:
|
||||
optional: true
|
||||
|
||||
hachure-fill@0.5.2:
|
||||
resolution: {integrity: sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==}
|
||||
|
||||
@@ -12744,6 +12868,9 @@ packages:
|
||||
httpxy@0.5.1:
|
||||
resolution: {integrity: sha512-JPhqYiixe1A1I+MXDewWDZqeudBGU8Q9jCHYN8ML+779RQzLjTi78HBvWz4jMxUD6h2/vUL12g4q/mFM0OUw1A==}
|
||||
|
||||
httpxy@0.5.5:
|
||||
resolution: {integrity: sha512-uDjmnPyp1q4Sgzf3w+J/Fc6UqcCEj0x4Wjp7OqK5dGhNeDgpyrAmnS6ey8QWrX3SWDon2DMKf9sBa5X9+CVyMA==}
|
||||
|
||||
human-signals@2.1.0:
|
||||
resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
|
||||
engines: {node: '>=10.17.0'}
|
||||
@@ -14641,9 +14768,17 @@ packages:
|
||||
sass:
|
||||
optional: true
|
||||
|
||||
nf3@0.3.24:
|
||||
resolution: {integrity: sha512-HxLK4bo+5jNsEETZp4w3tJblHOA9MCBY14IN9nZJJV8JDxt9yNIYxuBuLMjTAR5GFa3HL61+8VQDUrXv3/C8fw==}
|
||||
|
||||
nice-try@1.0.5:
|
||||
resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==}
|
||||
|
||||
nitro@3.0.260903-beta:
|
||||
resolution: {integrity: sha512-54gANPi62O8rfMvepiJUVuIzEIinYfpeHbebywlLxvVTgIYXDwSvpaU9Id+0sJOBjBx0wC1/CVYXJkH7SY+l0g==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
hasBin: true
|
||||
|
||||
nitropack@2.13.4:
|
||||
resolution: {integrity: sha512-tX7bT6zxNeMwkc6hxHiZeUoTOjVrcjoh1Z3cmxOlodIqjl4HISgqfGOmkWSayky3Nv9Z5+KQH52F8nmXJY5AAA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
@@ -14912,6 +15047,9 @@ packages:
|
||||
resolution: {integrity: sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==}
|
||||
engines: {node: '>=12.20.0'}
|
||||
|
||||
ocache@0.3.0:
|
||||
resolution: {integrity: sha512-RS/9P0zeBb0gDJmadGERLH8lZNXK7xbufTDhclkXGvFGTsj0G4M5/cLk+mizcERH29mLXNnocfB5wjcK70wGJg==}
|
||||
|
||||
ofetch@1.5.1:
|
||||
resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==}
|
||||
|
||||
@@ -16354,6 +16492,11 @@ packages:
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
hasBin: true
|
||||
|
||||
rolldown@1.2.8:
|
||||
resolution: {integrity: sha512-Z67nTmhZe7anqnM/EjI392w5i/ANUinjip7QYsOyN37oayduxt3ksdX0hf5OOamkAd53BiIHfbfSzfUmzKFQqQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
hasBin: true
|
||||
|
||||
rollup-plugin-visualizer@7.0.1:
|
||||
resolution: {integrity: sha512-UJUT4+1Ho4OcWmPYU3sYXgUqI8B8Ayfe06MX7y0qCJ1K8aGoKtR/NDd/2nZqM7ADkrzny+I99Ul7GgyoiVNAgg==}
|
||||
engines: {node: '>=22'}
|
||||
@@ -16378,6 +16521,9 @@ packages:
|
||||
rou3@0.9.1:
|
||||
resolution: {integrity: sha512-z/sSmzvtwMDDnxsPVhfWMuG6F6mbmhFDXoVqLmMfbpDD9qfV3GDmSQpf0+W296/ZDIpW2wcMmBfpVFzcnOi/nA==}
|
||||
|
||||
rou3@0.9.2:
|
||||
resolution: {integrity: sha512-3SOzvaAg8rkHrXtRjpCvCvbyO5to9oOO27Z/XqHEYXfMRVSw/qMIVdmaOk9W2lcRLtR6dlqTjo9hDeJk70QBYQ==}
|
||||
|
||||
roughjs@4.6.6:
|
||||
resolution: {integrity: sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==}
|
||||
|
||||
@@ -16836,6 +16982,11 @@ packages:
|
||||
engines: {node: '>=20.16.0'}
|
||||
hasBin: true
|
||||
|
||||
srvx@1.0.4:
|
||||
resolution: {integrity: sha512-eZmYaxUfZSo7/8m8UdsHRJNmTLSCTPPom9d7a60vMmuVeZvwhbvflRR+00/CxTCjMOFa5+H8tgBeNDVZ+w7AAQ==}
|
||||
engines: {node: '>=20.16.0'}
|
||||
hasBin: true
|
||||
|
||||
sse.js@2.2.0:
|
||||
resolution: {integrity: sha512-v1ciaikunC99FKS23rS973HYU0DnnvugtX13UggNvrgRUSungaGeLmKlm57t0dI2E1TcCqzc2Pj2njBDXFIpKQ==}
|
||||
|
||||
@@ -17765,6 +17916,9 @@ packages:
|
||||
uploadthing:
|
||||
optional: true
|
||||
|
||||
unstorage@2.0.0-alpha.10:
|
||||
resolution: {integrity: sha512-6h1veZp8gnp4dGllf0tDijoXxDYymJu251IpKKkrSVH+QHL6tXFbwG85KM+CBHSgpkkgtPuIiZ9oLCLP5+1Evw==}
|
||||
|
||||
until-async@3.0.2:
|
||||
resolution: {integrity: sha512-IiSk4HlzAMqTUseHHe3VhIGyuFmN90zMTpD3Z3y8jeQbzLIq500MVM7Jq2vUAnTKAFPJrqwkzr6PoTcPhGcOiw==}
|
||||
|
||||
@@ -18867,13 +19021,13 @@ snapshots:
|
||||
github-slugger: 2.0.0
|
||||
satteri: 0.10.5
|
||||
|
||||
'@astrojs/mdx@7.0.8(@astrojs/markdown-satteri@0.3.8)(astro@7.2.9(@astrojs/markdown-remark@7.2.4(supports-color@8.1.1))(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.3)(@types/node@22.13.14)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.4.5))(ioredis@5.10.1(supports-color@8.1.1))(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(supports-color@8.1.1)':
|
||||
'@astrojs/mdx@7.0.8(@astrojs/markdown-satteri@0.3.8)(astro@7.2.9(@astrojs/markdown-remark@7.2.4(supports-color@8.1.1))(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.3)(@types/node@22.13.14)(aws4fetch@1.0.20)(db0@0.4.1)(ioredis@5.10.1(supports-color@8.1.1))(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(supports-color@8.1.1)':
|
||||
dependencies:
|
||||
'@astrojs/internal-helpers': 0.10.4
|
||||
'@astrojs/markdown-remark': 7.2.4(supports-color@8.1.1)
|
||||
'@mdx-js/mdx': 3.1.1(supports-color@8.1.1)
|
||||
acorn: 8.18.0
|
||||
astro: 7.2.9(@astrojs/markdown-remark@7.2.4(supports-color@8.1.1))(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.3)(@types/node@22.13.14)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.4.5))(ioredis@5.10.1(supports-color@8.1.1))(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)
|
||||
astro: 7.2.9(@astrojs/markdown-remark@7.2.4(supports-color@8.1.1))(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.3)(@types/node@22.13.14)(aws4fetch@1.0.20)(db0@0.4.1)(ioredis@5.10.1(supports-color@8.1.1))(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)
|
||||
es-module-lexer: 2.3.2
|
||||
estree-util-visit: 2.0.0
|
||||
hast-util-to-html: 9.0.5
|
||||
@@ -21961,11 +22115,11 @@ snapshots:
|
||||
- rolldown
|
||||
- unplugin
|
||||
|
||||
'@nuxt/nitro-server@4.5.2(c3f0ccbf4bde9bd4a229f96b3badde35)':
|
||||
'@nuxt/nitro-server@4.5.2(4bec0acf20c572958b2bb91f944fc6a0)':
|
||||
dependencies:
|
||||
'@nuxt/devalue': 2.0.2
|
||||
'@nuxt/kit': 4.5.2(magic-string@1.1.0)(magicast@0.5.4)(oxc-parser@0.143.0)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.60.3)(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1)))
|
||||
'@unhead/vue': 3.3.1(@oxc-project/types@0.143.0)(esbuild@0.28.1)(lightningcss@1.33.0)(oxc-parser@0.143.0)(rolldown@1.2.3)(rollup@4.60.3)(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue@3.5.41(typescript@6.0.2))(webpack@5.105.4(esbuild@0.28.1))
|
||||
'@unhead/vue': 3.3.1(@oxc-project/types@0.149.0)(esbuild@0.28.1)(lightningcss@1.33.0)(oxc-parser@0.143.0)(rolldown@1.2.3)(rollup@4.60.3)(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue@3.5.41(typescript@6.0.2))(webpack@5.105.4(esbuild@0.28.1))
|
||||
'@vue/shared': 3.5.41
|
||||
consola: 3.4.2
|
||||
defu: 6.1.7
|
||||
@@ -21980,7 +22134,7 @@ snapshots:
|
||||
mocked-exports: 0.1.1
|
||||
nitropack: 2.13.4(@electric-sql/pglite@0.4.5)(aws4fetch@1.0.20)(encoding@0.1.13)(oxc-parser@0.143.0)(rolldown@1.2.3)(supports-color@8.1.1)(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))
|
||||
nostics: 1.2.0
|
||||
nuxt: 4.5.2(@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.29.7(supports-color@8.1.1)))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7(supports-color@8.1.1)))(@electric-sql/pglite@0.4.5)(@oxc-project/types@0.143.0)(@parcel/watcher@2.5.6)(@types/node@22.13.14)(@vue/compiler-sfc@3.5.41)(aws4fetch@1.0.20)(cac@6.7.14)(commander@14.0.1)(db0@0.3.4(@electric-sql/pglite@0.4.5))(encoding@0.1.13)(esbuild@0.28.1)(eslint@9.37.0(jiti@2.7.0)(supports-color@8.1.1))(ioredis@5.10.1(supports-color@8.1.1))(lightningcss@1.33.0)(magicast@0.5.4)(oxc-parser@0.143.0)(rolldown@1.2.3)(rollup-plugin-visualizer@7.0.1(rolldown@1.2.3)(rollup@4.60.3))(rollup@4.60.3)(sass@1.77.4)(supports-color@8.1.1)(terser@5.48.0)(tsx@4.22.4)(typescript@6.0.2)(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))(yaml@2.9.0)
|
||||
nuxt: 4.5.2(@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.29.7(supports-color@8.1.1)))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7(supports-color@8.1.1)))(@electric-sql/pglite@0.4.5)(@oxc-project/types@0.149.0)(@parcel/watcher@2.5.6)(@types/node@22.13.14)(@vue/compiler-sfc@3.5.41)(aws4fetch@1.0.20)(cac@6.7.14)(commander@14.0.1)(db0@0.3.4(@electric-sql/pglite@0.4.5))(encoding@0.1.13)(esbuild@0.28.1)(eslint@9.37.0(jiti@2.7.0)(supports-color@8.1.1))(ioredis@5.10.1(supports-color@8.1.1))(lightningcss@1.33.0)(magicast@0.5.4)(oxc-parser@0.143.0)(rolldown@1.2.3)(rollup-plugin-visualizer@7.0.1(rolldown@1.2.8)(rollup@4.60.3))(rollup@4.60.3)(sass@1.77.4)(supports-color@8.1.1)(terser@5.48.0)(tsx@4.22.4)(typescript@6.0.2)(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))(yaml@2.9.0)
|
||||
nypm: 0.6.9
|
||||
ohash: 2.0.11
|
||||
pathe: 2.0.3
|
||||
@@ -22060,7 +22214,7 @@ snapshots:
|
||||
rc9: 3.0.1
|
||||
std-env: 4.2.0
|
||||
|
||||
'@nuxt/vite-builder@4.5.2(b8937c6da1cc25d65b2c4fd0e82c4d2a)':
|
||||
'@nuxt/vite-builder@4.5.2(7593670026f098f90d303525f2479dbe)':
|
||||
dependencies:
|
||||
'@nuxt/kit': 4.5.2(magic-string@1.1.0)(magicast@0.5.4)(oxc-parser@0.143.0)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.60.3)(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1)))
|
||||
'@vitejs/plugin-vue': 6.0.8(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue@3.5.41(typescript@6.0.2))
|
||||
@@ -22078,7 +22232,7 @@ snapshots:
|
||||
knitwork: 1.3.0
|
||||
mlly: 1.8.2
|
||||
mocked-exports: 0.1.1
|
||||
nuxt: 4.5.2(@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.29.7(supports-color@8.1.1)))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7(supports-color@8.1.1)))(@electric-sql/pglite@0.4.5)(@oxc-project/types@0.143.0)(@parcel/watcher@2.5.6)(@types/node@22.13.14)(@vue/compiler-sfc@3.5.41)(aws4fetch@1.0.20)(cac@6.7.14)(commander@14.0.1)(db0@0.3.4(@electric-sql/pglite@0.4.5))(encoding@0.1.13)(esbuild@0.28.1)(eslint@9.37.0(jiti@2.7.0)(supports-color@8.1.1))(ioredis@5.10.1(supports-color@8.1.1))(lightningcss@1.33.0)(magicast@0.5.4)(oxc-parser@0.143.0)(rolldown@1.2.3)(rollup-plugin-visualizer@7.0.1(rolldown@1.2.3)(rollup@4.60.3))(rollup@4.60.3)(sass@1.77.4)(supports-color@8.1.1)(terser@5.48.0)(tsx@4.22.4)(typescript@6.0.2)(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))(yaml@2.9.0)
|
||||
nuxt: 4.5.2(@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.29.7(supports-color@8.1.1)))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7(supports-color@8.1.1)))(@electric-sql/pglite@0.4.5)(@oxc-project/types@0.149.0)(@parcel/watcher@2.5.6)(@types/node@22.13.14)(@vue/compiler-sfc@3.5.41)(aws4fetch@1.0.20)(cac@6.7.14)(commander@14.0.1)(db0@0.3.4(@electric-sql/pglite@0.4.5))(encoding@0.1.13)(esbuild@0.28.1)(eslint@9.37.0(jiti@2.7.0)(supports-color@8.1.1))(ioredis@5.10.1(supports-color@8.1.1))(lightningcss@1.33.0)(magicast@0.5.4)(oxc-parser@0.143.0)(rolldown@1.2.3)(rollup-plugin-visualizer@7.0.1(rolldown@1.2.8)(rollup@4.60.3))(rollup@4.60.3)(sass@1.77.4)(supports-color@8.1.1)(terser@5.48.0)(tsx@4.22.4)(typescript@6.0.2)(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))(yaml@2.9.0)
|
||||
nypm: 0.6.9
|
||||
pathe: 2.0.3
|
||||
pkg-types: 2.3.1
|
||||
@@ -22096,7 +22250,7 @@ snapshots:
|
||||
optionalDependencies:
|
||||
'@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.29.7(supports-color@8.1.1))
|
||||
rolldown: 1.2.3
|
||||
rollup-plugin-visualizer: 7.0.1(rolldown@1.2.3)(rollup@4.60.3)
|
||||
rollup-plugin-visualizer: 7.0.1(rolldown@1.2.8)(rollup@4.60.3)
|
||||
transitivePeerDependencies:
|
||||
- '@biomejs/biome'
|
||||
- '@types/node'
|
||||
@@ -22419,6 +22573,8 @@ snapshots:
|
||||
|
||||
'@oxc-project/types@0.143.0': {}
|
||||
|
||||
'@oxc-project/types@0.149.0': {}
|
||||
|
||||
'@oxc-resolver/binding-android-arm-eabi@11.24.2':
|
||||
optional: true
|
||||
|
||||
@@ -23578,48 +23734,93 @@ snapshots:
|
||||
|
||||
'@resvg/resvg-wasm@2.4.0': {}
|
||||
|
||||
'@rolldown/binding-android-arm-eabi@1.2.8':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-android-arm64@1.2.3':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-android-arm64@1.2.8':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-darwin-arm64@1.2.3':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-darwin-arm64@1.2.8':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-darwin-x64@1.2.3':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-darwin-x64@1.2.8':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-freebsd-x64@1.2.3':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-freebsd-x64@1.2.8':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-arm-gnueabihf@1.2.3':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-arm-gnueabihf@1.2.8':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-arm64-gnu@1.2.3':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-arm64-gnu@1.2.8':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-arm64-musl@1.2.3':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-arm64-musl@1.2.8':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-ppc64-gnu@1.2.3':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-ppc64-gnu@1.2.8':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-s390x-gnu@1.2.3':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-s390x-gnu@1.2.8':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-x64-gnu@1.2.3':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-x64-gnu@1.2.8':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-x64-musl@1.2.3':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-linux-x64-musl@1.2.8':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-openharmony-arm64@1.2.3':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-openharmony-arm64@1.2.8':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-win32-arm64-msvc@1.2.3':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-win32-arm64-msvc@1.2.8':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-win32-x64-msvc@1.2.3':
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-win32-x64-msvc@1.2.8':
|
||||
optional: true
|
||||
|
||||
'@rolldown/pluginutils@1.0.0-rc.3': {}
|
||||
|
||||
'@rolldown/pluginutils@1.0.0-rc.7': {}
|
||||
@@ -24993,16 +25194,16 @@ snapshots:
|
||||
react: 19.2.6
|
||||
react-dom: 19.2.6(react@19.2.6)
|
||||
|
||||
'@tanstack/react-start-rsc@0.1.17(esbuild@0.28.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(rolldown@1.2.3)(rollup@4.60.3)(supports-color@8.1.1)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))':
|
||||
'@tanstack/react-start-rsc@0.1.17(crossws@0.4.12(srvx@1.0.4))(esbuild@0.28.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(rolldown@1.2.8)(rollup@4.60.3)(supports-color@8.1.1)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))':
|
||||
dependencies:
|
||||
'@tanstack/react-router': 1.170.10(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
'@tanstack/react-start-server': 1.167.13(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
'@tanstack/react-start-server': 1.167.13(crossws@0.4.12(srvx@1.0.4))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
'@tanstack/router-core': 1.171.8
|
||||
'@tanstack/router-utils': 1.162.1(supports-color@8.1.1)
|
||||
'@tanstack/start-client-core': 1.170.6
|
||||
'@tanstack/start-fn-stubs': 1.162.0
|
||||
'@tanstack/start-plugin-core': 1.171.10(@tanstack/react-router@1.170.10(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.60.3)(supports-color@8.1.1)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))
|
||||
'@tanstack/start-server-core': 1.169.8
|
||||
'@tanstack/start-plugin-core': 1.171.10(@tanstack/react-router@1.170.10(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(crossws@0.4.12(srvx@1.0.4))(esbuild@0.28.1)(rolldown@1.2.8)(rollup@4.60.3)(supports-color@8.1.1)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))
|
||||
'@tanstack/start-server-core': 1.169.8(crossws@0.4.12(srvx@1.0.4))
|
||||
'@tanstack/start-storage-context': 1.167.10
|
||||
pathe: 2.0.3
|
||||
react: 19.2.6
|
||||
@@ -25021,28 +25222,28 @@ snapshots:
|
||||
- vite-plugin-solid
|
||||
- webpack
|
||||
|
||||
'@tanstack/react-start-server@1.167.13(react-dom@19.2.6(react@19.2.6))(react@19.2.6)':
|
||||
'@tanstack/react-start-server@1.167.13(crossws@0.4.12(srvx@1.0.4))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)':
|
||||
dependencies:
|
||||
'@tanstack/history': 1.162.0
|
||||
'@tanstack/react-router': 1.170.10(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
'@tanstack/router-core': 1.171.8
|
||||
'@tanstack/start-client-core': 1.170.6
|
||||
'@tanstack/start-server-core': 1.169.8
|
||||
'@tanstack/start-server-core': 1.169.8(crossws@0.4.12(srvx@1.0.4))
|
||||
react: 19.2.6
|
||||
react-dom: 19.2.6(react@19.2.6)
|
||||
transitivePeerDependencies:
|
||||
- crossws
|
||||
|
||||
'@tanstack/react-start@1.168.18(esbuild@0.28.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(rolldown@1.2.3)(rollup@4.60.3)(supports-color@8.1.1)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))':
|
||||
'@tanstack/react-start@1.168.18(crossws@0.4.12(srvx@1.0.4))(esbuild@0.28.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(rolldown@1.2.8)(rollup@4.60.3)(supports-color@8.1.1)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))':
|
||||
dependencies:
|
||||
'@tanstack/react-router': 1.170.10(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
'@tanstack/react-start-client': 1.168.7(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
'@tanstack/react-start-rsc': 0.1.17(esbuild@0.28.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(rolldown@1.2.3)(rollup@4.60.3)(supports-color@8.1.1)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))
|
||||
'@tanstack/react-start-server': 1.167.13(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
'@tanstack/react-start-rsc': 0.1.17(crossws@0.4.12(srvx@1.0.4))(esbuild@0.28.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(rolldown@1.2.8)(rollup@4.60.3)(supports-color@8.1.1)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))
|
||||
'@tanstack/react-start-server': 1.167.13(crossws@0.4.12(srvx@1.0.4))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
'@tanstack/router-utils': 1.162.1(supports-color@8.1.1)
|
||||
'@tanstack/start-client-core': 1.170.6
|
||||
'@tanstack/start-plugin-core': 1.171.10(@tanstack/react-router@1.170.10(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.60.3)(supports-color@8.1.1)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))
|
||||
'@tanstack/start-server-core': 1.169.8
|
||||
'@tanstack/start-plugin-core': 1.171.10(@tanstack/react-router@1.170.10(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(crossws@0.4.12(srvx@1.0.4))(esbuild@0.28.1)(rolldown@1.2.8)(rollup@4.60.3)(supports-color@8.1.1)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))
|
||||
'@tanstack/start-server-core': 1.169.8(crossws@0.4.12(srvx@1.0.4))
|
||||
pathe: 2.0.3
|
||||
react: 19.2.6
|
||||
react-dom: 19.2.6(react@19.2.6)
|
||||
@@ -25116,7 +25317,7 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@tanstack/router-plugin@1.168.13(@tanstack/react-router@1.170.10(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.60.3)(supports-color@8.1.1)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))':
|
||||
'@tanstack/router-plugin@1.168.13(@tanstack/react-router@1.170.10(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.28.1)(rolldown@1.2.8)(rollup@4.60.3)(supports-color@8.1.1)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))':
|
||||
dependencies:
|
||||
'@babel/core': 7.29.7(supports-color@8.1.1)
|
||||
'@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.29.7(supports-color@8.1.1))
|
||||
@@ -25129,7 +25330,7 @@ snapshots:
|
||||
'@tanstack/router-utils': 1.162.1(supports-color@8.1.1)
|
||||
'@tanstack/virtual-file-routes': 1.162.0
|
||||
chokidar: 5.0.0
|
||||
unplugin: 3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.60.3)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))
|
||||
unplugin: 3.3.0(esbuild@0.28.1)(rolldown@1.2.8)(rollup@4.60.3)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))
|
||||
zod: 4.4.3
|
||||
optionalDependencies:
|
||||
'@tanstack/react-router': 1.170.10(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
@@ -25173,7 +25374,7 @@ snapshots:
|
||||
|
||||
'@tanstack/start-fn-stubs@1.162.0': {}
|
||||
|
||||
'@tanstack/start-plugin-core@1.171.10(@tanstack/react-router@1.170.10(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.60.3)(supports-color@8.1.1)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))':
|
||||
'@tanstack/start-plugin-core@1.171.10(@tanstack/react-router@1.170.10(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(crossws@0.4.12(srvx@1.0.4))(esbuild@0.28.1)(rolldown@1.2.8)(rollup@4.60.3)(supports-color@8.1.1)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))':
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.27.1
|
||||
'@babel/core': 7.29.7(supports-color@8.1.1)
|
||||
@@ -25181,10 +25382,10 @@ snapshots:
|
||||
'@rolldown/pluginutils': 1.0.1
|
||||
'@tanstack/router-core': 1.171.8
|
||||
'@tanstack/router-generator': 1.167.12(supports-color@8.1.1)
|
||||
'@tanstack/router-plugin': 1.168.13(@tanstack/react-router@1.170.10(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.60.3)(supports-color@8.1.1)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))
|
||||
'@tanstack/router-plugin': 1.168.13(@tanstack/react-router@1.170.10(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(esbuild@0.28.1)(rolldown@1.2.8)(rollup@4.60.3)(supports-color@8.1.1)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))
|
||||
'@tanstack/router-utils': 1.162.1(supports-color@8.1.1)
|
||||
'@tanstack/start-client-core': 1.170.6
|
||||
'@tanstack/start-server-core': 1.169.8
|
||||
'@tanstack/start-server-core': 1.169.8(crossws@0.4.12(srvx@1.0.4))
|
||||
exsolve: 1.1.1
|
||||
lightningcss: 1.33.0
|
||||
pathe: 2.0.3
|
||||
@@ -25213,14 +25414,14 @@ snapshots:
|
||||
- vite-plugin-solid
|
||||
- webpack
|
||||
|
||||
'@tanstack/start-server-core@1.169.8':
|
||||
'@tanstack/start-server-core@1.169.8(crossws@0.4.12(srvx@1.0.4))':
|
||||
dependencies:
|
||||
'@tanstack/history': 1.162.0
|
||||
'@tanstack/router-core': 1.171.8
|
||||
'@tanstack/start-client-core': 1.170.6
|
||||
'@tanstack/start-storage-context': 1.167.10
|
||||
fetchdts: 0.1.7
|
||||
h3-v2: h3@2.0.1-rc.20
|
||||
h3-v2: h3@2.0.1-rc.20(crossws@0.4.12(srvx@1.0.4))
|
||||
seroval: 1.6.2
|
||||
transitivePeerDependencies:
|
||||
- crossws
|
||||
@@ -25944,10 +26145,10 @@ snapshots:
|
||||
|
||||
'@ungap/structured-clone@1.2.0': {}
|
||||
|
||||
'@unhead/bundler@3.3.1(@oxc-project/types@0.143.0)(esbuild@0.28.1)(lightningcss@1.33.0)(oxc-parser@0.143.0)(rolldown@1.2.3)(rollup@4.60.3)(unhead@3.3.1(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.60.3)(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1)))(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))':
|
||||
'@unhead/bundler@3.3.1(@oxc-project/types@0.149.0)(esbuild@0.28.1)(lightningcss@1.33.0)(oxc-parser@0.143.0)(rolldown@1.2.3)(rollup@4.60.3)(unhead@3.3.1(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.60.3)(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1)))(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))':
|
||||
dependencies:
|
||||
magic-string: 1.1.0
|
||||
oxc-walker: 1.1.1(@oxc-project/types@0.143.0)(oxc-parser@0.143.0)(rolldown@1.2.3)
|
||||
oxc-walker: 1.1.1(@oxc-project/types@0.149.0)(oxc-parser@0.143.0)(rolldown@1.2.3)
|
||||
unhead: 3.3.1(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.60.3)(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))
|
||||
unplugin: 3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.60.3)(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))
|
||||
optionalDependencies:
|
||||
@@ -25965,9 +26166,9 @@ snapshots:
|
||||
- rollup
|
||||
- unloader
|
||||
|
||||
'@unhead/vue@3.3.1(@oxc-project/types@0.143.0)(esbuild@0.28.1)(lightningcss@1.33.0)(oxc-parser@0.143.0)(rolldown@1.2.3)(rollup@4.60.3)(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue@3.5.41(typescript@6.0.2))(webpack@5.105.4(esbuild@0.28.1))':
|
||||
'@unhead/vue@3.3.1(@oxc-project/types@0.149.0)(esbuild@0.28.1)(lightningcss@1.33.0)(oxc-parser@0.143.0)(rolldown@1.2.3)(rollup@4.60.3)(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue@3.5.41(typescript@6.0.2))(webpack@5.105.4(esbuild@0.28.1))':
|
||||
dependencies:
|
||||
'@unhead/bundler': 3.3.1(@oxc-project/types@0.143.0)(esbuild@0.28.1)(lightningcss@1.33.0)(oxc-parser@0.143.0)(rolldown@1.2.3)(rollup@4.60.3)(unhead@3.3.1(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.60.3)(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1)))(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))
|
||||
'@unhead/bundler': 3.3.1(@oxc-project/types@0.149.0)(esbuild@0.28.1)(lightningcss@1.33.0)(oxc-parser@0.143.0)(rolldown@1.2.3)(rollup@4.60.3)(unhead@3.3.1(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.60.3)(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1)))(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))
|
||||
hookable: 6.1.1
|
||||
unhead: 3.3.1(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.60.3)(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))
|
||||
unplugin: 3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.60.3)(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))
|
||||
@@ -26795,7 +26996,7 @@ snapshots:
|
||||
|
||||
astring@1.9.0: {}
|
||||
|
||||
astro@7.2.9(@astrojs/markdown-remark@7.2.4(supports-color@8.1.1))(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.3)(@types/node@22.13.14)(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.4.5))(ioredis@5.10.1(supports-color@8.1.1))(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0):
|
||||
astro@7.2.9(@astrojs/markdown-remark@7.2.4(supports-color@8.1.1))(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.3)(@types/node@22.13.14)(aws4fetch@1.0.20)(db0@0.4.1)(ioredis@5.10.1(supports-color@8.1.1))(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0):
|
||||
dependencies:
|
||||
'@astrojs/compiler-rs': 0.4.0(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.3)
|
||||
'@astrojs/internal-helpers': 0.10.4
|
||||
@@ -26844,7 +27045,7 @@ snapshots:
|
||||
tinyglobby: 0.2.17
|
||||
ultrahtml: 1.7.0
|
||||
unifont: 0.7.5
|
||||
unstorage: 1.17.5(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.4.5))(ioredis@5.10.1(supports-color@8.1.1))
|
||||
unstorage: 1.17.5(aws4fetch@1.0.20)(db0@0.4.1)(ioredis@5.10.1(supports-color@8.1.1))
|
||||
vite: 8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)
|
||||
vitefu: 1.1.3(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))
|
||||
xxhash-wasm: 1.1.0
|
||||
@@ -27746,6 +27947,10 @@ snapshots:
|
||||
dependencies:
|
||||
uncrypto: 0.1.3
|
||||
|
||||
crossws@0.4.12(srvx@1.0.4):
|
||||
optionalDependencies:
|
||||
srvx: 1.0.4
|
||||
|
||||
crypto-js@4.2.0: {}
|
||||
|
||||
css-background-parser@0.1.0: {}
|
||||
@@ -28101,6 +28306,8 @@ snapshots:
|
||||
optionalDependencies:
|
||||
'@electric-sql/pglite': 0.4.5
|
||||
|
||||
db0@0.4.1: {}
|
||||
|
||||
dc-browser@1.0.4: {}
|
||||
|
||||
debounce-promise@3.1.2: {}
|
||||
@@ -28362,6 +28569,13 @@ snapshots:
|
||||
|
||||
env-paths@2.2.1: {}
|
||||
|
||||
env-runner@0.2.1:
|
||||
dependencies:
|
||||
crossws: 0.4.12(srvx@1.0.4)
|
||||
exsolve: 1.1.1
|
||||
httpxy: 0.5.5
|
||||
srvx: 1.0.4
|
||||
|
||||
err-code@2.0.3: {}
|
||||
|
||||
error-ex@1.3.2:
|
||||
@@ -29824,10 +30038,20 @@ snapshots:
|
||||
ufo: 1.6.4
|
||||
uncrypto: 0.1.3
|
||||
|
||||
h3@2.0.1-rc.20:
|
||||
h3@2.0.1-rc.20(crossws@0.4.12(srvx@1.0.4)):
|
||||
dependencies:
|
||||
rou3: 0.8.1
|
||||
srvx: 0.11.22
|
||||
optionalDependencies:
|
||||
crossws: 0.4.12(srvx@1.0.4)
|
||||
|
||||
h3@2.0.1-rc.31(crossws@0.4.12(srvx@1.0.4))(ocache@0.3.0):
|
||||
dependencies:
|
||||
rou3: 0.9.2
|
||||
srvx: 1.0.4
|
||||
optionalDependencies:
|
||||
crossws: 0.4.12(srvx@1.0.4)
|
||||
ocache: 0.3.0
|
||||
|
||||
hachure-fill@0.5.2: {}
|
||||
|
||||
@@ -30162,6 +30386,8 @@ snapshots:
|
||||
|
||||
httpxy@0.5.1: {}
|
||||
|
||||
httpxy@0.5.5: {}
|
||||
|
||||
human-signals@2.1.0: {}
|
||||
|
||||
human-signals@5.0.0: {}
|
||||
@@ -32606,8 +32832,26 @@ snapshots:
|
||||
- '@types/node'
|
||||
- babel-plugin-macros
|
||||
|
||||
nf3@0.3.24: {}
|
||||
|
||||
nice-try@1.0.5: {}
|
||||
|
||||
nitro@3.0.260903-beta:
|
||||
dependencies:
|
||||
consola: 3.4.2
|
||||
crossws: 0.4.12(srvx@1.0.4)
|
||||
db0: 0.4.1
|
||||
env-runner: 0.2.1
|
||||
h3: 2.0.1-rc.31(crossws@0.4.12(srvx@1.0.4))(ocache@0.3.0)
|
||||
hookable: 6.1.1
|
||||
nf3: 0.3.24
|
||||
ocache: 0.3.0
|
||||
rolldown: 1.2.8
|
||||
rou3: 0.9.2
|
||||
srvx: 1.0.4
|
||||
unenv: 2.0.0-rc.24
|
||||
unstorage: 2.0.0-alpha.10
|
||||
|
||||
nitropack@2.13.4(@electric-sql/pglite@0.4.5)(aws4fetch@1.0.20)(encoding@0.1.13)(oxc-parser@0.143.0)(rolldown@1.2.3)(supports-color@8.1.1)(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1)):
|
||||
dependencies:
|
||||
'@cloudflare/kv-asset-handler': 0.4.2
|
||||
@@ -32887,17 +33131,17 @@ snapshots:
|
||||
next: 15.5.25(@babel/core@7.29.7(supports-color@8.1.1))(@opentelemetry/api@1.9.1)(@playwright/test@1.59.1)(@types/node@22.13.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.77.4)
|
||||
react-router: 7.18.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
|
||||
nuxt@4.5.2(@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.29.7(supports-color@8.1.1)))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7(supports-color@8.1.1)))(@electric-sql/pglite@0.4.5)(@oxc-project/types@0.143.0)(@parcel/watcher@2.5.6)(@types/node@22.13.14)(@vue/compiler-sfc@3.5.41)(aws4fetch@1.0.20)(cac@6.7.14)(commander@14.0.1)(db0@0.3.4(@electric-sql/pglite@0.4.5))(encoding@0.1.13)(esbuild@0.28.1)(eslint@9.37.0(jiti@2.7.0)(supports-color@8.1.1))(ioredis@5.10.1(supports-color@8.1.1))(lightningcss@1.33.0)(magicast@0.5.4)(oxc-parser@0.143.0)(rolldown@1.2.3)(rollup-plugin-visualizer@7.0.1(rolldown@1.2.3)(rollup@4.60.3))(rollup@4.60.3)(sass@1.77.4)(supports-color@8.1.1)(terser@5.48.0)(tsx@4.22.4)(typescript@6.0.2)(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))(yaml@2.9.0):
|
||||
nuxt@4.5.2(@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.29.7(supports-color@8.1.1)))(@babel/plugin-syntax-typescript@7.29.7(@babel/core@7.29.7(supports-color@8.1.1)))(@electric-sql/pglite@0.4.5)(@oxc-project/types@0.149.0)(@parcel/watcher@2.5.6)(@types/node@22.13.14)(@vue/compiler-sfc@3.5.41)(aws4fetch@1.0.20)(cac@6.7.14)(commander@14.0.1)(db0@0.3.4(@electric-sql/pglite@0.4.5))(encoding@0.1.13)(esbuild@0.28.1)(eslint@9.37.0(jiti@2.7.0)(supports-color@8.1.1))(ioredis@5.10.1(supports-color@8.1.1))(lightningcss@1.33.0)(magicast@0.5.4)(oxc-parser@0.143.0)(rolldown@1.2.3)(rollup-plugin-visualizer@7.0.1(rolldown@1.2.8)(rollup@4.60.3))(rollup@4.60.3)(sass@1.77.4)(supports-color@8.1.1)(terser@5.48.0)(tsx@4.22.4)(typescript@6.0.2)(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))(yaml@2.9.0):
|
||||
dependencies:
|
||||
'@dxup/nuxt': 0.5.6(esbuild@0.28.1)(magicast@0.5.4)(oxc-parser@0.143.0)(rolldown@1.2.3)(rollup@4.60.3)(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))
|
||||
'@nuxt/cli': 3.37.0(@nuxt/schema@4.5.2)(cac@6.7.14)(commander@14.0.1)(magicast@0.5.4)(supports-color@8.1.1)
|
||||
'@nuxt/devtools': 3.4.1(aws4fetch@1.0.20)(db0@0.3.4(@electric-sql/pglite@0.4.5))(ioredis@5.10.1(supports-color@8.1.1))(magic-string@1.1.0)(oxc-parser@0.143.0)(rolldown@1.2.3)(supports-color@8.1.1)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.60.3)(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1)))(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue@3.5.41(typescript@6.0.2))
|
||||
'@nuxt/kit': 4.5.2(magic-string@1.1.0)(magicast@0.5.4)(oxc-parser@0.143.0)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.60.3)(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1)))
|
||||
'@nuxt/nitro-server': 4.5.2(c3f0ccbf4bde9bd4a229f96b3badde35)
|
||||
'@nuxt/nitro-server': 4.5.2(4bec0acf20c572958b2bb91f944fc6a0)
|
||||
'@nuxt/schema': 4.5.2
|
||||
'@nuxt/telemetry': 2.8.0(@nuxt/kit@4.5.2(magic-string@1.1.0)(magicast@0.5.4)(oxc-parser@0.143.0)(rolldown@1.2.3)(unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.60.3)(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1))))
|
||||
'@nuxt/vite-builder': 4.5.2(b8937c6da1cc25d65b2c4fd0e82c4d2a)
|
||||
'@unhead/vue': 3.3.1(@oxc-project/types@0.143.0)(esbuild@0.28.1)(lightningcss@1.33.0)(oxc-parser@0.143.0)(rolldown@1.2.3)(rollup@4.60.3)(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue@3.5.41(typescript@6.0.2))(webpack@5.105.4(esbuild@0.28.1))
|
||||
'@nuxt/vite-builder': 4.5.2(7593670026f098f90d303525f2479dbe)
|
||||
'@unhead/vue': 3.3.1(@oxc-project/types@0.149.0)(esbuild@0.28.1)(lightningcss@1.33.0)(oxc-parser@0.143.0)(rolldown@1.2.3)(rollup@4.60.3)(vite@7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(vue@3.5.41(typescript@6.0.2))(webpack@5.105.4(esbuild@0.28.1))
|
||||
'@vue/shared': 3.5.41
|
||||
chokidar: 5.0.0
|
||||
compatx: 0.2.0
|
||||
@@ -32924,7 +33168,7 @@ snapshots:
|
||||
ofetch: 1.5.1
|
||||
ohash: 2.0.11
|
||||
on-change: 6.0.2
|
||||
oxc-walker: 1.1.1(@oxc-project/types@0.143.0)(oxc-parser@0.143.0)(rolldown@1.2.3)
|
||||
oxc-walker: 1.1.1(@oxc-project/types@0.149.0)(oxc-parser@0.143.0)(rolldown@1.2.3)
|
||||
pathe: 2.0.3
|
||||
perfect-debounce: 2.1.0
|
||||
picomatch: 4.0.5
|
||||
@@ -33087,6 +33331,8 @@ snapshots:
|
||||
|
||||
obug@2.1.4: {}
|
||||
|
||||
ocache@0.3.0: {}
|
||||
|
||||
ofetch@1.5.1:
|
||||
dependencies:
|
||||
destr: 2.0.5
|
||||
@@ -33302,9 +33548,9 @@ snapshots:
|
||||
'@oxc-resolver/binding-win32-arm64-msvc': 11.24.2
|
||||
'@oxc-resolver/binding-win32-x64-msvc': 11.24.2
|
||||
|
||||
oxc-walker@1.1.1(@oxc-project/types@0.143.0)(oxc-parser@0.143.0)(rolldown@1.2.3):
|
||||
oxc-walker@1.1.1(@oxc-project/types@0.149.0)(oxc-parser@0.143.0)(rolldown@1.2.3):
|
||||
optionalDependencies:
|
||||
'@oxc-project/types': 0.143.0
|
||||
'@oxc-project/types': 0.149.0
|
||||
oxc-parser: 0.143.0
|
||||
rolldown: 1.2.3
|
||||
|
||||
@@ -34776,6 +35022,27 @@ snapshots:
|
||||
'@rolldown/binding-win32-arm64-msvc': 1.2.3
|
||||
'@rolldown/binding-win32-x64-msvc': 1.2.3
|
||||
|
||||
rolldown@1.2.8:
|
||||
dependencies:
|
||||
'@oxc-project/types': 0.149.0
|
||||
'@rolldown/pluginutils': 1.0.1
|
||||
optionalDependencies:
|
||||
'@rolldown/binding-android-arm-eabi': 1.2.8
|
||||
'@rolldown/binding-android-arm64': 1.2.8
|
||||
'@rolldown/binding-darwin-arm64': 1.2.8
|
||||
'@rolldown/binding-darwin-x64': 1.2.8
|
||||
'@rolldown/binding-freebsd-x64': 1.2.8
|
||||
'@rolldown/binding-linux-arm-gnueabihf': 1.2.8
|
||||
'@rolldown/binding-linux-arm64-gnu': 1.2.8
|
||||
'@rolldown/binding-linux-arm64-musl': 1.2.8
|
||||
'@rolldown/binding-linux-ppc64-gnu': 1.2.8
|
||||
'@rolldown/binding-linux-s390x-gnu': 1.2.8
|
||||
'@rolldown/binding-linux-x64-gnu': 1.2.8
|
||||
'@rolldown/binding-linux-x64-musl': 1.2.8
|
||||
'@rolldown/binding-openharmony-arm64': 1.2.8
|
||||
'@rolldown/binding-win32-arm64-msvc': 1.2.8
|
||||
'@rolldown/binding-win32-x64-msvc': 1.2.8
|
||||
|
||||
rollup-plugin-visualizer@7.0.1(rolldown@1.2.3)(rollup@4.60.3):
|
||||
dependencies:
|
||||
open: 11.0.0
|
||||
@@ -34786,6 +35053,17 @@ snapshots:
|
||||
rolldown: 1.2.3
|
||||
rollup: 4.60.3
|
||||
|
||||
rollup-plugin-visualizer@7.0.1(rolldown@1.2.8)(rollup@4.60.3):
|
||||
dependencies:
|
||||
open: 11.0.0
|
||||
picomatch: 4.0.7
|
||||
source-map: 0.7.6
|
||||
yargs: 18.0.0
|
||||
optionalDependencies:
|
||||
rolldown: 1.2.8
|
||||
rollup: 4.60.3
|
||||
optional: true
|
||||
|
||||
rollup@4.60.3:
|
||||
dependencies:
|
||||
'@types/estree': 1.0.8
|
||||
@@ -34821,6 +35099,8 @@ snapshots:
|
||||
|
||||
rou3@0.9.1: {}
|
||||
|
||||
rou3@0.9.2: {}
|
||||
|
||||
roughjs@4.6.6:
|
||||
dependencies:
|
||||
hachure-fill: 0.5.2
|
||||
@@ -35456,6 +35736,8 @@ snapshots:
|
||||
|
||||
srvx@0.11.22: {}
|
||||
|
||||
srvx@1.0.4: {}
|
||||
|
||||
sse.js@2.2.0: {}
|
||||
|
||||
ssri@10.0.6:
|
||||
@@ -36414,14 +36696,14 @@ snapshots:
|
||||
vite: 7.3.5(@types/node@22.13.14)(jiti@2.7.0)(lightningcss@1.33.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)
|
||||
webpack: 5.105.4(esbuild@0.28.1)
|
||||
|
||||
unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.3)(rollup@4.60.3)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1)):
|
||||
unplugin@3.3.0(esbuild@0.28.1)(rolldown@1.2.8)(rollup@4.60.3)(vite@8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.105.4(esbuild@0.28.1)):
|
||||
dependencies:
|
||||
'@jridgewell/remapping': 2.3.5
|
||||
picomatch: 4.0.5
|
||||
webpack-virtual-modules: 0.6.2
|
||||
optionalDependencies:
|
||||
esbuild: 0.28.1
|
||||
rolldown: 1.2.3
|
||||
rolldown: 1.2.8
|
||||
rollup: 4.60.3
|
||||
vite: 8.2.1(@types/node@22.13.14)(esbuild@0.28.1)(jiti@2.7.0)(sass@1.77.4)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)
|
||||
webpack: 5.105.4(esbuild@0.28.1)
|
||||
@@ -36446,6 +36728,23 @@ snapshots:
|
||||
db0: 0.3.4(@electric-sql/pglite@0.4.5)
|
||||
ioredis: 5.10.1(supports-color@8.1.1)
|
||||
|
||||
unstorage@1.17.5(aws4fetch@1.0.20)(db0@0.4.1)(ioredis@5.10.1(supports-color@8.1.1)):
|
||||
dependencies:
|
||||
anymatch: 3.1.3
|
||||
chokidar: 5.0.0
|
||||
destr: 2.0.5
|
||||
h3: 1.15.11
|
||||
lru-cache: 11.3.6
|
||||
node-fetch-native: 1.6.7
|
||||
ofetch: 1.5.1
|
||||
ufo: 1.6.4
|
||||
optionalDependencies:
|
||||
aws4fetch: 1.0.20
|
||||
db0: 0.4.1
|
||||
ioredis: 5.10.1(supports-color@8.1.1)
|
||||
|
||||
unstorage@2.0.0-alpha.10: {}
|
||||
|
||||
until-async@3.0.2: {}
|
||||
|
||||
untun@0.1.3:
|
||||
|
||||
@@ -20,17 +20,19 @@ const defaultEnv = {
|
||||
POSTGRES_HOST: 'db',
|
||||
POSTGRES_DB: 'postgres',
|
||||
POSTGRES_PORT: '5432',
|
||||
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',
|
||||
// Literal values, not `$API_URL` references: the TanStack server is started
|
||||
// with Node's --env-file, which does not expand variables.
|
||||
SUPABASE_ANON_KEY: generatedEnv.ANON_KEY,
|
||||
SUPABASE_SERVICE_KEY: generatedEnv.SERVICE_ROLE_KEY,
|
||||
SUPABASE_URL: generatedEnv.API_URL,
|
||||
STUDIO_PG_META_URL: `${generatedEnv.API_URL}/pg`,
|
||||
SUPABASE_PUBLIC_URL: generatedEnv.API_URL,
|
||||
SENTRY_IGNORE_API_RESOLUTION_ERROR: '1',
|
||||
LOGFLARE_URL: 'http://127.0.0.1:54327',
|
||||
LOGFLARE_PRIVATE_ACCESS_TOKEN: 'api-key',
|
||||
LOGFLARE_API_KEY: 'api-key',
|
||||
NEXT_PUBLIC_SITE_URL: 'http://localhost:8082',
|
||||
NEXT_PUBLIC_GOTRUE_URL: '$SUPABASE_PUBLIC_URL/auth/v1',
|
||||
NEXT_PUBLIC_GOTRUE_URL: `${generatedEnv.API_URL}/auth/v1`,
|
||||
NEXT_PUBLIC_HCAPTCHA_SITE_KEY: '10000000-ffff-ffff-ffff-000000000001',
|
||||
NEXT_PUBLIC_NODE_ENV: 'test',
|
||||
SNIPPETS_MANAGEMENT_FOLDER: '../../supabase/snippets',
|
||||
|
||||
Reference in new issue
Block a user