@tanstack/start-server-core 1.169.13 → 1.169.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -307,7 +307,7 @@ function createStartHandler(cbOrOptions) {
307
307
  manifest,
308
308
  getRequestAssets: () => getStartContext({ throwIfNotFound: false })?.requestAssets
309
309
  });
310
- routerInstance.update({ additionalContext: { serverContext } });
310
+ routerInstance.options.additionalContext = { serverContext };
311
311
  await routerInstance.load();
312
312
  if (routerInstance.state.redirect) return normalizeSsrResponse(routerInstance.state.redirect);
313
313
  earlyHints?.collectDynamic(routerInstance.stores.matches.get());
@@ -1 +1 @@
1
- {"version":3,"file":"createStartHandler.js","names":[],"sources":["../../src/createStartHandler.ts"],"sourcesContent":["import { createMemoryHistory } from '@tanstack/history'\nimport {\n createCsrfMiddleware,\n createNullProtoObject,\n csrfSymbol,\n flattenMiddlewares,\n mergeHeaders,\n safeObjectMerge,\n} from '@tanstack/start-client-core'\nimport {\n executeRewriteInput,\n isRedirect,\n isResolvedRedirect,\n} from '@tanstack/router-core'\nimport {\n attachRouterServerSsrUtils,\n getNormalizedURL,\n getOrigin,\n isSsrResponse,\n normalizeSsrResponse,\n replaceSsrResponse,\n stripSsrResponseBody,\n} from '@tanstack/router-core/ssr/server'\nimport {\n getStartContext,\n runWithStartContext,\n} from '@tanstack/start-storage-context'\nimport { requestHandler } from './request-response'\nimport { getStartManifest } from './router-manifest'\nimport { handleServerAction } from './server-functions-handler'\nimport { createEarlyHintsCollector } from './early-hints'\nimport {\n createCachedBaseManifestLoader,\n createFinalManifestResolver,\n} from './finalManifest'\n\nimport { HEADERS } from './constants'\nimport { ServerFunctionSerializationAdapter } from './serializer/ServerFunctionSerializationAdapter'\nimport type {\n AnyFunctionMiddleware,\n AnyRequestMiddleware,\n AnyStartInstanceOptions,\n RouteMethod,\n RouteMethodHandlerFn,\n RouterEntry,\n StartEntry,\n} from '@tanstack/start-client-core'\nimport type { RequestHandler } from './request-handler'\nimport type {\n AnyRoute,\n AnyRouter,\n AnySerializationAdapter,\n Register,\n} from '@tanstack/router-core'\nimport type {\n HandlerCallback,\n HandlerCallbackResult,\n SsrResponse,\n} from '@tanstack/router-core/ssr/server'\nimport type { FinalManifestOptions } from './finalManifest'\n\ntype TODO = any\n\ntype AnyMiddlewareServerFn =\n | AnyRequestMiddleware['options']['server']\n | AnyFunctionMiddleware['options']['server']\n\nexport interface CreateStartHandlerOptions extends FinalManifestOptions {\n handler: HandlerCallback<AnyRouter>\n}\n\nfunction getStartResponseHeaders(opts: { router: AnyRouter }) {\n const headers = mergeHeaders(\n {\n 'Content-Type': 'text/html; charset=utf-8',\n },\n ...opts.router.stores.matches.get().map((match) => {\n return match.headers\n }),\n )\n return headers\n}\n\ninterface PluginAdaptersEntry {\n hasPluginAdapters: boolean\n pluginSerializationAdapters: Array<AnySerializationAdapter>\n}\n\ninterface Entries {\n startEntry: StartEntry\n routerEntry: RouterEntry\n pluginAdapters: PluginAdaptersEntry\n}\n\n// Cached entries - promises stored immediately to prevent concurrent imports\n// that can cause race conditions during module initialization\nlet entriesPromise: Promise<Entries> | undefined\nlet hasWarnedMissingCsrfMiddleware = false\nconst defaultCsrfMiddleware = createCsrfMiddleware({\n filter: (ctx) => ctx.handlerType === 'serverFn',\n})\nconst getCachedBaseManifest = createCachedBaseManifestLoader(() =>\n getStartManifest(),\n)\nconst getProdBaseManifest: typeof getStartManifest = () =>\n getCachedBaseManifest()\nconst getBaseManifest =\n process.env.TSS_DEV_SERVER === 'true' ? getStartManifest : getProdBaseManifest\nconst createEarlyHintsForRequest: typeof createEarlyHintsCollector =\n process.env.TSS_DEV_SERVER === 'true'\n ? () => undefined\n : createEarlyHintsCollector\n\nasync function loadEntries(): Promise<Entries> {\n const [routerEntry, startEntry, pluginAdapters] = await Promise.all([\n // @ts-ignore When building, we currently don't respect tsconfig.ts' `include` so we are not picking up the .d.ts from start-client-core\n import('#tanstack-router-entry'),\n // @ts-ignore When building, we currently don't respect tsconfig.ts' `include` so we are not picking up the .d.ts from start-client-core\n import('#tanstack-start-entry'),\n // @ts-ignore When building, we currently don't respect tsconfig.ts' `include` so we are not picking up the .d.ts from start-client-core\n import('#tanstack-start-plugin-adapters'),\n ])\n return {\n routerEntry: routerEntry as unknown as RouterEntry,\n startEntry: startEntry as unknown as StartEntry,\n pluginAdapters: pluginAdapters as unknown as PluginAdaptersEntry,\n }\n}\n\nfunction getEntries() {\n if (!entriesPromise) {\n entriesPromise = loadEntries()\n }\n return entriesPromise\n}\n\nfunction hasCsrfMiddleware(\n middlewares: Array<AnyRequestMiddleware | AnyFunctionMiddleware>,\n): boolean {\n return middlewares.some((middleware) => csrfSymbol in middleware)\n}\n\nfunction warnMissingCsrfMiddlewareOnce() {\n if (hasWarnedMissingCsrfMiddleware) return\n hasWarnedMissingCsrfMiddleware = true\n\n console.warn(`TanStack Start server functions are not protected by the CSRF middleware.\n\nServer functions are same-origin RPC endpoints and should be protected from cross-site requests.\n\nAdd the CSRF middleware in src/start.ts:\n\n const csrfMiddleware = createCsrfMiddleware({\n filter: (ctx) => ctx.handlerType === 'serverFn',\n })\n\n export const startInstance = createStart(() => ({\n requestMiddleware: [csrfMiddleware],\n }))\n\nIf you intentionally handle CSRF another way, disable this warning:\n\n tanstackStart({\n serverFns: {\n disableCsrfMiddlewareWarning: true,\n },\n })`)\n}\n\n// Pre-computed constants\nconst ROUTER_BASEPATH = process.env.TSS_ROUTER_BASEPATH || '/'\nconst SERVER_FN_BASE = process.env.TSS_SERVER_FN_BASE\nconst IS_PRERENDERING = process.env.TSS_PRERENDERING === 'true'\nconst IS_SHELL_ENV = process.env.TSS_SHELL === 'true'\nconst IS_DEV = process.env.NODE_ENV === 'development'\n\n// Reusable error messages\nconst ERR_NO_RESPONSE = IS_DEV\n ? `It looks like you forgot to return a response from your server route handler. If you want to defer to the app router, make sure to have a component set in this route.`\n : 'Internal Server Error'\n\nconst ERR_NO_DEFER = IS_DEV\n ? `You cannot defer to the app router if there is no component defined on this route.`\n : 'Internal Server Error'\n\nfunction throwRouteHandlerError(): never {\n throw new Error(ERR_NO_RESPONSE)\n}\n\nfunction throwIfMayNotDefer(): never {\n throw new Error(ERR_NO_DEFER)\n}\n\n/**\n * Check if a value is a special response (Response or Redirect)\n */\nfunction isSpecialResponse(value: unknown): value is Response {\n return value instanceof Response || isRedirect(value)\n}\n\n/**\n * Normalize middleware result to context shape\n */\nfunction handleCtxResult(result: TODO) {\n if (isSsrResponse(result) || isSpecialResponse(result)) {\n return { response: result }\n }\n return result\n}\n\n/**\n * Execute a middleware chain\n */\nasync function executeMiddleware(\n middlewares: Array<TODO>,\n ctx: TODO,\n): Promise<{ ctx: TODO; response: HandlerCallbackResult }> {\n let index = -1\n let streamResponse:\n | Extract<SsrResponse, { serverSsrCleanup: 'stream' }>\n | undefined\n\n const setResponse = (response: TODO) => {\n if (isSsrResponse(response)) {\n if (response.serverSsrCleanup === 'stream') {\n streamResponse = response\n }\n ctx.response = response.response\n return\n }\n\n ctx.response = response\n }\n\n const disposeStreamResponse = async (reason: string) => {\n const response = streamResponse\n if (!response) {\n return\n }\n\n streamResponse = undefined\n const currentResponse = ctx.response\n if (\n currentResponse === response.response ||\n (currentResponse instanceof Response &&\n response.response.body !== null &&\n currentResponse.body === response.response.body)\n ) {\n ctx.response = undefined\n }\n await response.dispose(reason)\n }\n\n const getFinalResponse = async (): Promise<HandlerCallbackResult> => {\n const response = ctx.response\n if (!response) {\n throwRouteHandlerError()\n }\n\n if (!streamResponse) {\n return response\n }\n\n if (response === streamResponse.response) {\n return streamResponse\n }\n\n if (\n streamResponse.response.body !== null &&\n response.body === streamResponse.response.body\n ) {\n return { ...streamResponse, response }\n }\n\n await disposeStreamResponse('middleware response replaced')\n return response\n }\n\n const next = async (nextCtx?: TODO): Promise<TODO> => {\n // Merge context if provided using safeObjectMerge for prototype pollution prevention\n if (nextCtx) {\n if (nextCtx.context) {\n ctx.context = safeObjectMerge(ctx.context, nextCtx.context)\n }\n // Copy own properties except context (Object.keys returns only own enumerable properties)\n for (const key of Object.keys(nextCtx)) {\n if (key === 'response') {\n setResponse(nextCtx.response)\n } else if (key !== 'context') {\n ctx[key] = nextCtx[key]\n }\n }\n }\n\n index++\n const middleware = middlewares[index]\n if (!middleware) return ctx\n\n let result: TODO\n try {\n result = await middleware({ ...ctx, next })\n } catch (err) {\n if (isSpecialResponse(err)) {\n setResponse(err)\n return ctx\n }\n await disposeStreamResponse('middleware error')\n throw err\n }\n\n const normalized = handleCtxResult(result)\n if (normalized) {\n if (normalized.response !== undefined) {\n setResponse(normalized.response)\n }\n if (normalized.context) {\n ctx.context = safeObjectMerge(ctx.context, normalized.context)\n }\n }\n\n return ctx\n }\n\n await next()\n return { ctx, response: await getFinalResponse() }\n}\n\n/**\n * Wrap a route handler as middleware\n */\nfunction handlerToMiddleware(\n handler: RouteMethodHandlerFn<any, AnyRoute, any, any, any, any, any>,\n mayDefer: boolean = false,\n): TODO {\n if (mayDefer) {\n return handler\n }\n return async (ctx: TODO) => {\n const response = await handler({ ...ctx, next: throwIfMayNotDefer })\n if (!response) {\n throwRouteHandlerError()\n }\n return response\n }\n}\n\n/**\n * Creates the TanStack Start request handler.\n *\n * @example Backwards-compatible usage (handler callback only):\n * ```ts\n * export default createStartHandler(defaultStreamHandler)\n * ```\n *\n * @example With CDN URL rewriting:\n * ```ts\n * export default createStartHandler({\n * handler: defaultStreamHandler,\n * transformAssets: 'https://cdn.example.com',\n * })\n * ```\n *\n * @example With per-request URL rewriting:\n * ```ts\n * export default createStartHandler({\n * handler: defaultStreamHandler,\n * transformAssets: {\n * transform: ({ url }) => {\n * const cdnBase = getRequest().headers.get('x-cdn-base') || ''\n * return { href: `${cdnBase}${url}` }\n * },\n * cache: false,\n * },\n * })\n * ```\n */\nexport function createStartHandler<TRegister = Register>(\n cbOrOptions: HandlerCallback<AnyRouter> | CreateStartHandlerOptions,\n): RequestHandler<TRegister> {\n const handlerOptions: FinalManifestOptions =\n typeof cbOrOptions === 'function' ? {} : cbOrOptions\n const cb: HandlerCallback<AnyRouter> =\n typeof cbOrOptions === 'function' ? cbOrOptions : cbOrOptions.handler\n const finalManifestResolver = createFinalManifestResolver({\n ...handlerOptions,\n cacheCreateTransform: process.env.TSS_DEV_SERVER !== 'true',\n })\n const resolveManifestForRequest =\n process.env.TSS_DEV_SERVER === 'true'\n ? finalManifestResolver.resolveUncached\n : finalManifestResolver.resolveCached\n\n if (process.env.TSS_DEV_SERVER !== 'true') {\n finalManifestResolver.warmup({\n getBaseManifest: () => getBaseManifest(undefined),\n })\n }\n\n const startRequestResolver: RequestHandler<Register> = async (\n request,\n requestOpts,\n ) => {\n let router: AnyRouter | null = null as AnyRouter | null\n let responseOwnsCleanup = false as boolean\n\n try {\n // normalizing and sanitizing the pathname here for server, so we always deal with the same format during SSR.\n // during normalization paths like '//posts' are flattened to '/posts'.\n // in these cases we would prefer to redirect to the new path\n const { url, handledProtocolRelativeURL } = getNormalizedURL(request.url)\n const href = url.pathname + url.search + url.hash\n const origin = getOrigin(request)\n\n if (handledProtocolRelativeURL) {\n return Response.redirect(url, 308)\n }\n\n const entries = await getEntries()\n const hasStartInstance = !!entries.startEntry.startInstance\n const startOptions: AnyStartInstanceOptions =\n (await entries.startEntry.startInstance?.getOptions()) ||\n ({} as AnyStartInstanceOptions)\n\n const { hasPluginAdapters, pluginSerializationAdapters } =\n entries.pluginAdapters\n\n const serializationAdapters = [\n ...(startOptions.serializationAdapters || []),\n ...(hasPluginAdapters ? pluginSerializationAdapters : []),\n ServerFunctionSerializationAdapter,\n ]\n\n const requestStartOptions = {\n ...startOptions,\n requestMiddleware: hasStartInstance\n ? startOptions.requestMiddleware\n : [defaultCsrfMiddleware],\n serializationAdapters,\n }\n\n // Flatten request middlewares once\n const flattenedRequestMiddlewares = requestStartOptions.requestMiddleware\n ? flattenMiddlewares(requestStartOptions.requestMiddleware)\n : []\n\n // Create set for deduplication\n const executedRequestMiddlewares = new Set<TODO>(\n flattenedRequestMiddlewares,\n )\n\n // Memoized router getter\n const getRouter = async (): Promise<AnyRouter> => {\n if (router) return router\n\n router = await entries.routerEntry.getRouter()\n\n let isShell = IS_SHELL_ENV\n if (IS_PRERENDERING && !isShell) {\n isShell = request.headers.get(HEADERS.TSS_SHELL) === 'true'\n }\n\n const history = createMemoryHistory({\n initialEntries: [href],\n })\n\n router.update({\n history,\n isShell,\n isPrerendering: IS_PRERENDERING,\n origin: router.options.origin ?? origin,\n ...{\n defaultSsr: requestStartOptions.defaultSsr,\n serializationAdapters: [\n ...requestStartOptions.serializationAdapters,\n ...(router.options.serializationAdapters || []),\n ],\n },\n basepath: ROUTER_BASEPATH,\n })\n\n return router\n }\n\n // Check for server function requests first (early exit)\n if (SERVER_FN_BASE && url.pathname.startsWith(SERVER_FN_BASE)) {\n if (\n process.env.NODE_ENV !== 'production' &&\n process.env.TSS_DISABLE_CSRF_MIDDLEWARE_WARNING !== 'true' &&\n !hasCsrfMiddleware(flattenedRequestMiddlewares)\n ) {\n warnMissingCsrfMiddlewareOnce()\n }\n\n const serverFnId = url.pathname\n .slice(SERVER_FN_BASE.length)\n .split('/')[0]\n\n if (!serverFnId) {\n throw new Error('Invalid server action param for serverFnId')\n }\n\n const serverFnHandler = async ({ context }: TODO) => {\n return runWithStartContext(\n {\n getRouter,\n startOptions: requestStartOptions,\n contextAfterGlobalMiddlewares: context,\n request,\n executedRequestMiddlewares,\n handlerType: 'serverFn',\n },\n () =>\n handleServerAction({\n request,\n context: requestOpts?.context,\n serverFnId,\n }),\n )\n }\n\n const middlewares = flattenedRequestMiddlewares.map(\n (d) => d.options.server,\n )\n const { response: middlewareResponse } = await executeMiddleware(\n [...middlewares, serverFnHandler],\n {\n request,\n pathname: url.pathname,\n handlerType: 'serverFn',\n context: createNullProtoObject(requestOpts?.context),\n },\n )\n\n const result = await handleRedirectResponse(\n middlewareResponse,\n request,\n getRouter,\n )\n responseOwnsCleanup = result.serverSsrCleanup === 'stream'\n return result.response\n }\n\n // Router execution function\n const executeRouter = async (\n serverContext: TODO,\n matchedRoutes?: ReadonlyArray<AnyRoute>,\n ): Promise<SsrResponse> => {\n const acceptHeader = request.headers.get('Accept') || '*/*'\n const acceptParts = acceptHeader.split(',')\n const supportedMimeTypes = ['*/*', 'text/html']\n\n const isSupported = supportedMimeTypes.some((mimeType) =>\n acceptParts.some((part) => part.trim().startsWith(mimeType)),\n )\n\n if (!isSupported) {\n return normalizeSsrResponse(\n Response.json(\n { error: 'Only HTML requests are supported here' },\n { status: 500 },\n ),\n )\n }\n\n const manifest = await resolveManifestForRequest({\n request,\n requestInlineCss: requestOpts?.inlineCss,\n getBaseManifest: () => getBaseManifest(matchedRoutes),\n })\n\n const earlyHints = createEarlyHintsForRequest({\n onEarlyHints: requestOpts?.onEarlyHints,\n responseLinkHeader: requestOpts?.responseLinkHeader,\n })\n\n earlyHints?.collectStatic({ manifest, matchedRoutes })\n\n const routerInstance = await getRouter()\n\n attachRouterServerSsrUtils({\n router: routerInstance,\n manifest,\n getRequestAssets: () =>\n getStartContext({ throwIfNotFound: false })?.requestAssets,\n })\n\n routerInstance.update({ additionalContext: { serverContext } })\n await routerInstance.load()\n\n if (routerInstance.state.redirect) {\n return normalizeSsrResponse(routerInstance.state.redirect)\n }\n\n earlyHints?.collectDynamic(routerInstance.stores.matches.get())\n\n // Pass request-scoped assets to dehydrate for manifest injection\n const ctx = getStartContext({ throwIfNotFound: false })\n await routerInstance.serverSsr!.dehydrate({\n requestAssets: ctx?.requestAssets,\n })\n\n const responseHeaders = getStartResponseHeaders({\n router: routerInstance,\n })\n earlyHints?.appendResponseHeaders(responseHeaders)\n const response = await cb({\n request,\n router: routerInstance,\n responseHeaders,\n })\n return normalizeSsrResponse(response)\n }\n\n // Main request handler\n const requestHandlerMiddleware = async ({ context }: TODO) => {\n return runWithStartContext(\n {\n getRouter,\n startOptions: requestStartOptions,\n contextAfterGlobalMiddlewares: context,\n request,\n executedRequestMiddlewares,\n handlerType: 'router',\n },\n async () => {\n try {\n return await handleServerRoutes({\n getRouter,\n request,\n url,\n executeRouter,\n context,\n executedRequestMiddlewares,\n })\n } catch (err) {\n if (err instanceof Response) {\n return err\n }\n throw err\n }\n },\n )\n }\n\n const middlewares = flattenedRequestMiddlewares.map(\n (d) => d.options.server,\n )\n const { response: middlewareResponse } = await executeMiddleware(\n [...middlewares, requestHandlerMiddleware],\n {\n request,\n pathname: url.pathname,\n handlerType: 'router',\n context: createNullProtoObject(requestOpts?.context),\n },\n )\n\n const response = await handleRedirectResponse(\n middlewareResponse,\n request,\n getRouter,\n )\n responseOwnsCleanup = response.serverSsrCleanup === 'stream'\n return response.response\n } finally {\n if (router?.serverSsr && !responseOwnsCleanup) {\n // Clean up router SSR state if it was set up but won't be cleaned up by the callback\n // (e.g., in redirect cases or early returns before the callback is invoked).\n // Transformed streaming response bodies clean up when consumed/cancelled.\n router.serverSsr.cleanup()\n }\n router = null\n }\n }\n\n return requestHandler(startRequestResolver)\n}\n\nasync function handleRedirectResponse(\n response: HandlerCallbackResult,\n request: Request,\n getRouter: () => Promise<AnyRouter>,\n): Promise<SsrResponse> {\n const ssrResponse = normalizeSsrResponse(response)\n if (!isRedirect(ssrResponse.response)) {\n return ssrResponse\n }\n\n if (isResolvedRedirect(ssrResponse.response)) {\n if (request.headers.get('x-tsr-serverFn') === 'true') {\n return replaceSsrResponse(\n ssrResponse,\n Response.json(\n { ...ssrResponse.response.options, isSerializedRedirect: true },\n { headers: ssrResponse.response.headers },\n ),\n 'redirect response replaced',\n )\n }\n return ssrResponse\n }\n\n const opts = ssrResponse.response.options\n if (opts.to && typeof opts.to === 'string' && !opts.to.startsWith('/')) {\n throw new Error(\n `Server side redirects must use absolute paths via the 'href' or 'to' options. The redirect() method's \"to\" property accepts an internal path only. Use the \"href\" property to provide an external URL. Received: ${JSON.stringify(opts)}`,\n )\n }\n\n if (\n ['params', 'search', 'hash'].some(\n (d) => typeof (opts as TODO)[d] === 'function',\n )\n ) {\n throw new Error(\n `Server side redirects must use static search, params, and hash values and do not support functional values. Received functional values for: ${Object.keys(\n opts,\n )\n .filter((d) => typeof (opts as TODO)[d] === 'function')\n .map((d) => `\"${d}\"`)\n .join(', ')}`,\n )\n }\n\n const router = await getRouter()\n const redirect = router.resolveRedirect(ssrResponse.response)\n\n if (request.headers.get('x-tsr-serverFn') === 'true') {\n return replaceSsrResponse(\n ssrResponse,\n Response.json(\n { ...ssrResponse.response.options, isSerializedRedirect: true },\n { headers: ssrResponse.response.headers },\n ),\n 'redirect response replaced',\n )\n }\n\n return replaceSsrResponse(ssrResponse, redirect, 'redirect response replaced')\n}\n\nasync function handleServerRoutes({\n getRouter,\n request,\n url,\n executeRouter,\n context,\n executedRequestMiddlewares,\n}: {\n getRouter: () => Promise<AnyRouter>\n request: Request\n url: URL\n executeRouter: (\n serverContext: any,\n matchedRoutes?: ReadonlyArray<AnyRoute>,\n ) => Promise<SsrResponse>\n context: any\n executedRequestMiddlewares: Set<AnyRequestMiddleware>\n}): Promise<SsrResponse> {\n const router = await getRouter()\n const rewrittenUrl = executeRewriteInput(router.rewrite, url)\n const pathname = rewrittenUrl.pathname\n // this will perform a fuzzy match, however for server routes we need an exact match\n // if the route is not an exact match, executeRouter will handle rendering the app router\n // the match will be cached internally, so no extra work is done during the app router render\n const { matchedRoutes, foundRoute, routeParams } =\n router.getMatchedRoutes(pathname)\n\n const isExactMatch = foundRoute && routeParams['**'] === undefined\n\n // Collect and dedupe route middlewares\n const routeMiddlewares: Array<AnyMiddlewareServerFn> = []\n\n // Collect middleware from matched routes, filtering out those already executed\n // in the request phase\n for (const route of matchedRoutes) {\n const serverMiddleware = route.options.server?.middleware as\n | Array<AnyRequestMiddleware>\n | undefined\n if (serverMiddleware) {\n const flattened = flattenMiddlewares(serverMiddleware)\n for (const m of flattened) {\n if (!executedRequestMiddlewares.has(m)) {\n routeMiddlewares.push(m.options.server)\n }\n }\n }\n }\n\n // Add handler middleware if exact match\n const server = foundRoute?.options.server\n let isHeadFallback = false\n if (server?.handlers && isExactMatch) {\n const handlers =\n typeof server.handlers === 'function'\n ? server.handlers({ createHandlers: (d: any) => d })\n : server.handlers\n\n const requestMethod = request.method.toUpperCase() as RouteMethod\n // Per RFC 9110 §9.3.2, HEAD must return the same header fields as GET.\n // Priority for HEAD: explicit HEAD handler → GET → ANY (last resort).\n const handler =\n requestMethod === 'HEAD'\n ? (handlers['HEAD'] ?? handlers['GET'] ?? handlers['ANY'])\n : (handlers[requestMethod] ?? handlers['ANY'])\n isHeadFallback =\n requestMethod === 'HEAD' && handler !== undefined && !handlers['HEAD']\n\n if (handler) {\n const mayDefer = !!foundRoute.options.component\n\n if (typeof handler === 'function') {\n routeMiddlewares.push(handlerToMiddleware(handler, mayDefer))\n } else {\n if (handler.middleware?.length) {\n const handlerMiddlewares = flattenMiddlewares(handler.middleware)\n for (const m of handlerMiddlewares) {\n routeMiddlewares.push(m.options.server)\n }\n }\n if (handler.handler) {\n routeMiddlewares.push(handlerToMiddleware(handler.handler, mayDefer))\n }\n }\n }\n }\n\n // Final middleware: execute router with matched routes for dev styles\n routeMiddlewares.push(((ctx: TODO) =>\n executeRouter(ctx.context, matchedRoutes)) as TODO)\n\n const { ctx, response } = await executeMiddleware(routeMiddlewares, {\n request,\n context,\n params: routeParams,\n pathname,\n handlerType: 'router',\n })\n\n // RFC 9110 §9.3.2: HEAD must carry the same header fields as GET but no body.\n // Resolve any redirect before stripping so the Location header survives.\n if (isHeadFallback) {\n if (!ctx.response) {\n throwRouteHandlerError()\n }\n\n const resolved = await handleRedirectResponse(response, request, getRouter)\n return stripSsrResponseBody(resolved, 'HEAD body stripped')\n }\n\n return normalizeSsrResponse(response)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"createStartHandler.js","names":[],"sources":["../../src/createStartHandler.ts"],"sourcesContent":["import { createMemoryHistory } from '@tanstack/history'\nimport {\n createCsrfMiddleware,\n createNullProtoObject,\n csrfSymbol,\n flattenMiddlewares,\n mergeHeaders,\n safeObjectMerge,\n} from '@tanstack/start-client-core'\nimport {\n executeRewriteInput,\n isRedirect,\n isResolvedRedirect,\n} from '@tanstack/router-core'\nimport {\n attachRouterServerSsrUtils,\n getNormalizedURL,\n getOrigin,\n isSsrResponse,\n normalizeSsrResponse,\n replaceSsrResponse,\n stripSsrResponseBody,\n} from '@tanstack/router-core/ssr/server'\nimport {\n getStartContext,\n runWithStartContext,\n} from '@tanstack/start-storage-context'\nimport { requestHandler } from './request-response'\nimport { getStartManifest } from './router-manifest'\nimport { handleServerAction } from './server-functions-handler'\nimport { createEarlyHintsCollector } from './early-hints'\nimport {\n createCachedBaseManifestLoader,\n createFinalManifestResolver,\n} from './finalManifest'\n\nimport { HEADERS } from './constants'\nimport { ServerFunctionSerializationAdapter } from './serializer/ServerFunctionSerializationAdapter'\nimport type {\n AnyFunctionMiddleware,\n AnyRequestMiddleware,\n AnyStartInstanceOptions,\n RouteMethod,\n RouteMethodHandlerFn,\n RouterEntry,\n StartEntry,\n} from '@tanstack/start-client-core'\nimport type { RequestHandler } from './request-handler'\nimport type {\n AnyRoute,\n AnyRouter,\n AnySerializationAdapter,\n Register,\n} from '@tanstack/router-core'\nimport type {\n HandlerCallback,\n HandlerCallbackResult,\n SsrResponse,\n} from '@tanstack/router-core/ssr/server'\nimport type { FinalManifestOptions } from './finalManifest'\n\ntype TODO = any\n\ntype AnyMiddlewareServerFn =\n | AnyRequestMiddleware['options']['server']\n | AnyFunctionMiddleware['options']['server']\n\nexport interface CreateStartHandlerOptions extends FinalManifestOptions {\n handler: HandlerCallback<AnyRouter>\n}\n\nfunction getStartResponseHeaders(opts: { router: AnyRouter }) {\n const headers = mergeHeaders(\n {\n 'Content-Type': 'text/html; charset=utf-8',\n },\n ...opts.router.stores.matches.get().map((match) => {\n return match.headers\n }),\n )\n return headers\n}\n\ninterface PluginAdaptersEntry {\n hasPluginAdapters: boolean\n pluginSerializationAdapters: Array<AnySerializationAdapter>\n}\n\ninterface Entries {\n startEntry: StartEntry\n routerEntry: RouterEntry\n pluginAdapters: PluginAdaptersEntry\n}\n\n// Cached entries - promises stored immediately to prevent concurrent imports\n// that can cause race conditions during module initialization\nlet entriesPromise: Promise<Entries> | undefined\nlet hasWarnedMissingCsrfMiddleware = false\nconst defaultCsrfMiddleware = createCsrfMiddleware({\n filter: (ctx) => ctx.handlerType === 'serverFn',\n})\nconst getCachedBaseManifest = createCachedBaseManifestLoader(() =>\n getStartManifest(),\n)\nconst getProdBaseManifest: typeof getStartManifest = () =>\n getCachedBaseManifest()\nconst getBaseManifest =\n process.env.TSS_DEV_SERVER === 'true' ? getStartManifest : getProdBaseManifest\nconst createEarlyHintsForRequest: typeof createEarlyHintsCollector =\n process.env.TSS_DEV_SERVER === 'true'\n ? () => undefined\n : createEarlyHintsCollector\n\nasync function loadEntries(): Promise<Entries> {\n const [routerEntry, startEntry, pluginAdapters] = await Promise.all([\n // @ts-ignore When building, we currently don't respect tsconfig.ts' `include` so we are not picking up the .d.ts from start-client-core\n import('#tanstack-router-entry'),\n // @ts-ignore When building, we currently don't respect tsconfig.ts' `include` so we are not picking up the .d.ts from start-client-core\n import('#tanstack-start-entry'),\n // @ts-ignore When building, we currently don't respect tsconfig.ts' `include` so we are not picking up the .d.ts from start-client-core\n import('#tanstack-start-plugin-adapters'),\n ])\n return {\n routerEntry: routerEntry as unknown as RouterEntry,\n startEntry: startEntry as unknown as StartEntry,\n pluginAdapters: pluginAdapters as unknown as PluginAdaptersEntry,\n }\n}\n\nfunction getEntries() {\n if (!entriesPromise) {\n entriesPromise = loadEntries()\n }\n return entriesPromise\n}\n\nfunction hasCsrfMiddleware(\n middlewares: Array<AnyRequestMiddleware | AnyFunctionMiddleware>,\n): boolean {\n return middlewares.some((middleware) => csrfSymbol in middleware)\n}\n\nfunction warnMissingCsrfMiddlewareOnce() {\n if (hasWarnedMissingCsrfMiddleware) return\n hasWarnedMissingCsrfMiddleware = true\n\n console.warn(`TanStack Start server functions are not protected by the CSRF middleware.\n\nServer functions are same-origin RPC endpoints and should be protected from cross-site requests.\n\nAdd the CSRF middleware in src/start.ts:\n\n const csrfMiddleware = createCsrfMiddleware({\n filter: (ctx) => ctx.handlerType === 'serverFn',\n })\n\n export const startInstance = createStart(() => ({\n requestMiddleware: [csrfMiddleware],\n }))\n\nIf you intentionally handle CSRF another way, disable this warning:\n\n tanstackStart({\n serverFns: {\n disableCsrfMiddlewareWarning: true,\n },\n })`)\n}\n\n// Pre-computed constants\nconst ROUTER_BASEPATH = process.env.TSS_ROUTER_BASEPATH || '/'\nconst SERVER_FN_BASE = process.env.TSS_SERVER_FN_BASE\nconst IS_PRERENDERING = process.env.TSS_PRERENDERING === 'true'\nconst IS_SHELL_ENV = process.env.TSS_SHELL === 'true'\nconst IS_DEV = process.env.NODE_ENV === 'development'\n\n// Reusable error messages\nconst ERR_NO_RESPONSE = IS_DEV\n ? `It looks like you forgot to return a response from your server route handler. If you want to defer to the app router, make sure to have a component set in this route.`\n : 'Internal Server Error'\n\nconst ERR_NO_DEFER = IS_DEV\n ? `You cannot defer to the app router if there is no component defined on this route.`\n : 'Internal Server Error'\n\nfunction throwRouteHandlerError(): never {\n throw new Error(ERR_NO_RESPONSE)\n}\n\nfunction throwIfMayNotDefer(): never {\n throw new Error(ERR_NO_DEFER)\n}\n\n/**\n * Check if a value is a special response (Response or Redirect)\n */\nfunction isSpecialResponse(value: unknown): value is Response {\n return value instanceof Response || isRedirect(value)\n}\n\n/**\n * Normalize middleware result to context shape\n */\nfunction handleCtxResult(result: TODO) {\n if (isSsrResponse(result) || isSpecialResponse(result)) {\n return { response: result }\n }\n return result\n}\n\n/**\n * Execute a middleware chain\n */\nasync function executeMiddleware(\n middlewares: Array<TODO>,\n ctx: TODO,\n): Promise<{ ctx: TODO; response: HandlerCallbackResult }> {\n let index = -1\n let streamResponse:\n | Extract<SsrResponse, { serverSsrCleanup: 'stream' }>\n | undefined\n\n const setResponse = (response: TODO) => {\n if (isSsrResponse(response)) {\n if (response.serverSsrCleanup === 'stream') {\n streamResponse = response\n }\n ctx.response = response.response\n return\n }\n\n ctx.response = response\n }\n\n const disposeStreamResponse = async (reason: string) => {\n const response = streamResponse\n if (!response) {\n return\n }\n\n streamResponse = undefined\n const currentResponse = ctx.response\n if (\n currentResponse === response.response ||\n (currentResponse instanceof Response &&\n response.response.body !== null &&\n currentResponse.body === response.response.body)\n ) {\n ctx.response = undefined\n }\n await response.dispose(reason)\n }\n\n const getFinalResponse = async (): Promise<HandlerCallbackResult> => {\n const response = ctx.response\n if (!response) {\n throwRouteHandlerError()\n }\n\n if (!streamResponse) {\n return response\n }\n\n if (response === streamResponse.response) {\n return streamResponse\n }\n\n if (\n streamResponse.response.body !== null &&\n response.body === streamResponse.response.body\n ) {\n return { ...streamResponse, response }\n }\n\n await disposeStreamResponse('middleware response replaced')\n return response\n }\n\n const next = async (nextCtx?: TODO): Promise<TODO> => {\n // Merge context if provided using safeObjectMerge for prototype pollution prevention\n if (nextCtx) {\n if (nextCtx.context) {\n ctx.context = safeObjectMerge(ctx.context, nextCtx.context)\n }\n // Copy own properties except context (Object.keys returns only own enumerable properties)\n for (const key of Object.keys(nextCtx)) {\n if (key === 'response') {\n setResponse(nextCtx.response)\n } else if (key !== 'context') {\n ctx[key] = nextCtx[key]\n }\n }\n }\n\n index++\n const middleware = middlewares[index]\n if (!middleware) return ctx\n\n let result: TODO\n try {\n result = await middleware({ ...ctx, next })\n } catch (err) {\n if (isSpecialResponse(err)) {\n setResponse(err)\n return ctx\n }\n await disposeStreamResponse('middleware error')\n throw err\n }\n\n const normalized = handleCtxResult(result)\n if (normalized) {\n if (normalized.response !== undefined) {\n setResponse(normalized.response)\n }\n if (normalized.context) {\n ctx.context = safeObjectMerge(ctx.context, normalized.context)\n }\n }\n\n return ctx\n }\n\n await next()\n return { ctx, response: await getFinalResponse() }\n}\n\n/**\n * Wrap a route handler as middleware\n */\nfunction handlerToMiddleware(\n handler: RouteMethodHandlerFn<any, AnyRoute, any, any, any, any, any>,\n mayDefer: boolean = false,\n): TODO {\n if (mayDefer) {\n return handler\n }\n return async (ctx: TODO) => {\n const response = await handler({ ...ctx, next: throwIfMayNotDefer })\n if (!response) {\n throwRouteHandlerError()\n }\n return response\n }\n}\n\n/**\n * Creates the TanStack Start request handler.\n *\n * @example Backwards-compatible usage (handler callback only):\n * ```ts\n * export default createStartHandler(defaultStreamHandler)\n * ```\n *\n * @example With CDN URL rewriting:\n * ```ts\n * export default createStartHandler({\n * handler: defaultStreamHandler,\n * transformAssets: 'https://cdn.example.com',\n * })\n * ```\n *\n * @example With per-request URL rewriting:\n * ```ts\n * export default createStartHandler({\n * handler: defaultStreamHandler,\n * transformAssets: {\n * transform: ({ url }) => {\n * const cdnBase = getRequest().headers.get('x-cdn-base') || ''\n * return { href: `${cdnBase}${url}` }\n * },\n * cache: false,\n * },\n * })\n * ```\n */\nexport function createStartHandler<TRegister = Register>(\n cbOrOptions: HandlerCallback<AnyRouter> | CreateStartHandlerOptions,\n): RequestHandler<TRegister> {\n const handlerOptions: FinalManifestOptions =\n typeof cbOrOptions === 'function' ? {} : cbOrOptions\n const cb: HandlerCallback<AnyRouter> =\n typeof cbOrOptions === 'function' ? cbOrOptions : cbOrOptions.handler\n const finalManifestResolver = createFinalManifestResolver({\n ...handlerOptions,\n cacheCreateTransform: process.env.TSS_DEV_SERVER !== 'true',\n })\n const resolveManifestForRequest =\n process.env.TSS_DEV_SERVER === 'true'\n ? finalManifestResolver.resolveUncached\n : finalManifestResolver.resolveCached\n\n if (process.env.TSS_DEV_SERVER !== 'true') {\n finalManifestResolver.warmup({\n getBaseManifest: () => getBaseManifest(undefined),\n })\n }\n\n const startRequestResolver: RequestHandler<Register> = async (\n request,\n requestOpts,\n ) => {\n let router: AnyRouter | null = null as AnyRouter | null\n let responseOwnsCleanup = false as boolean\n\n try {\n // normalizing and sanitizing the pathname here for server, so we always deal with the same format during SSR.\n // during normalization paths like '//posts' are flattened to '/posts'.\n // in these cases we would prefer to redirect to the new path\n const { url, handledProtocolRelativeURL } = getNormalizedURL(request.url)\n const href = url.pathname + url.search + url.hash\n const origin = getOrigin(request)\n\n if (handledProtocolRelativeURL) {\n return Response.redirect(url, 308)\n }\n\n const entries = await getEntries()\n const hasStartInstance = !!entries.startEntry.startInstance\n const startOptions: AnyStartInstanceOptions =\n (await entries.startEntry.startInstance?.getOptions()) ||\n ({} as AnyStartInstanceOptions)\n\n const { hasPluginAdapters, pluginSerializationAdapters } =\n entries.pluginAdapters\n\n const serializationAdapters = [\n ...(startOptions.serializationAdapters || []),\n ...(hasPluginAdapters ? pluginSerializationAdapters : []),\n ServerFunctionSerializationAdapter,\n ]\n\n const requestStartOptions = {\n ...startOptions,\n requestMiddleware: hasStartInstance\n ? startOptions.requestMiddleware\n : [defaultCsrfMiddleware],\n serializationAdapters,\n }\n\n // Flatten request middlewares once\n const flattenedRequestMiddlewares = requestStartOptions.requestMiddleware\n ? flattenMiddlewares(requestStartOptions.requestMiddleware)\n : []\n\n // Create set for deduplication\n const executedRequestMiddlewares = new Set<TODO>(\n flattenedRequestMiddlewares,\n )\n\n // Memoized router getter\n const getRouter = async (): Promise<AnyRouter> => {\n if (router) return router\n\n router = await entries.routerEntry.getRouter()\n\n let isShell = IS_SHELL_ENV\n if (IS_PRERENDERING && !isShell) {\n isShell = request.headers.get(HEADERS.TSS_SHELL) === 'true'\n }\n\n const history = createMemoryHistory({\n initialEntries: [href],\n })\n\n router.update({\n history,\n isShell,\n isPrerendering: IS_PRERENDERING,\n origin: router.options.origin ?? origin,\n ...{\n defaultSsr: requestStartOptions.defaultSsr,\n serializationAdapters: [\n ...requestStartOptions.serializationAdapters,\n ...(router.options.serializationAdapters || []),\n ],\n },\n basepath: ROUTER_BASEPATH,\n })\n\n return router\n }\n\n // Check for server function requests first (early exit)\n if (SERVER_FN_BASE && url.pathname.startsWith(SERVER_FN_BASE)) {\n if (\n process.env.NODE_ENV !== 'production' &&\n process.env.TSS_DISABLE_CSRF_MIDDLEWARE_WARNING !== 'true' &&\n !hasCsrfMiddleware(flattenedRequestMiddlewares)\n ) {\n warnMissingCsrfMiddlewareOnce()\n }\n\n const serverFnId = url.pathname\n .slice(SERVER_FN_BASE.length)\n .split('/')[0]\n\n if (!serverFnId) {\n throw new Error('Invalid server action param for serverFnId')\n }\n\n const serverFnHandler = async ({ context }: TODO) => {\n return runWithStartContext(\n {\n getRouter,\n startOptions: requestStartOptions,\n contextAfterGlobalMiddlewares: context,\n request,\n executedRequestMiddlewares,\n handlerType: 'serverFn',\n },\n () =>\n handleServerAction({\n request,\n context: requestOpts?.context,\n serverFnId,\n }),\n )\n }\n\n const middlewares = flattenedRequestMiddlewares.map(\n (d) => d.options.server,\n )\n const { response: middlewareResponse } = await executeMiddleware(\n [...middlewares, serverFnHandler],\n {\n request,\n pathname: url.pathname,\n handlerType: 'serverFn',\n context: createNullProtoObject(requestOpts?.context),\n },\n )\n\n const result = await handleRedirectResponse(\n middlewareResponse,\n request,\n getRouter,\n )\n responseOwnsCleanup = result.serverSsrCleanup === 'stream'\n return result.response\n }\n\n // Router execution function\n const executeRouter = async (\n serverContext: TODO,\n matchedRoutes?: ReadonlyArray<AnyRoute>,\n ): Promise<SsrResponse> => {\n const acceptHeader = request.headers.get('Accept') || '*/*'\n const acceptParts = acceptHeader.split(',')\n const supportedMimeTypes = ['*/*', 'text/html']\n\n const isSupported = supportedMimeTypes.some((mimeType) =>\n acceptParts.some((part) => part.trim().startsWith(mimeType)),\n )\n\n if (!isSupported) {\n return normalizeSsrResponse(\n Response.json(\n { error: 'Only HTML requests are supported here' },\n { status: 500 },\n ),\n )\n }\n\n const manifest = await resolveManifestForRequest({\n request,\n requestInlineCss: requestOpts?.inlineCss,\n getBaseManifest: () => getBaseManifest(matchedRoutes),\n })\n\n const earlyHints = createEarlyHintsForRequest({\n onEarlyHints: requestOpts?.onEarlyHints,\n responseLinkHeader: requestOpts?.responseLinkHeader,\n })\n\n earlyHints?.collectStatic({ manifest, matchedRoutes })\n\n const routerInstance = await getRouter()\n\n attachRouterServerSsrUtils({\n router: routerInstance,\n manifest,\n getRequestAssets: () =>\n getStartContext({ throwIfNotFound: false })?.requestAssets,\n })\n\n // `additionalContext` is request-scoped and only read from router.options\n // during load; avoid a full router.update() and redundant location parse.\n routerInstance.options.additionalContext = { serverContext }\n await routerInstance.load()\n\n if (routerInstance.state.redirect) {\n return normalizeSsrResponse(routerInstance.state.redirect)\n }\n\n earlyHints?.collectDynamic(routerInstance.stores.matches.get())\n\n // Pass request-scoped assets to dehydrate for manifest injection\n const ctx = getStartContext({ throwIfNotFound: false })\n await routerInstance.serverSsr!.dehydrate({\n requestAssets: ctx?.requestAssets,\n })\n\n const responseHeaders = getStartResponseHeaders({\n router: routerInstance,\n })\n earlyHints?.appendResponseHeaders(responseHeaders)\n const response = await cb({\n request,\n router: routerInstance,\n responseHeaders,\n })\n return normalizeSsrResponse(response)\n }\n\n // Main request handler\n const requestHandlerMiddleware = async ({ context }: TODO) => {\n return runWithStartContext(\n {\n getRouter,\n startOptions: requestStartOptions,\n contextAfterGlobalMiddlewares: context,\n request,\n executedRequestMiddlewares,\n handlerType: 'router',\n },\n async () => {\n try {\n return await handleServerRoutes({\n getRouter,\n request,\n url,\n executeRouter,\n context,\n executedRequestMiddlewares,\n })\n } catch (err) {\n if (err instanceof Response) {\n return err\n }\n throw err\n }\n },\n )\n }\n\n const middlewares = flattenedRequestMiddlewares.map(\n (d) => d.options.server,\n )\n const { response: middlewareResponse } = await executeMiddleware(\n [...middlewares, requestHandlerMiddleware],\n {\n request,\n pathname: url.pathname,\n handlerType: 'router',\n context: createNullProtoObject(requestOpts?.context),\n },\n )\n\n const response = await handleRedirectResponse(\n middlewareResponse,\n request,\n getRouter,\n )\n responseOwnsCleanup = response.serverSsrCleanup === 'stream'\n return response.response\n } finally {\n if (router?.serverSsr && !responseOwnsCleanup) {\n // Clean up router SSR state if it was set up but won't be cleaned up by the callback\n // (e.g., in redirect cases or early returns before the callback is invoked).\n // Transformed streaming response bodies clean up when consumed/cancelled.\n router.serverSsr.cleanup()\n }\n router = null\n }\n }\n\n return requestHandler(startRequestResolver)\n}\n\nasync function handleRedirectResponse(\n response: HandlerCallbackResult,\n request: Request,\n getRouter: () => Promise<AnyRouter>,\n): Promise<SsrResponse> {\n const ssrResponse = normalizeSsrResponse(response)\n if (!isRedirect(ssrResponse.response)) {\n return ssrResponse\n }\n\n if (isResolvedRedirect(ssrResponse.response)) {\n if (request.headers.get('x-tsr-serverFn') === 'true') {\n return replaceSsrResponse(\n ssrResponse,\n Response.json(\n { ...ssrResponse.response.options, isSerializedRedirect: true },\n { headers: ssrResponse.response.headers },\n ),\n 'redirect response replaced',\n )\n }\n return ssrResponse\n }\n\n const opts = ssrResponse.response.options\n if (opts.to && typeof opts.to === 'string' && !opts.to.startsWith('/')) {\n throw new Error(\n `Server side redirects must use absolute paths via the 'href' or 'to' options. The redirect() method's \"to\" property accepts an internal path only. Use the \"href\" property to provide an external URL. Received: ${JSON.stringify(opts)}`,\n )\n }\n\n if (\n ['params', 'search', 'hash'].some(\n (d) => typeof (opts as TODO)[d] === 'function',\n )\n ) {\n throw new Error(\n `Server side redirects must use static search, params, and hash values and do not support functional values. Received functional values for: ${Object.keys(\n opts,\n )\n .filter((d) => typeof (opts as TODO)[d] === 'function')\n .map((d) => `\"${d}\"`)\n .join(', ')}`,\n )\n }\n\n const router = await getRouter()\n const redirect = router.resolveRedirect(ssrResponse.response)\n\n if (request.headers.get('x-tsr-serverFn') === 'true') {\n return replaceSsrResponse(\n ssrResponse,\n Response.json(\n { ...ssrResponse.response.options, isSerializedRedirect: true },\n { headers: ssrResponse.response.headers },\n ),\n 'redirect response replaced',\n )\n }\n\n return replaceSsrResponse(ssrResponse, redirect, 'redirect response replaced')\n}\n\nasync function handleServerRoutes({\n getRouter,\n request,\n url,\n executeRouter,\n context,\n executedRequestMiddlewares,\n}: {\n getRouter: () => Promise<AnyRouter>\n request: Request\n url: URL\n executeRouter: (\n serverContext: any,\n matchedRoutes?: ReadonlyArray<AnyRoute>,\n ) => Promise<SsrResponse>\n context: any\n executedRequestMiddlewares: Set<AnyRequestMiddleware>\n}): Promise<SsrResponse> {\n const router = await getRouter()\n const rewrittenUrl = executeRewriteInput(router.rewrite, url)\n const pathname = rewrittenUrl.pathname\n // this will perform a fuzzy match, however for server routes we need an exact match\n // if the route is not an exact match, executeRouter will handle rendering the app router\n // the match will be cached internally, so no extra work is done during the app router render\n const { matchedRoutes, foundRoute, routeParams } =\n router.getMatchedRoutes(pathname)\n\n const isExactMatch = foundRoute && routeParams['**'] === undefined\n\n // Collect and dedupe route middlewares\n const routeMiddlewares: Array<AnyMiddlewareServerFn> = []\n\n // Collect middleware from matched routes, filtering out those already executed\n // in the request phase\n for (const route of matchedRoutes) {\n const serverMiddleware = route.options.server?.middleware as\n | Array<AnyRequestMiddleware>\n | undefined\n if (serverMiddleware) {\n const flattened = flattenMiddlewares(serverMiddleware)\n for (const m of flattened) {\n if (!executedRequestMiddlewares.has(m)) {\n routeMiddlewares.push(m.options.server)\n }\n }\n }\n }\n\n // Add handler middleware if exact match\n const server = foundRoute?.options.server\n let isHeadFallback = false\n if (server?.handlers && isExactMatch) {\n const handlers =\n typeof server.handlers === 'function'\n ? server.handlers({ createHandlers: (d: any) => d })\n : server.handlers\n\n const requestMethod = request.method.toUpperCase() as RouteMethod\n // Per RFC 9110 §9.3.2, HEAD must return the same header fields as GET.\n // Priority for HEAD: explicit HEAD handler → GET → ANY (last resort).\n const handler =\n requestMethod === 'HEAD'\n ? (handlers['HEAD'] ?? handlers['GET'] ?? handlers['ANY'])\n : (handlers[requestMethod] ?? handlers['ANY'])\n isHeadFallback =\n requestMethod === 'HEAD' && handler !== undefined && !handlers['HEAD']\n\n if (handler) {\n const mayDefer = !!foundRoute.options.component\n\n if (typeof handler === 'function') {\n routeMiddlewares.push(handlerToMiddleware(handler, mayDefer))\n } else {\n if (handler.middleware?.length) {\n const handlerMiddlewares = flattenMiddlewares(handler.middleware)\n for (const m of handlerMiddlewares) {\n routeMiddlewares.push(m.options.server)\n }\n }\n if (handler.handler) {\n routeMiddlewares.push(handlerToMiddleware(handler.handler, mayDefer))\n }\n }\n }\n }\n\n // Final middleware: execute router with matched routes for dev styles\n routeMiddlewares.push(((ctx: TODO) =>\n executeRouter(ctx.context, matchedRoutes)) as TODO)\n\n const { ctx, response } = await executeMiddleware(routeMiddlewares, {\n request,\n context,\n params: routeParams,\n pathname,\n handlerType: 'router',\n })\n\n // RFC 9110 §9.3.2: HEAD must carry the same header fields as GET but no body.\n // Resolve any redirect before stripping so the Location header survives.\n if (isHeadFallback) {\n if (!ctx.response) {\n throwRouteHandlerError()\n }\n\n const resolved = await handleRedirectResponse(response, request, getRouter)\n return stripSsrResponseBody(resolved, 'HEAD body stripped')\n }\n\n return normalizeSsrResponse(response)\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/start-server-core",
3
- "version": "1.169.13",
3
+ "version": "1.169.15",
4
4
  "description": "Modern and scalable routing for React applications",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -77,7 +77,7 @@
77
77
  "seroval": "^1.5.4",
78
78
  "@tanstack/history": "1.162.0",
79
79
  "@tanstack/router-core": "1.171.13",
80
- "@tanstack/start-client-core": "1.170.11",
80
+ "@tanstack/start-client-core": "1.170.12",
81
81
  "@tanstack/start-storage-context": "1.167.15"
82
82
  },
83
83
  "devDependencies": {
@@ -157,7 +157,7 @@ const getUser = createServerFn({ method: 'GET' }).handler(async () => {
157
157
 
158
158
  // Update session
159
159
  const login = createServerFn({ method: 'POST' })
160
- .inputValidator((data: { userId: string }) => data)
160
+ .validator((data: { userId: string }) => data)
161
161
  .handler(async ({ data }) => {
162
162
  await updateSession(sessionConfig, { userId: data.userId })
163
163
  return { success: true }
@@ -584,7 +584,9 @@ export function createStartHandler<TRegister = Register>(
584
584
  getStartContext({ throwIfNotFound: false })?.requestAssets,
585
585
  })
586
586
 
587
- routerInstance.update({ additionalContext: { serverContext } })
587
+ // `additionalContext` is request-scoped and only read from router.options
588
+ // during load; avoid a full router.update() and redundant location parse.
589
+ routerInstance.options.additionalContext = { serverContext }
588
590
  await routerInstance.load()
589
591
 
590
592
  if (routerInstance.state.redirect) {