@tanstack/start-server-core 1.132.16 → 1.132.18

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.
@@ -338,29 +338,33 @@ function executeMiddleware(middlewares, ctx) {
338
338
  index++;
339
339
  const middleware = middlewares[index];
340
340
  if (!middleware) return ctx2;
341
- const result = await middleware({
342
- ...ctx2,
343
- // Allow the middleware to call the next middleware in the chain
344
- next: async (nextCtx) => {
345
- const nextResult = await next({
346
- ...ctx2,
347
- ...nextCtx,
348
- context: {
349
- ...ctx2.context,
350
- ...nextCtx?.context || {}
351
- }
352
- });
353
- return Object.assign(ctx2, handleCtxResult(nextResult));
354
- }
355
- // Allow the middleware result to extend the return context
356
- }).catch((err) => {
341
+ let result;
342
+ try {
343
+ result = await middleware({
344
+ ...ctx2,
345
+ // Allow the middleware to call the next middleware in the chain
346
+ next: async (nextCtx) => {
347
+ const nextResult = await next({
348
+ ...ctx2,
349
+ ...nextCtx,
350
+ context: {
351
+ ...ctx2.context,
352
+ ...nextCtx?.context || {}
353
+ }
354
+ });
355
+ return Object.assign(ctx2, handleCtxResult(nextResult));
356
+ }
357
+ // Allow the middleware result to extend the return context
358
+ });
359
+ } catch (err) {
357
360
  if (isSpecialResponse(err)) {
358
- return {
361
+ result = {
359
362
  response: err
360
363
  };
364
+ } else {
365
+ throw err;
361
366
  }
362
- throw err;
363
- });
367
+ }
364
368
  return Object.assign(ctx2, handleCtxResult(result));
365
369
  };
366
370
  return handleCtxResult(next(ctx));
@@ -1 +1 @@
1
- {"version":3,"file":"createStartHandler.js","sources":["../../src/createStartHandler.ts"],"sourcesContent":["import { createMemoryHistory } from '@tanstack/history'\nimport {\n flattenMiddlewares,\n json,\n mergeHeaders,\n} from '@tanstack/start-client-core'\nimport {\n executeRewriteInput,\n isRedirect,\n isResolvedRedirect,\n joinPaths,\n trimPath,\n} from '@tanstack/router-core'\nimport { attachRouterServerSsrUtils } from '@tanstack/router-core/ssr/server'\nimport { runWithStartContext } from '@tanstack/start-storage-context'\nimport { getResponseHeaders, requestHandler } from './request-response'\nimport { getStartManifest } from './router-manifest'\nimport { handleServerAction } from './server-functions-handler'\n\nimport { HEADERS } from './constants'\nimport { ServerFunctionSerializationAdapter } from './serializer/ServerFunctionSerializationAdapter'\nimport type {\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 Awaitable,\n Manifest,\n Register,\n} from '@tanstack/router-core'\nimport type { HandlerCallback } from '@tanstack/router-core/ssr/server'\n\ntype TODO = any\n\nfunction getStartResponseHeaders(opts: { router: AnyRouter }) {\n const headers = mergeHeaders(\n getResponseHeaders() as Headers,\n {\n 'Content-Type': 'text/html; charset=utf-8',\n },\n ...opts.router.state.matches.map((match) => {\n return match.headers\n }),\n )\n return headers\n}\n\nexport function createStartHandler<TRegister = Register>(\n cb: HandlerCallback<AnyRouter>,\n): RequestHandler<TRegister> {\n if (!process.env.TSS_SERVER_FN_BASE) {\n throw new Error(\n 'tanstack/start-server-core: TSS_SERVER_FN_BASE must be defined in your environment for createStartHandler()',\n )\n }\n // TODO do we remove this?\n const APP_BASE = process.env.TSS_APP_BASE || '/'\n // Add trailing slash to sanitise user defined TSS_SERVER_FN_BASE\n const serverFnBase = joinPaths([\n APP_BASE,\n trimPath(process.env.TSS_SERVER_FN_BASE),\n '/',\n ])\n let startRoutesManifest: Manifest | null = null\n let startEntry: StartEntry | null = null\n let routerEntry: RouterEntry | null = null\n const getEntries = async (): Promise<{\n startEntry: StartEntry\n routerEntry: RouterEntry\n }> => {\n if (routerEntry === null) {\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 routerEntry = await import('#tanstack-router-entry')\n }\n if (startEntry === null) {\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 startEntry = await import('#tanstack-start-entry')\n }\n return {\n startEntry: startEntry as unknown as StartEntry,\n routerEntry: routerEntry as unknown as RouterEntry,\n }\n }\n\n const originalFetch = globalThis.fetch\n\n const startRequestResolver: RequestHandler<Register> = async (\n request,\n requestOpts,\n ) => {\n function getOrigin() {\n const originHeader = request.headers.get('Origin')\n if (originHeader) {\n return originHeader\n }\n try {\n return new URL(request.url).origin\n } catch {}\n return 'http://localhost'\n }\n\n // Patching fetch function to use our request resolver\n // if the input starts with `/` which is a common pattern for\n // client-side routing.\n // When we encounter similar requests, we can assume that the\n // user wants to use the same origin as the current request.\n globalThis.fetch = async function (input, init) {\n function resolve(url: URL, requestOptions: RequestInit | undefined) {\n const fetchRequest = new Request(url, requestOptions)\n return startRequestResolver(fetchRequest, requestOpts)\n }\n\n if (typeof input === 'string' && input.startsWith('/')) {\n // e.g: fetch('/api/data')\n const url = new URL(input, getOrigin())\n return resolve(url, init)\n } else if (\n typeof input === 'object' &&\n 'url' in input &&\n typeof input.url === 'string' &&\n input.url.startsWith('/')\n ) {\n // e.g: fetch(new Request('/api/data'))\n const url = new URL(input.url, getOrigin())\n return resolve(url, init)\n }\n\n // If not, it should just use the original fetch\n return originalFetch(input, init)\n } as typeof fetch\n\n const url = new URL(request.url)\n const href = url.href.replace(url.origin, '')\n\n let router: AnyRouter | null = null\n const getRouter = async () => {\n if (router) return router\n // TODO how does this work with base path? does the router need to be configured the same as APP_BASE?\n router = await (await getEntries()).routerEntry.getRouter()\n\n // Update the client-side router with the history\n const isPrerendering = process.env.TSS_PRERENDERING === 'true'\n // env var is set during dev is SPA mode is enabled\n let isShell = process.env.TSS_SHELL === 'true'\n if (isPrerendering && !isShell) {\n // only read the shell header if we are prerendering\n // to avoid runtime behavior changes by injecting this header\n // the header is set by the prerender plugin\n isShell = request.headers.get(HEADERS.TSS_SHELL) === 'true'\n }\n\n // Create a history for the client-side router\n const history = createMemoryHistory({\n initialEntries: [href],\n })\n\n const origin = router.options.origin ?? getOrigin()\n router.update({\n history,\n isShell,\n isPrerendering,\n origin,\n ...{\n defaultSsr: startOptions.defaultSsr,\n serializationAdapters: startOptions.serializationAdapters,\n },\n })\n return router\n }\n\n const startOptions: AnyStartInstanceOptions =\n (await (await getEntries()).startEntry.startInstance?.getOptions()) ||\n ({} as AnyStartInstanceOptions)\n startOptions.serializationAdapters =\n startOptions.serializationAdapters || []\n // insert start specific default serialization adapters\n startOptions.serializationAdapters.push(ServerFunctionSerializationAdapter)\n\n const requestHandlerMiddleware = handlerToMiddleware(\n async ({ context }) => {\n const response = await runWithStartContext(\n {\n getRouter,\n startOptions,\n contextAfterGlobalMiddlewares: context,\n },\n async () => {\n try {\n // First, let's attempt to handle server functions\n if (href.startsWith(serverFnBase)) {\n return await handleServerAction({\n request,\n context: requestOpts?.context,\n })\n }\n\n const executeRouter = async ({\n serverContext,\n }: {\n serverContext: any\n }) => {\n const requestAcceptHeader =\n request.headers.get('Accept') || '*/*'\n const splitRequestAcceptHeader = requestAcceptHeader.split(',')\n\n const supportedMimeTypes = ['*/*', 'text/html']\n const isRouterAcceptSupported = supportedMimeTypes.some(\n (mimeType) =>\n splitRequestAcceptHeader.some((acceptedMimeType) =>\n acceptedMimeType.trim().startsWith(mimeType),\n ),\n )\n\n if (!isRouterAcceptSupported) {\n return json(\n {\n error: 'Only HTML requests are supported here',\n },\n {\n status: 500,\n },\n )\n }\n\n // if the startRoutesManifest is not loaded yet, load it once\n if (startRoutesManifest === null) {\n startRoutesManifest = await getStartManifest({\n basePath: APP_BASE,\n })\n }\n const router = await getRouter()\n attachRouterServerSsrUtils({\n router,\n manifest: startRoutesManifest,\n })\n\n router.update({ additionalContext: { serverContext } })\n await router.load()\n\n // If there was a redirect, skip rendering the page at all\n if (router.state.redirect) {\n return router.state.redirect\n }\n\n await router.serverSsr!.dehydrate()\n\n const responseHeaders = getStartResponseHeaders({ router })\n const response = await cb({\n request,\n router,\n responseHeaders,\n })\n\n return response\n }\n\n const response = await handleServerRoutes({\n getRouter,\n request,\n executeRouter,\n })\n\n return response\n } catch (err) {\n if (err instanceof Response) {\n return err\n }\n\n throw err\n }\n },\n )\n return response\n },\n )\n\n const flattenedMiddlewares = startOptions.requestMiddleware\n ? flattenMiddlewares(startOptions.requestMiddleware)\n : []\n const middlewares = flattenedMiddlewares.map((d) => d.options.server)\n const ctx = await executeMiddleware(\n [...middlewares, requestHandlerMiddleware],\n {\n request,\n\n context: requestOpts?.context || {},\n },\n )\n\n const response: Response = ctx.response\n\n if (isRedirect(response)) {\n if (isResolvedRedirect(response)) {\n if (request.headers.get('x-tsr-redirect') === 'manual') {\n return json(\n {\n ...response.options,\n isSerializedRedirect: true,\n },\n {\n headers: response.headers,\n },\n )\n }\n return response\n }\n if (\n response.options.to &&\n typeof response.options.to === 'string' &&\n !response.options.to.startsWith('/')\n ) {\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(response.options)}`,\n )\n }\n\n if (\n ['params', 'search', 'hash'].some(\n (d) => typeof (response.options as any)[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 response.options,\n )\n .filter((d) => typeof (response.options as any)[d] === 'function')\n .map((d) => `\"${d}\"`)\n .join(', ')}`,\n )\n }\n\n const router = await getRouter()\n const redirect = router.resolveRedirect(response)\n\n if (request.headers.get('x-tsr-redirect') === 'manual') {\n return json(\n {\n ...response.options,\n isSerializedRedirect: true,\n },\n {\n headers: response.headers,\n },\n )\n }\n\n return redirect\n }\n\n return response\n }\n\n return requestHandler(startRequestResolver)\n}\n\nasync function handleServerRoutes({\n getRouter,\n request,\n executeRouter,\n}: {\n getRouter: () => Awaitable<AnyRouter>\n request: Request\n executeRouter: ({\n serverContext,\n }: {\n serverContext: any\n }) => Promise<Response>\n}) {\n const router = await getRouter()\n let url = new URL(request.url)\n url = executeRewriteInput(router.rewrite, url)\n const pathname = url.pathname\n const { matchedRoutes, foundRoute, routeParams } = router.getMatchedRoutes(\n pathname,\n undefined,\n )\n\n // TODO: Error handling? What happens when its `throw redirect()` vs `throw new Error()`?\n\n const middlewares = flattenMiddlewares(\n matchedRoutes.flatMap((r) => r.options.server?.middleware).filter(Boolean),\n ).map((d) => d.options.server)\n\n const server = foundRoute?.options.server\n\n if (server) {\n if (server.handlers) {\n const handlers =\n typeof server.handlers === 'function'\n ? server.handlers({\n createHandlers: (d: any) => d,\n })\n : server.handlers\n\n const requestMethod = request.method.toLowerCase()\n\n // Attempt to find the method in the handlers\n let method = Object.keys(handlers).find(\n (method) => method.toLowerCase() === requestMethod,\n )\n\n // If no method is found, attempt to find the 'all' method\n if (!method) {\n method = Object.keys(handlers).find(\n (method) => method.toLowerCase() === 'all',\n )\n ? 'all'\n : undefined\n }\n\n // If a method is found, execute the handler\n if (method) {\n const handler = handlers[method as RouteMethod]\n if (handler) {\n const mayDefer = !!foundRoute.options.component\n if (typeof handler === 'function') {\n middlewares.push(handlerToMiddleware(handler, mayDefer))\n } else {\n const { middleware } = handler\n if (middleware && middleware.length) {\n middlewares.push(\n ...flattenMiddlewares(middleware).map((d) => d.options.server),\n )\n }\n if (handler.handler) {\n middlewares.push(handlerToMiddleware(handler.handler, mayDefer))\n }\n }\n }\n }\n }\n }\n\n // eventually, execute the router\n middlewares.push(\n handlerToMiddleware((ctx) => executeRouter({ serverContext: ctx.context })),\n )\n\n const ctx = await executeMiddleware(middlewares, {\n request,\n context: {},\n params: routeParams,\n pathname,\n })\n\n const response: Response = ctx.response\n\n return response\n}\n\nfunction throwRouteHandlerError() {\n if (process.env.NODE_ENV === 'development') {\n throw new Error(\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 )\n }\n throw new Error('Internal Server Error')\n}\n\nfunction throwIfMayNotDefer() {\n if (process.env.NODE_ENV === 'development') {\n throw new Error(\n `You cannot defer to the app router if there is no component defined on this route.`,\n )\n }\n throw new Error('Internal Server Error')\n}\nfunction handlerToMiddleware(\n handler: RouteMethodHandlerFn<any, AnyRoute, any, any, any, any>,\n mayDefer: boolean = false,\n) {\n if (mayDefer) {\n return handler as TODO\n }\n return async ({ next: _next, ...rest }: TODO) => {\n const response = await handler({ ...rest, next: throwIfMayNotDefer })\n if (!response) {\n throwRouteHandlerError()\n }\n return response\n }\n}\n\nfunction executeMiddleware(middlewares: TODO, ctx: TODO) {\n let index = -1\n\n const next = async (ctx: TODO) => {\n index++\n const middleware = middlewares[index]\n if (!middleware) return ctx\n\n const result = await middleware({\n ...ctx,\n // Allow the middleware to call the next middleware in the chain\n next: async (nextCtx: TODO) => {\n // Allow the caller to extend the context for the next middleware\n const nextResult = await next({\n ...ctx,\n ...nextCtx,\n context: {\n ...ctx.context,\n ...(nextCtx?.context || {}),\n },\n })\n\n // Merge the result into the context\\\n return Object.assign(ctx, handleCtxResult(nextResult))\n },\n // Allow the middleware result to extend the return context\n }).catch((err: TODO) => {\n if (isSpecialResponse(err)) {\n return {\n response: err,\n }\n }\n\n throw err\n })\n\n // Merge the middleware result into the context, just in case it\n // returns a partial context\n return Object.assign(ctx, handleCtxResult(result))\n }\n\n return handleCtxResult(next(ctx))\n}\n\nfunction handleCtxResult(result: TODO) {\n if (isSpecialResponse(result)) {\n return {\n response: result,\n }\n }\n\n return result\n}\n\nfunction isSpecialResponse(err: TODO) {\n return isResponse(err) || isRedirect(err)\n}\n\nfunction isResponse(response: Response): response is Response {\n return response instanceof Response\n}\n"],"names":["url","response","router","method","ctx"],"mappings":"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"}
1
+ {"version":3,"file":"createStartHandler.js","sources":["../../src/createStartHandler.ts"],"sourcesContent":["import { createMemoryHistory } from '@tanstack/history'\nimport {\n flattenMiddlewares,\n json,\n mergeHeaders,\n} from '@tanstack/start-client-core'\nimport {\n executeRewriteInput,\n isRedirect,\n isResolvedRedirect,\n joinPaths,\n trimPath,\n} from '@tanstack/router-core'\nimport { attachRouterServerSsrUtils } from '@tanstack/router-core/ssr/server'\nimport { runWithStartContext } from '@tanstack/start-storage-context'\nimport { getResponseHeaders, requestHandler } from './request-response'\nimport { getStartManifest } from './router-manifest'\nimport { handleServerAction } from './server-functions-handler'\n\nimport { HEADERS } from './constants'\nimport { ServerFunctionSerializationAdapter } from './serializer/ServerFunctionSerializationAdapter'\nimport type {\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 Awaitable,\n Manifest,\n Register,\n} from '@tanstack/router-core'\nimport type { HandlerCallback } from '@tanstack/router-core/ssr/server'\n\ntype TODO = any\n\nfunction getStartResponseHeaders(opts: { router: AnyRouter }) {\n const headers = mergeHeaders(\n getResponseHeaders() as Headers,\n {\n 'Content-Type': 'text/html; charset=utf-8',\n },\n ...opts.router.state.matches.map((match) => {\n return match.headers\n }),\n )\n return headers\n}\n\nexport function createStartHandler<TRegister = Register>(\n cb: HandlerCallback<AnyRouter>,\n): RequestHandler<TRegister> {\n if (!process.env.TSS_SERVER_FN_BASE) {\n throw new Error(\n 'tanstack/start-server-core: TSS_SERVER_FN_BASE must be defined in your environment for createStartHandler()',\n )\n }\n // TODO do we remove this?\n const APP_BASE = process.env.TSS_APP_BASE || '/'\n // Add trailing slash to sanitise user defined TSS_SERVER_FN_BASE\n const serverFnBase = joinPaths([\n APP_BASE,\n trimPath(process.env.TSS_SERVER_FN_BASE),\n '/',\n ])\n let startRoutesManifest: Manifest | null = null\n let startEntry: StartEntry | null = null\n let routerEntry: RouterEntry | null = null\n const getEntries = async (): Promise<{\n startEntry: StartEntry\n routerEntry: RouterEntry\n }> => {\n if (routerEntry === null) {\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 routerEntry = await import('#tanstack-router-entry')\n }\n if (startEntry === null) {\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 startEntry = await import('#tanstack-start-entry')\n }\n return {\n startEntry: startEntry as unknown as StartEntry,\n routerEntry: routerEntry as unknown as RouterEntry,\n }\n }\n\n const originalFetch = globalThis.fetch\n\n const startRequestResolver: RequestHandler<Register> = async (\n request,\n requestOpts,\n ) => {\n function getOrigin() {\n const originHeader = request.headers.get('Origin')\n if (originHeader) {\n return originHeader\n }\n try {\n return new URL(request.url).origin\n } catch {}\n return 'http://localhost'\n }\n\n // Patching fetch function to use our request resolver\n // if the input starts with `/` which is a common pattern for\n // client-side routing.\n // When we encounter similar requests, we can assume that the\n // user wants to use the same origin as the current request.\n globalThis.fetch = async function (input, init) {\n function resolve(url: URL, requestOptions: RequestInit | undefined) {\n const fetchRequest = new Request(url, requestOptions)\n return startRequestResolver(fetchRequest, requestOpts)\n }\n\n if (typeof input === 'string' && input.startsWith('/')) {\n // e.g: fetch('/api/data')\n const url = new URL(input, getOrigin())\n return resolve(url, init)\n } else if (\n typeof input === 'object' &&\n 'url' in input &&\n typeof input.url === 'string' &&\n input.url.startsWith('/')\n ) {\n // e.g: fetch(new Request('/api/data'))\n const url = new URL(input.url, getOrigin())\n return resolve(url, init)\n }\n\n // If not, it should just use the original fetch\n return originalFetch(input, init)\n } as typeof fetch\n\n const url = new URL(request.url)\n const href = url.href.replace(url.origin, '')\n\n let router: AnyRouter | null = null\n const getRouter = async () => {\n if (router) return router\n // TODO how does this work with base path? does the router need to be configured the same as APP_BASE?\n router = await (await getEntries()).routerEntry.getRouter()\n\n // Update the client-side router with the history\n const isPrerendering = process.env.TSS_PRERENDERING === 'true'\n // env var is set during dev is SPA mode is enabled\n let isShell = process.env.TSS_SHELL === 'true'\n if (isPrerendering && !isShell) {\n // only read the shell header if we are prerendering\n // to avoid runtime behavior changes by injecting this header\n // the header is set by the prerender plugin\n isShell = request.headers.get(HEADERS.TSS_SHELL) === 'true'\n }\n\n // Create a history for the client-side router\n const history = createMemoryHistory({\n initialEntries: [href],\n })\n\n const origin = router.options.origin ?? getOrigin()\n router.update({\n history,\n isShell,\n isPrerendering,\n origin,\n ...{\n defaultSsr: startOptions.defaultSsr,\n serializationAdapters: startOptions.serializationAdapters,\n },\n })\n return router\n }\n\n const startOptions: AnyStartInstanceOptions =\n (await (await getEntries()).startEntry.startInstance?.getOptions()) ||\n ({} as AnyStartInstanceOptions)\n startOptions.serializationAdapters =\n startOptions.serializationAdapters || []\n // insert start specific default serialization adapters\n startOptions.serializationAdapters.push(ServerFunctionSerializationAdapter)\n\n const requestHandlerMiddleware = handlerToMiddleware(\n async ({ context }) => {\n const response = await runWithStartContext(\n {\n getRouter,\n startOptions,\n contextAfterGlobalMiddlewares: context,\n },\n async () => {\n try {\n // First, let's attempt to handle server functions\n if (href.startsWith(serverFnBase)) {\n return await handleServerAction({\n request,\n context: requestOpts?.context,\n })\n }\n\n const executeRouter = async ({\n serverContext,\n }: {\n serverContext: any\n }) => {\n const requestAcceptHeader =\n request.headers.get('Accept') || '*/*'\n const splitRequestAcceptHeader = requestAcceptHeader.split(',')\n\n const supportedMimeTypes = ['*/*', 'text/html']\n const isRouterAcceptSupported = supportedMimeTypes.some(\n (mimeType) =>\n splitRequestAcceptHeader.some((acceptedMimeType) =>\n acceptedMimeType.trim().startsWith(mimeType),\n ),\n )\n\n if (!isRouterAcceptSupported) {\n return json(\n {\n error: 'Only HTML requests are supported here',\n },\n {\n status: 500,\n },\n )\n }\n\n // if the startRoutesManifest is not loaded yet, load it once\n if (startRoutesManifest === null) {\n startRoutesManifest = await getStartManifest({\n basePath: APP_BASE,\n })\n }\n const router = await getRouter()\n attachRouterServerSsrUtils({\n router,\n manifest: startRoutesManifest,\n })\n\n router.update({ additionalContext: { serverContext } })\n await router.load()\n\n // If there was a redirect, skip rendering the page at all\n if (router.state.redirect) {\n return router.state.redirect\n }\n\n await router.serverSsr!.dehydrate()\n\n const responseHeaders = getStartResponseHeaders({ router })\n const response = await cb({\n request,\n router,\n responseHeaders,\n })\n\n return response\n }\n\n const response = await handleServerRoutes({\n getRouter,\n request,\n executeRouter,\n })\n\n return response\n } catch (err) {\n if (err instanceof Response) {\n return err\n }\n\n throw err\n }\n },\n )\n return response\n },\n )\n\n const flattenedMiddlewares = startOptions.requestMiddleware\n ? flattenMiddlewares(startOptions.requestMiddleware)\n : []\n const middlewares = flattenedMiddlewares.map((d) => d.options.server)\n const ctx = await executeMiddleware(\n [...middlewares, requestHandlerMiddleware],\n {\n request,\n\n context: requestOpts?.context || {},\n },\n )\n\n const response: Response = ctx.response\n\n if (isRedirect(response)) {\n if (isResolvedRedirect(response)) {\n if (request.headers.get('x-tsr-redirect') === 'manual') {\n return json(\n {\n ...response.options,\n isSerializedRedirect: true,\n },\n {\n headers: response.headers,\n },\n )\n }\n return response\n }\n if (\n response.options.to &&\n typeof response.options.to === 'string' &&\n !response.options.to.startsWith('/')\n ) {\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(response.options)}`,\n )\n }\n\n if (\n ['params', 'search', 'hash'].some(\n (d) => typeof (response.options as any)[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 response.options,\n )\n .filter((d) => typeof (response.options as any)[d] === 'function')\n .map((d) => `\"${d}\"`)\n .join(', ')}`,\n )\n }\n\n const router = await getRouter()\n const redirect = router.resolveRedirect(response)\n\n if (request.headers.get('x-tsr-redirect') === 'manual') {\n return json(\n {\n ...response.options,\n isSerializedRedirect: true,\n },\n {\n headers: response.headers,\n },\n )\n }\n\n return redirect\n }\n\n return response\n }\n\n return requestHandler(startRequestResolver)\n}\n\nasync function handleServerRoutes({\n getRouter,\n request,\n executeRouter,\n}: {\n getRouter: () => Awaitable<AnyRouter>\n request: Request\n executeRouter: ({\n serverContext,\n }: {\n serverContext: any\n }) => Promise<Response>\n}) {\n const router = await getRouter()\n let url = new URL(request.url)\n url = executeRewriteInput(router.rewrite, url)\n const pathname = url.pathname\n const { matchedRoutes, foundRoute, routeParams } = router.getMatchedRoutes(\n pathname,\n undefined,\n )\n\n // TODO: Error handling? What happens when its `throw redirect()` vs `throw new Error()`?\n\n const middlewares = flattenMiddlewares(\n matchedRoutes.flatMap((r) => r.options.server?.middleware).filter(Boolean),\n ).map((d) => d.options.server)\n\n const server = foundRoute?.options.server\n\n if (server) {\n if (server.handlers) {\n const handlers =\n typeof server.handlers === 'function'\n ? server.handlers({\n createHandlers: (d: any) => d,\n })\n : server.handlers\n\n const requestMethod = request.method.toLowerCase()\n\n // Attempt to find the method in the handlers\n let method = Object.keys(handlers).find(\n (method) => method.toLowerCase() === requestMethod,\n )\n\n // If no method is found, attempt to find the 'all' method\n if (!method) {\n method = Object.keys(handlers).find(\n (method) => method.toLowerCase() === 'all',\n )\n ? 'all'\n : undefined\n }\n\n // If a method is found, execute the handler\n if (method) {\n const handler = handlers[method as RouteMethod]\n if (handler) {\n const mayDefer = !!foundRoute.options.component\n if (typeof handler === 'function') {\n middlewares.push(handlerToMiddleware(handler, mayDefer))\n } else {\n const { middleware } = handler\n if (middleware && middleware.length) {\n middlewares.push(\n ...flattenMiddlewares(middleware).map((d) => d.options.server),\n )\n }\n if (handler.handler) {\n middlewares.push(handlerToMiddleware(handler.handler, mayDefer))\n }\n }\n }\n }\n }\n }\n\n // eventually, execute the router\n middlewares.push(\n handlerToMiddleware((ctx) => executeRouter({ serverContext: ctx.context })),\n )\n\n const ctx = await executeMiddleware(middlewares, {\n request,\n context: {},\n params: routeParams,\n pathname,\n })\n\n const response: Response = ctx.response\n\n return response\n}\n\nfunction throwRouteHandlerError() {\n if (process.env.NODE_ENV === 'development') {\n throw new Error(\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 )\n }\n throw new Error('Internal Server Error')\n}\n\nfunction throwIfMayNotDefer() {\n if (process.env.NODE_ENV === 'development') {\n throw new Error(\n `You cannot defer to the app router if there is no component defined on this route.`,\n )\n }\n throw new Error('Internal Server Error')\n}\nfunction handlerToMiddleware(\n handler: RouteMethodHandlerFn<any, AnyRoute, any, any, any, any>,\n mayDefer: boolean = false,\n) {\n if (mayDefer) {\n return handler as TODO\n }\n return async ({ next: _next, ...rest }: TODO) => {\n const response = await handler({ ...rest, next: throwIfMayNotDefer })\n if (!response) {\n throwRouteHandlerError()\n }\n return response\n }\n}\n\nfunction executeMiddleware(middlewares: TODO, ctx: TODO) {\n let index = -1\n\n const next = async (ctx: TODO) => {\n index++\n const middleware = middlewares[index]\n if (!middleware) return ctx\n\n let result\n try {\n result = await middleware({\n ...ctx,\n // Allow the middleware to call the next middleware in the chain\n next: async (nextCtx: TODO) => {\n // Allow the caller to extend the context for the next middleware\n const nextResult = await next({\n ...ctx,\n ...nextCtx,\n context: {\n ...ctx.context,\n ...(nextCtx?.context || {}),\n },\n })\n\n // Merge the result into the context\\\n return Object.assign(ctx, handleCtxResult(nextResult))\n },\n // Allow the middleware result to extend the return context\n })\n } catch (err: TODO) {\n if (isSpecialResponse(err)) {\n result = {\n response: err,\n }\n } else {\n throw err\n }\n }\n\n // Merge the middleware result into the context, just in case it\n // returns a partial context\n return Object.assign(ctx, handleCtxResult(result))\n }\n\n return handleCtxResult(next(ctx))\n}\n\nfunction handleCtxResult(result: TODO) {\n if (isSpecialResponse(result)) {\n return {\n response: result,\n }\n }\n\n return result\n}\n\nfunction isSpecialResponse(err: TODO) {\n return isResponse(err) || isRedirect(err)\n}\n\nfunction isResponse(response: Response): response is Response {\n return response instanceof Response\n}\n"],"names":["url","response","router","method","ctx"],"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.132.16",
3
+ "version": "1.132.18",
4
4
  "description": "Modern and scalable routing for React applications",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -52,10 +52,10 @@
52
52
  "h3": "2.0.0-beta.4",
53
53
  "seroval": "^1.3.2",
54
54
  "tiny-invariant": "^1.3.3",
55
- "@tanstack/router-core": "1.132.7",
56
55
  "@tanstack/history": "1.132.0",
57
- "@tanstack/start-storage-context": "1.132.7",
58
- "@tanstack/start-client-core": "1.132.16"
56
+ "@tanstack/start-client-core": "1.132.17",
57
+ "@tanstack/router-core": "1.132.17",
58
+ "@tanstack/start-storage-context": "1.132.17"
59
59
  },
60
60
  "devDependencies": {
61
61
  "@standard-schema/spec": "^1.0.0",
@@ -495,33 +495,36 @@ function executeMiddleware(middlewares: TODO, ctx: TODO) {
495
495
  const middleware = middlewares[index]
496
496
  if (!middleware) return ctx
497
497
 
498
- const result = await middleware({
499
- ...ctx,
500
- // Allow the middleware to call the next middleware in the chain
501
- next: async (nextCtx: TODO) => {
502
- // Allow the caller to extend the context for the next middleware
503
- const nextResult = await next({
504
- ...ctx,
505
- ...nextCtx,
506
- context: {
507
- ...ctx.context,
508
- ...(nextCtx?.context || {}),
509
- },
510
- })
498
+ let result
499
+ try {
500
+ result = await middleware({
501
+ ...ctx,
502
+ // Allow the middleware to call the next middleware in the chain
503
+ next: async (nextCtx: TODO) => {
504
+ // Allow the caller to extend the context for the next middleware
505
+ const nextResult = await next({
506
+ ...ctx,
507
+ ...nextCtx,
508
+ context: {
509
+ ...ctx.context,
510
+ ...(nextCtx?.context || {}),
511
+ },
512
+ })
511
513
 
512
- // Merge the result into the context\
513
- return Object.assign(ctx, handleCtxResult(nextResult))
514
- },
515
- // Allow the middleware result to extend the return context
516
- }).catch((err: TODO) => {
514
+ // Merge the result into the context\
515
+ return Object.assign(ctx, handleCtxResult(nextResult))
516
+ },
517
+ // Allow the middleware result to extend the return context
518
+ })
519
+ } catch (err: TODO) {
517
520
  if (isSpecialResponse(err)) {
518
- return {
521
+ result = {
519
522
  response: err,
520
523
  }
524
+ } else {
525
+ throw err
521
526
  }
522
-
523
- throw err
524
- })
527
+ }
525
528
 
526
529
  // Merge the middleware result into the context, just in case it
527
530
  // returns a partial context