From 2d182c74412dad7149d2cb4ca4d5822a5ae046fd Mon Sep 17 00:00:00 2001 From: Tanner Linsley Date: Mon, 20 Jan 2025 17:33:42 -0700 Subject: [PATCH] fix: replace vinxi/https exports with start/server exports --- docs/framework/react/guide/tanstack-start.md | 17 +- docs/framework/react/overview.md | 2 +- docs/framework/react/start/api-routes.md | 8 +- .../react/start/build-from-scratch.md | 7 +- .../framework/react/start/learn-the-basics.md | 2 - docs/framework/react/start/overview.md | 4 +- .../framework/react/start/server-functions.md | 24 +- e2e/start/basic-auth/app/utils/session.ts | 2 +- e2e/start/basic/app/routes/status.tsx | 2 +- e2e/start/clerk-basic/app/routes/__root.tsx | 4 +- .../start-basic-auth/app/utils/session.ts | 2 +- .../start-clerk-basic/app/routes/__root.tsx | 4 +- .../app/utils/supabase.ts | 2 +- .../trpc-server.handler.ts | 2 +- .../react/with-trpc/trpc-server.handler.ts | 2 +- packages/start/package.json | 2 + packages/start/src/api/index.ts | 4 +- packages/start/src/server-handler/index.tsx | 7 +- .../start/src/server/createStartHandler.ts | 13 +- packages/start/src/server/index.tsx | 375 ++++++++++++++++++ packages/start/vite.config.ts | 1 + pnpm-lock.yaml | 89 +++-- 22 files changed, 496 insertions(+), 79 deletions(-) diff --git a/docs/framework/react/guide/tanstack-start.md b/docs/framework/react/guide/tanstack-start.md index d7cd312bde..7068d8b914 100644 --- a/docs/framework/react/guide/tanstack-start.md +++ b/docs/framework/react/guide/tanstack-start.md @@ -43,7 +43,14 @@ Create a `tsconfig.json` file with at least the following settings: # Install Dependencies -TanStack Start is powered by [Vinxi](https://vinxi.vercel.app/) and [TanStack Router](https://tanstack.com/router) and requires them as dependencies. +TanStack Start is powered by the following packages and need to be installed as dependencies: + +- [@tanstack/start](https://github.com/tanstack/start) +- [@tanstack/react-router](https://tanstack.com/router) +- [Vinxi](https://vinxi.vercel.app/) + +> [!NOTE] +> Vinxi is a temporary dependency that will be replaced by a simple vite plugin or a dedicated Start CLI. To install them, run: @@ -51,13 +58,13 @@ To install them, run: npm i @tanstack/start @tanstack/react-router vinxi ``` -You'll also need React and the Vite React plugin, so install them too: +You'll also need React and the Vite React plugin, so install their dependencies as well: ```shell npm i react react-dom @vitejs/plugin-react ``` -and some TypeScript: +Please, for you, your fellow developers, and your users' sake, use TypeScript: ```shell npm i -D typescript @types/react @types/react-dom @@ -65,7 +72,7 @@ npm i -D typescript @types/react @types/react-dom # Update Configuration Files -We'll then update our `package.json` to reference the new Vinxi entry point and set `"type": "module"`: +We'll then update our `package.json` to use Vinxi's CLI and set `"type": "module"`: ```jsonc { @@ -79,7 +86,7 @@ We'll then update our `package.json` to reference the new Vinxi entry point and } ``` -To tell Vinxi that it should start TanStack Start's minimal behavior, we need to configure the `app.config.ts` file: +Then configure TanStack Start's `app.config.ts` file: ```typescript // app.config.ts diff --git a/docs/framework/react/overview.md b/docs/framework/react/overview.md index 9b44eea08f..a59254e08b 100644 --- a/docs/framework/react/overview.md +++ b/docs/framework/react/overview.md @@ -38,7 +38,7 @@ It's probably no surprise at this point that picking a router is so important th **Does this mean that TanStack Router is a framework?** -TanStack Router itself is not a "framework" in the traditional sense, since it doesn't address a few other common full-stack concerns. However TanStack Router has been designed to be upgradable to a full-stack framework when used in conjunction with other tools that address bundling, deployments, and server-side-specific functionality. This is why we are currently developing [TanStack Start](https://tanstack.com/start), a full-stack framework that is built on top of TanStack Router and tools like Vinxi, Nitro, and Vite. +TanStack Router itself is not a "framework" in the traditional sense, since it doesn't address a few other common full-stack concerns. However TanStack Router has been designed to be upgradable to a full-stack framework when used in conjunction with other tools that address bundling, deployments, and server-side-specific functionality. This is why we are currently developing [TanStack Start](https://tanstack.com/start), a full-stack framework that is built on top of TanStack Router and tools like Nitro, and Vite. For a deeper dive on the history of TanStack Router, feel free to read [TanStack Router's History](./decisions-on-dx.md#tanstack-routers-origin-story). diff --git a/docs/framework/react/start/api-routes.md b/docs/framework/react/start/api-routes.md index ec3a51fd92..7354c2eca9 100644 --- a/docs/framework/react/start/api-routes.md +++ b/docs/framework/react/start/api-routes.md @@ -237,13 +237,13 @@ You can set the status code of the response by either: }) ``` -- Using the `setResponseStatus` helper function from `vinxi/http` +- Using the `setResponseStatus` helper function from `@tanstack/start/server` ```ts // routes/api/hello.ts import { json } from '@tanstack/start' import { createAPIFileRoute } from '@tanstack/start/api' - import { setResponseStatus } from 'vinxi/http' + import { setResponseStatus } from '@tanstack/start/server' export const APIRoute = createAPIFileRoute('/users/$id')({ GET: async ({ request, params }) => { @@ -283,12 +283,12 @@ Sometimes you may need to set headers in the response. You can do this by either // Hello, World! ``` -- Or using the `setHeaders` helper function from `vinxi/http`. +- Or using the `setHeaders` helper function from `@tanstack/start/server`. ```ts // routes/api/hello.ts import { createAPIFileRoute } from '@tanstack/start/api' - import { setHeaders } from 'vinxi/http' + import { setHeaders } from '@tanstack/start/server' export const APIRoute = createAPIFileRoute('/hello')({ GET: async ({ request }) => { diff --git a/docs/framework/react/start/build-from-scratch.md b/docs/framework/react/start/build-from-scratch.md index df7bf2dbff..8ed2b2ccab 100644 --- a/docs/framework/react/start/build-from-scratch.md +++ b/docs/framework/react/start/build-from-scratch.md @@ -45,7 +45,7 @@ We highly recommend using TypeScript with TanStack Start. Create a `tsconfig.jso TanStack Start is (currently\*) powered by [Vinxi](https://vinxi.vercel.app/) and [TanStack Router](https://tanstack.com/router) and requires them as dependencies. -> [!NOTE] > \*Vinxi will be removed before version 1.0.0 is released and TanStack will rely only on Vite and Nitro. The commands and APIs that use Vinxi will likely be replaced with a Vite plugin. +> [!NOTE] > \*Vinxi will be removed before version 1.0.0 is released and TanStack will rely only on Vite and Nitro. The commands and APIs that use Vinxi will likely be replaced with a Vite plugin or dedicated TanStack Start CLI. To install them, run: @@ -67,7 +67,7 @@ npm i -D typescript @types/react @types/react-dom ## Update Configuration Files -We'll then update our `package.json` to reference the new Vinxi entry point and set `"type": "module"`: +We'll then update our `package.json` to use Vinxi's CLI and set `"type": "module"`: ```json { @@ -81,7 +81,7 @@ We'll then update our `package.json` to reference the new Vinxi entry point and } ``` -To tell Vinxi that it should start TanStack Start's minimal behavior, we need to configure the `app.config.ts` file: +Then configure TanStack Start's `app.config.ts` file: ```typescript // app.config.ts @@ -160,7 +160,6 @@ information to our server entry point: ```tsx // app/ssr.tsx -/// import { createStartHandler, defaultStreamHandler, diff --git a/docs/framework/react/start/learn-the-basics.md b/docs/framework/react/start/learn-the-basics.md index c58f0efab7..89196b484f 100644 --- a/docs/framework/react/start/learn-the-basics.md +++ b/docs/framework/react/start/learn-the-basics.md @@ -52,7 +52,6 @@ This is done via the `app/ssr.tsx` file: ```tsx // app/ssr.tsx -/// import { createStartHandler, defaultStreamHandler, @@ -79,7 +78,6 @@ Getting our html to the client is only half the battle. Once there, we need to h ```tsx // app/client.tsx -/// import { hydrateRoot } from 'react-dom/client' import { StartClient } from '@tanstack/start' import { createRouter } from './router' diff --git a/docs/framework/react/start/overview.md b/docs/framework/react/start/overview.md index 4f259935ef..aeda041902 100644 --- a/docs/framework/react/start/overview.md +++ b/docs/framework/react/start/overview.md @@ -3,7 +3,7 @@ id: overview title: TanStack Start Overview --- -TanStack Start is a full-stack React framework powered by TanStack Router. It provides a full-document SSR, streaming, server functions, bundling, and more, powered by TanStack Router, Vinxi, and Vite. It is ready to deploy to your favorite hosting provider! +TanStack Start is a full-stack React framework powered by TanStack Router. It provides a full-document SSR, streaming, server functions, bundling, and more using tools like [Nitro](https://nitro.unjs.io/) and [Vite](https://vitejs.dev/). It is ready to deploy to your favorite hosting provider! ## Router or Start? @@ -39,7 +39,7 @@ What you get with TanStack Start: ## How does it work? -TanStack Start uses a tool called **Vinxi** to bundle and deploy your application. In fact, this is the same tool that powers Solid Start! With Vinxi, we can do a few things we couldn't do before: +TanStack Start uses [Nitro](https://nitro.unjs.io/) and [Vite](https://vitejs.dev/) to bundle and deploy your application. In fact, these are the same tools that power Solid Start! With these tools, we can do a few things we couldn't do before: - Provide a unified API for SSR, streaming, and hydration - Extract server-only code from your client-side code (e.g. server functions) diff --git a/docs/framework/react/start/server-functions.md b/docs/framework/react/start/server-functions.md index a18c0e342e..243752a88d 100644 --- a/docs/framework/react/start/server-functions.md +++ b/docs/framework/react/start/server-functions.md @@ -321,7 +321,7 @@ function Test() { ## Server Function Context -In addition to the single parameter that server functions accept, you can also access server request context from within any server function using utilities from `vinxi/http`. Under the hood, Vinxi uses `unjs`'s `h3` package to perform cross-platform HTTP requests. +In addition to the single parameter that server functions accept, you can also access server request context from within any server function using utilities from `@tanstack/start/server`. Under the hood, we use [Unjs](https://unjs.io/)'s `h3` package to perform cross-platform HTTP requests. There are many context functions available to you for things like: @@ -332,17 +332,17 @@ There are many context functions available to you for things like: - Dealing with multi-part form data - Reading/Setting custom server context properties -For a full list of available context functions, see all of the available [h3 Methods](https://h3.unjs.io/utils/request) or inspect the [Vinxi Exports Source Code](https://github.com/nksaraf/vinxi/blob/main/packages/vinxi/runtime/http.js#L232-L320). +For a full list of available context functions, see all of the available [h3 Methods](https://h3.unjs.io/utils/request) or inspect the [@tanstack/start/server Source Code](https://github.com/tanstack/router/tree/main/packages/start/src/server/index.tsx). For starters, here are a few examples: ## Accessing the Request Context -Let's use Vinxi's `getWebRequest` function to access the request itself from within a server function: +Let's use the `getWebRequest` function to access the request itself from within a server function: ```tsx import { createServerFn } from '@tanstack/start' -import { getWebRequest } from 'vinxi/http' +import { getWebRequest } from '@tanstack/start/server' export const getServerTime = createServerFn({ method: 'GET' }).handler( async () => { @@ -357,11 +357,11 @@ export const getServerTime = createServerFn({ method: 'GET' }).handler( ## Accessing Headers -Use Vinxi's `getHeaders` function to access all headers from within a server function: +Use the `getHeaders` function to access all headers from within a server function: ```tsx import { createServerFn } from '@tanstack/start' -import { getHeaders } from 'vinxi/http' +import { getHeaders } from '@tanstack/start/server' export const getServerTime = createServerFn({ method: 'GET' }).handler( async () => { @@ -382,7 +382,7 @@ You can also access individual headers using the `getHeader` function: ```tsx import { createServerFn } from '@tanstack/start' -import { getHeader } from 'vinxi/http' +import { getHeader } from '@tanstack/start/server' export const getServerTime = createServerFn({ method: 'GET' }).handler( async () => { @@ -427,11 +427,11 @@ By default, server functions assume that any non-Response object returned is eit ## Responding with Custom Headers -To respond with custom headers, you can use Vinxi's `setHeader` function: +To respond with custom headers, you can use the `setHeader` function: ```tsx import { createServerFn } from '@tanstack/start' -import { setHeader } from 'vinxi/http' +import { setHeader } from '@tanstack/start/server' export const getServerTime = createServerFn({ method: 'GET' }).handler( async () => { @@ -443,11 +443,11 @@ export const getServerTime = createServerFn({ method: 'GET' }).handler( ## Responding with Custom Status Codes -To respond with a custom status code, you can use Vinxi's `setResponseStatus` function: +To respond with a custom status code, you can use the `setResponseStatus` function: ```tsx import { createServerFn } from '@tanstack/start' -import { setResponseStatus } from 'vinxi/http' +import { setResponseStatus } from '@tanstack/start/server' export const getServerTime = createServerFn({ method: 'GET' }).handler( async () => { @@ -599,7 +599,7 @@ export const auth = createServerFn({ method: 'GET' }).handler(async () => { }) ``` -> ⚠️ Do not use Vinxi's `sendRedirect` function to send soft redirects from within server functions. This will send the redirect using the `Location` header and will force a full page hard navigation on the client. +> ⚠️ Do not use `@tanstack/start/server`'s `sendRedirect` function to send soft redirects from within server functions. This will send the redirect using the `Location` header and will force a full page hard navigation on the client. ## Redirect Headers diff --git a/e2e/start/basic-auth/app/utils/session.ts b/e2e/start/basic-auth/app/utils/session.ts index 08d28177cb..b4e5fc5bf3 100644 --- a/e2e/start/basic-auth/app/utils/session.ts +++ b/e2e/start/basic-auth/app/utils/session.ts @@ -1,5 +1,5 @@ // app/services/session.server.ts -import { useSession } from 'vinxi/http' +import { useSession } from '@tanstack/start/server' import type { User } from '@prisma/client' type SessionUser = { diff --git a/e2e/start/basic/app/routes/status.tsx b/e2e/start/basic/app/routes/status.tsx index cc6187275f..59c961c74d 100644 --- a/e2e/start/basic/app/routes/status.tsx +++ b/e2e/start/basic/app/routes/status.tsx @@ -1,6 +1,6 @@ import { createFileRoute } from '@tanstack/react-router' import { createServerFn, useServerFn } from '@tanstack/start' -import { setResponseStatus } from 'vinxi/http' +import { setResponseStatus } from '@tanstack/start/server' const helloFn = createServerFn().handler(() => { setResponseStatus(225, `hello`) diff --git a/e2e/start/clerk-basic/app/routes/__root.tsx b/e2e/start/clerk-basic/app/routes/__root.tsx index ffcca2b011..e1ee17b41d 100644 --- a/e2e/start/clerk-basic/app/routes/__root.tsx +++ b/e2e/start/clerk-basic/app/routes/__root.tsx @@ -16,13 +16,13 @@ import { TanStackRouterDevtools } from '@tanstack/router-devtools' import { Meta, Scripts, createServerFn } from '@tanstack/start' import * as React from 'react' import { getAuth } from '@clerk/tanstack-start/server' -import { getWebRequest } from 'vinxi/http' +import { getWebRequest } from '@tanstack/start/server' import { DefaultCatchBoundary } from '~/components/DefaultCatchBoundary.js' import { NotFound } from '~/components/NotFound.js' import appCss from '~/styles/app.css?url' const fetchClerkAuth = createServerFn({ method: 'GET' }).handler(async () => { - const user = await getAuth(getWebRequest()) + const user = await getAuth(getWebRequest()!) return { user, diff --git a/examples/react/start-basic-auth/app/utils/session.ts b/examples/react/start-basic-auth/app/utils/session.ts index 08d28177cb..b4e5fc5bf3 100644 --- a/examples/react/start-basic-auth/app/utils/session.ts +++ b/examples/react/start-basic-auth/app/utils/session.ts @@ -1,5 +1,5 @@ // app/services/session.server.ts -import { useSession } from 'vinxi/http' +import { useSession } from '@tanstack/start/server' import type { User } from '@prisma/client' type SessionUser = { diff --git a/examples/react/start-clerk-basic/app/routes/__root.tsx b/examples/react/start-clerk-basic/app/routes/__root.tsx index 2ebf5816f1..653335c52b 100644 --- a/examples/react/start-clerk-basic/app/routes/__root.tsx +++ b/examples/react/start-clerk-basic/app/routes/__root.tsx @@ -16,13 +16,13 @@ import { TanStackRouterDevtools } from '@tanstack/router-devtools' import { Meta, Scripts, createServerFn } from '@tanstack/start' import * as React from 'react' import { getAuth } from '@clerk/tanstack-start/server' -import { getWebRequest } from 'vinxi/http' +import { getWebRequest } from '@tanstack/start/server' import { DefaultCatchBoundary } from '~/components/DefaultCatchBoundary.js' import { NotFound } from '~/components/NotFound.js' import appCss from '~/styles/app.css?url' const fetchClerkAuth = createServerFn({ method: 'GET' }).handler(async () => { - const { userId } = await getAuth(getWebRequest()) + const { userId } = await getAuth(getWebRequest()!) return { userId, diff --git a/examples/react/start-supabase-basic/app/utils/supabase.ts b/examples/react/start-supabase-basic/app/utils/supabase.ts index b7d33639d4..feaf35fba6 100644 --- a/examples/react/start-supabase-basic/app/utils/supabase.ts +++ b/examples/react/start-supabase-basic/app/utils/supabase.ts @@ -1,4 +1,4 @@ -import { parseCookies, setCookie } from 'vinxi/http' +import { parseCookies, setCookie } from '@tanstack/start/server' import { createServerClient } from '@supabase/ssr' export function getSupabaseServerClient() { diff --git a/examples/react/with-trpc-react-query/trpc-server.handler.ts b/examples/react/with-trpc-react-query/trpc-server.handler.ts index 7149102360..8bd181b015 100644 --- a/examples/react/with-trpc-react-query/trpc-server.handler.ts +++ b/examples/react/with-trpc-react-query/trpc-server.handler.ts @@ -1,4 +1,4 @@ -import { defineEventHandler, toWebRequest } from 'vinxi/http' +import { defineEventHandler, toWebRequest } from '@tanstack/start/server' import { initTRPC } from '@trpc/server' import { fetchRequestHandler } from '@trpc/server/adapters/fetch' diff --git a/examples/react/with-trpc/trpc-server.handler.ts b/examples/react/with-trpc/trpc-server.handler.ts index 3a74b1a2ae..a2de012cbd 100644 --- a/examples/react/with-trpc/trpc-server.handler.ts +++ b/examples/react/with-trpc/trpc-server.handler.ts @@ -1,4 +1,4 @@ -import { defineEventHandler, toWebRequest } from 'vinxi/http' +import { defineEventHandler, toWebRequest } from '@tanstack/start/server' import { initTRPC } from '@trpc/server' import { fetchRequestHandler } from '@trpc/server/adapters/fetch' diff --git a/packages/start/package.json b/packages/start/package.json index 7c974abdf9..d2c227cbe4 100644 --- a/packages/start/package.json +++ b/packages/start/package.json @@ -144,11 +144,13 @@ "@vinxi/server-components": "0.5.0", "@vinxi/server-functions": "0.5.0", "@vitejs/plugin-react": "^4.3.4", + "h3": "^1.13.1", "import-meta-resolve": "^4.1.0", "isbot": "^5.1.17", "jsesc": "^3.0.2", "ofetch": "^1.4.1", "tiny-invariant": "^1.3.3", + "unctx": "^2.4.1", "vinxi": "0.5.1", "zod": "^3.24.1" }, diff --git a/packages/start/src/api/index.ts b/packages/start/src/api/index.ts index 78e645b44d..04f79ea9f2 100644 --- a/packages/start/src/api/index.ts +++ b/packages/start/src/api/index.ts @@ -1,4 +1,4 @@ -import { eventHandler, toWebRequest } from 'vinxi/http' +import { eventHandler, toWebRequest } from '@tanstack/start/server' import vinxiFileRoutes from 'vinxi/routes' import type { ResolveParams } from '@tanstack/react-router' @@ -29,7 +29,7 @@ export type HTTP_API_METHOD = (typeof HTTP_API_METHODS)[number] */ export function createStartAPIHandler(cb: StartAPIHandlerCallback) { return eventHandler(async (event) => { - const request = toWebRequest(event) + const request = toWebRequest(event)! const res = await cb({ request }) return res }) diff --git a/packages/start/src/server-handler/index.tsx b/packages/start/src/server-handler/index.tsx index afc4a1a7ff..adb1020c40 100644 --- a/packages/start/src/server-handler/index.tsx +++ b/packages/start/src/server-handler/index.tsx @@ -1,4 +1,3 @@ -/// import { defaultTransformer, isNotFound, @@ -11,10 +10,10 @@ import { getEvent, getResponseStatus, toWebRequest, -} from 'vinxi/http' +} from '@tanstack/start/server' // @ts-expect-error import _serverFnManifest from 'tsr:server-fn-manifest' -import type { H3Event } from 'vinxi/server' +import type { H3Event } from '@tanstack/start/server' export default eventHandler(handleServerAction) @@ -28,7 +27,7 @@ const serverFnManifest = _serverFnManifest as Record< > async function handleServerAction(event: H3Event) { - return handleServerRequest(toWebRequest(event), event) + return handleServerRequest(toWebRequest(event)!, event) } function sanitizeBase(base: string | undefined) { diff --git a/packages/start/src/server/createStartHandler.ts b/packages/start/src/server/createStartHandler.ts index 99d8b7a21c..b1c86a8865 100644 --- a/packages/start/src/server/createStartHandler.ts +++ b/packages/start/src/server/createStartHandler.ts @@ -1,14 +1,18 @@ -import { eventHandler, getResponseHeaders, toWebRequest } from 'vinxi/http' +import { + eventHandler, + getResponseHeaders, + toWebRequest, +} from '@tanstack/start/server' import { createMemoryHistory } from '@tanstack/react-router' import { serializeLoaderData } from '../client/serialization' import { mergeHeaders } from '../client/headers' -import type { EventHandler, EventHandlerRequest, H3Event } from 'vinxi/http' +import type { H3Event } from '@tanstack/start/server' import type { AnyRouter, Manifest } from '@tanstack/react-router' import type { HandlerCallback } from './defaultStreamHandler' export type CustomizeStartHandler = ( cb: HandlerCallback, -) => EventHandler +) => ReturnType export function createStartHandler({ createRouter, @@ -20,6 +24,7 @@ export function createStartHandler({ return (cb) => { return eventHandler(async (event) => { const request = toWebRequest(event) + if (!request) throw new Error('No request found') const url = new URL(request.url) const href = url.href.replace(url.origin, '') @@ -62,7 +67,7 @@ export function createStartHandler({ } function getRequestHeaders(opts: { - event: H3Event + event: H3Event router: AnyRouter }): Headers { ;(opts.event as any).__tsrHeadersSent = true diff --git a/packages/start/src/server/index.tsx b/packages/start/src/server/index.tsx index 56448dd9f3..0fd7d4a1f3 100644 --- a/packages/start/src/server/index.tsx +++ b/packages/start/src/server/index.tsx @@ -1,7 +1,382 @@ /// +import { AsyncLocalStorage } from 'node:async_hooks' +import { + H3Event, + appendCorsHeaders as _appendCorsHeaders, + appendCorsPreflightHeaders as _appendCorsPreflightHeaders, + appendHeader as _appendHeader, + appendHeaders as _appendHeaders, + appendResponseHeader as _appendResponseHeader, + appendResponseHeaders as _appendResponseHeaders, + assertMethod as _assertMethod, + clearResponseHeaders as _clearResponseHeaders, + clearSession as _clearSession, + defaultContentType as _defaultContentType, + deleteCookie as _deleteCookie, + fetchWithEvent as _fetchWithEvent, + getCookie as _getCookie, + getHeader as _getHeader, + getHeaders as _getHeaders, + getProxyRequestHeaders as _getProxyRequestHeaders, + getQuery as _getQuery, + getRequestFingerprint as _getRequestFingerprint, + getRequestHeader as _getRequestHeader, + getRequestHeaders as _getRequestHeaders, + getRequestHost as _getRequestHost, + getRequestIP as _getRequestIP, + getRequestProtocol as _getRequestProtocol, + getRequestURL as _getRequestURL, + getRequestWebStream as _getRequestWebStream, + getResponseHeader as _getResponseHeader, + getResponseHeaders as _getResponseHeaders, + getResponseStatus as _getResponseStatus, + getResponseStatusText as _getResponseStatusText, + getRouterParam as _getRouterParam, + getRouterParams as _getRouterParams, + getSession as _getSession, + getValidatedQuery as _getValidatedQuery, + getValidatedRouterParams as _getValidatedRouterParams, + handleCacheHeaders as _handleCacheHeaders, + handleCors as _handleCors, + isMethod as _isMethod, + isPreflightRequest as _isPreflightRequest, + parseCookies as _parseCookies, + proxyRequest as _proxyRequest, + readBody as _readBody, + readFormData as _readFormData, + readMultipartFormData as _readMultipartFormData, + readRawBody as _readRawBody, + readValidatedBody as _readValidatedBody, + removeResponseHeader as _removeResponseHeader, + sealSession as _sealSession, + send as _send, + sendError as _sendError, + sendNoContent as _sendNoContent, + sendProxy as _sendProxy, + sendRedirect as _sendRedirect, + sendStream as _sendStream, + sendWebResponse as _sendWebResponse, + setCookie as _setCookie, + setHeader as _setHeader, + setHeaders as _setHeaders, + setResponseHeader as _setResponseHeader, + setResponseHeaders as _setResponseHeaders, + setResponseStatus as _setResponseStatus, + unsealSession as _unsealSession, + updateSession as _updateSession, + useBase as _useBase, + useSession as _useSession, + writeEarlyHints as _writeEarlyHints, +} from 'h3' +import { getContext as getUnctxContext } from 'unctx' +import type { _RequestMiddleware, _ResponseMiddleware } from 'h3' + export { StartServer } from './StartServer' export { createStartHandler } from './createStartHandler' export { createRequestHandler } from './createRequestHandler' export { defaultStreamHandler } from './defaultStreamHandler' export { defaultRenderHandler } from './defaultRenderHandler' + +function _setContext(event: H3Event, key: string, value: any) { + event.context[key] = value +} + +function _getContext(event: H3Event, key: string) { + return event.context[key] +} + +export function defineMiddleware(options: { + onRequest?: _RequestMiddleware | Array<_RequestMiddleware> + onBeforeResponse?: _ResponseMiddleware | Array<_ResponseMiddleware> +}) { + return options +} + +function toWebRequestH3(event: H3Event) { + /** + * @type {ReadableStream | undefined} + */ + let readableStream: ReadableStream | undefined + + const url = getRequestURL(event) + const base = { + // @ts-ignore Undici option + duplex: 'half', + method: event.method, + headers: event.headers, + } + + if ((event.node.req as any).body instanceof ArrayBuffer) { + return new Request(url, { + ...base, + body: (event.node.req as any).body, + }) + } + + return new Request(url, { + ...base, + get body() { + if (readableStream) { + return readableStream + } + readableStream = getRequestWebStream(event) + return readableStream + }, + }) +} + +export function toWebRequest(event: H3Event) { + event.web ??= { + request: toWebRequestH3(event), + url: getRequestURL(event), + } + return event.web.request +} + +export { + H3Error, + H3Event, + MIMES, + callNodeListener, + createApp, + createAppEventHandler, + createEvent, + createRouter, + defineEventHandler, + defineLazyEventHandler, + defineNodeListener, + defineNodeMiddleware, + defineRequestMiddleware, + defineResponseMiddleware, + dynamicEventHandler, + defineWebSocket, + eventHandler, + splitCookiesString, + fromNodeMiddleware, + fromPlainHandler, + fromWebHandler, + isError, + isEventHandler, + isWebResponse, + lazyEventHandler, + promisifyNodeListener, + serveStatic, + toEventHandler, + toNodeListener, + toPlainHandler, + toWebHandler, + isCorsOriginAllowed, + isStream, + createError, + sanitizeStatusCode, + sanitizeStatusMessage, + type AddRouteShortcuts, + type App, + type AppOptions, + type AppUse, + type CacheConditions, + type CreateRouterOptions, + type Duplex, + type DynamicEventHandler, + type Encoding, + type EventHandler, + type EventHandlerObject, + type EventHandlerRequest, + type EventHandlerResponse, + type H3CorsOptions, + type H3EventContext, + type HTTPHeaderName, + type HTTPMethod, + type InferEventInput, + type InputLayer, + type InputStack, + type Layer, + type LazyEventHandler, + type Matcher, + type MultiPartData, + type NodeEventContext, + type NodeListener, + type NodeMiddleware, + type NodePromisifiedHandler, + type PlainHandler, + type PlainRequest, + type PlainResponse, + type ProxyOptions, + type RequestFingerprintOptions, + type RequestHeaders, + type RouteNode, + type Router, + type RouterMethod, + type RouterUse, + type ServeStaticOptions, + type Session, + type SessionConfig, + type SessionData, + type Stack, + type StaticAssetMeta, + type ValidateFunction, + type ValidateResult, + type WebEventContext, + type WebHandler, + type _RequestMiddleware, + type _ResponseMiddleware, +} from 'h3' + +function getHTTPEvent() { + return getEvent() +} + +export const HTTPEventSymbol = Symbol('$HTTPEvent') + +export function isEvent(obj: any) { + return ( + typeof obj === 'object' && + (obj instanceof H3Event || + obj?.[HTTPEventSymbol] instanceof H3Event || + obj?.__is_event__ === true) + ) + // Implement logic to check if obj is an H3Event +} + +function createWrapperFunction) => any>( + h3Function: TFn, +): ( + ...args: Parameters extends [H3Event, ...infer TArgs] + ? TArgs | Parameters + : Parameters +) => ReturnType { + return function (...args: Array) { + let event = args[0] + if (!isEvent(event)) { + if (!(globalThis as any).app.config.server.experimental?.asyncContext) { + throw new Error( + 'AsyncLocalStorage was not enabled. Use the `server.experimental.asyncContext: true` option in your app configuration to enable it. Or, pass the instance of HTTPEvent that you have as the first argument to the function.', + ) + } + event = getHTTPEvent() + if (!event) { + throw new Error( + `No HTTPEvent found in AsyncLocalStorage. Make sure you are using the function within the server runtime.`, + ) + } + args.unshift(event) + } else { + args[0] = + event instanceof H3Event || event.__is_event__ + ? event + : event[HTTPEventSymbol] + } + + return (h3Function as any)(...args) + } +} + +// Creating wrappers for each utility and exporting them with their original names +export const readRawBody = createWrapperFunction(_readRawBody) +export const readBody = createWrapperFunction(_readBody) +export const getQuery = createWrapperFunction(_getQuery) +export const isMethod = createWrapperFunction(_isMethod) +export const isPreflightRequest = createWrapperFunction(_isPreflightRequest) +export const getValidatedQuery = createWrapperFunction(_getValidatedQuery) +export const getRouterParams = createWrapperFunction(_getRouterParams) +export const getRouterParam = createWrapperFunction(_getRouterParam) +export const getValidatedRouterParams = createWrapperFunction( + _getValidatedRouterParams, +) +export const assertMethod = createWrapperFunction(_assertMethod) +export const getRequestHeaders = createWrapperFunction(_getRequestHeaders) +export const getRequestHeader = createWrapperFunction(_getRequestHeader) +export const getRequestURL = createWrapperFunction(_getRequestURL) +export const getRequestHost = createWrapperFunction(_getRequestHost) +export const getRequestProtocol = createWrapperFunction(_getRequestProtocol) +export const getRequestIP = createWrapperFunction(_getRequestIP) +export const send = createWrapperFunction(_send) +export const sendNoContent = createWrapperFunction(_sendNoContent) +export const setResponseStatus = createWrapperFunction(_setResponseStatus) +export const getResponseStatus = createWrapperFunction(_getResponseStatus) +export const getResponseStatusText = createWrapperFunction( + _getResponseStatusText, +) +export const getResponseHeaders = createWrapperFunction(_getResponseHeaders) +export const getResponseHeader = createWrapperFunction(_getResponseHeader) +export const setResponseHeaders = createWrapperFunction(_setResponseHeaders) +export const setResponseHeader = createWrapperFunction(_setResponseHeader) +export const appendResponseHeaders = createWrapperFunction( + _appendResponseHeaders, +) +export const appendResponseHeader = createWrapperFunction(_appendResponseHeader) +export const defaultContentType = createWrapperFunction(_defaultContentType) +export const sendRedirect = createWrapperFunction(_sendRedirect) +export const sendStream = createWrapperFunction(_sendStream) +export const writeEarlyHints = createWrapperFunction(_writeEarlyHints) +export const sendError = createWrapperFunction(_sendError) +export const sendProxy = createWrapperFunction(_sendProxy) +export const proxyRequest = createWrapperFunction(_proxyRequest) +export const fetchWithEvent = createWrapperFunction(_fetchWithEvent) +export const getProxyRequestHeaders = createWrapperFunction( + _getProxyRequestHeaders, +) + +export const parseCookies = createWrapperFunction(_parseCookies) +export const getCookie = createWrapperFunction(_getCookie) +export const setCookie = createWrapperFunction(_setCookie) +export const deleteCookie = createWrapperFunction(_deleteCookie) +export const useBase = createWrapperFunction(_useBase) +export const useSession = createWrapperFunction(_useSession) +export const getSession = createWrapperFunction(_getSession) +export const updateSession = createWrapperFunction(_updateSession) +export const sealSession = createWrapperFunction(_sealSession) +export const unsealSession = createWrapperFunction(_unsealSession) +export const clearSession = createWrapperFunction(_clearSession) +export const handleCacheHeaders = createWrapperFunction(_handleCacheHeaders) +export const handleCors = createWrapperFunction(_handleCors) +export const appendCorsHeaders = createWrapperFunction(_appendCorsHeaders) +export const appendCorsPreflightHeaders = createWrapperFunction( + _appendCorsPreflightHeaders, +) +export const sendWebResponse = createWrapperFunction(_sendWebResponse) +export const appendHeader = createWrapperFunction(_appendHeader) +export const appendHeaders = createWrapperFunction(_appendHeaders) +export const setHeader = createWrapperFunction(_setHeader) +export const setHeaders = createWrapperFunction(_setHeaders) +export const getHeader = createWrapperFunction(_getHeader) +export const getHeaders = createWrapperFunction(_getHeaders) +export const getRequestFingerprint = createWrapperFunction( + _getRequestFingerprint, +) +export const getRequestWebStream = createWrapperFunction(_getRequestWebStream) +export const readFormData = createWrapperFunction(_readFormData) +export const readMultipartFormData = createWrapperFunction( + _readMultipartFormData, +) +export const readValidatedBody = createWrapperFunction(_readValidatedBody) +export const removeResponseHeader = createWrapperFunction(_removeResponseHeader) +export const getContext = createWrapperFunction(_getContext) +export const setContext = createWrapperFunction(_setContext) + +export const clearResponseHeaders = createWrapperFunction(_clearResponseHeaders) + +export const getWebRequest = createWrapperFunction(toWebRequest) + +export { createApp as createServer } from 'h3' + +function getNitroAsyncContext() { + const nitroAsyncContext = getUnctxContext('nitro-app', { + asyncContext: (globalThis as any).app.config.server.experimental + ?.asyncContext + ? true + : false, + AsyncLocalStorage, + }) + + return nitroAsyncContext +} + +export function getEvent() { + return (getNitroAsyncContext().use() as any).event +} + +export async function handleHTTPEvent(event: H3Event) { + return await (globalThis as any).$handle(event) +} diff --git a/packages/start/vite.config.ts b/packages/start/vite.config.ts index 18b5876c64..2b49afe581 100644 --- a/packages/start/vite.config.ts +++ b/packages/start/vite.config.ts @@ -19,6 +19,7 @@ export default mergeConfig( tanstackViteConfig({ externalDeps: [ '@tanstack/start/client', + '@tanstack/start/server', '@tanstack/start/router-manifest', 'tsr:server-fn-manifest', ], diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0e8e987a8c..28661e19a4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2006,10 +2006,10 @@ importers: version: 18.3.1 html-webpack-plugin: specifier: ^5.6.3 - version: 5.6.3(@rspack/core@1.1.8(@swc/helpers@0.5.15))(webpack@5.97.1) + version: 5.6.3(@rspack/core@1.1.8(@swc/helpers@0.5.15))(webpack@5.97.1(@swc/core@1.10.1(@swc/helpers@0.5.15))(esbuild@0.24.2)(webpack-cli@5.1.4)) swc-loader: specifier: ^0.2.6 - version: 0.2.6(@swc/core@1.10.1(@swc/helpers@0.5.15))(webpack@5.97.1) + version: 0.2.6(@swc/core@1.10.1(@swc/helpers@0.5.15))(webpack@5.97.1(@swc/core@1.10.1(@swc/helpers@0.5.15))(esbuild@0.24.2)(webpack-cli@5.1.4)) typescript: specifier: ^5.7.2 version: 5.7.2 @@ -3236,7 +3236,7 @@ importers: version: 7.0.6 html-webpack-plugin: specifier: ^5.6.0 - version: 5.6.3(@rspack/core@1.1.8(@swc/helpers@0.5.15))(webpack@5.97.1) + version: 5.6.3(@rspack/core@1.1.8(@swc/helpers@0.5.15))(webpack@5.97.1(@swc/core@1.10.1(@swc/helpers@0.5.15))(esbuild@0.24.2)(webpack-cli@5.1.4)) picocolors: specifier: ^1.1.1 version: 1.1.1 @@ -3248,7 +3248,7 @@ importers: version: 18.3.1(react@18.3.1) swc-loader: specifier: ^0.2.6 - version: 0.2.6(@swc/core@1.10.1(@swc/helpers@0.5.15))(webpack@5.97.1) + version: 0.2.6(@swc/core@1.10.1(@swc/helpers@0.5.15))(webpack@5.97.1(@swc/core@1.10.1(@swc/helpers@0.5.15))(esbuild@0.24.2)(webpack-cli@5.1.4)) tinyglobby: specifier: ^0.2.10 version: 0.2.10 @@ -3764,6 +3764,9 @@ importers: '@vitejs/plugin-react': specifier: ^4.3.4 version: 4.3.4(vite@6.0.3(@types/node@22.10.2)(jiti@2.4.1)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1)) + h3: + specifier: ^1.13.1 + version: 1.13.1 import-meta-resolve: specifier: ^4.1.0 version: 4.1.0 @@ -3779,6 +3782,9 @@ importers: tiny-invariant: specifier: ^1.3.3 version: 1.3.3 + unctx: + specifier: ^2.4.1 + version: 2.4.1 vinxi: specifier: 0.5.1 version: 0.5.1(@types/node@22.10.2)(ioredis@5.4.1)(jiti@2.4.1)(terser@5.36.0)(tsx@4.19.2)(typescript@5.7.2)(yaml@2.6.1) @@ -7965,6 +7971,9 @@ packages: h3@1.13.0: resolution: {integrity: sha512-vFEAu/yf8UMUcB4s43OaDaigcqpQd14yanmOsn+NcRX3/guSKncyE2rOYhq8RIchgJrPSs/QiIddnTTR1ddiAg==} + h3@1.13.1: + resolution: {integrity: sha512-u/z6Z4YY+ANZ05cRRfsFJadTBrNA6e3jxdU+AN5UCbZSZEUwgHiwjvUEe0k1NoQmAvQmETwr+xB5jd7mhCJuIQ==} + handle-thing@2.0.1: resolution: {integrity: sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==} @@ -10361,8 +10370,8 @@ packages: uncrypto@0.1.3: resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} - unctx@2.3.1: - resolution: {integrity: sha512-PhKke8ZYauiqh3FEMVNm7ljvzQiph0Mt3GBRve03IJm7ukfaON2OBK795tLwhbyfzknuRRkW0+Ze+CQUmzOZ+A==} + unctx@2.4.1: + resolution: {integrity: sha512-AbaYw0Nm4mK4qjhns67C+kgxR2YWiwlDBPzxrN8h8C6VtAdCgditAY5Dezu3IJy4XVqAnbrXt9oQJvsn3fyozg==} undici-types@5.28.4: resolution: {integrity: sha512-3OeMF5Lyowe8VW0skf5qaIE7Or3yS9LS7fvMUI0gg4YxpIBVg0L8BxCmROw2CcYhSkpR68Epz7CGc8MPj94Uww==} @@ -10408,6 +10417,10 @@ packages: resolution: {integrity: sha512-5liCNPuJW8dqh3+DM6uNM2EI3MLLpCKp/KY+9pB5M2S2SR2qvvDHhKgBOaTWEbZTAws3CXfB0rKTIolWKL05VQ==} engines: {node: '>=14.0.0'} + unplugin@2.1.2: + resolution: {integrity: sha512-Q3LU0e4zxKfRko1wMV2HmP8lB9KWislY7hxXpxd+lGx0PRInE4vhMBVEZwpdVYHvtqzhSrzuIfErsob6bQfCzw==} + engines: {node: '>=18.12.0'} + unstorage@1.13.1: resolution: {integrity: sha512-ELexQHUrG05QVIM/iUeQNdl9FXDZhqLJ4yP59fnmn2jGUh0TEulwOgov1ubOb3Gt2ZGK/VMchJwPDNVEGWQpRg==} peerDependencies: @@ -13158,7 +13171,7 @@ snapshots: consola: 3.2.3 defu: 6.1.4 get-port-please: 3.1.2 - h3: 1.13.0 + h3: 1.13.1 http-shutdown: 1.2.2 jiti: 1.21.6 mlly: 1.7.3 @@ -13399,17 +13412,17 @@ snapshots: '@webassemblyjs/ast': 1.14.1 '@xtuc/long': 4.2.2 - '@webpack-cli/configtest@2.1.1(webpack-cli@5.1.4)(webpack@5.97.1)': + '@webpack-cli/configtest@2.1.1(webpack-cli@5.1.4(webpack-dev-server@5.1.0)(webpack@5.97.1))(webpack@5.97.1(@swc/core@1.10.1(@swc/helpers@0.5.15))(esbuild@0.24.2)(webpack-cli@5.1.4))': dependencies: webpack: 5.97.1(@swc/core@1.10.1(@swc/helpers@0.5.15))(esbuild@0.24.2)(webpack-cli@5.1.4) webpack-cli: 5.1.4(webpack-dev-server@5.1.0)(webpack@5.97.1) - '@webpack-cli/info@2.0.2(webpack-cli@5.1.4)(webpack@5.97.1)': + '@webpack-cli/info@2.0.2(webpack-cli@5.1.4(webpack-dev-server@5.1.0)(webpack@5.97.1))(webpack@5.97.1(@swc/core@1.10.1(@swc/helpers@0.5.15))(esbuild@0.24.2)(webpack-cli@5.1.4))': dependencies: webpack: 5.97.1(@swc/core@1.10.1(@swc/helpers@0.5.15))(esbuild@0.24.2)(webpack-cli@5.1.4) webpack-cli: 5.1.4(webpack-dev-server@5.1.0)(webpack@5.97.1) - '@webpack-cli/serve@2.0.5(webpack-cli@5.1.4)(webpack-dev-server@5.1.0)(webpack@5.97.1)': + '@webpack-cli/serve@2.0.5(webpack-cli@5.1.4(webpack-dev-server@5.1.0)(webpack@5.97.1))(webpack-dev-server@5.1.0(webpack-cli@5.1.4)(webpack@5.97.1))(webpack@5.97.1(@swc/core@1.10.1(@swc/helpers@0.5.15))(esbuild@0.24.2)(webpack-cli@5.1.4))': dependencies: webpack: 5.97.1(@swc/core@1.10.1(@swc/helpers@0.5.15))(esbuild@0.24.2)(webpack-cli@5.1.4) webpack-cli: 5.1.4(webpack-dev-server@5.1.0)(webpack@5.97.1) @@ -15258,6 +15271,19 @@ snapshots: uncrypto: 0.1.3 unenv: 1.10.0 + h3@1.13.1: + dependencies: + cookie-es: 1.2.2 + crossws: 0.3.1 + defu: 6.1.4 + destr: 2.0.3 + iron-webcrypto: 1.2.1 + ohash: 1.1.4 + radix3: 1.1.2 + ufo: 1.5.4 + uncrypto: 0.1.3 + unenv: 1.10.0 + handle-thing@2.0.1: {} has-flag@4.0.0: {} @@ -15313,7 +15339,7 @@ snapshots: relateurl: 0.2.7 terser: 5.36.0 - html-webpack-plugin@5.6.3(@rspack/core@1.1.8(@swc/helpers@0.5.15))(webpack@5.97.1): + html-webpack-plugin@5.6.3(@rspack/core@1.1.8(@swc/helpers@0.5.15))(webpack@5.97.1(@swc/core@1.10.1(@swc/helpers@0.5.15))(esbuild@0.24.2)(webpack-cli@5.1.4)): dependencies: '@types/html-minifier-terser': 6.1.0 html-minifier-terser: 6.1.0 @@ -15756,7 +15782,7 @@ snapshots: crossws: 0.3.1 defu: 6.1.4 get-port-please: 3.1.2 - h3: 1.13.0 + h3: 1.13.1 http-shutdown: 1.2.2 jiti: 2.4.1 mlly: 1.7.3 @@ -16095,7 +16121,7 @@ snapshots: fs-extra: 11.2.0 globby: 14.0.2 gzip-size: 7.0.0 - h3: 1.13.0 + h3: 1.13.1 hookable: 5.5.3 httpxy: 0.1.5 ioredis: 5.4.1 @@ -16125,7 +16151,7 @@ snapshots: std-env: 3.8.0 ufo: 1.5.4 uncrypto: 0.1.3 - unctx: 2.3.1 + unctx: 2.4.1 unenv: 1.10.0 unimport: 3.14.3(rollup@4.29.1) unstorage: 1.13.1(ioredis@5.4.1) @@ -17396,7 +17422,7 @@ snapshots: csso: 5.0.5 picocolors: 1.1.1 - swc-loader@0.2.6(@swc/core@1.10.1(@swc/helpers@0.5.15))(webpack@5.97.1): + swc-loader@0.2.6(@swc/core@1.10.1(@swc/helpers@0.5.15))(webpack@5.97.1(@swc/core@1.10.1(@swc/helpers@0.5.15))(esbuild@0.24.2)(webpack-cli@5.1.4)): dependencies: '@swc/core': 1.10.1(@swc/helpers@0.5.15) '@swc/counter': 0.1.3 @@ -17475,26 +17501,26 @@ snapshots: type-fest: 2.19.0 unique-string: 3.0.0 - terser-webpack-plugin@5.3.10(@swc/core@1.10.1(@swc/helpers@0.5.15))(esbuild@0.24.2)(webpack@5.97.1(@swc/core@1.10.1(@swc/helpers@0.5.15))(esbuild@0.24.2)): + terser-webpack-plugin@5.3.10(@swc/core@1.10.1(@swc/helpers@0.5.15))(esbuild@0.24.2)(webpack@5.97.1(@swc/core@1.10.1(@swc/helpers@0.5.15))(esbuild@0.24.2)(webpack-cli@5.1.4)): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 3.3.0 serialize-javascript: 6.0.2 terser: 5.36.0 - webpack: 5.97.1(@swc/core@1.10.1(@swc/helpers@0.5.15))(esbuild@0.24.2) + webpack: 5.97.1(@swc/core@1.10.1(@swc/helpers@0.5.15))(esbuild@0.24.2)(webpack-cli@5.1.4) optionalDependencies: '@swc/core': 1.10.1(@swc/helpers@0.5.15) esbuild: 0.24.2 - terser-webpack-plugin@5.3.10(@swc/core@1.10.1(@swc/helpers@0.5.15))(esbuild@0.24.2)(webpack@5.97.1): + terser-webpack-plugin@5.3.10(@swc/core@1.10.1(@swc/helpers@0.5.15))(esbuild@0.24.2)(webpack@5.97.1(@swc/core@1.10.1(@swc/helpers@0.5.15))(esbuild@0.24.2)): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 3.3.0 serialize-javascript: 6.0.2 terser: 5.36.0 - webpack: 5.97.1(@swc/core@1.10.1(@swc/helpers@0.5.15))(esbuild@0.24.2)(webpack-cli@5.1.4) + webpack: 5.97.1(@swc/core@1.10.1(@swc/helpers@0.5.15))(esbuild@0.24.2) optionalDependencies: '@swc/core': 1.10.1(@swc/helpers@0.5.15) esbuild: 0.24.2 @@ -17734,12 +17760,12 @@ snapshots: uncrypto@0.1.3: {} - unctx@2.3.1: + unctx@2.4.1: dependencies: acorn: 8.14.0 estree-walker: 3.0.3 magic-string: 0.30.17 - unplugin: 1.16.0 + unplugin: 2.1.2 undici-types@5.28.4: {} @@ -17793,13 +17819,18 @@ snapshots: acorn: 8.14.0 webpack-virtual-modules: 0.6.2 + unplugin@2.1.2: + dependencies: + acorn: 8.14.0 + webpack-virtual-modules: 0.6.2 + unstorage@1.13.1(ioredis@5.4.1): dependencies: anymatch: 3.1.3 chokidar: 3.6.0 citty: 0.1.6 destr: 2.0.3 - h3: 1.13.0 + h3: 1.13.1 listhen: 1.9.0 lru-cache: 10.4.3 node-fetch-native: 1.6.4 @@ -17926,7 +17957,7 @@ snapshots: serve-placeholder: 2.0.2 serve-static: 1.16.2 ufo: 1.5.4 - unctx: 2.3.1 + unctx: 2.4.1 unenv: 1.10.0 unstorage: 1.13.1(ioredis@5.4.1) vite: 6.0.3(@types/node@22.10.2)(jiti@2.4.1)(terser@5.36.0)(tsx@4.19.2)(yaml@2.6.1) @@ -18142,9 +18173,9 @@ snapshots: webpack-cli@5.1.4(webpack-dev-server@5.1.0)(webpack@5.97.1): dependencies: '@discoveryjs/json-ext': 0.5.7 - '@webpack-cli/configtest': 2.1.1(webpack-cli@5.1.4)(webpack@5.97.1) - '@webpack-cli/info': 2.0.2(webpack-cli@5.1.4)(webpack@5.97.1) - '@webpack-cli/serve': 2.0.5(webpack-cli@5.1.4)(webpack-dev-server@5.1.0)(webpack@5.97.1) + '@webpack-cli/configtest': 2.1.1(webpack-cli@5.1.4(webpack-dev-server@5.1.0)(webpack@5.97.1))(webpack@5.97.1(@swc/core@1.10.1(@swc/helpers@0.5.15))(esbuild@0.24.2)(webpack-cli@5.1.4)) + '@webpack-cli/info': 2.0.2(webpack-cli@5.1.4(webpack-dev-server@5.1.0)(webpack@5.97.1))(webpack@5.97.1(@swc/core@1.10.1(@swc/helpers@0.5.15))(esbuild@0.24.2)(webpack-cli@5.1.4)) + '@webpack-cli/serve': 2.0.5(webpack-cli@5.1.4(webpack-dev-server@5.1.0)(webpack@5.97.1))(webpack-dev-server@5.1.0(webpack-cli@5.1.4)(webpack@5.97.1))(webpack@5.97.1(@swc/core@1.10.1(@swc/helpers@0.5.15))(esbuild@0.24.2)(webpack-cli@5.1.4)) colorette: 2.0.20 commander: 10.0.1 cross-spawn: 7.0.6 @@ -18158,7 +18189,7 @@ snapshots: optionalDependencies: webpack-dev-server: 5.1.0(webpack-cli@5.1.4)(webpack@5.97.1) - webpack-dev-middleware@7.4.2(webpack@5.97.1): + webpack-dev-middleware@7.4.2(webpack@5.97.1(@swc/core@1.10.1(@swc/helpers@0.5.15))(esbuild@0.24.2)(webpack-cli@5.1.4)): dependencies: colorette: 2.0.20 memfs: 4.14.1 @@ -18197,7 +18228,7 @@ snapshots: serve-index: 1.9.1 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 7.4.2(webpack@5.97.1) + webpack-dev-middleware: 7.4.2(webpack@5.97.1(@swc/core@1.10.1(@swc/helpers@0.5.15))(esbuild@0.24.2)(webpack-cli@5.1.4)) ws: 8.18.0 optionalDependencies: webpack: 5.97.1(@swc/core@1.10.1(@swc/helpers@0.5.15))(esbuild@0.24.2)(webpack-cli@5.1.4) @@ -18270,7 +18301,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 3.3.0 tapable: 2.2.1 - terser-webpack-plugin: 5.3.10(@swc/core@1.10.1(@swc/helpers@0.5.15))(esbuild@0.24.2)(webpack@5.97.1) + terser-webpack-plugin: 5.3.10(@swc/core@1.10.1(@swc/helpers@0.5.15))(esbuild@0.24.2)(webpack@5.97.1(@swc/core@1.10.1(@swc/helpers@0.5.15))(esbuild@0.24.2)(webpack-cli@5.1.4)) watchpack: 2.4.2 webpack-sources: 3.2.3 optionalDependencies: