{"version":3,"sources":["../../src/router-utils.ts","../../src/lib/router-utils/RouteErrorBoundary.tsx","../../src/lib/internal/UnirendHead/UnirendHeadProvider.tsx","../../src/lib/internal/UnirendHead/UnirendHead.tsx","../../src/lib/router-utils/DefaultNotFound.tsx","../../src/lib/router-utils/DefaultApplicationError.tsx","../../src/lib/router-utils/use-data-loader-envelope-error-hook.ts","../../src/lib/router-utils/page-data-loader.ts","../../src/lib/router-utils/page-data-loader-consts.ts","../../src/lib/router-utils/page-data-loader-utils.ts","../../src/lib/internal/error-envelope-send.ts","../../src/lib/api-envelope/response-helpers.ts","../../src/lib/router-utils/page-data-loader-helpers.ts"],"sourcesContent":["/**\n * Router utilities exports for unirend\n *\n * This entry point includes shared functionality that can be used in both\n * client-side and server-side code, particularly for routing and data loading.\n * It's designed to work seamlessly in both environments.\n *\n * Import from 'unirend/router-utils' in your code\n */\n\n// Error boundary components\nexport { default as RouteErrorBoundary } from './lib/router-utils/RouteErrorBoundary';\nexport type { RouteErrorBoundaryProps } from './lib/router-utils/RouteErrorBoundary';\nexport { useDataLoaderEnvelopeError } from './lib/router-utils/use-data-loader-envelope-error-hook';\nexport {\n  createPageDataLoader,\n  createDefaultPageDataLoaderConfig,\n  createDefaultLocalPageDataLoaderConfig,\n} from './lib/router-utils/page-data-loader';\nexport {\n  type PageDataLoaderConfig,\n  type BasePageDataLoaderConfig,\n  type LocalPageDataLoaderConfig,\n  type LocalPageDataLoaderConfigOverrides,\n  type PageDataLoaderConfigOverrides,\n  type ErrorDefaults,\n  type BaseErrorDefinition,\n  type FullErrorDefinition,\n  type CustomStatusCodeHandler,\n  type LocalPageHandler,\n  type LocalPageHandlerParams,\n} from './lib/router-utils/page-data-loader-types';\n","import React from 'react';\nimport { isRouteErrorResponse, useRouteError } from 'react-router';\nimport DefaultNotFound from './DefaultNotFound';\nimport DefaultApplicationError from './DefaultApplicationError';\n\n/**\n * Props for RouteErrorBoundary component\n *\n * For consistent user experience, custom error components should ideally match\n * the styling and behavior of your server-side error pages (configured via\n * `get500ErrorPage` in ServeSSROptions for SSR applications).\n */\nexport interface RouteErrorBoundaryProps {\n  /** Custom component to render for 404 Not Found errors */\n  NotFoundComponent?: React.ComponentType<{ error?: unknown }>;\n  /** Custom component to render for application errors */\n  ApplicationErrorComponent?: React.ComponentType<{ error: unknown }>;\n}\n\n/**\n * Customizable route error boundary that handles 404s and application errors\n *\n * Consider matching server-side error pages (get500ErrorPage in ServeSSROptions) for consistent UX.\n *\n * @param NotFoundComponent - Custom component for 404 errors (receives error prop)\n * @param ApplicationErrorComponent - Custom component for application errors (receives error prop)\n */\nexport default function RouteErrorBoundary({\n  NotFoundComponent = DefaultNotFound,\n  ApplicationErrorComponent = DefaultApplicationError,\n}: RouteErrorBoundaryProps = {}) {\n  const error = useRouteError();\n\n  // For 404 errors, show the NotFound component with regular app layout\n  if (isRouteErrorResponse(error) && error.status === 404) {\n    return <NotFoundComponent error={error} />;\n  }\n\n  // For all other errors (application errors, other HTTP errors),\n  // show the standalone error page without wrapping in AppLayout\n  // This is because if there's an error in the app layout, it will\n  // cause an infinite loop of errors\n  return <ApplicationErrorComponent error={error} />;\n}\n","import type { ReactNode } from 'react';\nimport { UnirendHeadContext } from './context';\nimport type { HeadCollector } from './context';\n\n/**\n * Wraps the app tree to enable UnirendHead on both server and client.\n *\n * Server: pass a collector object — UnirendHead will push entries into it\n * during renderToString, then the caller reads the collected data.\n *\n * Client: pass null — UnirendHead renders the actual <title>/<meta>/<link>\n * tags and React 19 hoists them to <head> automatically.\n */\nexport function UnirendHeadProvider({\n  children,\n  collector,\n}: {\n  children: ReactNode;\n  collector: HeadCollector | null;\n}) {\n  return (\n    <UnirendHeadContext.Provider value={collector}>\n      {children}\n    </UnirendHeadContext.Provider>\n  );\n}\n","import React, { useContext } from 'react';\nimport type { ReactNode } from 'react';\nimport { UnirendHeadContext } from './context';\nimport type { HeadCollector } from './context';\n\n/**\n * Framework-native document head manager.\n *\n * Place <title>, <meta>, and <link> tags as direct children.\n * Works identically in SSR, SSG, and SPA modes.\n *\n * Server: collects tags via context for injection into the HTML template.\n * Client: renders tags directly; React 19 hoists them to <head>.\n *\n * @example\n * ```tsx\n * import { UnirendHead } from 'unirend/client';\n *\n * function HomePage() {\n *   return (\n *     <>\n *       <UnirendHead>\n *         <title>Home - My App</title>\n *         <meta name=\"description\" content=\"Welcome to my app\" />\n *         <link rel=\"canonical\" href=\"https://example.com/\" />\n *       </UnirendHead>\n *       <main>...</main>\n *     </>\n *   );\n * }\n * ```\n */\nexport function UnirendHead({ children }: { children?: ReactNode }) {\n  const collector = useContext(UnirendHeadContext);\n\n  if (collector !== null) {\n    // Server-side: walk children and collect into the ref.\n    // renderToString is synchronous so mutations here are safe.\n    collectServerHead(collector, children);\n\n    // Render nothing server-side — data is captured in the collector.\n    // The server injects it into <head> via the <!--ss-head--> marker.\n    return null;\n  }\n\n  // Client-side: render the children as real DOM elements.\n  // React 19 automatically hoists <title>, <meta>, <link> to <head>.\n  return <>{children}</>;\n}\n\nfunction collectServerHead(\n  collector: HeadCollector,\n  children: ReactNode,\n): void {\n  React.Children.forEach(children, (child) => {\n    if (!React.isValidElement(child)) {\n      return;\n    }\n\n    const type = child.type as string;\n    const props = child.props as Record<string, unknown>;\n\n    if (type === 'title') {\n      // Last write wins — child route titles override parent layout titles\n      collector.title = toTitleText(props.children as ReactNode);\n    } else if (type === 'meta') {\n      // Accumulate — parent layout and child page metas coexist\n      collector.metas.push(toHeadAttributes(props));\n    } else if (type === 'link') {\n      collector.links.push(toHeadAttributes(props));\n    }\n  });\n}\n\nfunction toTitleText(children: ReactNode): string {\n  return React.Children.toArray(children)\n    .map((node) => {\n      if (\n        typeof node === 'string' ||\n        typeof node === 'number' ||\n        typeof node === 'bigint'\n      ) {\n        return String(node);\n      }\n\n      return '';\n    })\n    .join('');\n}\n\nfunction toHeadAttributes(\n  props: Record<string, unknown>,\n): Record<string, string> {\n  const attrs: Record<string, string> = {};\n\n  for (const [key, value] of Object.entries(props)) {\n    if (key === 'children' || value === null || value === undefined) {\n      continue;\n    }\n\n    const attrValue = toHeadAttributeValue(value);\n    if (attrValue !== null) {\n      attrs[key] = attrValue;\n    }\n  }\n\n  return attrs;\n}\n\nfunction toHeadAttributeValue(value: unknown): string | null {\n  if (typeof value === 'string') {\n    return value;\n  }\n\n  if (typeof value === 'number' || typeof value === 'bigint') {\n    return String(value);\n  }\n\n  if (typeof value === 'boolean') {\n    return value ? 'true' : 'false';\n  }\n\n  return null;\n}\n","import React from 'react';\nimport { UnirendHead } from '../internal/UnirendHead';\n\nexport interface DefaultNotFoundProps {\n  /** The error object from React Router */\n  error?: unknown;\n}\n\n/**\n * Default 404 Not Found component with clean, unbranded styling\n */\nexport default function DefaultNotFound({\n  error: _error,\n}: DefaultNotFoundProps) {\n  return (\n    <div\n      style={{\n        minHeight: '100vh',\n        display: 'flex',\n        alignItems: 'center',\n        justifyContent: 'center',\n        fontFamily: 'system-ui, Arial, sans-serif',\n        background: '#f7f7f8',\n      }}\n    >\n      <UnirendHead>\n        <title>404 - Page Not Found</title>\n      </UnirendHead>\n      <main\n        style={{\n          background: '#fff',\n          borderRadius: '14px',\n          boxShadow: '0 2px 16px rgba(0,0,0,0.08)',\n          maxWidth: '440px',\n          width: '100%',\n          margin: '32px',\n          padding: '32px 28px 24px 28px',\n          textAlign: 'center',\n          boxSizing: 'content-box',\n        }}\n      >\n        <div\n          style={{\n            color: '#e53935',\n            fontSize: '2rem',\n            fontWeight: '600',\n            marginBottom: '12px',\n            letterSpacing: '0.01em',\n          }}\n        >\n          404 - Page Not Found\n        </div>\n\n        <div\n          style={{\n            fontSize: '1.1rem',\n            fontWeight: '500',\n            marginBottom: '24px',\n            color: '#222',\n          }}\n        >\n          The page you're looking for doesn't exist.\n        </div>\n\n        <div\n          style={{\n            background: '#f1f1f3',\n            borderRadius: '6px',\n            padding: '12px 14px',\n            fontSize: '0.98rem',\n            color: '#222',\n            marginBottom: '18px',\n          }}\n        >\n          The requested page could not be found or has been moved to a different\n          location.\n        </div>\n\n        <button\n          onClick={() => window.history.back()}\n          type=\"button\"\n          style={{\n            margin: '18px auto 0 auto',\n            display: 'block',\n            background: '#2563eb',\n            color: '#fff',\n            border: 'none',\n            borderRadius: '6px',\n            padding: '10px 22px',\n            fontSize: '1rem',\n            fontWeight: '500',\n            cursor: 'pointer',\n            boxShadow: '0 1px 3px rgba(0,0,0,0.1)',\n            transition: 'background 0.15s',\n          }}\n          onMouseEnter={(e) => {\n            e.currentTarget.style.background = '#1d4ed8';\n          }}\n          onMouseLeave={(e) => {\n            e.currentTarget.style.background = '#2563eb';\n          }}\n        >\n          Go Back\n        </button>\n      </main>\n    </div>\n  );\n}\n","import React from 'react';\nimport { UnirendHead } from '../internal/UnirendHead';\nimport { getDevMode } from 'lifecycleion/dev-mode';\n\nexport interface DefaultApplicationErrorProps {\n  /** The error object */\n  error: unknown;\n}\n\n/**\n * Default application error component with clean, unbranded styling\n * Designed to be standalone (not wrapped in app layout) to avoid infinite error loops\n */\nexport default function DefaultApplicationError({\n  error,\n}: DefaultApplicationErrorProps) {\n  const errorMessage =\n    error instanceof Error ? error.message : 'An unexpected error occurred';\n  const errorStack = error instanceof Error ? error.stack : undefined;\n\n  const isDevelopment = getDevMode();\n\n  return (\n    <div\n      style={{\n        minHeight: '100vh',\n        display: 'flex',\n        alignItems: 'center',\n        justifyContent: 'center',\n        fontFamily: 'system-ui, Arial, sans-serif',\n        background: '#f7f7f8',\n      }}\n    >\n      <UnirendHead>\n        <title>500 - Internal Server Error</title>\n      </UnirendHead>\n      <main\n        style={{\n          background: '#fff',\n          borderRadius: '14px',\n          boxShadow: '0 2px 16px rgba(0,0,0,0.08)',\n          maxWidth: '440px',\n          width: '100%',\n          margin: '32px',\n          padding: '32px 28px 24px 28px',\n          textAlign: 'center',\n          boxSizing: 'content-box',\n        }}\n      >\n        <div\n          style={{\n            color: '#e53935',\n            fontSize: '2rem',\n            fontWeight: '600',\n            marginBottom: '12px',\n            letterSpacing: '0.01em',\n          }}\n        >\n          500 - Internal Server Error\n        </div>\n\n        <div\n          style={{\n            fontSize: '1.1rem',\n            fontWeight: '500',\n            marginBottom: '24px',\n            color: '#222',\n          }}\n        >\n          {isDevelopment\n            ? 'Error Details (Development Mode)'\n            : \"We're sorry, something went wrong.\"}\n        </div>\n\n        {isDevelopment ? (\n          <>\n            <div style={{ marginBottom: '18px', textAlign: 'left' }}>\n              <div\n                style={{\n                  fontSize: '1rem',\n                  fontWeight: '600',\n                  color: '#444',\n                  marginBottom: '2px',\n                }}\n              >\n                Message:\n              </div>\n              <div\n                style={{\n                  background: '#f1f1f3',\n                  borderRadius: '6px',\n                  padding: '12px 14px',\n                  fontSize: '0.98rem',\n                  color: '#222',\n                  wordBreak: 'break-all',\n                  overflowX: 'auto',\n                }}\n              >\n                {errorMessage}\n              </div>\n            </div>\n            {errorStack && (\n              <div style={{ marginBottom: '18px', textAlign: 'left' }}>\n                <div\n                  style={{\n                    fontSize: '1rem',\n                    fontWeight: '600',\n                    color: '#444',\n                    marginBottom: '2px',\n                  }}\n                >\n                  Stack Trace:\n                </div>\n                <div\n                  style={{\n                    background: '#f1f1f3',\n                    borderRadius: '6px',\n                    padding: '12px 14px',\n                    fontSize: '0.92rem',\n                    color: '#222',\n                    whiteSpace: 'pre-wrap',\n                    fontFamily:\n                      'ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace',\n                    maxHeight: '300px',\n                    overflowY: 'auto',\n                    wordBreak: 'break-all',\n                    overflowX: 'auto',\n                  }}\n                >\n                  {errorStack}\n                </div>\n              </div>\n            )}\n          </>\n        ) : (\n          <div\n            style={{\n              background: '#f1f1f3',\n              borderRadius: '6px',\n              padding: '12px 14px',\n              fontSize: '0.98rem',\n              color: '#222',\n              marginBottom: '18px',\n            }}\n          >\n            An unexpected error occurred. Please try again later.\n          </div>\n        )}\n\n        <button\n          onClick={() => window.location.reload()}\n          type=\"button\"\n          style={{\n            margin: '18px auto 0 auto',\n            display: 'block',\n            background: '#2563eb',\n            color: '#fff',\n            border: 'none',\n            borderRadius: '6px',\n            padding: '10px 22px',\n            fontSize: '1rem',\n            fontWeight: '500',\n            cursor: 'pointer',\n            boxShadow: '0 1px 3px rgba(0,0,0,0.1)',\n            transition: 'background 0.15s',\n          }}\n          onMouseEnter={(e) => {\n            e.currentTarget.style.background = '#1d4ed8';\n          }}\n          onMouseLeave={(e) => {\n            e.currentTarget.style.background = '#2563eb';\n          }}\n        >\n          Refresh Page\n        </button>\n\n        {isDevelopment && (\n          <div\n            style={{\n              marginTop: '30px',\n              fontSize: '0.97rem',\n              color: '#888',\n            }}\n          >\n            <b>Note:</b> Detailed error information is only shown in development\n            mode.\n          </div>\n        )}\n      </main>\n    </div>\n  );\n}\n","import { useMatches } from 'react-router';\nimport type {\n  PageErrorResponse,\n  PageResponseEnvelope,\n} from '../api-envelope/api-envelope-types';\n\nexport interface RouteErrorState {\n  hasError: boolean;\n  is404: boolean;\n  errorResponse: PageErrorResponse | null;\n}\n\n/**\n * Detects envelope-based errors from any route in the current hierarchy.\n *\n * Typically used by a parent layout component to detect errors from child routes.\n * Uses useMatches() instead of useLoaderData() because useLoaderData() only returns\n * the current route's data, but we need to inspect data from child routes.\n */\nexport function useDataLoaderEnvelopeError() {\n  const matches = useMatches();\n\n  // Find error response from any active route\n  let errorResponse: PageErrorResponse | null = null;\n\n  // We need to check all matches because the error could be in any child route\n  for (const match of matches) {\n    const data = match.data as PageResponseEnvelope | undefined;\n\n    if (data?.status === 'error') {\n      errorResponse = data;\n      break;\n    }\n  }\n\n  // Determine if we have an error and what type\n  const hasError = !!errorResponse;\n  const is404 = hasError && errorResponse?.status_code === 404;\n\n  return {\n    hasError,\n    is404,\n    errorResponse,\n  };\n}\n","/**\n * Page Data Loader System\n * -----------------\n *\n * This is a centralized page data loader system that handles all route data fetching for the application.\n * Instead of having multiple specialized loaders for separate pages, we've consolidated all page data fetching\n * into this single data loader that communicates with our API server.\n *\n * How it works:\n * 1. Each route uses createPageDataLoader(config, pageType) to create a loader for that route\n * 2. The pageDataLoader makes a POST request to {APIBaseURL}{pageDataEndpoint}/{pageType} with route params and query params\n *    (default endpoint: /api/v1/page_data/{pageType}, configurable via pageDataEndpoint option)\n * 3. The API server handles the request and returns data in a standardized response format\n * 4. The loader processes the response, handling errors, redirects, and authentication\n *\n * Benefits:\n * - Consistent error handling and response processing\n * - Centralized authentication flow\n * - Simplified route definitions\n * - Easier maintenance with a single loader implementation\n *\n * This approach eliminates the need for multiple loader files and consolidates all\n * data fetching logic in one place, making it easier to maintain and extend.\n *\n * Usage Example:\n * ```typescript\n * import { createPageDataLoader, createDefaultPageDataLoaderConfig } from './pageDataLoader';\n *\n * // Create a configuration (typically done once in your app setup)\n * const config = createDefaultPageDataLoaderConfig('http://localhost:3001');\n *\n * // Or create a custom configuration with your own titles/branding\n * const customConfig = {\n *   APIBaseURL: 'https://api.myapp.com',\n *   pageDataEndpoint: '/api/v1/page_data', // Custom page data endpoint (default: '/api/v1/page_data')\n *   loginURL: '/auth/login',\n *   returnToParam: 'redirect_to', // Custom query param name for login redirects\n *   timeoutMS: 15000, // Custom timeout in milliseconds (default: 10000)\n *   generateFallbackRequestID: (context) => `myapp_${context}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,\n *   connectionErrorMessages: {\n *     server: 'API service unavailable. Please try again later.',\n *     client: 'Network error. Please check your connection and try again.',\n *   },\n *   errorDefaults: {\n *     notFound: {\n *       title: 'Page Not Found | MyApp',\n *       description: 'The page you are looking for could not be found.',\n *       code: 'not_found',\n *       message: 'The requested resource was not found.',\n *     },\n *     internalError: {\n *       title: 'Server Error | MyApp',\n *       description: 'An internal server error occurred.',\n *       code: 'internal_server_error',\n *       message: 'An internal server error occurred.',\n *     },\n *     authRequired: {\n *       title: 'Login Required | MyApp',\n *       description: 'You must be logged in to access this page.',\n *     },\n *     accessDenied: {\n *       title: 'Access Denied | MyApp',\n *       description: 'You do not have permission to access this page.',\n *       message: 'Sorry, you don\\'t have access to this feature.',\n *       code: 'access_denied', // Standard error code (can be customized)\n *     },\n *     genericError: {\n *       title: 'Oops! | MyApp',\n *       description: 'Something unexpected happened.',\n *       message: 'Oops! Something went wrong. Please try again.',\n *       code: 'unknown_error', // Standard error code (can be customized)\n *     },\n *     invalidResponse: {\n *       title: 'Server Error | MyApp',\n *       description: 'The server sent an unexpected response.',\n *       message: 'Sorry, we received an unexpected response from the server.',\n *       code: 'invalid_response', // Standard error code (can be customized)\n *     },\n *     invalidRedirect: {\n *       title: 'Invalid Redirect | MyApp',\n *       description: 'The server attempted an invalid redirect.',\n *       message: 'Sorry, the redirect information was incomplete.',\n *       code: 'invalid_redirect', // Standard error code (can be customized)\n *     },\n *     redirectNotFollowed: {\n *       title: 'Redirect Error | MyApp',\n *       description: 'HTTP redirects from the API are not supported.',\n *       message: 'Sorry, the API attempted an unsupported redirect.',\n *       code: 'api_redirect_not_followed', // Standard error code (can be customized)\n *     },\n *     unsafeRedirect: {\n *       title: 'Unsafe Redirect Blocked | MyApp',\n *       description: 'The redirect target is not allowed for security reasons.',\n *       message: 'Sorry, this redirect is not allowed for security reasons.',\n *       code: 'unsafe_redirect', // Standard error code (can be customized)\n *     },\n *   },\n *   // Optional: Configure allowed redirect origins for security\n *   allowedRedirectOrigins: [\n *     'https://myapp.com',\n *     'https://auth.myapp.com'\n *   ],\n *   // Optional: Transform metadata when converting API errors to page errors\n *   transformErrorMeta: ({ baseMeta, originalMetadata }) => ({\n *     ...baseMeta, // Keep the base page info (title/description)\n *     // Preserve app-specific fields from the original API response\n *     account: originalMetadata?.account,\n *     site_info: originalMetadata?.site_info || { current_year: new Date().getFullYear() },\n *     user_preferences: originalMetadata?.user_preferences,\n *   }),\n *   // Optional: Custom status code handlers\n *   statusCodeHandlers: {\n *     // Handle payment required with API envelope redirect\n *     402: (statusCode, responseData, config) => {\n *       return {\n *         status: 'redirect',\n *         status_code: 200,\n *         request_id: responseData?.request_id || `redirect_${Date.now()}`,\n *         type: 'page',\n *         data: null,\n *         meta: { page: { title: 'Payment Required', description: 'Redirecting to payment page' } },\n *         error: null,\n *         redirect: { target: '/payment-required', permanent: false }\n *       };\n *     },\n *     // Custom handling for maintenance mode\n *     503: (statusCode, responseData, config) => {\n *       // Manually construct a page error response\n *       return {\n *         status: 'error',\n *         status_code: 503,\n *         request_id: responseData?.request_id || `maint_${Date.now()}`,\n *         type: 'page',\n *         data: null,\n *         meta: {\n *           page: {\n *             title: 'Maintenance Mode',\n *             description: 'Service temporarily unavailable for maintenance.'\n *           }\n *         },\n *         error: {\n *           code: 'maintenance_mode',\n *           message: 'Service temporarily unavailable for maintenance.'\n *         }\n *       };\n *     },\n *     // Override default 404 but fall back if needed\n *     404: (statusCode, responseData, config) => {\n *       if (responseData?.error?.code === 'special_not_found') {\n *         // Handle special case with manual response\n *         return {\n *           status: 'error',\n *           status_code: 404,\n *           request_id: responseData?.request_id || `404_${Date.now()}`,\n *           type: 'page',\n *           data: null,\n *           meta: { page: { title: 'Special Not Found', description: 'Special page not found' } },\n *           error: { code: 'special_not_found', message: 'Special page not found' }\n *         };\n *       }\n *       // Fall back to default handling\n *       return null;\n *     }\n *   }\n * };\n *\n * // Create loaders for each page type\n * const homeLoader = createPageDataLoader(config, 'home');\n * const dashboardLoader = createPageDataLoader(config, 'dashboard');\n * const profileLoader = createPageDataLoader(config, 'profile');\n *\n * // Use in React Router\n * export const routes: RouteObject[] = [\n *   { path: '/', loader: homeLoader, element: <HomePage /> },\n *   { path: '/dashboard', loader: dashboardLoader, element: <DashboardPage /> },\n *   { path: '/profile/:id', loader: profileLoader, element: <ProfilePage /> },\n * ];\n * ```\n */\n\nimport type { LoaderFunctionArgs } from 'react-router';\nimport qs from 'qs';\nimport type {\n  PageResponseEnvelope,\n  BaseMeta,\n  APIResponseEnvelope,\n} from '../api-envelope/api-envelope-types';\nimport type { SSRHelpers } from '../types';\nimport { getDevMode } from 'lifecycleion/dev-mode';\nimport {\n  createBaseHeaders,\n  createErrorResponse,\n  decorateWithSsrOnlyData,\n  fetchWithTimeout,\n} from './page-data-loader-utils';\nimport type {\n  PageDataLoaderConfig,\n  PageDataLoaderOptions,\n  LocalPageHandler,\n  LocalPageHandlerParams,\n  LocalPageDataLoaderConfig,\n  LocalPageDataLoaderConfigOverrides,\n  ErrorDefaults,\n  PageDataLoaderConfigOverrides,\n} from './page-data-loader-types';\nimport { APIResponseHelpers } from '../api-envelope/response-helpers';\nimport {\n  processRedirectResponse,\n  processAPIResponse,\n} from './page-data-loader-helpers';\nimport {\n  DEBUG_PAGE_LOADER,\n  DEFAULT_CONNECTION_ERROR_MESSAGES,\n  DEFAULT_ERROR_DEFAULTS,\n  DEFAULT_LOGIN_URL,\n  DEFAULT_RETURN_TO_PARAM,\n  DEFAULT_PAGE_DATA_ENDPOINT,\n  DEFAULT_FALLBACK_REQUEST_ID_GENERATOR,\n  DEFAULT_TIMEOUT_MS,\n} from './page-data-loader-consts';\n\n/**\n * Creates a default configuration object with sensible defaults\n */\nexport function createDefaultPageDataLoaderConfig(\n  APIBaseURL: string,\n  overrides: PageDataLoaderConfigOverrides = {},\n): PageDataLoaderConfig {\n  // Overrides are applied shallowly. If you override nested objects such as\n  // errorDefaults or connectionErrorMessages, provide the full nested object\n  // shape you want to use.\n  const {\n    pageDataEndpoint = DEFAULT_PAGE_DATA_ENDPOINT,\n    loginURL = DEFAULT_LOGIN_URL,\n    returnToParam = DEFAULT_RETURN_TO_PARAM,\n    statusCodeHandlers,\n    ...localOverrides\n  } = overrides;\n\n  const defaultLocalConfig =\n    createDefaultLocalPageDataLoaderConfig(localOverrides);\n\n  const config: PageDataLoaderConfig = {\n    APIBaseURL,\n    ...defaultLocalConfig,\n  };\n\n  config.pageDataEndpoint = pageDataEndpoint;\n  config.loginURL = loginURL;\n  config.returnToParam = returnToParam;\n\n  if (statusCodeHandlers) {\n    config.statusCodeHandlers = statusCodeHandlers;\n  }\n\n  return config;\n}\n\nexport function createDefaultLocalPageDataLoaderConfig(\n  overrides: LocalPageDataLoaderConfigOverrides = {},\n): LocalPageDataLoaderConfig {\n  // Overrides are applied shallowly. If you override nested objects such as\n  // errorDefaults or connectionErrorMessages, provide the full nested object\n  // shape you want to use.\n  // Deep-clone nested defaults to avoid shared references\n  const errorDefaultsClone: ErrorDefaults = JSON.parse(\n    JSON.stringify(DEFAULT_ERROR_DEFAULTS),\n  ) as ErrorDefaults;\n\n  const connectionErrorMessagesClone = {\n    ...DEFAULT_CONNECTION_ERROR_MESSAGES,\n  } as const;\n\n  return {\n    errorDefaults: errorDefaultsClone,\n    connectionErrorMessages: connectionErrorMessagesClone,\n    loginURL: DEFAULT_LOGIN_URL,\n    returnToParam: DEFAULT_RETURN_TO_PARAM,\n    generateFallbackRequestID: DEFAULT_FALLBACK_REQUEST_ID_GENERATOR,\n    timeoutMS: DEFAULT_TIMEOUT_MS,\n    ...overrides,\n  };\n}\n\n// Define a factory function to create page data loaders with specific page types\nexport function createPageDataLoader(\n  config: PageDataLoaderConfig,\n  pageType: string,\n): (args: LoaderFunctionArgs) => Promise<unknown>;\nexport function createPageDataLoader(\n  config: LocalPageDataLoaderConfig,\n  handler: LocalPageHandler,\n): (args: LoaderFunctionArgs) => Promise<unknown>;\nexport function createPageDataLoader(\n  config: PageDataLoaderConfig | LocalPageDataLoaderConfig,\n  pageTypeOrHandler: string | LocalPageHandler,\n) {\n  // If the pageTypeOrHandler is a string, create a page data loader that uses the page type\n  if (typeof pageTypeOrHandler === 'string') {\n    const pageType = pageTypeOrHandler;\n\n    return ({ request, params }: LoaderFunctionArgs) =>\n      pageDataLoader({\n        request,\n        params,\n        pageType,\n        config: config as PageDataLoaderConfig,\n      });\n  }\n\n  // If the pageTypeOrHandler is a LocalPageHandler, create a page data loader that uses the handler\n  const handler = pageTypeOrHandler;\n  return (args: LoaderFunctionArgs) =>\n    localPageDataLoader(config as LocalPageDataLoaderConfig, handler, args);\n}\n\n/**\n * Main page data loader function that handles data fetching for a specific page type\n */\nasync function pageDataLoader({\n  request,\n  params,\n  pageType,\n  config,\n}: PageDataLoaderOptions): Promise<PageResponseEnvelope> {\n  const isServer = typeof window === 'undefined';\n  const SSRHelpers = (request as unknown as { SSRHelpers?: SSRHelpers })\n    .SSRHelpers;\n\n  // Per-request isDevelopment: prefer the Fastify request decoration (set by\n  // the onRequest hook), fall back to the global for client-side loaders.\n  const isDevelopment =\n    (isServer\n      ? (SSRHelpers?.fastifyRequest as { isDevelopment?: boolean } | undefined)\n          ?.isDevelopment\n      : undefined) ?? getDevMode();\n\n  // Get the API server URL (already normalized)\n  const APIBaseURL = config.APIBaseURL;\n  const pageDataEndpoint =\n    config.pageDataEndpoint || DEFAULT_PAGE_DATA_ENDPOINT;\n\n  // Single source of truth for the external page-data URL\n  // Note: Internal short-circuit calls do NOT rely on this URL; they reuse the\n  // same routing context we place in requestBody (route_params, query_params,\n  // request_path, original_url) to ensure consistency.\n  const apiEndpoint = `${APIBaseURL}${pageDataEndpoint}/${pageType}`;\n\n  // build the request body\n  const url = new URL(request.url);\n\n  // Convert params to ensure all values are strings\n  const routeParams: Record<string, string> = {};\n\n  for (const [key, value] of Object.entries(params)) {\n    routeParams[key] = value || '';\n  }\n\n  // Assemble the request body\n  const requestBody: Record<string, unknown> = {\n    route_params: routeParams, // react router params\n    query_params: qs.parse(url.search, { ignoreQueryPrefix: true }),\n    // Include the requested path and original URL for debugging\n    request_path: url.pathname,\n    original_url: request.url,\n  };\n\n  // Forward SSR request context to API server (SSR-only, not sent from browser)\n  if (isServer && SSRHelpers?.fastifyRequest) {\n    const fastifyReq = SSRHelpers.fastifyRequest as {\n      requestContext?: Record<string, unknown>;\n    };\n\n    // Only include if there's actual data (skip empty objects and arrays)\n    if (\n      fastifyReq.requestContext &&\n      !Array.isArray(fastifyReq.requestContext) &&\n      Object.keys(fastifyReq.requestContext).length > 0\n    ) {\n      requestBody.ssr_request_context = fastifyReq.requestContext;\n    }\n  }\n\n  try {\n    if (isServer) {\n      if (DEBUG_PAGE_LOADER) {\n        const hasInternalHandler = !!SSRHelpers?.handlers?.hasHandler(pageType);\n\n        // eslint-disable-next-line no-console\n        console.log('[pageDataLoader] server-side data fetching decision', {\n          pageType,\n          SSRHelpersAttached: !!SSRHelpers,\n          hasInternalHandler,\n          strategy: hasInternalHandler\n            ? 'internal_short_circuit'\n            : 'http_fetch',\n        });\n      }\n\n      // If SSRHelper is available (not undefined) and there is a registered handler, try internal call first before falling back to HTTP fetch\n      if (SSRHelpers?.handlers?.hasHandler(pageType)) {\n        // Note: internal_short_circuit selected\n\n        try {\n          const outcome = await SSRHelpers.handlers.callHandler({\n            originalRequest: SSRHelpers.fastifyRequest,\n            controlledReply: SSRHelpers.controlledReply,\n            pageType,\n            timeoutMS: config.timeoutMS ?? DEFAULT_TIMEOUT_MS,\n            // Pass the exact same data that would be in the POST body (converted from snake_case)\n            // Extract from requestBody (React Router context from frontend loader)\n            // Fallback to empty values if requestBody is malformed (defensive programming)\n            // Note: These represent the React Router URL/params, NOT the Fastify request URL\n            routeParams:\n              (requestBody.route_params as Record<string, string>) || {},\n            queryParams:\n              (requestBody.query_params as Record<string, unknown>) || {},\n            requestPath: (requestBody.request_path as string) || '',\n            originalURL: (requestBody.original_url as string) || '',\n          });\n\n          if (outcome.exists && outcome.result) {\n            // Internal handler returned an envelope\n            const result = outcome.result as PageResponseEnvelope;\n\n            if (result.type === 'page') {\n              if (\n                result.status === 'redirect' &&\n                result.type === 'page' &&\n                result.redirect\n              ) {\n                return processRedirectResponse(\n                  config,\n                  result as unknown as Record<string, unknown>,\n                  {},\n                );\n              }\n\n              return decorateWithSsrOnlyData(result, {});\n            }\n          } else if (DEBUG_PAGE_LOADER) {\n            // No internal handler; fall back to HTTP fetch\n            // eslint-disable-next-line no-console\n            console.warn(\n              `[pageDataLoader] fallback to http_fetch for ${pageType}`,\n            );\n          }\n        } catch (internalError) {\n          if (DEBUG_PAGE_LOADER) {\n            // eslint-disable-next-line no-console\n            console.error(\n              `[pageDataLoader] Internal handler error for ${pageType}; converting to 500 error`,\n              internalError,\n            );\n          }\n\n          // Choose a clearer message for internal handler timeouts vs. generic internal errors\n          const isHandlerTimeout =\n            internalError instanceof Error &&\n            (internalError as unknown as { errorCode?: string }).errorCode ===\n              'handler_timeout';\n\n          // Safe, user-facing messages; do not expose internal error messages\n          // For internal timeouts, reuse the server connection error message if provided\n          const message = isHandlerTimeout\n            ? config.connectionErrorMessages?.server ||\n              DEFAULT_CONNECTION_ERROR_MESSAGES.server\n            : config.errorDefaults.internalError.message;\n\n          // Return a 500 error envelope immediately to avoid reattempt via HTTP\n          return decorateWithSsrOnlyData(\n            createErrorResponse(\n              config,\n              500,\n              config.errorDefaults.internalError.code,\n              message,\n              undefined,\n              undefined,\n              isDevelopment\n                ? internalError instanceof Error\n                  ? {\n                      name: internalError.name,\n                      message: internalError.message,\n                      stack: internalError.stack,\n                      ...(isHandlerTimeout\n                        ? {\n                            errorCode: 'handler_timeout',\n                            timeoutMS: (\n                              internalError as unknown as { timeoutMS?: number }\n                            ).timeoutMS,\n                          }\n                        : {}),\n                    }\n                  : { value: String(internalError) }\n                : undefined,\n            ),\n            {},\n          );\n        }\n      }\n\n      // Set to JSON and copy relevant headers from ssr request to api server\n      // Forward: cookies, language preferences, and tracking headers\n\n      const headers = createBaseHeaders();\n\n      // Properly access headers from the Request object\n      const xssrRequest = request.headers.get('x-ssr-request');\n      const originalIP = request.headers.get('x-ssr-original-ip');\n      const userAgent = request.headers.get('user-agent');\n      const correlationID = request.headers.get('x-correlation-id');\n      const cookie = request.headers.get('cookie');\n      const acceptLanguage = request.headers.get('accept-language');\n\n      // Set headers if they exist\n      if (xssrRequest) {\n        headers.set('X-SSR-Request', xssrRequest);\n      }\n\n      if (originalIP) {\n        headers.set('X-SSR-Original-IP', originalIP);\n      }\n\n      if (userAgent) {\n        headers.set('X-SSR-Forwarded-User-Agent', userAgent);\n      }\n\n      if (correlationID) {\n        headers.set('X-Correlation-ID', correlationID);\n      }\n\n      if (cookie) {\n        headers.set('Cookie', cookie);\n      }\n\n      // Forward Accept-Language header for internationalization support\n      if (acceptLanguage) {\n        headers.set('Accept-Language', acceptLanguage);\n      }\n\n      const response = await fetchWithTimeout(\n        apiEndpoint,\n        {\n          method: 'POST',\n          headers,\n          body: JSON.stringify(requestBody),\n          redirect: 'manual', // Don't automatically follow redirects\n        },\n        config.timeoutMS ?? DEFAULT_TIMEOUT_MS,\n      );\n\n      const result = await processAPIResponse(response, config, isDevelopment);\n\n      // Merge ssr_request_context from API response back into SSR request (SSR-only)\n      if (\n        result.ssr_request_context &&\n        typeof result.ssr_request_context === 'object' &&\n        !Array.isArray(result.ssr_request_context) &&\n        Object.keys(result.ssr_request_context).length > 0 &&\n        SSRHelpers?.fastifyRequest\n      ) {\n        const fastifyReq = SSRHelpers.fastifyRequest as {\n          requestContext?: Record<string, unknown>;\n        };\n\n        if (!fastifyReq.requestContext) {\n          fastifyReq.requestContext = {};\n        }\n\n        Object.assign(fastifyReq.requestContext, result.ssr_request_context);\n      }\n\n      return result;\n    } else {\n      if (DEBUG_PAGE_LOADER) {\n        // eslint-disable-next-line no-console\n        console.log(`Client side data fetching for ${pageType} page`);\n      }\n\n      // Client side data fetching\n      const headers = createBaseHeaders();\n\n      // Forward Accept-Language header for internationalization support\n      // In the browser, navigator.languages provides the user's preferred languages\n      if (typeof navigator !== 'undefined') {\n        if (navigator.languages && navigator.languages.length) {\n          headers.set('Accept-Language', navigator.languages.join(','));\n        } else if (navigator.language) {\n          headers.set('Accept-Language', navigator.language);\n        }\n      }\n\n      // On client side, we include credentials: 'include' to allow cookies to be sent\n      const response = await fetchWithTimeout(\n        apiEndpoint,\n        {\n          method: 'POST',\n          headers,\n          body: JSON.stringify(requestBody),\n          credentials: 'include', // This allows cookies to be sent with the request\n          redirect: 'manual', // Don't automatically follow redirects\n        },\n        config.timeoutMS ?? DEFAULT_TIMEOUT_MS,\n      );\n\n      return processAPIResponse(response, config, isDevelopment);\n    }\n  } catch (error) {\n    if (DEBUG_PAGE_LOADER) {\n      // eslint-disable-next-line no-console\n      console.error('Error fetching page data:', error);\n    }\n\n    // Check for common connection errors\n    const errorMessage =\n      error instanceof Error\n        ? error.message\n        : 'Failed to fetch data from server';\n\n    const isConnectionError =\n      errorMessage.includes('fetch failed') ||\n      errorMessage.includes('Unable to connect') ||\n      errorMessage.includes('ECONNREFUSED') ||\n      errorMessage.includes('NetworkError') ||\n      errorMessage.includes('Request timeout after'); // Treat timeout as connection error\n\n    // Create appropriate message based on server/client context\n    let friendlyMessage = errorMessage;\n\n    if (isConnectionError) {\n      friendlyMessage = isServer\n        ? config.connectionErrorMessages?.server ||\n          DEFAULT_CONNECTION_ERROR_MESSAGES.server\n        : config.connectionErrorMessages?.client ||\n          DEFAULT_CONNECTION_ERROR_MESSAGES.client;\n    }\n\n    // Network or other errors that prevent the fetch from completing\n    // No cookies would be available here since the fetch failed\n    return decorateWithSsrOnlyData(\n      createErrorResponse(\n        config,\n        500,\n        config.errorDefaults.internalError.code,\n        friendlyMessage,\n      ),\n      {}, // No SSR-only data for failed fetches\n    );\n  }\n}\n\n/**\n * Local page data loader (framework does not perform HTTP or short-circuit calls)\n *\n * Purpose:\n * - Run a page data loader locally without the framework doing an HTTP fetch or short-circuit calls\n * - Preserve the same ergonomics as the normal loader: timeout handling,\n *   redirect support, envelope validation, and consistent error envelopes\n *\n * Notes:\n * - Your handler may still perform its own fetch/database calls; the timeout\n *   here applies to the entire handler execution\n * - The handler receives `LocalPageHandlerParams` (no Fastify request object)\n * - `invocationOrigin` is set to \"local\" for debugging\n * - Timeout uses `config.timeoutMS` (0 disables); local timeout failures reuse\n *   `connectionErrorMessages.server` for parity with the HTTP loader path\n */\nasync function localPageDataLoader<T = unknown, M extends BaseMeta = BaseMeta>(\n  config: LocalPageDataLoaderConfig,\n  handler: LocalPageHandler<T, M>,\n  { request, params }: LoaderFunctionArgs,\n): Promise<unknown> {\n  const url = new URL(request.url);\n\n  // Convert params to ensure all values are strings\n  const routeParams: Record<string, string> = {};\n  for (const [key, value] of Object.entries(params)) {\n    routeParams[key] = value || '';\n  }\n\n  // Assemble the local handler params with origin and routing context\n  const localParams: LocalPageHandlerParams = {\n    pageType: 'local',\n    invocationOrigin: 'local',\n    routeParams: routeParams,\n    queryParams: qs.parse(url.search, { ignoreQueryPrefix: true }),\n    requestPath: url.pathname,\n    originalURL: request.url,\n  };\n\n  // Configure timeout (0 disables)\n  const timeoutMS = config.timeoutMS ?? DEFAULT_TIMEOUT_MS;\n\n  // Defer invocation to the microtask queue and normalize to a Promise.\n  // Using Promise.resolve().then(() => ...) ensures synchronous throws from\n  // the handler become Promise rejections instead of escaping before our\n  // timeout race is set up. Non-Promise returns are treated as resolved values.\n  const invocation = Promise.resolve().then(() => handler(localParams));\n\n  // Attach a no-op catch when using a timeout to prevent a possible\n  // unhandledRejection if the timeout \"wins\" and the handler later rejects.\n  if (timeoutMS && timeoutMS > 0) {\n    void invocation.catch(() => {});\n  }\n\n  // Track the timeout ID to ensure it is cleared regardless of timeout path\n  let timeoutID: ReturnType<typeof setTimeout> | undefined;\n\n  // Build a single promise that either resolves to the handler result or rejects on timeout\n  const resultPromise: Promise<PageResponseEnvelope | APIResponseEnvelope> =\n    // Check if a timeout is specified\n    !timeoutMS || timeoutMS <= 0\n      ? // No timeout specified, return the handler result immediately\n        // Handler promise when no timer is specified\n        (invocation as Promise<PageResponseEnvelope | APIResponseEnvelope>)\n      : // If a timeout is specified, race the handler promise with a timer promise\n        (Promise.race([\n          // Handler promise\n          invocation,\n          // Timer promise\n          new Promise<never>((_, reject) => {\n            timeoutID = setTimeout(() => {\n              const error = new Error(`Request timeout after ${timeoutMS}ms`);\n              (error as unknown as { errorCode: string }).errorCode =\n                'handler_timeout';\n              (error as unknown as { timeoutMS: number }).timeoutMS = timeoutMS;\n              reject(error);\n            }, timeoutMS);\n          }),\n        ]) as Promise<PageResponseEnvelope | APIResponseEnvelope>);\n\n  try {\n    // Ensure timer cleared regardless of outcome\n    const result = await resultPromise.finally(() => {\n      if (timeoutID) {\n        clearTimeout(timeoutID);\n      }\n    });\n\n    // Validate that the handler returned a proper envelope object\n    if (!APIResponseHelpers.isValidEnvelope(result)) {\n      return createErrorResponse(\n        config,\n        500,\n        config.errorDefaults.invalidResponse.code,\n        config.errorDefaults.invalidResponse.message,\n      );\n    }\n\n    // Handle API-style redirect envelopes (status: \"redirect\")\n    if (\n      result.status === 'redirect' &&\n      result.type === 'page' &&\n      result.redirect\n    ) {\n      return processRedirectResponse(\n        config,\n        result as unknown as Record<string, unknown>,\n        {},\n      );\n    }\n\n    // Success or error envelopes are returned as-is and decorated\n    // Note:\n    // - Status codes provided by the handler's envelope (status_code) are preserved.\n    //   The SSR base renderer will read loaderData and set the HTTP status accordingly.\n    // - SSR-only cookies are NOT available in the local path because there is no HTTP\n    //   response to extract Set-Cookie headers from. If you need to set cookies, use\n    //   the HTTP-backed loader path (API fetch) so cookies can be forwarded via __ssOnly.\n    return decorateWithSsrOnlyData(result as PageResponseEnvelope, {});\n  } catch (internalError) {\n    const isDevelopment = getDevMode();\n\n    // Identify timeout errors produced by the race above\n    const isHandlerTimeout =\n      internalError instanceof Error &&\n      (internalError as unknown as { errorCode?: string }).errorCode ===\n        'handler_timeout';\n\n    // Local timeout failures reuse the same user-facing message bucket as\n    // HTTP timeout/connection-style failures.\n    const message = isHandlerTimeout\n      ? config.connectionErrorMessages?.server ||\n        DEFAULT_CONNECTION_ERROR_MESSAGES.server\n      : config.errorDefaults.internalError.message;\n\n    // Build a standardized page error envelope\n    return decorateWithSsrOnlyData(\n      createErrorResponse(\n        config,\n        500,\n        config.errorDefaults.internalError.code,\n        message,\n        undefined,\n        undefined,\n        isDevelopment\n          ? internalError instanceof Error\n            ? {\n                name: internalError.name,\n                message: internalError.message,\n                stack: internalError.stack,\n                ...(isHandlerTimeout\n                  ? {\n                      errorCode: 'handler_timeout',\n                      timeoutMS: (\n                        internalError as unknown as { timeoutMS?: number }\n                      ).timeoutMS,\n                    }\n                  : {}),\n              }\n            : { value: String(internalError) }\n          : undefined,\n      ),\n      {},\n    );\n  }\n}\n","import type { ErrorDefaults } from './page-data-loader-types';\n\n// Debug flag to enable/disable logging in the page data loader\nexport const DEBUG_PAGE_LOADER = false; // Set to false in a production release\n\n/**\n * Internal default values - not exported publicly, used for fallbacks and createDefaultPageDataLoaderConfig\n */\n\nexport const DEFAULT_ERROR_DEFAULTS: ErrorDefaults = {\n  notFound: {\n    title: 'Page Not Found',\n    description: 'The page you are looking for could not be found.',\n    code: 'not_found',\n    message: 'The requested resource was not found.',\n  },\n  internalError: {\n    title: 'Server Error',\n    description: 'An internal server error occurred.',\n    code: 'internal_server_error',\n    message: 'An internal server error occurred.',\n  },\n  authRequired: {\n    title: 'Authentication Required',\n    description: 'You must be logged in to access this page.',\n  },\n  accessDenied: {\n    title: 'Access Denied',\n    description: 'You do not have permission to access this page.',\n    message: 'You do not have permission to access this resource.',\n    code: 'access_denied',\n  },\n  genericError: {\n    title: 'Error',\n    description: 'An unexpected error occurred.',\n    message: 'An unexpected error occurred.',\n    code: 'unknown_error',\n  },\n  invalidResponse: {\n    title: 'Invalid Response',\n    description: 'The server returned an unexpected response format.',\n    message: 'The server returned an unexpected response format.',\n    code: 'invalid_response',\n  },\n  invalidRedirect: {\n    title: 'Invalid Redirect',\n    description: 'The server attempted an invalid redirect.',\n    message: 'Redirect target not specified in response',\n    code: 'invalid_redirect',\n  },\n  redirectNotFollowed: {\n    title: 'Redirect Not Followed',\n    description: 'HTTP redirects from the API are not supported.',\n    message:\n      'The API attempted to redirect the request, which is not supported.',\n    code: 'api_redirect_not_followed',\n  },\n  unsafeRedirect: {\n    title: 'Unsafe Redirect Blocked',\n    description: 'The redirect target is not allowed for security reasons.',\n    message: 'Unsafe redirect blocked',\n    code: 'unsafe_redirect',\n  },\n} as const;\n\nexport const DEFAULT_CONNECTION_ERROR_MESSAGES = {\n  server: 'Internal server error: Unable to connect to the API service.',\n  client:\n    'Unable to connect to the API server. Please check your network connection and try again.',\n} as const;\n\nexport const DEFAULT_LOGIN_URL = '/login';\nexport const DEFAULT_RETURN_TO_PARAM = 'return_to';\nexport const DEFAULT_PAGE_DATA_ENDPOINT = '/api/v1/page_data';\nexport const DEFAULT_TIMEOUT_MS = 10000; // 10 seconds\n\n/**\n * Default fallback request ID generator for error responses\n * Used when API doesn't provide a request_id (e.g., network errors, captive portals, etc.)\n * @param context - The context for the request ID (\"error\" or \"redirect\")\n */\nexport const DEFAULT_FALLBACK_REQUEST_ID_GENERATOR = (\n  context: 'error' | 'redirect' = 'error',\n) => `${context}_${Date.now()}`;\n","import type {\n  BaseMeta,\n  ErrorDetailsValue,\n  PageErrorResponse,\n  PageResponseEnvelope,\n} from '../api-envelope/api-envelope-types';\nimport {\n  DEBUG_PAGE_LOADER,\n  DEFAULT_FALLBACK_REQUEST_ID_GENERATOR,\n  DEFAULT_TIMEOUT_MS,\n} from './page-data-loader-consts';\nimport type {\n  LocalPageDataLoaderConfig,\n  PageDataLoaderConfig,\n} from './page-data-loader-types';\nimport { matchesOriginList } from 'lifecycleion/domain-utils';\n\n/**\n * Helper function to create base headers with Content-Type: application/json\n * Used by both server and client-side data fetching\n */\nexport function createBaseHeaders() {\n  const headers = new Headers();\n  headers.set('Content-Type', 'application/json');\n  return headers;\n}\n\nexport function decorateWithSsrOnlyData(\n  response: PageResponseEnvelope,\n  // eslint-disable-next-line @typescript-eslint/naming-convention\n  SSR_ONLY_DATA: Record<string, unknown>,\n) {\n  const isServer = typeof window === 'undefined'; // detecting here again instead of passing to promote tree-shaking\n\n  if (isServer) {\n    return {\n      ...response,\n      // eslint-disable-next-line @typescript-eslint/naming-convention\n      __ssOnly: SSR_ONLY_DATA,\n    };\n  }\n\n  return response;\n}\n\n/**\n * Helper function to validate if a redirect target is safe\n * @param target - The redirect target URL or path\n * @param allowedOrigins - Array of allowed origins, or undefined to disable validation\n * @returns true if the redirect is safe, false otherwise\n */\nexport function isSafeRedirect(\n  target: string,\n  allowedOrigins?: string[],\n): boolean {\n  // If allowedOrigins is undefined, disable validation (allow any redirect)\n  if (allowedOrigins === undefined) {\n    return true;\n  }\n\n  // Allow root-relative paths, but block protocol-relative URLs such as //evil.com\n  if (target.startsWith('/') && !target.startsWith('//')) {\n    return true;\n  }\n\n  // If allowedOrigins is an empty array, only allow relative paths (block all external URLs)\n  if (allowedOrigins.length === 0) {\n    return false;\n  }\n\n  try {\n    const targetURL = new URL(target);\n\n    if (!['http:', 'https:'].includes(targetURL.protocol)) {\n      return false;\n    }\n\n    return matchesOriginList(targetURL.origin, allowedOrigins);\n  } catch {\n    return false;\n  }\n}\n\n/**\n * Fetch with timeout using AbortController\n *\n * Prevents requests from hanging indefinitely by canceling them after the specified timeout.\n * Uses AbortController which is supported in Node 16+ and all modern browsers.\n *\n * @param url - The URL to fetch\n * @param options - Fetch options (headers, method, body, etc.)\n * @param timeoutMS - Timeout in milliseconds (0 to disable timeout)\n * @returns Promise that resolves to Response or rejects with timeout/network error\n */\nexport async function fetchWithTimeout(\n  url: string,\n  options: RequestInit = {},\n  timeoutMS: number = DEFAULT_TIMEOUT_MS,\n): Promise<Response> {\n  // If timeout is 0 or negative, use regular fetch without timeout\n  if (timeoutMS <= 0) {\n    return fetch(url, options);\n  }\n\n  const controller = new AbortController();\n  const timer = setTimeout(() => controller.abort(), timeoutMS);\n\n  try {\n    const response = await fetch(url, {\n      ...options,\n      signal: controller.signal,\n    });\n    return response;\n  } catch (error) {\n    // Abort the controller to ensure cleanup in case of non-timeout errors\n    controller.abort();\n\n    // Check if the error is due to abortion (timeout)\n    if (error instanceof Error && error.name === 'AbortError') {\n      throw new Error(`Request timeout after ${timeoutMS}ms`);\n    }\n\n    // Re-throw other errors (network issues, etc.)\n    throw error;\n  } finally {\n    clearTimeout(timer); // Prevent Node.js warning on fulfilled request\n  }\n}\n\n/**\n * Creates a page error response, optionally preserving metadata from original API responses\n *\n * When an API endpoint returns an error with type \"api\", this function converts it to\n * a page error response (type \"page\") that React Router can handle. The metadata parameter\n * contains fields from the original API response that should be preserved (like account info).\n */\nexport function createErrorResponse(\n  config: PageDataLoaderConfig | LocalPageDataLoaderConfig,\n  statusCode: number,\n  errorCode: string,\n  message: string,\n  requestID?: string,\n  metadata?: {\n    title?: string;\n    description?: string;\n    [key: string]: unknown;\n  },\n  errorDetails?: ErrorDetailsValue,\n): PageErrorResponse {\n  // Default error response creation - use generic error as fallback\n  let title = config.errorDefaults.genericError.title;\n  let description = config.errorDefaults.genericError.description;\n\n  if (statusCode === 404) {\n    title = config.errorDefaults.notFound.title;\n    description = config.errorDefaults.notFound.description;\n  } else if (statusCode === 500) {\n    title = config.errorDefaults.internalError.title;\n    description = config.errorDefaults.internalError.description;\n  } else if (statusCode === 401) {\n    title = config.errorDefaults.authRequired.title;\n    description = config.errorDefaults.authRequired.description;\n  } else if (statusCode === 403) {\n    title = config.errorDefaults.accessDenied.title;\n    description = config.errorDefaults.accessDenied.description;\n  }\n\n  // Override with provided metadata if present\n  if (metadata?.title) {\n    title = metadata.title;\n  }\n\n  if (metadata?.description) {\n    description = metadata.description;\n  }\n\n  const baseMeta: BaseMeta = {\n    page: {\n      title,\n      description,\n    },\n  };\n\n  // Transform meta if transformer is provided\n  const finalMeta = config.transformErrorMeta\n    ? config.transformErrorMeta({\n        baseMeta,\n        statusCode,\n        errorCode,\n        originalMetadata: metadata,\n      })\n    : baseMeta;\n\n  return {\n    status: 'error',\n    status_code: statusCode,\n    request_id:\n      requestID ||\n      (config.generateFallbackRequestID\n        ? config.generateFallbackRequestID('error')\n        : DEFAULT_FALLBACK_REQUEST_ID_GENERATOR('error')),\n    type: 'page',\n    data: null,\n    meta: finalMeta as BaseMeta,\n    error: {\n      code: errorCode,\n      message,\n      ...(errorDetails ? { details: errorDetails } : {}),\n    },\n  } as PageErrorResponse;\n}\n\n/**\n * Helper function to check for and execute custom status code handlers\n */\nexport function applyCustomHTTPStatusHandler(\n  statusCode: number,\n  responseData: unknown,\n  config: PageDataLoaderConfig,\n  ssrOnlyData: Record<string, unknown>,\n  isDevelopment: boolean,\n): PageResponseEnvelope | null {\n  // Check for specific status code handlers first (number or string)\n  const specificHandler =\n    config.statusCodeHandlers?.[statusCode] ||\n    config.statusCodeHandlers?.[statusCode.toString()];\n\n  // Check for wildcard handler as fallback\n  const wildcardHandler = config.statusCodeHandlers?.['*'];\n\n  const statusHandler = specificHandler || wildcardHandler;\n\n  if (!statusHandler) {\n    return null;\n  }\n\n  const customResult = statusHandler(\n    statusCode,\n    responseData,\n    config,\n    isDevelopment,\n  );\n\n  if (customResult === null || customResult === undefined) {\n    if (DEBUG_PAGE_LOADER) {\n      // eslint-disable-next-line no-console\n      console.log(\n        `Custom handler for status code ${statusCode} returned null/undefined, falling back to default handling`,\n      );\n    }\n\n    return null;\n  }\n\n  if (DEBUG_PAGE_LOADER) {\n    // eslint-disable-next-line no-console\n    console.log(`Using custom handler for status code ${statusCode}`);\n  }\n\n  // Automatically decorate PageResponseEnvelope with SSR-only data\n  return decorateWithSsrOnlyData(customResult, ssrOnlyData);\n}\n","import type { FastifyRequest, FastifyReply } from 'fastify';\nimport type { OutgoingHttpHeaders } from 'node:http';\nimport type {\n  APIErrorResponse,\n  BaseMeta,\n  PageErrorResponse,\n} from '../api-envelope/api-envelope-types';\n\n/**\n * Sends an error envelope immediately via the raw/hijacked response path.\n *\n * This is shared by controlled reply wrappers and the public helper fallback so\n * both paths apply the same CORS/header logic before writing the final JSON\n * body directly to the socket.\n */\nexport async function sendRawErrorEnvelopeResponse(\n  request: FastifyRequest,\n  reply: FastifyReply,\n  statusCode: number,\n  errorResponse: APIErrorResponse<BaseMeta> | PageErrorResponse<BaseMeta>,\n): Promise<void> {\n  const body = JSON.stringify(errorResponse);\n\n  // Raw/hijacked sends bypass Fastify's normal onSend pipeline, so any\n  // plugin-managed headers that still matter here must be applied explicitly\n  // before we snapshot reply.getHeaders() for writeHead(). Keep this ahead of\n  // reply.hijack() so header-application failures still propagate through\n  // Fastify's normal error handling instead of failing after raw ownership has\n  // already been taken.\n  await request.applyCORSHeaders?.(reply);\n\n  // Keep Fastify's reply state aligned with the status/content-type we are\n  // about to send even though the final body write happens on reply.raw.\n  reply.code(statusCode);\n  reply.type('application/json; charset=utf-8');\n  reply.header('Content-Length', String(Buffer.byteLength(body)));\n\n  // Hijack before writeHead() so Fastify does not attempt its own send path\n  // after this helper has already fully terminated the response.\n  reply.hijack();\n  reply.raw.writeHead(statusCode, reply.getHeaders() as OutgoingHttpHeaders);\n\n  // Error envelopes are always JSON here, so a single buffered end() keeps the\n  // transport simple and makes the termination point explicit.\n  reply.raw.end(request.method === 'HEAD' ? undefined : body);\n}\n","import type { FastifyRequest, FastifyReply } from 'fastify';\nimport type {\n  ErrorDetailsValue,\n  BaseMeta,\n  APIErrorResponse,\n  APISuccessResponse,\n  PageErrorResponse,\n  PageSuccessResponse,\n  PageRedirectResponse,\n  RedirectInfo,\n  PageMetadata,\n  APIResponseEnvelope,\n  PageResponseEnvelope,\n} from './api-envelope-types';\nimport type { ControlledReply } from '../types';\nimport { sendRawErrorEnvelopeResponse } from '../internal/error-envelope-send';\n\n/**\n * Helper utilities for constructing API/Page response envelopes.\n *\n * These are static so the class can be easily subclassed or the methods can be\n * re-exported. Users may extend this class to inject their own default meta or\n * wrap additional logic (e.g., account metadata, logging, etc.).\n */\nexport class APIResponseHelpers {\n  // API Response Helpers\n\n  /**\n   * Creates a standardized API success response envelope for API (AJAX/JSON) endpoints.\n   *\n   * @typeParam T - The type of the response data payload.\n   * @typeParam M - Meta type that extends BaseMeta.\n   *   Allows consumers to add application specific meta keys\n   *   (e.g. `account`, `pagination`, etc.).\n   * @param params - Object containing request, data, statusCode (default 200), and optional meta.\n   * @returns An APISuccessResponse envelope with merged meta and a request_id.\n   */\n\n  public static createAPISuccessResponse<\n    T,\n    M extends BaseMeta = BaseMeta,\n  >(params: {\n    request: FastifyRequest;\n    data: T;\n    statusCode?: number;\n    meta?: Partial<M>;\n  }): APISuccessResponse<T, M> {\n    const { request, data, statusCode = 200, meta } = params;\n\n    // API responses should not include page metadata by default\n    // Only include meta if explicitly provided\n    const defaultMeta = {} as M;\n\n    const receivedAt = (request as { receivedAt?: number }).receivedAt;\n\n    return {\n      status: 'success',\n      status_code: statusCode,\n      request_id: (request as { requestID?: string }).requestID ?? 'unknown',\n      ...(receivedAt !== undefined\n        ? { request_timestamp: new Date(receivedAt).toISOString() }\n        : {}),\n      type: 'api',\n      data,\n      meta: { ...defaultMeta, ...(meta as Partial<M>) } as M,\n    };\n  }\n\n  /**\n   * Creates a standardized API error response envelope for API (AJAX/JSON) endpoints.\n   *\n   * @typeParam M - Meta type that extends BaseMeta.\n   *   Allows consumers to add application specific meta keys\n   *   (e.g. `account`, `pagination`, etc.).\n   * @param params - Object containing request, statusCode, errorCode, errorMessage, optional errorDetails, and optional meta.\n   * @returns An APIErrorResponse envelope with merged meta and a request_id.\n   */\n  public static createAPIErrorResponse<M extends BaseMeta = BaseMeta>(params: {\n    request: FastifyRequest;\n    statusCode: number;\n    errorCode: string;\n    errorMessage: string;\n    errorDetails?: ErrorDetailsValue;\n    meta?: Partial<M>;\n  }): APIErrorResponse<M> {\n    const { request, statusCode, errorCode, errorMessage, errorDetails, meta } =\n      params;\n\n    // API responses should not include page metadata by default\n    // Only include meta if explicitly provided\n    const defaultMeta = {} as M;\n\n    const receivedAt = (request as { receivedAt?: number }).receivedAt;\n\n    return {\n      status: 'error',\n      status_code: statusCode,\n      request_id: (request as { requestID?: string }).requestID ?? 'unknown',\n      ...(receivedAt !== undefined\n        ? { request_timestamp: new Date(receivedAt).toISOString() }\n        : {}),\n      type: 'api',\n      data: null,\n      meta: { ...defaultMeta, ...(meta as Partial<M>) } as M,\n      error: {\n        code: errorCode,\n        message: errorMessage,\n        ...(errorDetails && { details: errorDetails }),\n      },\n    };\n  }\n\n  // Page Response Helpers\n\n  /**\n   * Creates a standardized Page success response envelope for SSR/data loaders.\n   *\n   * @typeParam T - The type of the response data payload.\n   * @typeParam M - Meta type that extends BaseMeta.\n   *   Allows consumers to add application specific meta keys\n   *   (e.g. `account`, `pagination`, etc.).\n   * @param params - Object containing request, data, pageMetadata, statusCode (default 200), and optional meta.\n   * @returns A PageSuccessResponse envelope with merged meta and a request_id.\n   */\n  public static createPageSuccessResponse<\n    T,\n    M extends BaseMeta = BaseMeta,\n  >(params: {\n    request: FastifyRequest;\n    data: T;\n    pageMetadata: PageMetadata;\n    statusCode?: number;\n    meta?: Partial<M>;\n  }): PageSuccessResponse<T, M> {\n    const { request, data, pageMetadata, statusCode = 200, meta } = params;\n\n    const baseMeta: BaseMeta = {\n      page: pageMetadata,\n    };\n\n    // Auto-populate ssr_request_context from request.requestContext if available and non-empty\n    const requestContext = (\n      request as { requestContext?: Record<string, unknown> }\n    ).requestContext;\n\n    const receivedAt = (request as { receivedAt?: number }).receivedAt;\n\n    return {\n      status: 'success',\n      status_code: statusCode,\n      request_id: (request as { requestID?: string }).requestID ?? 'unknown',\n      ...(receivedAt !== undefined\n        ? { request_timestamp: new Date(receivedAt).toISOString() }\n        : {}),\n      type: 'page',\n      data,\n      meta: { ...(baseMeta as M), ...(meta as Partial<M>) } as M,\n      ...(requestContext &&\n      typeof requestContext === 'object' &&\n      !Array.isArray(requestContext) &&\n      Object.keys(requestContext).length > 0\n        ? { ssr_request_context: requestContext }\n        : {}),\n    };\n  }\n\n  /**\n   * Creates a standardized Page redirect response envelope for SSR/data loaders.\n   * Always uses status code 200 to avoid confusion with HTTP redirects.\n   *\n   * @typeParam M - Meta type that extends BaseMeta.\n   *   Allows consumers to add application specific meta keys.\n   * @param params - Object containing request, redirectInfo, pageMetadata, and optional meta.\n   * @returns A PageRedirectResponse envelope with merged meta and a request_id.\n   */\n  public static createPageRedirectResponse<\n    M extends BaseMeta = BaseMeta,\n  >(params: {\n    request: FastifyRequest;\n    redirectInfo: RedirectInfo;\n    pageMetadata: PageMetadata;\n    meta?: Partial<M>;\n  }): PageRedirectResponse<M> {\n    const { request, redirectInfo, pageMetadata, meta } = params;\n\n    const baseMeta: BaseMeta = {\n      page: pageMetadata,\n    };\n\n    // Auto-populate ssr_request_context from request.requestContext if available and non-empty\n    const requestContext = (\n      request as { requestContext?: Record<string, unknown> }\n    ).requestContext;\n\n    const receivedAt = (request as { receivedAt?: number }).receivedAt;\n\n    return {\n      status: 'redirect',\n      status_code: 200,\n      request_id: (request as { requestID?: string }).requestID ?? 'unknown',\n      ...(receivedAt !== undefined\n        ? { request_timestamp: new Date(receivedAt).toISOString() }\n        : {}),\n      type: 'page',\n      data: null,\n      meta: { ...(baseMeta as M), ...(meta as Partial<M>) } as M,\n      redirect: redirectInfo,\n      ...(requestContext &&\n      typeof requestContext === 'object' &&\n      !Array.isArray(requestContext) &&\n      Object.keys(requestContext).length > 0\n        ? { ssr_request_context: requestContext }\n        : {}),\n    };\n  }\n\n  /**\n   * Creates a standardized Page error response envelope for SSR/data loaders.\n   *\n   * @typeParam M - Meta type that extends BaseMeta.\n   *   Allows consumers to add application specific meta keys\n   *   (e.g. `account`, `pagination`, etc.).\n   * @param params - Object containing request, statusCode, errorCode, errorMessage,\n   *   optional errorDetails, pageMetadata, and optional meta.\n   * @returns A PageErrorResponse envelope with merged meta and a request_id.\n   */\n\n  public static createPageErrorResponse<M extends BaseMeta = BaseMeta>(params: {\n    request: FastifyRequest;\n    statusCode: number;\n    errorCode: string;\n    errorMessage: string;\n    errorDetails?: ErrorDetailsValue;\n    pageMetadata: PageMetadata;\n    meta?: Partial<M>;\n  }): PageErrorResponse<M> {\n    const {\n      request,\n      statusCode,\n      errorCode,\n      errorMessage,\n      pageMetadata,\n      errorDetails,\n      meta,\n    } = params;\n\n    const baseMeta: BaseMeta = {\n      page: pageMetadata,\n    };\n\n    // Auto-populate ssr_request_context from request.requestContext if available and non-empty\n    const requestContext = (\n      request as { requestContext?: Record<string, unknown> }\n    ).requestContext;\n\n    const receivedAt = (request as { receivedAt?: number }).receivedAt;\n\n    return {\n      status: 'error',\n      status_code: statusCode,\n      request_id: (request as { requestID?: string }).requestID ?? 'unknown',\n      ...(receivedAt !== undefined\n        ? { request_timestamp: new Date(receivedAt).toISOString() }\n        : {}),\n      type: 'page',\n      data: null,\n      meta: { ...(baseMeta as M), ...(meta as Partial<M>) } as M,\n      error: {\n        code: errorCode,\n        message: errorMessage,\n        ...(errorDetails && { details: errorDetails }),\n      },\n      ...(requestContext &&\n      typeof requestContext === 'object' &&\n      !Array.isArray(requestContext) &&\n      Object.keys(requestContext).length > 0\n        ? { ssr_request_context: requestContext }\n        : {}),\n    };\n  }\n\n  // Validation Helpers\n\n  /**\n   * Send an error envelope response with the appropriate method\n   * Works with both FastifyReply and ControlledReply\n   *\n   * This is a public utility for sending error responses in a way that works\n   * with both standard Fastify handlers and controlled reply handlers.\n   *\n   * @param reply - Fastify reply object or ControlledReply\n   * @param statusCode - HTTP status code to send\n   * @param errorResponse - Error envelope to send\n   *\n   * @example\n   * ```typescript\n   * const errorResponse = APIResponseHelpers.createAPIErrorResponse({\n   *   request,\n   *   statusCode: 400,\n   *   errorCode: 'invalid_input',\n   *   errorMessage: 'Invalid input provided',\n   * });\n   *\n   * await APIResponseHelpers.sendErrorEnvelope(\n   *   request,\n   *   reply,\n   *   400,\n   *   errorResponse,\n   * );\n   * ```\n   *\n   * This helper is usable directly, but it is also part of the framework's\n   * controlled early-termination path. Unlike the envelope creation helpers,\n   * it has transport semantics (shared headers, hijack/raw write, immediate\n   * response finalization), so overriding it in a custom helpers subclass is\n   * discouraged unless you intend to preserve that contract.\n   */\n  public static async sendErrorEnvelope(\n    request: FastifyRequest,\n    reply: FastifyReply | ControlledReply,\n    statusCode: number,\n    errorResponse: APIErrorResponse<BaseMeta> | PageErrorResponse<BaseMeta>,\n  ): Promise<void> {\n    // Controlled handlers are intentionally not given general-purpose send\n    // methods. When the framework wrapped the reply, use its internal\n    // _sendErrorEnvelope hook; otherwise fall back to the shared raw-send path\n    // for direct FastifyReply usage (including tests and non-controlled routes).\n    if ('_sendErrorEnvelope' in reply) {\n      await reply._sendErrorEnvelope(statusCode, errorResponse);\n      return;\n    }\n\n    await sendRawErrorEnvelopeResponse(\n      request,\n      reply,\n      statusCode,\n      errorResponse,\n    );\n  }\n\n  /**\n   * Ensures an incoming Fastify request has a valid JSON body.\n   * If invalid, sends a standardized error response and returns false.\n   *\n   * Use this helper for POST, PUT, PATCH, and DELETE endpoints that expect JSON payloads.\n   * This is a pre-validation convenience before using schema validators like Zod.\n   *\n   * @param request - Fastify request object\n   * @param reply - Fastify reply object or ControlledReply\n   * @returns true if body is valid JSON, otherwise false (error envelope already sent)\n   *\n   * @example\n   * ```typescript\n   * server.api.post('users', async (request, reply) => {\n   *   if (!(await APIResponseHelpers.ensureJSONBody(request, reply))) {\n   *     return false; // Error envelope already sent\n   *   }\n   *\n   *   // Now safe to validate using a schema validator (e.g. Zod) or process the body\n   *   const validated = userSchema.parse(request.body);\n   *   // ...\n   * });\n   * ```\n   */\n  public static async ensureJSONBody(\n    request: FastifyRequest,\n    reply: FastifyReply | ControlledReply,\n  ): Promise<boolean> {\n    // Check Content-Type header first\n    const contentType = request.headers['content-type'];\n\n    if (!contentType || !contentType.includes('application/json')) {\n      const errorResponse = this.createAPIErrorResponse({\n        request,\n        statusCode: 415, // Unsupported Media Type\n        errorCode: 'invalid_content_type',\n        errorMessage: 'Content-Type must be application/json',\n        errorDetails: {\n          received_content_type: contentType || 'none',\n          expected_content_type: 'application/json',\n        },\n      });\n\n      // Send the standardized error envelope and terminate early.\n      await this.sendErrorEnvelope(request, reply, 415, errorResponse);\n      return false;\n    }\n\n    // Then validate the parsed body exists and is an object\n    if (!request.body || typeof request.body !== 'object') {\n      const errorResponse = this.createAPIErrorResponse({\n        request,\n        statusCode: 400,\n        errorCode: 'invalid_request_body_format',\n        errorMessage:\n          'Request body is required and must be a valid JSON object',\n        errorDetails: {\n          received_body_type: typeof request.body,\n        },\n      });\n\n      // Send the standardized error envelope and terminate early.\n      await this.sendErrorEnvelope(request, reply, 400, errorResponse);\n      return false;\n    }\n\n    return true;\n  }\n\n  /**\n   * Ensures an incoming Fastify request has a valid URL-encoded form body.\n   * If invalid, sends a standardized error response and returns false.\n   *\n   * Use this helper for POST, PUT, or PATCH endpoints that expect URL-encoded form data.\n   * This is a pre-validation convenience before processing form fields.\n   *\n   * Note: For file uploads with multipart/form-data, use ensureMultipartBody instead.\n   *\n   * @param request - Fastify request object\n   * @param reply - Fastify reply object or ControlledReply\n   * @returns true if form body is valid, otherwise false (error envelope already sent)\n   *\n   * @example\n   * ```typescript\n   * server.api.post('contact', async (request, reply) => {\n   *   if (!(await APIResponseHelpers.ensureURLEncodedBody(request, reply))) {\n   *     return false; // Error envelope already sent\n   *   }\n   *\n   *   // Now safe to process form fields\n   *   const formData = request.body as Record<string, unknown>;\n   *   // ...\n   * });\n   * ```\n   */\n  public static async ensureURLEncodedBody(\n    request: FastifyRequest,\n    reply: FastifyReply | ControlledReply,\n  ): Promise<boolean> {\n    // Check Content-Type header first\n    const contentType = request.headers['content-type'];\n\n    if (\n      !contentType ||\n      !contentType.includes('application/x-www-form-urlencoded')\n    ) {\n      const errorResponse = this.createAPIErrorResponse({\n        request,\n        statusCode: 415, // Unsupported Media Type\n        errorCode: 'invalid_content_type',\n        errorMessage: 'Content-Type must be application/x-www-form-urlencoded',\n        errorDetails: {\n          received_content_type: contentType || 'none',\n          expected_content_type: 'application/x-www-form-urlencoded',\n        },\n      });\n\n      // Send the standardized error envelope and terminate early.\n      await this.sendErrorEnvelope(request, reply, 415, errorResponse);\n      return false;\n    }\n\n    // Validate the parsed body exists and is an object\n    if (!request.body || typeof request.body !== 'object') {\n      const errorResponse = this.createAPIErrorResponse({\n        request,\n        statusCode: 400,\n        errorCode: 'invalid_request_body_format',\n        errorMessage:\n          'Request body is required and must be valid URL-encoded form data',\n        errorDetails: {\n          received_body_type: typeof request.body,\n        },\n      });\n\n      // Send the standardized error envelope and terminate early.\n      await this.sendErrorEnvelope(request, reply, 400, errorResponse);\n      return false;\n    }\n\n    return true;\n  }\n\n  /**\n   * Ensures an incoming Fastify request has multipart/form-data Content-Type.\n   * If invalid, sends a standardized error response and returns false.\n   *\n   * **Note:** `processFileUpload()` automatically validates Content-Type,\n   * so you typically don't need this helper when using `processFileUpload()`.\n   *\n   * **Advanced use case:** Use this for early validation in middleware (e.g., auth/rate-limiting)\n   * before multipart parsing begins:\n   *\n   * ```typescript\n   * // Block uploads for non-premium users before parsing\n   * pluginHost.addHook('preHandler', async (request, reply) => {\n   *   if (request.headers['content-type']?.includes('multipart/form-data')) {\n   *     if (!user.isPremium) {\n   *       return reply.code(403).send({ error: 'Premium feature' });\n   *     }\n   *   }\n   * });\n   * ```\n   *\n   * For standard file uploads, use `processFileUpload()` instead:\n   * ```typescript\n   * import { processFileUpload } from 'unirend/server';\n   *\n   * const results = await processFileUpload({\n   *   request,\n   *   reply,\n   *   maxSizePerFile: 5 * 1024 * 1024,\n   *   allowedMimeTypes: ['image/jpeg', 'image/png'],\n   *   processor: async (stream, metadata, context) => {\n   *     // ... handle upload\n   *   },\n   * });\n   * ```\n   *\n   * @param request - Fastify request object\n   * @param reply - Fastify reply object or ControlledReply\n   * @returns true if Content-Type is multipart/form-data, otherwise false (error envelope already sent)\n   *\n   */\n  public static async ensureMultipartBody(\n    request: FastifyRequest,\n    reply: FastifyReply | ControlledReply,\n  ): Promise<boolean> {\n    // Check Content-Type header\n    const contentType = request.headers['content-type'];\n\n    if (!contentType || !contentType.includes('multipart/form-data')) {\n      const errorResponse = this.createAPIErrorResponse({\n        request,\n        statusCode: 415, // Unsupported Media Type\n        errorCode: 'invalid_content_type',\n        errorMessage: 'Content-Type must be multipart/form-data',\n        errorDetails: {\n          received_content_type: contentType || 'none',\n          expected_content_type: 'multipart/form-data',\n        },\n      });\n\n      // Send the standardized error envelope and terminate early.\n      await this.sendErrorEnvelope(request, reply, 415, errorResponse);\n      return false;\n    }\n\n    // Note: This helper only validates the Content-Type header.\n    // In this codebase, multipart payloads are consumed later through the\n    // streaming request.file()/request.files() APIs, so we do not validate\n    // request.body here.\n    return true;\n  }\n\n  // ---------------------------------------------------------------------------\n  // Static Type-Guard Helpers\n  // ---------------------------------------------------------------------------\n\n  /** Determines if envelope is a success response */\n  public static isSuccessResponse<T, M extends BaseMeta = BaseMeta>(\n    response: APIResponseEnvelope<T, M> | PageResponseEnvelope<T, M>,\n  ): response is APISuccessResponse<T, M> | PageSuccessResponse<T, M> {\n    return response.status === 'success';\n  }\n\n  /** Determines if envelope is an error response */\n  public static isErrorResponse<M extends BaseMeta = BaseMeta>(\n    response:\n      | APIResponseEnvelope<unknown, M>\n      | PageResponseEnvelope<unknown, M>,\n  ): response is APIErrorResponse<M> | PageErrorResponse<M> {\n    return response.status === 'error';\n  }\n\n  /** Determines if envelope is a redirect response */\n  public static isRedirectResponse<M extends BaseMeta = BaseMeta>(\n    response:\n      | APIResponseEnvelope<unknown, M>\n      | PageResponseEnvelope<unknown, M>,\n  ): response is PageRedirectResponse<M> {\n    return response.status === 'redirect';\n  }\n\n  /** Determines if envelope is a page (SSR) response */\n  public static isPageResponse<T, M extends BaseMeta = BaseMeta>(\n    response: APIResponseEnvelope<T, M> | PageResponseEnvelope<T, M>,\n  ): response is PageResponseEnvelope<T, M> {\n    return response.type === 'page';\n  }\n\n  /**\n   * Validates that an unknown value is a proper envelope object\n   * This is a catch-all validation function that checks for proper envelope structure\n   * without requiring specific typing - useful for runtime validation of handler responses\n   */\n  public static isValidEnvelope(\n    result: unknown,\n  ): result is PageResponseEnvelope | APIResponseEnvelope {\n    if (!result || typeof result !== 'object') {\n      return false;\n    }\n\n    const envelope = result as Record<string, unknown>;\n\n    // Check required fields\n    const hasStatus =\n      typeof envelope.status === 'string' &&\n      ['success', 'error', 'redirect'].includes(envelope.status);\n\n    const hasStatusCode = typeof envelope.status_code === 'number';\n\n    const hasType =\n      typeof envelope.type === 'string' &&\n      ['api', 'page'].includes(envelope.type);\n\n    const hasRequestID = typeof envelope.request_id === 'string';\n    const hasMeta = envelope.meta && typeof envelope.meta === 'object';\n\n    // Basic structure validation\n    if (!hasStatus || !hasStatusCode || !hasType || !hasRequestID || !hasMeta) {\n      return false;\n    }\n\n    // Validate meta has required page field ONLY for page type envelopes\n    // API type envelopes do not require page metadata\n    if (envelope.type === 'page') {\n      const meta = envelope.meta as Record<string, unknown>;\n\n      if (!meta.page || typeof meta.page !== 'object') {\n        return false;\n      }\n\n      const page = meta.page as Record<string, unknown>;\n\n      if (\n        typeof page.title !== 'string' ||\n        typeof page.description !== 'string'\n      ) {\n        return false;\n      }\n    }\n\n    // Status-specific validation\n    if (envelope.status === 'success') {\n      return (\n        envelope.data !== undefined &&\n        (envelope.error === undefined || envelope.error === null)\n      );\n    } else if (envelope.status === 'error') {\n      return (\n        envelope.data === null &&\n        envelope.error !== null &&\n        typeof envelope.error === 'object'\n      );\n    } else if (envelope.status === 'redirect') {\n      return (\n        envelope.data === null &&\n        (envelope.error === undefined || envelope.error === null) &&\n        envelope.redirect !== null &&\n        typeof envelope.redirect === 'object'\n      );\n    }\n\n    return false;\n  }\n}\n","import type {\n  ErrorObject,\n  PageResponseEnvelope,\n  RedirectInfo,\n} from '../api-envelope/api-envelope-types';\nimport type {\n  LocalPageDataLoaderConfig,\n  PageDataLoaderConfig,\n} from './page-data-loader-types';\nimport {\n  applyCustomHTTPStatusHandler,\n  createErrorResponse,\n  decorateWithSsrOnlyData,\n  isSafeRedirect,\n} from './page-data-loader-utils';\nimport {\n  DEBUG_PAGE_LOADER,\n  DEFAULT_FALLBACK_REQUEST_ID_GENERATOR,\n  DEFAULT_RETURN_TO_PARAM,\n} from './page-data-loader-consts';\nimport { redirect } from 'react-router';\n\nexport function processRedirectResponse(\n  config: PageDataLoaderConfig | LocalPageDataLoaderConfig,\n  responseData: Record<string, unknown>,\n  ssrOnlyData: Record<string, unknown>,\n): PageResponseEnvelope {\n  const redirectInfo = responseData.redirect as RedirectInfo;\n  const target = redirectInfo.target;\n\n  if (!target) {\n    // If no target provided, return an error\n    return decorateWithSsrOnlyData(\n      createErrorResponse(\n        config,\n        400,\n        config.errorDefaults.invalidRedirect.code,\n        config.errorDefaults.invalidRedirect.message,\n        responseData?.request_id as string,\n        responseData?.meta as Record<string, unknown>,\n      ),\n      ssrOnlyData,\n    );\n  }\n\n  // Validate redirect safety if allowedRedirectOrigins is configured\n  if (!isSafeRedirect(target, config.allowedRedirectOrigins)) {\n    return decorateWithSsrOnlyData(\n      createErrorResponse(\n        config,\n        400,\n        config.errorDefaults.unsafeRedirect.code,\n        config.errorDefaults.unsafeRedirect.message,\n        responseData?.request_id as string,\n        responseData?.meta as Record<string, unknown>,\n      ),\n      ssrOnlyData,\n    );\n  }\n\n  // If preserve_query is true and we have a URL object, preserve query params\n  let redirectTarget = target;\n  const currentURL =\n    typeof window !== 'undefined' ? window.location.href : null;\n\n  if (redirectInfo.preserve_query && currentURL) {\n    try {\n      const url = new URL(currentURL);\n\n      // Only append query if the target doesn't already have query params\n      if (!target.includes('?') && url.search) {\n        redirectTarget = `${target}${url.search}`;\n      }\n    } catch (error) {\n      if (DEBUG_PAGE_LOADER) {\n        // eslint-disable-next-line no-console\n        console.warn('Failed to preserve query parameters in redirect', error);\n      }\n    }\n  }\n\n  if (DEBUG_PAGE_LOADER) {\n    // eslint-disable-next-line no-console\n    console.log(\n      `Application redirect to: ${redirectTarget} (${redirectInfo.permanent ? 'permanent' : 'temporary'})`,\n    );\n  }\n\n  return redirect(redirectTarget, {\n    // Use the appropriate React Router redirect status\n    status: redirectInfo.permanent ? 301 : 302,\n  }) as unknown as PageResponseEnvelope;\n}\n\nexport async function processAPIResponse(\n  response: Response,\n  config: PageDataLoaderConfig,\n  isDevelopment: boolean,\n): Promise<PageResponseEnvelope> {\n  const isServer = typeof window === 'undefined'; // detecting here again instead of passing to promote tree-shaking\n  const statusCode = response.status;\n\n  // Extract cookies from response when on server\n  const cookies = isServer ? response.headers.getSetCookie() : [];\n  const ssrOnlyData = {\n    ...(isServer ? { cookies } : {}),\n  };\n\n  // Handle HTTP redirects explicitly before attempting to parse JSON\n  if (\n    response.type === 'opaqueredirect' ||\n    [301, 302, 303, 307, 308].includes(statusCode)\n  ) {\n    if (DEBUG_PAGE_LOADER) {\n      // eslint-disable-next-line no-console\n      console.warn(\n        `API returned a HTTP redirect to: ${response.headers.get('Location')}`,\n      );\n    }\n\n    return decorateWithSsrOnlyData(\n      createErrorResponse(\n        config,\n        statusCode,\n        config.errorDefaults.redirectNotFollowed.code,\n        config.errorDefaults.redirectNotFollowed.message,\n        config.generateFallbackRequestID\n          ? config.generateFallbackRequestID('redirect')\n          : DEFAULT_FALLBACK_REQUEST_ID_GENERATOR('redirect'),\n        undefined,\n        {\n          originalStatus: statusCode,\n          location: response.headers.get('Location'),\n        },\n      ),\n      ssrOnlyData,\n    );\n  }\n\n  // extract the response data and check if it is valid json\n  let responseData: unknown;\n  let isValidJSON = false;\n\n  try {\n    responseData = (await response.json()) as unknown;\n    isValidJSON = true;\n  } catch {\n    responseData = null;\n  }\n\n  if (DEBUG_PAGE_LOADER) {\n    // eslint-disable-next-line no-console\n    console.log('response Info', {\n      isValidJSON,\n      statusCode,\n      responseData,\n    });\n  }\n\n  if (isValidJSON) {\n    // Check for custom status code handlers first\n    const customHandlerResult = applyCustomHTTPStatusHandler(\n      statusCode,\n      responseData,\n      config,\n      ssrOnlyData,\n      isDevelopment,\n    );\n\n    if (customHandlerResult) {\n      // If the custom handler returned a redirect, process it.\n      if (\n        customHandlerResult.status === 'redirect' &&\n        customHandlerResult.type === 'page' &&\n        customHandlerResult.redirect\n      ) {\n        return processRedirectResponse(\n          config,\n          customHandlerResult as unknown as Record<string, unknown>,\n          ssrOnlyData,\n        );\n      }\n\n      // Otherwise, the custom handler's response is final.\n      return customHandlerResult;\n    }\n\n    // Check for redirect status - only for page-type responses with status 200\n    // Our convention is that redirect responses always use status_code 200\n    if (\n      typeof responseData === 'object' &&\n      responseData !== null &&\n      'status' in responseData &&\n      responseData.status === 'redirect' &&\n      'type' in responseData &&\n      responseData.type === 'page' &&\n      'redirect' in responseData &&\n      responseData.redirect\n    ) {\n      return processRedirectResponse(\n        config,\n        responseData as Record<string, unknown>,\n        ssrOnlyData,\n      );\n    }\n\n    // Continue with existing checks for page responses and auth redirects\n    if (\n      statusCode === 200 &&\n      typeof responseData === 'object' &&\n      responseData !== null &&\n      'type' in responseData &&\n      responseData.type === 'page'\n    ) {\n      // successful page response as is\n      return decorateWithSsrOnlyData(\n        responseData as PageResponseEnvelope,\n        ssrOnlyData,\n      );\n    } else {\n      // if it already is a page / error response, return it as is\n      if (\n        typeof responseData === 'object' &&\n        responseData !== null &&\n        'type' in responseData &&\n        responseData.type === 'page'\n      ) {\n        return decorateWithSsrOnlyData(\n          responseData as PageResponseEnvelope,\n          ssrOnlyData,\n        );\n      } else if (\n        statusCode === 401 &&\n        typeof responseData === 'object' &&\n        responseData !== null &&\n        'status' in responseData &&\n        responseData.status === 'error' &&\n        'error' in responseData &&\n        typeof responseData.error === 'object' &&\n        responseData.error !== null &&\n        'code' in responseData.error &&\n        responseData.error.code === 'authentication_required'\n      ) {\n        // redirect to login - check for return_to in the error details\n        // Type guard already confirmed error exists and is an object with code property\n        const authResponse = responseData as {\n          request_id?: string;\n          meta?: Record<string, unknown>;\n          error: ErrorObject;\n        };\n\n        const errorObj = authResponse.error;\n        const requestID =\n          authResponse.request_id ||\n          (config.generateFallbackRequestID\n            ? config.generateFallbackRequestID('redirect')\n            : DEFAULT_FALLBACK_REQUEST_ID_GENERATOR('redirect'));\n\n        // Safely extract return_to from error details with proper type narrowing\n        let returnTo: string | undefined;\n        if (\n          errorObj.details &&\n          typeof errorObj.details === 'object' &&\n          !Array.isArray(errorObj.details) &&\n          'return_to' in errorObj.details &&\n          typeof errorObj.details.return_to === 'string'\n        ) {\n          returnTo = errorObj.details.return_to;\n        }\n\n        const returnToParam = config.returnToParam || DEFAULT_RETURN_TO_PARAM;\n\n        // Validate login redirect safety if allowedRedirectOrigins is configured.\n        // `return_to` remains application-owned data and is intentionally not validated here.\n        if (!isSafeRedirect(config.loginURL, config.allowedRedirectOrigins)) {\n          return decorateWithSsrOnlyData(\n            createErrorResponse(\n              config,\n              400,\n              config.errorDefaults.unsafeRedirect.code,\n              config.errorDefaults.unsafeRedirect.message,\n              requestID,\n              authResponse.meta,\n              {\n                loginURL: config.loginURL,\n              },\n            ),\n            ssrOnlyData,\n          );\n        }\n\n        // Only include return_to in the URL if it has a value, and ensure it's properly encoded\n        if (returnTo) {\n          const encodedReturnTo = encodeURIComponent(returnTo);\n          return redirect(\n            `${config.loginURL}?${returnToParam}=${encodedReturnTo}`,\n          ) as unknown as PageResponseEnvelope;\n        }\n\n        return redirect(config.loginURL) as unknown as PageResponseEnvelope;\n      } else {\n        // Convert API responses to page responses\n        // This happens when the API returns an \"api\" type response but we need a \"page\" type\n        // for React Router data loaders. We preserve metadata from the original API response.\n        if (\n          typeof responseData === 'object' &&\n          responseData !== null &&\n          'type' in responseData &&\n          responseData.type === 'api'\n        ) {\n          if ('status' in responseData && responseData.status === 'error') {\n            const apiResponse = responseData as {\n              request_id?: string;\n              error?: ErrorObject;\n              meta?: Record<string, unknown>;\n            };\n\n            const requestID =\n              apiResponse.request_id ||\n              (config.generateFallbackRequestID\n                ? config.generateFallbackRequestID('error')\n                : DEFAULT_FALLBACK_REQUEST_ID_GENERATOR('error'));\n\n            if (statusCode === 404) {\n              return decorateWithSsrOnlyData(\n                createErrorResponse(\n                  config,\n                  404,\n                  config.errorDefaults.notFound.code,\n                  apiResponse.error?.message ||\n                    config.errorDefaults.notFound.message,\n                  requestID,\n                  apiResponse.meta,\n                ),\n                ssrOnlyData,\n              );\n            } else if (statusCode === 500) {\n              return decorateWithSsrOnlyData(\n                createErrorResponse(\n                  config,\n                  500,\n                  config.errorDefaults.internalError.code,\n                  apiResponse.error?.message ||\n                    config.errorDefaults.internalError.message,\n                  requestID,\n                  apiResponse.meta,\n                  // If in development mode, include error details\n                  isDevelopment ? apiResponse.error?.details : undefined,\n                ),\n                ssrOnlyData,\n              );\n            } else if (statusCode === 403) {\n              // access denied is different from the auth required error, meaning logged out\n              return decorateWithSsrOnlyData(\n                createErrorResponse(\n                  config,\n                  403,\n                  config.errorDefaults.accessDenied.code,\n                  apiResponse.error?.message ||\n                    config.errorDefaults.accessDenied.message,\n                  requestID,\n                  apiResponse.meta,\n                  // If in development mode, include error details\n                  isDevelopment ? apiResponse.error?.details : undefined,\n                ),\n                ssrOnlyData,\n              );\n            } else {\n              // Generic error response\n              return decorateWithSsrOnlyData(\n                createErrorResponse(\n                  config,\n                  statusCode,\n                  apiResponse.error?.code ||\n                    config.errorDefaults.genericError.code,\n                  apiResponse.error?.message ||\n                    config.errorDefaults.genericError.message,\n                  requestID,\n                  apiResponse.meta,\n                  // If in development mode, include error details\n                  isDevelopment ? apiResponse.error?.details : undefined,\n                ),\n                ssrOnlyData,\n              );\n            }\n          } else {\n            // Success API response that should be a page response\n            const apiResponse = responseData as {\n              request_id?: string;\n              meta?: Record<string, unknown>;\n            };\n\n            return decorateWithSsrOnlyData(\n              createErrorResponse(\n                config,\n                500,\n                config.errorDefaults.invalidResponse.code,\n                config.errorDefaults.invalidResponse.message,\n                apiResponse.request_id,\n                apiResponse.meta,\n              ),\n              ssrOnlyData,\n            );\n          }\n        } else {\n          // Not an API response, create appropriate page error\n          if (statusCode === 404) {\n            return decorateWithSsrOnlyData(\n              createErrorResponse(\n                config,\n                404,\n                config.errorDefaults.notFound.code,\n                config.errorDefaults.notFound.message,\n              ),\n              ssrOnlyData,\n            );\n          } else if (statusCode === 500) {\n            return decorateWithSsrOnlyData(\n              createErrorResponse(\n                config,\n                500,\n                config.errorDefaults.internalError.code,\n                config.errorDefaults.internalError.message,\n              ),\n              ssrOnlyData,\n            );\n          } else {\n            // Generic error for any other status code\n            return decorateWithSsrOnlyData(\n              createErrorResponse(\n                config,\n                statusCode,\n                'http_error',\n                `HTTP Error: ${statusCode}`,\n              ),\n              ssrOnlyData,\n            );\n          }\n        }\n      }\n    }\n  } else {\n    // Check for custom status code handlers for non-JSON responses\n    const customHandlerResult = applyCustomHTTPStatusHandler(\n      statusCode,\n      null,\n      config,\n      ssrOnlyData,\n      isDevelopment,\n    );\n\n    if (customHandlerResult) {\n      // If the custom handler returned a redirect, process it.\n      if (\n        customHandlerResult.status === 'redirect' &&\n        customHandlerResult.type === 'page' &&\n        customHandlerResult.redirect\n      ) {\n        return processRedirectResponse(\n          config,\n          customHandlerResult as unknown as Record<string, unknown>,\n          ssrOnlyData,\n        );\n      }\n\n      // Otherwise, the custom handler's response is final.\n      return customHandlerResult;\n    }\n\n    // Not valid JSON response\n    return decorateWithSsrOnlyData(\n      createErrorResponse(\n        config,\n        statusCode || 500,\n        config.errorDefaults.invalidResponse.code,\n        config.errorDefaults.invalidResponse.message,\n      ),\n      ssrOnlyData,\n    );\n  }\n}\n"],"mappings":"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","names":["import_context","import_jsx_runtime","React","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_react_router","import_dev_mode","import_react_router","qs","result"]}