vinext 0.0.53 → 0.0.54
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build/inline-css.d.ts +7 -0
- package/dist/build/inline-css.js +50 -0
- package/dist/build/inline-css.js.map +1 -0
- package/dist/build/prerender.js +2 -1
- package/dist/build/prerender.js.map +1 -1
- package/dist/check.js +4 -0
- package/dist/check.js.map +1 -1
- package/dist/client/navigation-runtime.d.ts +2 -1
- package/dist/client/navigation-runtime.js.map +1 -1
- package/dist/client/window-next.d.ts +7 -0
- package/dist/client/window-next.js.map +1 -1
- package/dist/config/next-config.d.ts +83 -1
- package/dist/config/next-config.js +131 -2
- package/dist/config/next-config.js.map +1 -1
- package/dist/deploy.js +13 -0
- package/dist/deploy.js.map +1 -1
- package/dist/entries/app-browser-entry.d.ts +11 -1
- package/dist/entries/app-browser-entry.js +16 -6
- package/dist/entries/app-browser-entry.js.map +1 -1
- package/dist/entries/app-rsc-entry.d.ts +8 -1
- package/dist/entries/app-rsc-entry.js +18 -5
- package/dist/entries/app-rsc-entry.js.map +1 -1
- package/dist/entries/app-rsc-manifest.d.ts +21 -1
- package/dist/entries/app-rsc-manifest.js +6 -4
- package/dist/entries/app-rsc-manifest.js.map +1 -1
- package/dist/entries/pages-client-entry.d.ts +4 -1
- package/dist/entries/pages-client-entry.js +18 -2
- package/dist/entries/pages-client-entry.js.map +1 -1
- package/dist/entries/pages-server-entry.js +82 -4
- package/dist/entries/pages-server-entry.js.map +1 -1
- package/dist/entries/runtime-entry-module.d.ts +1 -10
- package/dist/entries/runtime-entry-module.js +2 -12
- package/dist/entries/runtime-entry-module.js.map +1 -1
- package/dist/index.js +63 -5
- package/dist/index.js.map +1 -1
- package/dist/plugins/remove-console.d.ts +16 -0
- package/dist/plugins/remove-console.js +176 -0
- package/dist/plugins/remove-console.js.map +1 -0
- package/dist/routing/app-route-graph.d.ts +24 -1
- package/dist/routing/app-route-graph.js +52 -4
- package/dist/routing/app-route-graph.js.map +1 -1
- package/dist/routing/app-router.d.ts +2 -2
- package/dist/routing/app-router.js +2 -2
- package/dist/routing/app-router.js.map +1 -1
- package/dist/routing/file-matcher.d.ts +21 -1
- package/dist/routing/file-matcher.js +39 -1
- package/dist/routing/file-matcher.js.map +1 -1
- package/dist/routing/pages-router.d.ts +1 -1
- package/dist/routing/pages-router.js +10 -3
- package/dist/routing/pages-router.js.map +1 -1
- package/dist/server/api-handler.js +1 -1
- package/dist/server/app-browser-entry.js +25 -16
- package/dist/server/app-browser-entry.js.map +1 -1
- package/dist/server/app-browser-navigation-controller.d.ts +2 -0
- package/dist/server/app-browser-navigation-controller.js +4 -0
- package/dist/server/app-browser-navigation-controller.js.map +1 -1
- package/dist/server/app-elements-wire.d.ts +13 -4
- package/dist/server/app-elements-wire.js +10 -1
- package/dist/server/app-elements-wire.js.map +1 -1
- package/dist/server/app-elements.d.ts +2 -2
- package/dist/server/app-elements.js +2 -2
- package/dist/server/app-elements.js.map +1 -1
- package/dist/server/app-fallback-renderer.d.ts +15 -5
- package/dist/server/app-fallback-renderer.js +10 -4
- package/dist/server/app-fallback-renderer.js.map +1 -1
- package/dist/server/app-inline-css-client.d.ts +7 -0
- package/dist/server/app-inline-css-client.js +37 -0
- package/dist/server/app-inline-css-client.js.map +1 -0
- package/dist/server/app-page-boundary.d.ts +21 -1
- package/dist/server/app-page-boundary.js +28 -3
- package/dist/server/app-page-boundary.js.map +1 -1
- package/dist/server/app-page-cache.d.ts +7 -3
- package/dist/server/app-page-cache.js +7 -7
- package/dist/server/app-page-cache.js.map +1 -1
- package/dist/server/app-page-dispatch.d.ts +10 -1
- package/dist/server/app-page-dispatch.js +126 -79
- package/dist/server/app-page-dispatch.js.map +1 -1
- package/dist/server/app-page-element-builder.js +12 -28
- package/dist/server/app-page-element-builder.js.map +1 -1
- package/dist/server/app-page-render-identity.d.ts +22 -0
- package/dist/server/app-page-render-identity.js +42 -0
- package/dist/server/app-page-render-identity.js.map +1 -0
- package/dist/server/app-page-render.d.ts +8 -1
- package/dist/server/app-page-render.js +4 -1
- package/dist/server/app-page-render.js.map +1 -1
- package/dist/server/app-page-request.d.ts +6 -3
- package/dist/server/app-page-request.js +5 -2
- package/dist/server/app-page-request.js.map +1 -1
- package/dist/server/app-page-response.js +2 -2
- package/dist/server/app-page-response.js.map +1 -1
- package/dist/server/app-page-route-wiring.d.ts +15 -0
- package/dist/server/app-page-route-wiring.js +7 -5
- package/dist/server/app-page-route-wiring.js.map +1 -1
- package/dist/server/app-page-stream.d.ts +11 -0
- package/dist/server/app-page-stream.js +1 -0
- package/dist/server/app-page-stream.js.map +1 -1
- package/dist/server/app-route-handler-response.js +37 -5
- package/dist/server/app-route-handler-response.js.map +1 -1
- package/dist/server/app-rsc-handler.d.ts +14 -3
- package/dist/server/app-rsc-handler.js +45 -5
- package/dist/server/app-rsc-handler.js.map +1 -1
- package/dist/server/app-rsc-request-normalization.d.ts +2 -1
- package/dist/server/app-rsc-request-normalization.js +3 -2
- package/dist/server/app-rsc-request-normalization.js.map +1 -1
- package/dist/server/app-server-action-execution.d.ts +21 -3
- package/dist/server/app-server-action-execution.js +42 -7
- package/dist/server/app-server-action-execution.js.map +1 -1
- package/dist/server/app-ssr-entry.d.ts +6 -0
- package/dist/server/app-ssr-entry.js +22 -7
- package/dist/server/app-ssr-entry.js.map +1 -1
- package/dist/server/app-ssr-error-meta.js +3 -3
- package/dist/server/app-ssr-error-meta.js.map +1 -1
- package/dist/server/app-ssr-stream.d.ts +2 -1
- package/dist/server/app-ssr-stream.js +176 -31
- package/dist/server/app-ssr-stream.js.map +1 -1
- package/dist/server/client-trace-metadata.d.ts +31 -0
- package/dist/server/client-trace-metadata.js +83 -0
- package/dist/server/client-trace-metadata.js.map +1 -0
- package/dist/server/cookie-utils.d.ts +13 -0
- package/dist/server/cookie-utils.js +20 -0
- package/dist/server/cookie-utils.js.map +1 -0
- package/dist/server/dev-server.d.ts +8 -1
- package/dist/server/dev-server.js +34 -5
- package/dist/server/dev-server.js.map +1 -1
- package/dist/server/html.d.ts +2 -1
- package/dist/server/html.js +6 -1
- package/dist/server/html.js.map +1 -1
- package/dist/server/isr-cache.d.ts +7 -5
- package/dist/server/isr-cache.js +17 -6
- package/dist/server/isr-cache.js.map +1 -1
- package/dist/server/middleware-runtime.js +1 -2
- package/dist/server/middleware-runtime.js.map +1 -1
- package/dist/server/pages-document-initial-props.d.ts +7 -0
- package/dist/server/pages-document-initial-props.js +14 -0
- package/dist/server/pages-document-initial-props.js.map +1 -0
- package/dist/server/pages-page-data.js +3 -0
- package/dist/server/pages-page-data.js.map +1 -1
- package/dist/server/pages-page-method.d.ts +48 -0
- package/dist/server/pages-page-method.js +19 -0
- package/dist/server/pages-page-method.js.map +1 -0
- package/dist/server/pages-page-response.d.ts +6 -0
- package/dist/server/pages-page-response.js +10 -3
- package/dist/server/pages-page-response.js.map +1 -1
- package/dist/server/pages-serializable-props.d.ts +25 -0
- package/dist/server/pages-serializable-props.js +69 -0
- package/dist/server/pages-serializable-props.js.map +1 -0
- package/dist/server/prod-server.js +3 -0
- package/dist/server/prod-server.js.map +1 -1
- package/dist/server/server-action-not-found.js +3 -2
- package/dist/server/server-action-not-found.js.map +1 -1
- package/dist/server/static-file-cache.js +2 -1
- package/dist/server/static-file-cache.js.map +1 -1
- package/dist/shims/app-router-scroll-state.d.ts +4 -2
- package/dist/shims/app-router-scroll-state.js +16 -3
- package/dist/shims/app-router-scroll-state.js.map +1 -1
- package/dist/shims/app-router-scroll.d.ts +16 -2
- package/dist/shims/app-router-scroll.js +18 -3
- package/dist/shims/app-router-scroll.js.map +1 -1
- package/dist/shims/cache.d.ts +6 -0
- package/dist/shims/cache.js +7 -0
- package/dist/shims/cache.js.map +1 -1
- package/dist/shims/error.js +3 -0
- package/dist/shims/error.js.map +1 -1
- package/dist/shims/headers.d.ts +7 -0
- package/dist/shims/headers.js +9 -1
- package/dist/shims/headers.js.map +1 -1
- package/dist/shims/internal/app-route-detection.d.ts +37 -0
- package/dist/shims/internal/app-route-detection.js +69 -0
- package/dist/shims/internal/app-route-detection.js.map +1 -0
- package/dist/shims/link.d.ts +18 -2
- package/dist/shims/link.js +70 -6
- package/dist/shims/link.js.map +1 -1
- package/dist/shims/metadata.d.ts +7 -6
- package/dist/shims/metadata.js +9 -5
- package/dist/shims/metadata.js.map +1 -1
- package/dist/shims/navigation.d.ts +1 -2
- package/dist/shims/navigation.js +63 -12
- package/dist/shims/navigation.js.map +1 -1
- package/dist/shims/router.d.ts +5 -0
- package/dist/shims/router.js +14 -4
- package/dist/shims/router.js.map +1 -1
- package/dist/shims/script.d.ts +11 -1
- package/dist/shims/script.js +75 -6
- package/dist/shims/script.js.map +1 -1
- package/dist/utils/path.d.ts +13 -0
- package/dist/utils/path.js +16 -0
- package/dist/utils/path.js.map +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"headers.js","names":[],"sources":["../../src/shims/headers.ts"],"sourcesContent":["/**\n * next/headers shim\n *\n * Provides cookies() and headers() functions for App Router Server Components.\n * These read from a request context set by the RSC handler before rendering.\n *\n * In Next.js 15+, cookies() and headers() return Promises (async).\n * We support both the sync (legacy) and async patterns.\n */\n\nimport { MIDDLEWARE_SET_COOKIE_HEADER } from \"../server/headers.js\";\nimport { buildRequestHeadersFromMiddlewareResponse } from \"../server/middleware-request-headers.js\";\nimport { getOrCreateAls } from \"./internal/als-registry.js\";\nimport {\n serializeSetCookie,\n validateCookieAttributeValue,\n validateCookieName,\n} from \"./internal/cookie-serialize.js\";\nimport { parseCookieHeader } from \"./internal/parse-cookie-header.js\";\nimport {\n isInsideUnifiedScope,\n getRequestContext,\n runWithUnifiedStateMutation,\n} from \"./unified-request-context.js\";\nimport type { RenderRequestApiKind } from \"../server/cache-proof.js\";\n\n// ---------------------------------------------------------------------------\n// Request context\n// ---------------------------------------------------------------------------\n\nexport type HeadersContext = {\n headers: Headers;\n cookies: Map<string, string>;\n accessError?: Error;\n forceStatic?: boolean;\n mutableCookies?: RequestCookies;\n readonlyCookies?: RequestCookies;\n readonlyHeaders?: Headers;\n draftModeSecret?: string;\n};\n\ntype HeadersContextFromRequestOptions = {\n draftModeSecret?: string;\n};\n\nexport type HeadersAccessPhase = \"render\" | \"action\" | \"route-handler\";\n\nexport type VinextHeadersShimState = {\n headersContext: HeadersContext | null;\n dynamicUsageDetected: boolean;\n renderRequestApiUsage: Set<RenderRequestApiKind>;\n /** Error recorded by throwIfInsideCacheScope for dev diagnostics, persists even if caught by user code. */\n invalidDynamicUsageError: unknown;\n pendingSetCookies: string[];\n draftModeCookieHeader: string | null;\n phase: HeadersAccessPhase;\n};\n\n// NOTE:\n// - This shim can be loaded under multiple module specifiers in Vite's\n// multi-environment setup (RSC/SSR). Store the AsyncLocalStorage on\n// globalThis so `connection()` (next/server) and `consumeDynamicUsage()`\n// (next/headers) always share it.\n// - We use AsyncLocalStorage so concurrent requests don't stomp each other's\n// headers/cookies/dynamic-usage state.\nconst _FALLBACK_KEY = Symbol.for(\"vinext.nextHeadersShim.fallback\");\nconst _g = globalThis as unknown as Record<PropertyKey, unknown>;\nconst _als = getOrCreateAls<VinextHeadersShimState>(\"vinext.nextHeadersShim.als\");\n\nconst _fallbackState = (_g[_FALLBACK_KEY] ??= {\n headersContext: null,\n dynamicUsageDetected: false,\n renderRequestApiUsage: new Set<RenderRequestApiKind>(),\n invalidDynamicUsageError: null,\n pendingSetCookies: [],\n draftModeCookieHeader: null,\n phase: \"render\",\n} satisfies VinextHeadersShimState) as VinextHeadersShimState;\nconst EXPIRED_COOKIE_DATE = new Date(0).toUTCString();\n\nfunction splitMiddlewareSetCookieHeader(value: string): string[] {\n const cookies: string[] = [];\n let start = 0;\n let inExpires = false;\n let expiresCommaSeen = false;\n\n for (let i = 0; i < value.length; i++) {\n if (value.slice(i, i + 8).toLowerCase() === \"expires=\") {\n inExpires = true;\n expiresCommaSeen = false;\n i += 7;\n continue;\n }\n\n const ch = value[i];\n if (inExpires && ch === \";\") {\n inExpires = false;\n expiresCommaSeen = false;\n continue;\n }\n\n if (ch !== \",\") continue;\n if (inExpires && !expiresCommaSeen) {\n expiresCommaSeen = true;\n continue;\n }\n\n const cookie = value.slice(start, i).trim();\n if (cookie) cookies.push(cookie);\n start = i + 1;\n inExpires = false;\n expiresCommaSeen = false;\n }\n\n const cookie = value.slice(start).trim();\n if (cookie) cookies.push(cookie);\n return cookies;\n}\n\nfunction setCookieNameValue(setCookie: string): { name: string; value: string } | null {\n const equalsIndex = setCookie.indexOf(\"=\");\n if (equalsIndex <= 0) return null;\n\n const name = setCookie.slice(0, equalsIndex).trim();\n const valueEnd = setCookie.indexOf(\";\", equalsIndex + 1);\n const encodedValue = setCookie.slice(equalsIndex + 1, valueEnd === -1 ? undefined : valueEnd);\n let value: string;\n try {\n value = decodeURIComponent(encodedValue);\n } catch {\n value = encodedValue;\n }\n\n return { name, value };\n}\n\nfunction rebuildCookiesFromHeader(ctx: HeadersContext, cookieHeader: string | null): void {\n ctx.cookies.clear();\n if (cookieHeader === null) return;\n\n const nextCookies = parseCookieHeader(cookieHeader);\n for (const [name, value] of nextCookies) {\n ctx.cookies.set(name, value);\n }\n}\n\nfunction mergeMiddlewareSetCookies(ctx: HeadersContext, rawHeader: string | null): boolean {\n if (rawHeader === null) return false;\n\n let merged = false;\n for (const setCookie of splitMiddlewareSetCookieHeader(rawHeader)) {\n const entry = setCookieNameValue(setCookie);\n if (!entry) continue;\n ctx.cookies.set(entry.name, entry.value);\n merged = true;\n }\n\n return merged;\n}\n\nfunction _getState(): VinextHeadersShimState {\n if (isInsideUnifiedScope()) {\n return getRequestContext();\n }\n return _als.getStore() ?? _fallbackState;\n}\n\n/**\n * Dynamic usage flag — set when a component calls connection(), cookies(),\n * headers(), or noStore() during rendering. When true, ISR caching is\n * bypassed and the response gets Cache-Control: no-store.\n */\n// (stored on _state)\n\n/**\n * Mark the current render as requiring dynamic (uncached) rendering.\n * Called by connection(), cookies(), headers(), and noStore().\n */\nexport function markDynamicUsage(): void {\n const state = _getState();\n if (state.headersContext?.forceStatic) {\n return;\n }\n state.dynamicUsageDetected = true;\n}\n\nexport function markRenderRequestApiUsage(kind: RenderRequestApiKind): void {\n _getState().renderRequestApiUsage.add(kind);\n}\n\nexport function peekRenderRequestApiUsage(): RenderRequestApiKind[] {\n return [..._getState().renderRequestApiUsage].sort();\n}\n\nexport function consumeRenderRequestApiUsage(): RenderRequestApiKind[] {\n const state = _getState();\n const observed = [...state.renderRequestApiUsage].sort();\n state.renderRequestApiUsage = new Set<RenderRequestApiKind>();\n return observed;\n}\n\n// ---------------------------------------------------------------------------\n// Cache scope detection — checks whether we're inside \"use cache\" or\n// unstable_cache() by reading ALS instances stored on globalThis via Symbols.\n// This avoids circular imports between headers.ts, cache.ts, and cache-runtime.ts.\n// The ALS instances are registered by cache-runtime.ts and cache.ts respectively.\n// ---------------------------------------------------------------------------\n\n/** Symbol used by cache-runtime.ts to store the \"use cache\" ALS on globalThis */\nconst _USE_CACHE_ALS_KEY = Symbol.for(\"vinext.cacheRuntime.contextAls\");\n/** Symbol used by cache.ts to store the unstable_cache ALS on globalThis */\nconst _UNSTABLE_CACHE_ALS_KEY = Symbol.for(\"vinext.unstableCache.als\");\n\ntype UseCacheGuardContext = {\n variant?: unknown;\n};\n\ntype CacheScopeStorage = {\n getStore: () => unknown;\n};\n\nfunction _getGlobalCacheScopeStorage(key: symbol): CacheScopeStorage | null {\n const value = Reflect.get(globalThis, key);\n if (!value || typeof value !== \"object\") return null;\n\n const getStore = Reflect.get(value, \"getStore\");\n if (typeof getStore !== \"function\") return null;\n\n return {\n getStore: () => getStore.call(value),\n };\n}\n\nfunction _getUseCacheGuardContext(): UseCacheGuardContext | null {\n const store = _getGlobalCacheScopeStorage(_USE_CACHE_ALS_KEY)?.getStore();\n if (!store || typeof store !== \"object\") return null;\n return store;\n}\n\nfunction _isInsidePublicUseCache(): boolean {\n const ctx = _getUseCacheGuardContext();\n // Next.js models \"use cache: private\" as a private-cache work unit that\n // carries request headers and cookies. Only public \"use cache\" scopes freeze\n // request APIs into persisted cache entries and must reject these reads.\n // https://github.com/vercel/next.js/blob/canary/packages/next/src/server/app-render/work-unit-async-storage.external.ts\n return ctx !== null && ctx.variant !== \"private\";\n}\n\nfunction _isInsideUnstableCache(): boolean {\n return _getGlobalCacheScopeStorage(_UNSTABLE_CACHE_ALS_KEY)?.getStore() === true;\n}\n\n/**\n * Throw if the current execution is inside a \"use cache\" or unstable_cache()\n * scope. Called by dynamic request APIs (headers, cookies, connection) to\n * prevent request-specific data from being frozen into cached results.\n *\n * @param apiName - The name of the API being called (e.g. \"connection()\")\n */\nexport function throwIfInsideCacheScope(apiName: string): void {\n if (_isInsidePublicUseCache()) {\n const error = new Error(\n `\\`${apiName}\\` cannot be called inside \"use cache\". ` +\n `If you need this data inside a cached function, call \\`${apiName}\\` ` +\n \"outside and pass the required data as an argument.\",\n );\n // Record the error on the request context so it survives user try/catch\n // and can be forwarded to the dev overlay on client-side navigations.\n // Ported from Next.js: workStore.invalidDynamicUsageError assignment in\n // packages/next/src/server/app-render/app-render.tsx\n // https://github.com/vercel/next.js/commit/f5e54c06726b571a042fce67417e40a29f6b8689\n try {\n const ctx = getRequestContext();\n if (ctx) ctx.invalidDynamicUsageError = error;\n } catch {\n // Ignore — best-effort recording for dev diagnostics\n }\n throw error;\n }\n if (_isInsideUnstableCache()) {\n const error = new Error(\n `\\`${apiName}\\` cannot be called inside a function cached with \\`unstable_cache()\\`. ` +\n `If you need this data inside a cached function, call \\`${apiName}\\` ` +\n \"outside and pass the required data as an argument.\",\n );\n try {\n const ctx = getRequestContext();\n if (ctx) ctx.invalidDynamicUsageError = error;\n } catch {\n // Ignore\n }\n throw error;\n }\n}\n\n/**\n * Check, consume, and return any invalid dynamic usage error recorded during\n * the render (e.g. cookies() called inside \"use cache\"). This error persists\n * even if the throw was caught by user-code try/catch, so it can surface on\n * client-side navigations where the static shell validation is skipped.\n * Ported from Next.js: workStore.invalidDynamicUsageError in\n * packages/next/src/server/app-render/app-render.tsx\n * https://github.com/vercel/next.js/commit/f5e54c06726b571a042fce67417e40a29f6b8689\n */\nexport function consumeInvalidDynamicUsageError(): unknown {\n const state = _getState();\n const err = state.invalidDynamicUsageError;\n state.invalidDynamicUsageError = null;\n return err;\n}\n\n/**\n * Check and reset the dynamic usage flag.\n * Called by the server after rendering to decide on caching.\n */\nexport function consumeDynamicUsage(): boolean {\n const state = _getState();\n const used = state.dynamicUsageDetected;\n state.dynamicUsageDetected = false;\n return used;\n}\n\nfunction _setStatePhase(\n state: VinextHeadersShimState,\n phase: HeadersAccessPhase,\n): HeadersAccessPhase {\n const previous = state.phase;\n state.phase = phase;\n return previous;\n}\n\nfunction _areCookiesMutableInCurrentPhase(): boolean {\n const phase = _getState().phase;\n return phase === \"action\" || phase === \"route-handler\";\n}\n\nexport function setHeadersAccessPhase(phase: HeadersAccessPhase): HeadersAccessPhase {\n return _setStatePhase(_getState(), phase);\n}\n\nexport function getHeadersAccessPhase(): HeadersAccessPhase {\n return _getState().phase;\n}\n\n/**\n * Set the headers/cookies context for the current RSC render.\n * Called by the framework's RSC entry before rendering each request.\n *\n * @deprecated Prefer runWithHeadersContext() which uses als.run() for\n * proper per-request isolation. This function mutates the ALS store\n * in-place and is only safe for cleanup (ctx=null) within an existing\n * als.run() scope.\n */\n/**\n * Returns the current live HeadersContext from ALS (or the fallback).\n * Used after applyMiddlewareRequestHeaders() to build a post-middleware\n * request context for afterFiles/fallback rewrite has/missing evaluation.\n */\nexport function getHeadersContext(): HeadersContext | null {\n return _getState().headersContext;\n}\n\nexport function setHeadersContext(ctx: HeadersContext | null): void {\n const state = _getState();\n if (ctx !== null) {\n state.headersContext = ctx;\n state.dynamicUsageDetected = false;\n state.renderRequestApiUsage = new Set();\n state.pendingSetCookies = [];\n state.draftModeCookieHeader = null;\n state.phase = \"render\";\n } else {\n state.headersContext = null;\n state.phase = \"render\";\n }\n}\n\n/**\n * Run a function with headers context, ensuring the context propagates\n * through all async operations (including RSC streaming).\n *\n * Uses AsyncLocalStorage.run() to guarantee per-request isolation.\n * The ALS store propagates through all async continuations including\n * ReadableStream consumption, setTimeout callbacks, and Promise chains,\n * so RSC streaming works correctly — components that render when the\n * stream is consumed still see the correct request's context.\n */\nexport function runWithHeadersContext<T>(ctx: HeadersContext, fn: () => Promise<T>): Promise<T>;\nexport function runWithHeadersContext<T>(\n ctx: HeadersContext,\n fn: () => T | Promise<T>,\n): T | Promise<T>;\nexport function runWithHeadersContext<T>(\n ctx: HeadersContext,\n fn: () => T | Promise<T>,\n): T | Promise<T> {\n if (isInsideUnifiedScope()) {\n return runWithUnifiedStateMutation((uCtx) => {\n uCtx.headersContext = ctx;\n uCtx.dynamicUsageDetected = false;\n uCtx.renderRequestApiUsage = new Set();\n uCtx.pendingSetCookies = [];\n uCtx.draftModeCookieHeader = null;\n uCtx.phase = \"render\";\n }, fn);\n }\n\n const state: VinextHeadersShimState = {\n headersContext: ctx,\n dynamicUsageDetected: false,\n renderRequestApiUsage: new Set(),\n invalidDynamicUsageError: null,\n pendingSetCookies: [],\n draftModeCookieHeader: null,\n phase: \"render\",\n };\n\n return _als.run(state, fn);\n}\n\n/**\n * Apply middleware-forwarded request headers to the current headers context.\n *\n * When Next.js middleware calls `NextResponse.next()` or `NextResponse.rewrite()`\n * with `{ request: { headers } }`, the modified headers are encoded on the\n * middleware response. This function decodes that protocol and applies the\n * resulting request header set to the live `HeadersContext`. When an override\n * list is present, omitted headers are deleted as part of the rebuild.\n *\n * Cached `readonlyHeaders` and `readonlyCookies` snapshots on the\n * HeadersContext must be invalidated whenever this function rebuilds the\n * underlying `headers`/`cookies`. Otherwise a middleware that reads\n * `headers()` (or `cookies()`) before returning a request-header override —\n * for example `@clerk/nextjs`, whose `clerkClient()` reads `headers()` via\n * `buildRequestLike()` during middleware execution — primes a sealed snapshot\n * built from the *pre*-override request, and any subsequent `headers()` call\n * from a Server Component would return that stale snapshot instead of the\n * middleware-modified view.\n */\nexport function applyMiddlewareRequestHeaders(middlewareResponseHeaders: Headers): void {\n const state = _getState();\n if (!state.headersContext) return;\n\n const ctx = state.headersContext;\n const previousCookieHeader = ctx.headers.get(\"cookie\");\n const middlewareSetCookieHeader = middlewareResponseHeaders.get(MIDDLEWARE_SET_COOKIE_HEADER);\n const nextHeaders = buildRequestHeadersFromMiddlewareResponse(\n ctx.headers,\n middlewareResponseHeaders,\n );\n\n if (!nextHeaders && middlewareSetCookieHeader === null) return;\n\n if (nextHeaders) {\n ctx.headers = nextHeaders;\n // Invalidate any sealed snapshot of the pre-override headers. A middleware\n // that read `headers()` before returning the override (e.g. clerkMiddleware)\n // would otherwise leak the pre-override view into the Server Component.\n ctx.readonlyHeaders = undefined;\n const nextCookieHeader = nextHeaders.get(\"cookie\");\n if (previousCookieHeader !== nextCookieHeader) {\n rebuildCookiesFromHeader(ctx, nextCookieHeader);\n ctx.readonlyCookies = undefined;\n ctx.mutableCookies = undefined;\n }\n }\n\n if (mergeMiddlewareSetCookies(ctx, middlewareSetCookieHeader)) {\n ctx.readonlyCookies = undefined;\n ctx.mutableCookies = undefined;\n }\n}\n\n/** Methods on `Headers` that mutate state. Hoisted to module scope — static. */\nconst _HEADERS_MUTATING_METHODS = new Set([\"set\", \"delete\", \"append\"]);\n\nclass ReadonlyHeadersError extends Error {\n constructor() {\n super(\n \"Headers cannot be modified. Read more: https://nextjs.org/docs/app/api-reference/functions/headers\",\n );\n }\n\n static callable(): never {\n throw new ReadonlyHeadersError();\n }\n}\n\n// Keep this error message in sync with server.ts. The two RequestCookies\n// adapters are separate until the next/headers and NextRequest cookie paths\n// share one implementation.\nclass ReadonlyRequestCookiesError extends Error {\n constructor() {\n super(\n \"Cookies can only be modified in a Server Action or Route Handler. Read more: https://nextjs.org/docs/app/api-reference/functions/cookies#options\",\n );\n }\n\n static callable(): never {\n throw new ReadonlyRequestCookiesError();\n }\n}\n\nfunction _decorateRequestApiPromise<T extends object>(\n promise: Promise<T>,\n target: T,\n): Promise<T> & T {\n return new Proxy(promise as Promise<T> & T, {\n get(promiseTarget, prop) {\n if (prop in promiseTarget) {\n const value = Reflect.get(promiseTarget, prop, promiseTarget);\n return typeof value === \"function\" ? value.bind(promiseTarget) : value;\n }\n\n const value = Reflect.get(target, prop, target);\n return typeof value === \"function\" ? value.bind(target) : value;\n },\n has(promiseTarget, prop) {\n return prop in promiseTarget || prop in target;\n },\n ownKeys(promiseTarget) {\n return Array.from(new Set([...Reflect.ownKeys(promiseTarget), ...Reflect.ownKeys(target)]));\n },\n getOwnPropertyDescriptor(promiseTarget, prop) {\n return (\n Reflect.getOwnPropertyDescriptor(promiseTarget, prop) ??\n Reflect.getOwnPropertyDescriptor(target, prop)\n );\n },\n });\n}\n\n// React.use() tracks thenables by identity, so request APIs must reuse the\n// same decorated promise for the same underlying request view.\nconst _decoratedHeadersPromises = new WeakMap<Headers, Promise<Headers> & Headers>();\nconst _decoratedCookiesPromises = new WeakMap<\n RequestCookies,\n Promise<RequestCookies> & RequestCookies\n>();\n\nfunction _getOrCreateDecoratedRequestApiPromise<T extends object>(\n cache: WeakMap<T, Promise<T> & T>,\n target: T,\n): Promise<T> & T {\n const cached = cache.get(target);\n if (cached) return cached;\n\n const promise = _decorateRequestApiPromise(Promise.resolve(target), target);\n cache.set(target, promise);\n return promise;\n}\n\nfunction _decorateRejectedRequestApiPromise<T extends object>(error: unknown): Promise<T> & T {\n const normalizedError = error instanceof Error ? error : new Error(String(error));\n const promise = Promise.reject(normalizedError) as Promise<T>;\n // Mark the rejection as handled so legacy sync access does not trigger\n // spurious unhandled rejection noise before callers await/catch it.\n promise.catch(() => {});\n\n const throwingTarget = new Proxy({} as T, {\n get(_target, prop) {\n if (prop === \"then\" || prop === \"catch\" || prop === \"finally\") {\n return undefined;\n }\n throw normalizedError;\n },\n });\n\n return _decorateRequestApiPromise(promise, throwingTarget);\n}\n\nfunction _sealHeaders(headers: Headers): Headers {\n return new Proxy(headers, {\n get(target, prop) {\n if (typeof prop === \"string\" && _HEADERS_MUTATING_METHODS.has(prop)) {\n throw new ReadonlyHeadersError();\n }\n\n const value = Reflect.get(target, prop, target);\n return typeof value === \"function\" ? value.bind(target) : value;\n },\n }) as Headers;\n}\n\nfunction _wrapMutableCookies(cookies: RequestCookies): RequestCookies {\n return new Proxy(cookies, {\n get(target, prop) {\n if (prop === \"set\" || prop === \"delete\") {\n return (...args: unknown[]) => {\n if (!_areCookiesMutableInCurrentPhase()) {\n throw new ReadonlyRequestCookiesError();\n }\n\n return (Reflect.get(target, prop, target) as (...callArgs: unknown[]) => unknown).apply(\n target,\n args,\n );\n };\n }\n\n const value = Reflect.get(target, prop, target);\n return typeof value === \"function\" ? value.bind(target) : value;\n },\n }) as RequestCookies;\n}\n\nfunction _sealCookies(cookies: RequestCookies): RequestCookies {\n return new Proxy(cookies, {\n get(target, prop) {\n if (prop === \"set\" || prop === \"delete\") {\n throw new ReadonlyRequestCookiesError();\n }\n\n const value = Reflect.get(target, prop, target);\n return typeof value === \"function\" ? value.bind(target) : value;\n },\n }) as RequestCookies;\n}\n\nfunction _getMutableCookies(ctx: HeadersContext): RequestCookies {\n if (!ctx.mutableCookies) {\n ctx.mutableCookies = _wrapMutableCookies(new RequestCookies(ctx.cookies));\n }\n\n return ctx.mutableCookies;\n}\n\nfunction _getReadonlyCookies(ctx: HeadersContext): RequestCookies {\n if (!ctx.readonlyCookies) {\n // Keep a separate readonly wrapper so render-path reads avoid the\n // mutable phase-checking proxy while still reflecting the shared cookie map.\n ctx.readonlyCookies = _sealCookies(new RequestCookies(ctx.cookies));\n }\n\n return ctx.readonlyCookies;\n}\n\nfunction _getReadonlyHeaders(ctx: HeadersContext): Headers {\n if (!ctx.readonlyHeaders) {\n ctx.readonlyHeaders = _sealHeaders(ctx.headers);\n }\n\n return ctx.readonlyHeaders;\n}\n\n/**\n * Create a HeadersContext from a standard Request object.\n *\n * Performance note: In Workerd (Cloudflare Workers), `new Headers(request.headers)`\n * copies the entire header map across the V8/C++ boundary, which shows up as\n * ~815 ms self-time in production profiles when requests carry many headers.\n * We defer this copy with a lazy proxy:\n *\n * - Reads (`get`, `has`, `entries`, …) are forwarded directly to the original\n * immutable `request.headers` — zero copy cost on the hot path.\n * - The first mutating call (`set`, `delete`, `append`) materialises\n * `new Headers(request.headers)` once, then applies the mutation to the copy.\n * All subsequent operations go to the copy.\n *\n * This means the ~815 ms copy only occurs when middleware actually rewrites\n * request headers via `NextResponse.next({ request: { headers } })`, which is\n * uncommon. Pure read requests (the vast majority) pay zero copy cost.\n *\n * Cookie parsing is also deferred: the `cookie` header string is not split\n * until the first call to `cookies()` or `draftMode()`.\n */\nexport function headersContextFromRequest(\n request: Request,\n options?: HeadersContextFromRequestOptions,\n): HeadersContext {\n // ---------------------------------------------------------------------------\n // Lazy mutable Headers proxy\n // ---------------------------------------------------------------------------\n // `_mutable` holds the materialised copy once a write is needed.\n let _mutable: Headers | null = null;\n\n const headersProxy = new Proxy(request.headers, {\n get(target, prop: string | symbol) {\n // Route to the materialised copy if it exists.\n const src = _mutable ?? target;\n\n // Intercept mutating methods: materialise on first write.\n if (typeof prop === \"string\" && _HEADERS_MUTATING_METHODS.has(prop)) {\n return (...args: unknown[]) => {\n if (!_mutable) {\n _mutable = new Headers(target);\n }\n return (_mutable[prop as \"set\" | \"delete\" | \"append\"] as (...a: unknown[]) => unknown)(\n ...args,\n );\n };\n }\n\n // Non-mutating method or property: bind to current source.\n const value = Reflect.get(src, prop, src);\n return typeof value === \"function\" ? value.bind(src) : value;\n },\n }) as Headers;\n\n // ---------------------------------------------------------------------------\n // Lazy cookie map\n // ---------------------------------------------------------------------------\n // Parsing cookies requires splitting on `;` and `=`, which is cheap but\n // still unnecessary overhead if `cookies()` is never called for this request.\n let _cookies: Map<string, string> | null = null;\n\n function getCookies(): Map<string, string> {\n if (_cookies) return _cookies;\n // Read from the proxy so middleware-modified cookie headers are respected.\n const cookieHeader = headersProxy.get(\"cookie\") || \"\";\n _cookies = parseCookieHeader(cookieHeader);\n return _cookies;\n }\n\n // Expose cookies as a lazy getter that memoises on first access.\n const ctx = {\n headers: headersProxy,\n get cookies(): Map<string, string> {\n return getCookies();\n },\n draftModeSecret: options?.draftModeSecret,\n } satisfies HeadersContext;\n\n return ctx;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Read-only Headers instance from the incoming request.\n * Returns a Promise in Next.js 15+ style (but resolves synchronously since\n * the context is already available).\n */\nexport function headers(): Promise<Headers> & Headers {\n markRenderRequestApiUsage(\"headers\");\n try {\n throwIfInsideCacheScope(\"headers()\");\n } catch (error) {\n return _decorateRejectedRequestApiPromise<Headers>(error);\n }\n\n const state = _getState();\n if (!state.headersContext) {\n return _decorateRejectedRequestApiPromise<Headers>(\n new Error(\n \"headers() can only be called from a Server Component, Route Handler, \" +\n \"or Server Action. Make sure you're not calling it from a Client Component.\",\n ),\n );\n }\n\n if (state.headersContext.accessError) {\n return _decorateRejectedRequestApiPromise<Headers>(state.headersContext.accessError);\n }\n\n markDynamicUsage();\n const readonlyHeaders = _getReadonlyHeaders(state.headersContext);\n return _getOrCreateDecoratedRequestApiPromise(_decoratedHeadersPromises, readonlyHeaders);\n}\n\n/**\n * Cookie jar from the incoming request.\n * Returns a ReadonlyRequestCookies-like object.\n */\nexport function cookies(): Promise<RequestCookies> & RequestCookies {\n markRenderRequestApiUsage(\"cookies\");\n try {\n throwIfInsideCacheScope(\"cookies()\");\n } catch (error) {\n return _decorateRejectedRequestApiPromise<RequestCookies>(error);\n }\n\n const state = _getState();\n if (!state.headersContext) {\n return _decorateRejectedRequestApiPromise<RequestCookies>(\n new Error(\n \"cookies() can only be called from a Server Component, Route Handler, or Server Action.\",\n ),\n );\n }\n\n if (state.headersContext.accessError) {\n return _decorateRejectedRequestApiPromise<RequestCookies>(state.headersContext.accessError);\n }\n\n markDynamicUsage();\n const cookieStore = _areCookiesMutableInCurrentPhase()\n ? _getMutableCookies(state.headersContext)\n : _getReadonlyCookies(state.headersContext);\n\n return _getOrCreateDecoratedRequestApiPromise(_decoratedCookiesPromises, cookieStore);\n}\n\n// ---------------------------------------------------------------------------\n// Writable cookie accumulator for Route Handlers / Server Actions\n// ---------------------------------------------------------------------------\n\n/** Accumulated Set-Cookie headers from cookies().set() / .delete() calls */\n// (stored on _state)\n\n/**\n * Get and clear all pending Set-Cookie headers generated by cookies().set()/delete().\n * Called by the framework after rendering to attach headers to the response.\n */\nexport function getAndClearPendingCookies(): string[] {\n const state = _getState();\n const cookies = state.pendingSetCookies;\n state.pendingSetCookies = [];\n return cookies;\n}\n\n// Draft mode cookie name (matches Next.js convention)\nconst DRAFT_MODE_COOKIE = \"__prerender_bypass\";\nconst DRAFT_MODE_EXPIRED_DATE = new Date(0).toUTCString();\n\n// Store for Set-Cookie headers generated by draftMode().enable()/disable()\n// (stored on _state)\n\n/**\n * Get any Set-Cookie header generated by draftMode().enable()/disable().\n * Called by the framework after rendering to attach the header to the response.\n */\nexport function getDraftModeCookieHeader(): string | null {\n const state = _getState();\n const header = state.draftModeCookieHeader;\n state.draftModeCookieHeader = null;\n return header;\n}\n\nfunction validateDraftModeSecret(secret: string): string {\n if (secret.length === 0) {\n throw new Error(\"[vinext] draft mode secret must be a non-empty string.\");\n }\n return secret;\n}\n\nfunction createDraftModeSecret(): string {\n const crypto = globalThis.crypto;\n if (crypto && typeof crypto.randomUUID === \"function\") {\n return crypto.randomUUID();\n }\n\n throw new Error(\n \"[vinext] draft mode secret is not initialized. \" +\n \"This should be initialized by the server entry before handling requests.\",\n );\n}\n\nfunction ensureContextDraftModeSecret(ctx: HeadersContext): string {\n if (ctx.draftModeSecret !== undefined) {\n return validateDraftModeSecret(ctx.draftModeSecret);\n }\n\n const secret = createDraftModeSecret();\n ctx.draftModeSecret = secret;\n return secret;\n}\n\nexport function isDraftModeRequest(request: Request, draftModeSecret: string): boolean {\n const cookieHeader = request.headers.get(\"cookie\");\n if (!cookieHeader) return false;\n return (\n parseCookieHeader(cookieHeader).get(DRAFT_MODE_COOKIE) ===\n validateDraftModeSecret(draftModeSecret)\n );\n}\n\ntype DraftModeResult = {\n readonly isEnabled: boolean;\n enable(): void;\n disable(): void;\n};\n\nfunction draftModeCookieAttributes(): string {\n if (typeof process !== \"undefined\" && process.env?.NODE_ENV === \"development\") {\n return \"Path=/; HttpOnly; SameSite=Lax\";\n }\n return \"Path=/; HttpOnly; SameSite=None; Secure\";\n}\n\nfunction createDraftModeScopeError(expression: string): Error {\n return new Error(\n `${expression} can only be called from a Server Component, Route Handler, or Server Action.`,\n );\n}\n\nfunction requireActiveDraftModeContext(\n state: VinextHeadersShimState,\n expectedContext: HeadersContext,\n expression: string,\n): HeadersContext {\n const currentContext = state.headersContext;\n if (currentContext !== expectedContext) {\n throw createDraftModeScopeError(expression);\n }\n if (currentContext.accessError) {\n throw currentContext.accessError;\n }\n return currentContext;\n}\n\n/**\n * Draft mode — check/toggle via a `__prerender_bypass` cookie.\n *\n * - `isEnabled`: true if the bypass cookie is present in the request\n * - `enable()`: sets the bypass cookie (for Route Handlers)\n * - `disable()`: clears the bypass cookie\n */\nexport async function draftMode(): Promise<DraftModeResult> {\n markRenderRequestApiUsage(\"draftMode\");\n throwIfInsideCacheScope(\"draftMode()\");\n\n const state = _getState();\n const context = state.headersContext;\n if (!context) {\n throw createDraftModeScopeError(\"draftMode()\");\n }\n if (context.accessError) {\n throw context.accessError;\n }\n // Reading `draftMode()` itself is not dynamic — `isEnabled` is a plain\n // getter and merely calling `draftMode()` does not require bailing out\n // of static prerendering. Only `enable()`/`disable()` mutate state and\n // must be tracked as dynamic, mirroring Next.js's `trackDynamicDraftMode`\n // (see .nextjs-ref/packages/next/src/server/request/draft-mode.ts:152-165).\n const secret = ensureContextDraftModeSecret(context);\n\n return {\n get isEnabled(): boolean {\n return context.cookies.get(DRAFT_MODE_COOKIE) === secret;\n },\n enable(): void {\n const activeContext = requireActiveDraftModeContext(state, context, \"draftMode().enable()\");\n markDynamicUsage();\n activeContext.cookies.set(DRAFT_MODE_COOKIE, secret);\n state.draftModeCookieHeader = `${DRAFT_MODE_COOKIE}=${secret}; ${draftModeCookieAttributes()}`;\n },\n disable(): void {\n const activeContext = requireActiveDraftModeContext(state, context, \"draftMode().disable()\");\n markDynamicUsage();\n activeContext.cookies.delete(DRAFT_MODE_COOKIE);\n state.draftModeCookieHeader = `${DRAFT_MODE_COOKIE}=; ${draftModeCookieAttributes()}; Expires=${DRAFT_MODE_EXPIRED_DATE}`;\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// RequestCookies implementation\n// ---------------------------------------------------------------------------\n\nclass RequestCookies {\n private _cookies: Map<string, string>;\n\n constructor(cookies: Map<string, string>) {\n this._cookies = cookies;\n }\n\n get(name: string): { name: string; value: string } | undefined {\n const value = this._cookies.get(name);\n if (value === undefined) return undefined;\n return { name, value };\n }\n\n getAll(nameOrOptions?: string | { name: string }): Array<{ name: string; value: string }> {\n const name = typeof nameOrOptions === \"string\" ? nameOrOptions : nameOrOptions?.name;\n const result: Array<{ name: string; value: string }> = [];\n for (const [cookieName, value] of this._cookies) {\n if (name === undefined || cookieName === name) {\n result.push({ name: cookieName, value });\n }\n }\n return result;\n }\n\n has(name: string): boolean {\n return this._cookies.has(name);\n }\n\n /**\n * Set a cookie. In Route Handlers and Server Actions, this produces\n * a Set-Cookie header on the response.\n */\n set(\n nameOrOptions:\n | string\n | {\n name: string;\n value: string;\n path?: string;\n domain?: string;\n maxAge?: number;\n expires?: Date;\n httpOnly?: boolean;\n secure?: boolean;\n sameSite?: \"Strict\" | \"Lax\" | \"None\";\n },\n value?: string,\n options?: {\n path?: string;\n domain?: string;\n maxAge?: number;\n expires?: Date;\n httpOnly?: boolean;\n secure?: boolean;\n sameSite?: \"Strict\" | \"Lax\" | \"None\";\n },\n ): this {\n let cookieName: string;\n let cookieValue: string;\n let opts: typeof options;\n\n if (typeof nameOrOptions === \"string\") {\n cookieName = nameOrOptions;\n cookieValue = value ?? \"\";\n opts = options;\n } else {\n cookieName = nameOrOptions.name;\n cookieValue = nameOrOptions.value;\n opts = nameOrOptions;\n }\n\n validateCookieName(cookieName);\n\n // Update the local cookie map\n this._cookies.set(cookieName, cookieValue);\n\n _getState().pendingSetCookies.push(serializeSetCookie(cookieName, cookieValue, opts));\n return this;\n }\n\n /**\n * Delete a cookie by emitting an expired Set-Cookie header.\n */\n delete(nameOrOptions: string | { name: string; path?: string; domain?: string }): this {\n const name = typeof nameOrOptions === \"string\" ? nameOrOptions : nameOrOptions.name;\n const path = typeof nameOrOptions === \"string\" ? \"/\" : (nameOrOptions.path ?? \"/\");\n const domain = typeof nameOrOptions === \"string\" ? undefined : nameOrOptions.domain;\n\n validateCookieName(name);\n validateCookieAttributeValue(path, \"Path\");\n if (domain) {\n validateCookieAttributeValue(domain, \"Domain\");\n }\n\n this._cookies.delete(name);\n const parts = [`${name}=`, `Path=${path}`];\n if (domain) parts.push(`Domain=${domain}`);\n parts.push(`Expires=${EXPIRED_COOKIE_DATE}`);\n _getState().pendingSetCookies.push(parts.join(\"; \"));\n return this;\n }\n\n get size(): number {\n return this._cookies.size;\n }\n\n [Symbol.iterator](): IterableIterator<[string, { name: string; value: string }]> {\n const entries = this._cookies.entries();\n const iter: IterableIterator<[string, { name: string; value: string }]> = {\n [Symbol.iterator]() {\n return iter;\n },\n next() {\n const { value, done } = entries.next();\n if (done) return { value: undefined, done: true };\n const [name, val] = value;\n return { value: [name, { name, value: val }], done: false };\n },\n };\n return iter;\n }\n\n toString(): string {\n const parts: string[] = [];\n for (const [name, value] of this._cookies) {\n parts.push(`${name}=${value}`);\n }\n return parts.join(\"; \");\n }\n}\n\n// Re-export types\nexport type { RequestCookies };\n"],"mappings":";;;;;;;;;;;;;;;;AAiEA,MAAM,gBAAgB,OAAO,IAAI,kCAAkC;AACnE,MAAM,KAAK;AACX,MAAM,OAAO,eAAuC,6BAA6B;AAEjF,MAAM,iBAAkB,GAAG,mBAAmB;CAC5C,gBAAgB;CAChB,sBAAsB;CACtB,uCAAuB,IAAI,KAA2B;CACtD,0BAA0B;CAC1B,mBAAmB,EAAE;CACrB,uBAAuB;CACvB,OAAO;CACR;AACD,MAAM,uCAAsB,IAAI,KAAK,EAAE,EAAC,aAAa;AAErD,SAAS,+BAA+B,OAAyB;CAC/D,MAAM,UAAoB,EAAE;CAC5B,IAAI,QAAQ;CACZ,IAAI,YAAY;CAChB,IAAI,mBAAmB;CAEvB,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;EACrC,IAAI,MAAM,MAAM,GAAG,IAAI,EAAE,CAAC,aAAa,KAAK,YAAY;GACtD,YAAY;GACZ,mBAAmB;GACnB,KAAK;GACL;;EAGF,MAAM,KAAK,MAAM;EACjB,IAAI,aAAa,OAAO,KAAK;GAC3B,YAAY;GACZ,mBAAmB;GACnB;;EAGF,IAAI,OAAO,KAAK;EAChB,IAAI,aAAa,CAAC,kBAAkB;GAClC,mBAAmB;GACnB;;EAGF,MAAM,SAAS,MAAM,MAAM,OAAO,EAAE,CAAC,MAAM;EAC3C,IAAI,QAAQ,QAAQ,KAAK,OAAO;EAChC,QAAQ,IAAI;EACZ,YAAY;EACZ,mBAAmB;;CAGrB,MAAM,SAAS,MAAM,MAAM,MAAM,CAAC,MAAM;CACxC,IAAI,QAAQ,QAAQ,KAAK,OAAO;CAChC,OAAO;;AAGT,SAAS,mBAAmB,WAA2D;CACrF,MAAM,cAAc,UAAU,QAAQ,IAAI;CAC1C,IAAI,eAAe,GAAG,OAAO;CAE7B,MAAM,OAAO,UAAU,MAAM,GAAG,YAAY,CAAC,MAAM;CACnD,MAAM,WAAW,UAAU,QAAQ,KAAK,cAAc,EAAE;CACxD,MAAM,eAAe,UAAU,MAAM,cAAc,GAAG,aAAa,KAAK,KAAA,IAAY,SAAS;CAC7F,IAAI;CACJ,IAAI;EACF,QAAQ,mBAAmB,aAAa;SAClC;EACN,QAAQ;;CAGV,OAAO;EAAE;EAAM;EAAO;;AAGxB,SAAS,yBAAyB,KAAqB,cAAmC;CACxF,IAAI,QAAQ,OAAO;CACnB,IAAI,iBAAiB,MAAM;CAE3B,MAAM,cAAc,kBAAkB,aAAa;CACnD,KAAK,MAAM,CAAC,MAAM,UAAU,aAC1B,IAAI,QAAQ,IAAI,MAAM,MAAM;;AAIhC,SAAS,0BAA0B,KAAqB,WAAmC;CACzF,IAAI,cAAc,MAAM,OAAO;CAE/B,IAAI,SAAS;CACb,KAAK,MAAM,aAAa,+BAA+B,UAAU,EAAE;EACjE,MAAM,QAAQ,mBAAmB,UAAU;EAC3C,IAAI,CAAC,OAAO;EACZ,IAAI,QAAQ,IAAI,MAAM,MAAM,MAAM,MAAM;EACxC,SAAS;;CAGX,OAAO;;AAGT,SAAS,YAAoC;CAC3C,IAAI,sBAAsB,EACxB,OAAO,mBAAmB;CAE5B,OAAO,KAAK,UAAU,IAAI;;;;;;;;;;;AAc5B,SAAgB,mBAAyB;CACvC,MAAM,QAAQ,WAAW;CACzB,IAAI,MAAM,gBAAgB,aACxB;CAEF,MAAM,uBAAuB;;AAG/B,SAAgB,0BAA0B,MAAkC;CAC1E,WAAW,CAAC,sBAAsB,IAAI,KAAK;;AAG7C,SAAgB,4BAAoD;CAClE,OAAO,CAAC,GAAG,WAAW,CAAC,sBAAsB,CAAC,MAAM;;AAGtD,SAAgB,+BAAuD;CACrE,MAAM,QAAQ,WAAW;CACzB,MAAM,WAAW,CAAC,GAAG,MAAM,sBAAsB,CAAC,MAAM;CACxD,MAAM,wCAAwB,IAAI,KAA2B;CAC7D,OAAO;;;AAWT,MAAM,qBAAqB,OAAO,IAAI,iCAAiC;;AAEvE,MAAM,0BAA0B,OAAO,IAAI,2BAA2B;AAUtE,SAAS,4BAA4B,KAAuC;CAC1E,MAAM,QAAQ,QAAQ,IAAI,YAAY,IAAI;CAC1C,IAAI,CAAC,SAAS,OAAO,UAAU,UAAU,OAAO;CAEhD,MAAM,WAAW,QAAQ,IAAI,OAAO,WAAW;CAC/C,IAAI,OAAO,aAAa,YAAY,OAAO;CAE3C,OAAO,EACL,gBAAgB,SAAS,KAAK,MAAM,EACrC;;AAGH,SAAS,2BAAwD;CAC/D,MAAM,QAAQ,4BAA4B,mBAAmB,EAAE,UAAU;CACzE,IAAI,CAAC,SAAS,OAAO,UAAU,UAAU,OAAO;CAChD,OAAO;;AAGT,SAAS,0BAAmC;CAC1C,MAAM,MAAM,0BAA0B;CAKtC,OAAO,QAAQ,QAAQ,IAAI,YAAY;;AAGzC,SAAS,yBAAkC;CACzC,OAAO,4BAA4B,wBAAwB,EAAE,UAAU,KAAK;;;;;;;;;AAU9E,SAAgB,wBAAwB,SAAuB;CAC7D,IAAI,yBAAyB,EAAE;EAC7B,MAAM,wBAAQ,IAAI,MAChB,KAAK,QAAQ,iGAC+C,QAAQ,uDAErE;EAMD,IAAI;GACF,MAAM,MAAM,mBAAmB;GAC/B,IAAI,KAAK,IAAI,2BAA2B;UAClC;EAGR,MAAM;;CAER,IAAI,wBAAwB,EAAE;EAC5B,MAAM,wBAAQ,IAAI,MAChB,KAAK,QAAQ,iIAC+C,QAAQ,uDAErE;EACD,IAAI;GACF,MAAM,MAAM,mBAAmB;GAC/B,IAAI,KAAK,IAAI,2BAA2B;UAClC;EAGR,MAAM;;;;;;;;;;;;AAaV,SAAgB,kCAA2C;CACzD,MAAM,QAAQ,WAAW;CACzB,MAAM,MAAM,MAAM;CAClB,MAAM,2BAA2B;CACjC,OAAO;;;;;;AAOT,SAAgB,sBAA+B;CAC7C,MAAM,QAAQ,WAAW;CACzB,MAAM,OAAO,MAAM;CACnB,MAAM,uBAAuB;CAC7B,OAAO;;AAGT,SAAS,eACP,OACA,OACoB;CACpB,MAAM,WAAW,MAAM;CACvB,MAAM,QAAQ;CACd,OAAO;;AAGT,SAAS,mCAA4C;CACnD,MAAM,QAAQ,WAAW,CAAC;CAC1B,OAAO,UAAU,YAAY,UAAU;;AAGzC,SAAgB,sBAAsB,OAA+C;CACnF,OAAO,eAAe,WAAW,EAAE,MAAM;;AAG3C,SAAgB,wBAA4C;CAC1D,OAAO,WAAW,CAAC;;;;;;;;;;;;;;;;AAiBrB,SAAgB,oBAA2C;CACzD,OAAO,WAAW,CAAC;;AAGrB,SAAgB,kBAAkB,KAAkC;CAClE,MAAM,QAAQ,WAAW;CACzB,IAAI,QAAQ,MAAM;EAChB,MAAM,iBAAiB;EACvB,MAAM,uBAAuB;EAC7B,MAAM,wCAAwB,IAAI,KAAK;EACvC,MAAM,oBAAoB,EAAE;EAC5B,MAAM,wBAAwB;EAC9B,MAAM,QAAQ;QACT;EACL,MAAM,iBAAiB;EACvB,MAAM,QAAQ;;;AAmBlB,SAAgB,sBACd,KACA,IACgB;CAChB,IAAI,sBAAsB,EACxB,OAAO,6BAA6B,SAAS;EAC3C,KAAK,iBAAiB;EACtB,KAAK,uBAAuB;EAC5B,KAAK,wCAAwB,IAAI,KAAK;EACtC,KAAK,oBAAoB,EAAE;EAC3B,KAAK,wBAAwB;EAC7B,KAAK,QAAQ;IACZ,GAAG;CAGR,MAAM,QAAgC;EACpC,gBAAgB;EAChB,sBAAsB;EACtB,uCAAuB,IAAI,KAAK;EAChC,0BAA0B;EAC1B,mBAAmB,EAAE;EACrB,uBAAuB;EACvB,OAAO;EACR;CAED,OAAO,KAAK,IAAI,OAAO,GAAG;;;;;;;;;;;;;;;;;;;;;AAsB5B,SAAgB,8BAA8B,2BAA0C;CACtF,MAAM,QAAQ,WAAW;CACzB,IAAI,CAAC,MAAM,gBAAgB;CAE3B,MAAM,MAAM,MAAM;CAClB,MAAM,uBAAuB,IAAI,QAAQ,IAAI,SAAS;CACtD,MAAM,4BAA4B,0BAA0B,IAAI,6BAA6B;CAC7F,MAAM,cAAc,0CAClB,IAAI,SACJ,0BACD;CAED,IAAI,CAAC,eAAe,8BAA8B,MAAM;CAExD,IAAI,aAAa;EACf,IAAI,UAAU;EAId,IAAI,kBAAkB,KAAA;EACtB,MAAM,mBAAmB,YAAY,IAAI,SAAS;EAClD,IAAI,yBAAyB,kBAAkB;GAC7C,yBAAyB,KAAK,iBAAiB;GAC/C,IAAI,kBAAkB,KAAA;GACtB,IAAI,iBAAiB,KAAA;;;CAIzB,IAAI,0BAA0B,KAAK,0BAA0B,EAAE;EAC7D,IAAI,kBAAkB,KAAA;EACtB,IAAI,iBAAiB,KAAA;;;;AAKzB,MAAM,4BAA4B,IAAI,IAAI;CAAC;CAAO;CAAU;CAAS,CAAC;AAEtE,IAAM,uBAAN,MAAM,6BAA6B,MAAM;CACvC,cAAc;EACZ,MACE,qGACD;;CAGH,OAAO,WAAkB;EACvB,MAAM,IAAI,sBAAsB;;;AAOpC,IAAM,8BAAN,MAAM,oCAAoC,MAAM;CAC9C,cAAc;EACZ,MACE,mJACD;;CAGH,OAAO,WAAkB;EACvB,MAAM,IAAI,6BAA6B;;;AAI3C,SAAS,2BACP,SACA,QACgB;CAChB,OAAO,IAAI,MAAM,SAA2B;EAC1C,IAAI,eAAe,MAAM;GACvB,IAAI,QAAQ,eAAe;IACzB,MAAM,QAAQ,QAAQ,IAAI,eAAe,MAAM,cAAc;IAC7D,OAAO,OAAO,UAAU,aAAa,MAAM,KAAK,cAAc,GAAG;;GAGnE,MAAM,QAAQ,QAAQ,IAAI,QAAQ,MAAM,OAAO;GAC/C,OAAO,OAAO,UAAU,aAAa,MAAM,KAAK,OAAO,GAAG;;EAE5D,IAAI,eAAe,MAAM;GACvB,OAAO,QAAQ,iBAAiB,QAAQ;;EAE1C,QAAQ,eAAe;GACrB,OAAO,MAAM,KAAK,IAAI,IAAI,CAAC,GAAG,QAAQ,QAAQ,cAAc,EAAE,GAAG,QAAQ,QAAQ,OAAO,CAAC,CAAC,CAAC;;EAE7F,yBAAyB,eAAe,MAAM;GAC5C,OACE,QAAQ,yBAAyB,eAAe,KAAK,IACrD,QAAQ,yBAAyB,QAAQ,KAAK;;EAGnD,CAAC;;AAKJ,MAAM,4CAA4B,IAAI,SAA8C;AACpF,MAAM,4CAA4B,IAAI,SAGnC;AAEH,SAAS,uCACP,OACA,QACgB;CAChB,MAAM,SAAS,MAAM,IAAI,OAAO;CAChC,IAAI,QAAQ,OAAO;CAEnB,MAAM,UAAU,2BAA2B,QAAQ,QAAQ,OAAO,EAAE,OAAO;CAC3E,MAAM,IAAI,QAAQ,QAAQ;CAC1B,OAAO;;AAGT,SAAS,mCAAqD,OAAgC;CAC5F,MAAM,kBAAkB,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,MAAM,CAAC;CACjF,MAAM,UAAU,QAAQ,OAAO,gBAAgB;CAG/C,QAAQ,YAAY,GAAG;CAWvB,OAAO,2BAA2B,SAAS,IAThB,MAAM,EAAE,EAAO,EACxC,IAAI,SAAS,MAAM;EACjB,IAAI,SAAS,UAAU,SAAS,WAAW,SAAS,WAClD;EAEF,MAAM;IAET,CAEwD,CAAC;;AAG5D,SAAS,aAAa,SAA2B;CAC/C,OAAO,IAAI,MAAM,SAAS,EACxB,IAAI,QAAQ,MAAM;EAChB,IAAI,OAAO,SAAS,YAAY,0BAA0B,IAAI,KAAK,EACjE,MAAM,IAAI,sBAAsB;EAGlC,MAAM,QAAQ,QAAQ,IAAI,QAAQ,MAAM,OAAO;EAC/C,OAAO,OAAO,UAAU,aAAa,MAAM,KAAK,OAAO,GAAG;IAE7D,CAAC;;AAGJ,SAAS,oBAAoB,SAAyC;CACpE,OAAO,IAAI,MAAM,SAAS,EACxB,IAAI,QAAQ,MAAM;EAChB,IAAI,SAAS,SAAS,SAAS,UAC7B,QAAQ,GAAG,SAAoB;GAC7B,IAAI,CAAC,kCAAkC,EACrC,MAAM,IAAI,6BAA6B;GAGzC,OAAQ,QAAQ,IAAI,QAAQ,MAAM,OAAO,CAAyC,MAChF,QACA,KACD;;EAIL,MAAM,QAAQ,QAAQ,IAAI,QAAQ,MAAM,OAAO;EAC/C,OAAO,OAAO,UAAU,aAAa,MAAM,KAAK,OAAO,GAAG;IAE7D,CAAC;;AAGJ,SAAS,aAAa,SAAyC;CAC7D,OAAO,IAAI,MAAM,SAAS,EACxB,IAAI,QAAQ,MAAM;EAChB,IAAI,SAAS,SAAS,SAAS,UAC7B,MAAM,IAAI,6BAA6B;EAGzC,MAAM,QAAQ,QAAQ,IAAI,QAAQ,MAAM,OAAO;EAC/C,OAAO,OAAO,UAAU,aAAa,MAAM,KAAK,OAAO,GAAG;IAE7D,CAAC;;AAGJ,SAAS,mBAAmB,KAAqC;CAC/D,IAAI,CAAC,IAAI,gBACP,IAAI,iBAAiB,oBAAoB,IAAI,eAAe,IAAI,QAAQ,CAAC;CAG3E,OAAO,IAAI;;AAGb,SAAS,oBAAoB,KAAqC;CAChE,IAAI,CAAC,IAAI,iBAGP,IAAI,kBAAkB,aAAa,IAAI,eAAe,IAAI,QAAQ,CAAC;CAGrE,OAAO,IAAI;;AAGb,SAAS,oBAAoB,KAA8B;CACzD,IAAI,CAAC,IAAI,iBACP,IAAI,kBAAkB,aAAa,IAAI,QAAQ;CAGjD,OAAO,IAAI;;;;;;;;;;;;;;;;;;;;;;;AAwBb,SAAgB,0BACd,SACA,SACgB;CAKhB,IAAI,WAA2B;CAE/B,MAAM,eAAe,IAAI,MAAM,QAAQ,SAAS,EAC9C,IAAI,QAAQ,MAAuB;EAEjC,MAAM,MAAM,YAAY;EAGxB,IAAI,OAAO,SAAS,YAAY,0BAA0B,IAAI,KAAK,EACjE,QAAQ,GAAG,SAAoB;GAC7B,IAAI,CAAC,UACH,WAAW,IAAI,QAAQ,OAAO;GAEhC,OAAQ,SAAS,MACf,GAAG,KACJ;;EAKL,MAAM,QAAQ,QAAQ,IAAI,KAAK,MAAM,IAAI;EACzC,OAAO,OAAO,UAAU,aAAa,MAAM,KAAK,IAAI,GAAG;IAE1D,CAAC;CAOF,IAAI,WAAuC;CAE3C,SAAS,aAAkC;EACzC,IAAI,UAAU,OAAO;EAGrB,WAAW,kBADU,aAAa,IAAI,SAAS,IAAI,GACT;EAC1C,OAAO;;CAYT,OAAO;EAPL,SAAS;EACT,IAAI,UAA+B;GACjC,OAAO,YAAY;;EAErB,iBAAiB,SAAS;EAGlB;;;;;;;AAYZ,SAAgB,UAAsC;CACpD,0BAA0B,UAAU;CACpC,IAAI;EACF,wBAAwB,YAAY;UAC7B,OAAO;EACd,OAAO,mCAA4C,MAAM;;CAG3D,MAAM,QAAQ,WAAW;CACzB,IAAI,CAAC,MAAM,gBACT,OAAO,mDACL,IAAI,MACF,kJAED,CACF;CAGH,IAAI,MAAM,eAAe,aACvB,OAAO,mCAA4C,MAAM,eAAe,YAAY;CAGtF,kBAAkB;CAElB,OAAO,uCAAuC,2BADtB,oBAAoB,MAAM,eACsC,CAAC;;;;;;AAO3F,SAAgB,UAAoD;CAClE,0BAA0B,UAAU;CACpC,IAAI;EACF,wBAAwB,YAAY;UAC7B,OAAO;EACd,OAAO,mCAAmD,MAAM;;CAGlE,MAAM,QAAQ,WAAW;CACzB,IAAI,CAAC,MAAM,gBACT,OAAO,mDACL,IAAI,MACF,yFACD,CACF;CAGH,IAAI,MAAM,eAAe,aACvB,OAAO,mCAAmD,MAAM,eAAe,YAAY;CAG7F,kBAAkB;CAKlB,OAAO,uCAAuC,2BAJ1B,kCAAkC,GAClD,mBAAmB,MAAM,eAAe,GACxC,oBAAoB,MAAM,eAAe,CAEwC;;;;;;;AAcvF,SAAgB,4BAAsC;CACpD,MAAM,QAAQ,WAAW;CACzB,MAAM,UAAU,MAAM;CACtB,MAAM,oBAAoB,EAAE;CAC5B,OAAO;;AAIT,MAAM,oBAAoB;AAC1B,MAAM,2CAA0B,IAAI,KAAK,EAAE,EAAC,aAAa;;;;;AASzD,SAAgB,2BAA0C;CACxD,MAAM,QAAQ,WAAW;CACzB,MAAM,SAAS,MAAM;CACrB,MAAM,wBAAwB;CAC9B,OAAO;;AAGT,SAAS,wBAAwB,QAAwB;CACvD,IAAI,OAAO,WAAW,GACpB,MAAM,IAAI,MAAM,yDAAyD;CAE3E,OAAO;;AAGT,SAAS,wBAAgC;CACvC,MAAM,SAAS,WAAW;CAC1B,IAAI,UAAU,OAAO,OAAO,eAAe,YACzC,OAAO,OAAO,YAAY;CAG5B,MAAM,IAAI,MACR,0HAED;;AAGH,SAAS,6BAA6B,KAA6B;CACjE,IAAI,IAAI,oBAAoB,KAAA,GAC1B,OAAO,wBAAwB,IAAI,gBAAgB;CAGrD,MAAM,SAAS,uBAAuB;CACtC,IAAI,kBAAkB;CACtB,OAAO;;AAGT,SAAgB,mBAAmB,SAAkB,iBAAkC;CACrF,MAAM,eAAe,QAAQ,QAAQ,IAAI,SAAS;CAClD,IAAI,CAAC,cAAc,OAAO;CAC1B,OACE,kBAAkB,aAAa,CAAC,IAAI,kBAAkB,KACtD,wBAAwB,gBAAgB;;AAU5C,SAAS,4BAAoC;CAC3C,IAAI,OAAO,YAAY,eAAe,QAAQ,KAAK,aAAa,eAC9D,OAAO;CAET,OAAO;;AAGT,SAAS,0BAA0B,YAA2B;CAC5D,uBAAO,IAAI,MACT,GAAG,WAAW,+EACf;;AAGH,SAAS,8BACP,OACA,iBACA,YACgB;CAChB,MAAM,iBAAiB,MAAM;CAC7B,IAAI,mBAAmB,iBACrB,MAAM,0BAA0B,WAAW;CAE7C,IAAI,eAAe,aACjB,MAAM,eAAe;CAEvB,OAAO;;;;;;;;;AAUT,eAAsB,YAAsC;CAC1D,0BAA0B,YAAY;CACtC,wBAAwB,cAAc;CAEtC,MAAM,QAAQ,WAAW;CACzB,MAAM,UAAU,MAAM;CACtB,IAAI,CAAC,SACH,MAAM,0BAA0B,cAAc;CAEhD,IAAI,QAAQ,aACV,MAAM,QAAQ;CAOhB,MAAM,SAAS,6BAA6B,QAAQ;CAEpD,OAAO;EACL,IAAI,YAAqB;GACvB,OAAO,QAAQ,QAAQ,IAAI,kBAAkB,KAAK;;EAEpD,SAAe;GACb,MAAM,gBAAgB,8BAA8B,OAAO,SAAS,uBAAuB;GAC3F,kBAAkB;GAClB,cAAc,QAAQ,IAAI,mBAAmB,OAAO;GACpD,MAAM,wBAAwB,GAAG,kBAAkB,GAAG,OAAO,IAAI,2BAA2B;;EAE9F,UAAgB;GACd,MAAM,gBAAgB,8BAA8B,OAAO,SAAS,wBAAwB;GAC5F,kBAAkB;GAClB,cAAc,QAAQ,OAAO,kBAAkB;GAC/C,MAAM,wBAAwB,GAAG,kBAAkB,KAAK,2BAA2B,CAAC,YAAY;;EAEnG;;AAOH,IAAM,iBAAN,MAAqB;CACnB;CAEA,YAAY,SAA8B;EACxC,KAAK,WAAW;;CAGlB,IAAI,MAA2D;EAC7D,MAAM,QAAQ,KAAK,SAAS,IAAI,KAAK;EACrC,IAAI,UAAU,KAAA,GAAW,OAAO,KAAA;EAChC,OAAO;GAAE;GAAM;GAAO;;CAGxB,OAAO,eAAmF;EACxF,MAAM,OAAO,OAAO,kBAAkB,WAAW,gBAAgB,eAAe;EAChF,MAAM,SAAiD,EAAE;EACzD,KAAK,MAAM,CAAC,YAAY,UAAU,KAAK,UACrC,IAAI,SAAS,KAAA,KAAa,eAAe,MACvC,OAAO,KAAK;GAAE,MAAM;GAAY;GAAO,CAAC;EAG5C,OAAO;;CAGT,IAAI,MAAuB;EACzB,OAAO,KAAK,SAAS,IAAI,KAAK;;;;;;CAOhC,IACE,eAaA,OACA,SASM;EACN,IAAI;EACJ,IAAI;EACJ,IAAI;EAEJ,IAAI,OAAO,kBAAkB,UAAU;GACrC,aAAa;GACb,cAAc,SAAS;GACvB,OAAO;SACF;GACL,aAAa,cAAc;GAC3B,cAAc,cAAc;GAC5B,OAAO;;EAGT,mBAAmB,WAAW;EAG9B,KAAK,SAAS,IAAI,YAAY,YAAY;EAE1C,WAAW,CAAC,kBAAkB,KAAK,mBAAmB,YAAY,aAAa,KAAK,CAAC;EACrF,OAAO;;;;;CAMT,OAAO,eAAgF;EACrF,MAAM,OAAO,OAAO,kBAAkB,WAAW,gBAAgB,cAAc;EAC/E,MAAM,OAAO,OAAO,kBAAkB,WAAW,MAAO,cAAc,QAAQ;EAC9E,MAAM,SAAS,OAAO,kBAAkB,WAAW,KAAA,IAAY,cAAc;EAE7E,mBAAmB,KAAK;EACxB,6BAA6B,MAAM,OAAO;EAC1C,IAAI,QACF,6BAA6B,QAAQ,SAAS;EAGhD,KAAK,SAAS,OAAO,KAAK;EAC1B,MAAM,QAAQ,CAAC,GAAG,KAAK,IAAI,QAAQ,OAAO;EAC1C,IAAI,QAAQ,MAAM,KAAK,UAAU,SAAS;EAC1C,MAAM,KAAK,WAAW,sBAAsB;EAC5C,WAAW,CAAC,kBAAkB,KAAK,MAAM,KAAK,KAAK,CAAC;EACpD,OAAO;;CAGT,IAAI,OAAe;EACjB,OAAO,KAAK,SAAS;;CAGvB,CAAC,OAAO,YAAyE;EAC/E,MAAM,UAAU,KAAK,SAAS,SAAS;EACvC,MAAM,OAAoE;GACxE,CAAC,OAAO,YAAY;IAClB,OAAO;;GAET,OAAO;IACL,MAAM,EAAE,OAAO,SAAS,QAAQ,MAAM;IACtC,IAAI,MAAM,OAAO;KAAE,OAAO,KAAA;KAAW,MAAM;KAAM;IACjD,MAAM,CAAC,MAAM,OAAO;IACpB,OAAO;KAAE,OAAO,CAAC,MAAM;MAAE;MAAM,OAAO;MAAK,CAAC;KAAE,MAAM;KAAO;;GAE9D;EACD,OAAO;;CAGT,WAAmB;EACjB,MAAM,QAAkB,EAAE;EAC1B,KAAK,MAAM,CAAC,MAAM,UAAU,KAAK,UAC/B,MAAM,KAAK,GAAG,KAAK,GAAG,QAAQ;EAEhC,OAAO,MAAM,KAAK,KAAK"}
|
|
1
|
+
{"version":3,"file":"headers.js","names":[],"sources":["../../src/shims/headers.ts"],"sourcesContent":["/**\n * next/headers shim\n *\n * Provides cookies() and headers() functions for App Router Server Components.\n * These read from a request context set by the RSC handler before rendering.\n *\n * In Next.js 15+, cookies() and headers() return Promises (async).\n * We support both the sync (legacy) and async patterns.\n */\n\nimport { MIDDLEWARE_SET_COOKIE_HEADER } from \"../server/headers.js\";\nimport { buildRequestHeadersFromMiddlewareResponse } from \"../server/middleware-request-headers.js\";\nimport { getOrCreateAls } from \"./internal/als-registry.js\";\nimport {\n serializeSetCookie,\n validateCookieAttributeValue,\n validateCookieName,\n} from \"./internal/cookie-serialize.js\";\nimport { parseCookieHeader } from \"./internal/parse-cookie-header.js\";\nimport {\n isInsideUnifiedScope,\n getRequestContext,\n runWithUnifiedStateMutation,\n} from \"./unified-request-context.js\";\nimport type { RenderRequestApiKind } from \"../server/cache-proof.js\";\n\n// ---------------------------------------------------------------------------\n// Request context\n// ---------------------------------------------------------------------------\n\nexport type HeadersContext = {\n headers: Headers;\n cookies: Map<string, string>;\n accessError?: Error;\n forceStatic?: boolean;\n mutableCookies?: RequestCookies;\n readonlyCookies?: RequestCookies;\n readonlyHeaders?: Headers;\n draftModeSecret?: string;\n};\n\ntype HeadersContextFromRequestOptions = {\n draftModeSecret?: string;\n};\n\nexport type HeadersAccessPhase = \"render\" | \"action\" | \"route-handler\";\n\nexport type VinextHeadersShimState = {\n headersContext: HeadersContext | null;\n dynamicUsageDetected: boolean;\n renderRequestApiUsage: Set<RenderRequestApiKind>;\n /** Error recorded by throwIfInsideCacheScope for dev diagnostics, persists even if caught by user code. */\n invalidDynamicUsageError: unknown;\n pendingSetCookies: string[];\n draftModeCookieHeader: string | null;\n phase: HeadersAccessPhase;\n};\n\n// NOTE:\n// - This shim can be loaded under multiple module specifiers in Vite's\n// multi-environment setup (RSC/SSR). Store the AsyncLocalStorage on\n// globalThis so `connection()` (next/server) and `consumeDynamicUsage()`\n// (next/headers) always share it.\n// - We use AsyncLocalStorage so concurrent requests don't stomp each other's\n// headers/cookies/dynamic-usage state.\nconst _FALLBACK_KEY = Symbol.for(\"vinext.nextHeadersShim.fallback\");\nconst _g = globalThis as unknown as Record<PropertyKey, unknown>;\nconst _als = getOrCreateAls<VinextHeadersShimState>(\"vinext.nextHeadersShim.als\");\n\nconst _fallbackState = (_g[_FALLBACK_KEY] ??= {\n headersContext: null,\n dynamicUsageDetected: false,\n renderRequestApiUsage: new Set<RenderRequestApiKind>(),\n invalidDynamicUsageError: null,\n pendingSetCookies: [],\n draftModeCookieHeader: null,\n phase: \"render\",\n} satisfies VinextHeadersShimState) as VinextHeadersShimState;\nconst EXPIRED_COOKIE_DATE = new Date(0).toUTCString();\n\nfunction splitMiddlewareSetCookieHeader(value: string): string[] {\n const cookies: string[] = [];\n let start = 0;\n let inExpires = false;\n let expiresCommaSeen = false;\n\n for (let i = 0; i < value.length; i++) {\n if (value.slice(i, i + 8).toLowerCase() === \"expires=\") {\n inExpires = true;\n expiresCommaSeen = false;\n i += 7;\n continue;\n }\n\n const ch = value[i];\n if (inExpires && ch === \";\") {\n inExpires = false;\n expiresCommaSeen = false;\n continue;\n }\n\n if (ch !== \",\") continue;\n if (inExpires && !expiresCommaSeen) {\n expiresCommaSeen = true;\n continue;\n }\n\n const cookie = value.slice(start, i).trim();\n if (cookie) cookies.push(cookie);\n start = i + 1;\n inExpires = false;\n expiresCommaSeen = false;\n }\n\n const cookie = value.slice(start).trim();\n if (cookie) cookies.push(cookie);\n return cookies;\n}\n\nfunction setCookieNameValue(setCookie: string): { name: string; value: string } | null {\n const equalsIndex = setCookie.indexOf(\"=\");\n if (equalsIndex <= 0) return null;\n\n const name = setCookie.slice(0, equalsIndex).trim();\n const valueEnd = setCookie.indexOf(\";\", equalsIndex + 1);\n const encodedValue = setCookie.slice(equalsIndex + 1, valueEnd === -1 ? undefined : valueEnd);\n let value: string;\n try {\n value = decodeURIComponent(encodedValue);\n } catch {\n value = encodedValue;\n }\n\n return { name, value };\n}\n\nfunction rebuildCookiesFromHeader(ctx: HeadersContext, cookieHeader: string | null): void {\n ctx.cookies.clear();\n if (cookieHeader === null) return;\n\n const nextCookies = parseCookieHeader(cookieHeader);\n for (const [name, value] of nextCookies) {\n ctx.cookies.set(name, value);\n }\n}\n\nfunction mergeMiddlewareSetCookies(ctx: HeadersContext, rawHeader: string | null): boolean {\n if (rawHeader === null) return false;\n\n let merged = false;\n for (const setCookie of splitMiddlewareSetCookieHeader(rawHeader)) {\n const entry = setCookieNameValue(setCookie);\n if (!entry) continue;\n ctx.cookies.set(entry.name, entry.value);\n merged = true;\n }\n\n return merged;\n}\n\nfunction _getState(): VinextHeadersShimState {\n if (isInsideUnifiedScope()) {\n return getRequestContext();\n }\n return _als.getStore() ?? _fallbackState;\n}\n\n/**\n * Dynamic usage flag — set when a component calls connection(), cookies(),\n * headers(), or noStore() during rendering. When true, ISR caching is\n * bypassed and the response gets Cache-Control: no-store.\n */\n// (stored on _state)\n\n/**\n * Mark the current render as requiring dynamic (uncached) rendering.\n * Called by connection(), cookies(), headers(), and noStore().\n */\nexport function markDynamicUsage(): void {\n const state = _getState();\n if (state.headersContext?.forceStatic) {\n return;\n }\n state.dynamicUsageDetected = true;\n}\n\nexport function markRenderRequestApiUsage(kind: RenderRequestApiKind): void {\n _getState().renderRequestApiUsage.add(kind);\n}\n\nexport function peekRenderRequestApiUsage(): RenderRequestApiKind[] {\n return [..._getState().renderRequestApiUsage].sort();\n}\n\nexport function consumeRenderRequestApiUsage(): RenderRequestApiKind[] {\n const state = _getState();\n const observed = [...state.renderRequestApiUsage].sort();\n state.renderRequestApiUsage = new Set<RenderRequestApiKind>();\n return observed;\n}\n\n// ---------------------------------------------------------------------------\n// Cache scope detection — checks whether we're inside \"use cache\" or\n// unstable_cache() by reading ALS instances stored on globalThis via Symbols.\n// This avoids circular imports between headers.ts, cache.ts, and cache-runtime.ts.\n// The ALS instances are registered by cache-runtime.ts and cache.ts respectively.\n// ---------------------------------------------------------------------------\n\n/** Symbol used by cache-runtime.ts to store the \"use cache\" ALS on globalThis */\nconst _USE_CACHE_ALS_KEY = Symbol.for(\"vinext.cacheRuntime.contextAls\");\n/** Symbol used by cache.ts to store the unstable_cache ALS on globalThis */\nconst _UNSTABLE_CACHE_ALS_KEY = Symbol.for(\"vinext.unstableCache.als\");\n\ntype UseCacheGuardContext = {\n variant?: unknown;\n};\n\ntype CacheScopeStorage = {\n getStore: () => unknown;\n};\n\nfunction _getGlobalCacheScopeStorage(key: symbol): CacheScopeStorage | null {\n const value = Reflect.get(globalThis, key);\n if (!value || typeof value !== \"object\") return null;\n\n const getStore = Reflect.get(value, \"getStore\");\n if (typeof getStore !== \"function\") return null;\n\n return {\n getStore: () => getStore.call(value),\n };\n}\n\nfunction _getUseCacheGuardContext(): UseCacheGuardContext | null {\n const store = _getGlobalCacheScopeStorage(_USE_CACHE_ALS_KEY)?.getStore();\n if (!store || typeof store !== \"object\") return null;\n return store;\n}\n\nfunction _isInsidePublicUseCache(): boolean {\n const ctx = _getUseCacheGuardContext();\n // Next.js models \"use cache: private\" as a private-cache work unit that\n // carries request headers and cookies. Only public \"use cache\" scopes freeze\n // request APIs into persisted cache entries and must reject these reads.\n // https://github.com/vercel/next.js/blob/canary/packages/next/src/server/app-render/work-unit-async-storage.external.ts\n return ctx !== null && ctx.variant !== \"private\";\n}\n\nfunction _isInsideUnstableCache(): boolean {\n return _getGlobalCacheScopeStorage(_UNSTABLE_CACHE_ALS_KEY)?.getStore() === true;\n}\n\n/**\n * Throw if the current execution is inside a \"use cache\" or unstable_cache()\n * scope. Called by dynamic request APIs (headers, cookies, connection) to\n * prevent request-specific data from being frozen into cached results.\n *\n * @param apiName - The name of the API being called (e.g. \"connection()\")\n */\nexport function throwIfInsideCacheScope(apiName: string): void {\n if (_isInsidePublicUseCache()) {\n const error = new Error(\n `\\`${apiName}\\` cannot be called inside \"use cache\". ` +\n `If you need this data inside a cached function, call \\`${apiName}\\` ` +\n \"outside and pass the required data as an argument.\",\n );\n // Record the error on the request context so it survives user try/catch\n // and can be forwarded to the dev overlay on client-side navigations.\n // Ported from Next.js: workStore.invalidDynamicUsageError assignment in\n // packages/next/src/server/app-render/app-render.tsx\n // https://github.com/vercel/next.js/commit/f5e54c06726b571a042fce67417e40a29f6b8689\n try {\n const ctx = getRequestContext();\n if (ctx) ctx.invalidDynamicUsageError = error;\n } catch {\n // Ignore — best-effort recording for dev diagnostics\n }\n throw error;\n }\n if (_isInsideUnstableCache()) {\n const error = new Error(\n `\\`${apiName}\\` cannot be called inside a function cached with \\`unstable_cache()\\`. ` +\n `If you need this data inside a cached function, call \\`${apiName}\\` ` +\n \"outside and pass the required data as an argument.\",\n );\n try {\n const ctx = getRequestContext();\n if (ctx) ctx.invalidDynamicUsageError = error;\n } catch {\n // Ignore\n }\n throw error;\n }\n}\n\n/**\n * Check, consume, and return any invalid dynamic usage error recorded during\n * the render (e.g. cookies() called inside \"use cache\"). This error persists\n * even if the throw was caught by user-code try/catch, so it can surface on\n * client-side navigations where the static shell validation is skipped.\n * Ported from Next.js: workStore.invalidDynamicUsageError in\n * packages/next/src/server/app-render/app-render.tsx\n * https://github.com/vercel/next.js/commit/f5e54c06726b571a042fce67417e40a29f6b8689\n */\nexport function consumeInvalidDynamicUsageError(): unknown {\n const state = _getState();\n const err = state.invalidDynamicUsageError;\n state.invalidDynamicUsageError = null;\n return err;\n}\n\n/**\n * Check and reset the dynamic usage flag.\n * Called by the server after rendering to decide on caching.\n */\nexport function consumeDynamicUsage(): boolean {\n const state = _getState();\n const used = state.dynamicUsageDetected;\n state.dynamicUsageDetected = false;\n return used;\n}\n\nfunction _setStatePhase(\n state: VinextHeadersShimState,\n phase: HeadersAccessPhase,\n): HeadersAccessPhase {\n const previous = state.phase;\n state.phase = phase;\n return previous;\n}\n\nfunction _areCookiesMutableInCurrentPhase(): boolean {\n const phase = _getState().phase;\n return phase === \"action\" || phase === \"route-handler\";\n}\n\nexport function setHeadersAccessPhase(phase: HeadersAccessPhase): HeadersAccessPhase {\n return _setStatePhase(_getState(), phase);\n}\n\nexport function getHeadersAccessPhase(): HeadersAccessPhase {\n return _getState().phase;\n}\n\n/**\n * Set the headers/cookies context for the current RSC render.\n * Called by the framework's RSC entry before rendering each request.\n *\n * @deprecated Prefer runWithHeadersContext() which uses als.run() for\n * proper per-request isolation. This function mutates the ALS store\n * in-place and is only safe for cleanup (ctx=null) within an existing\n * als.run() scope.\n */\n/**\n * Returns the current live HeadersContext from ALS (or the fallback).\n * Used after applyMiddlewareRequestHeaders() to build a post-middleware\n * request context for afterFiles/fallback rewrite has/missing evaluation.\n */\nexport function getHeadersContext(): HeadersContext | null {\n return _getState().headersContext;\n}\n\nexport function setHeadersContext(ctx: HeadersContext | null): void {\n const state = _getState();\n if (ctx !== null) {\n state.headersContext = ctx;\n state.dynamicUsageDetected = false;\n state.renderRequestApiUsage = new Set();\n state.pendingSetCookies = [];\n state.draftModeCookieHeader = null;\n state.phase = \"render\";\n } else {\n state.headersContext = null;\n state.phase = \"render\";\n }\n}\n\n/**\n * Run a function with headers context, ensuring the context propagates\n * through all async operations (including RSC streaming).\n *\n * Uses AsyncLocalStorage.run() to guarantee per-request isolation.\n * The ALS store propagates through all async continuations including\n * ReadableStream consumption, setTimeout callbacks, and Promise chains,\n * so RSC streaming works correctly — components that render when the\n * stream is consumed still see the correct request's context.\n */\nexport function runWithHeadersContext<T>(ctx: HeadersContext, fn: () => Promise<T>): Promise<T>;\nexport function runWithHeadersContext<T>(\n ctx: HeadersContext,\n fn: () => T | Promise<T>,\n): T | Promise<T>;\nexport function runWithHeadersContext<T>(\n ctx: HeadersContext,\n fn: () => T | Promise<T>,\n): T | Promise<T> {\n if (isInsideUnifiedScope()) {\n return runWithUnifiedStateMutation((uCtx) => {\n uCtx.headersContext = ctx;\n uCtx.dynamicUsageDetected = false;\n uCtx.renderRequestApiUsage = new Set();\n uCtx.pendingSetCookies = [];\n uCtx.draftModeCookieHeader = null;\n uCtx.phase = \"render\";\n }, fn);\n }\n\n const state: VinextHeadersShimState = {\n headersContext: ctx,\n dynamicUsageDetected: false,\n renderRequestApiUsage: new Set(),\n invalidDynamicUsageError: null,\n pendingSetCookies: [],\n draftModeCookieHeader: null,\n phase: \"render\",\n };\n\n return _als.run(state, fn);\n}\n\n/**\n * Apply middleware-forwarded request headers to the current headers context.\n *\n * When Next.js middleware calls `NextResponse.next()` or `NextResponse.rewrite()`\n * with `{ request: { headers } }`, the modified headers are encoded on the\n * middleware response. This function decodes that protocol and applies the\n * resulting request header set to the live `HeadersContext`. When an override\n * list is present, omitted headers are deleted as part of the rebuild.\n *\n * Cached `readonlyHeaders` and `readonlyCookies` snapshots on the\n * HeadersContext must be invalidated whenever this function rebuilds the\n * underlying `headers`/`cookies`. Otherwise a middleware that reads\n * `headers()` (or `cookies()`) before returning a request-header override —\n * for example `@clerk/nextjs`, whose `clerkClient()` reads `headers()` via\n * `buildRequestLike()` during middleware execution — primes a sealed snapshot\n * built from the *pre*-override request, and any subsequent `headers()` call\n * from a Server Component would return that stale snapshot instead of the\n * middleware-modified view.\n */\nexport function applyMiddlewareRequestHeaders(middlewareResponseHeaders: Headers): void {\n const state = _getState();\n if (!state.headersContext) return;\n\n const ctx = state.headersContext;\n const previousCookieHeader = ctx.headers.get(\"cookie\");\n const middlewareSetCookieHeader = middlewareResponseHeaders.get(MIDDLEWARE_SET_COOKIE_HEADER);\n const nextHeaders = buildRequestHeadersFromMiddlewareResponse(\n ctx.headers,\n middlewareResponseHeaders,\n );\n\n if (!nextHeaders && middlewareSetCookieHeader === null) return;\n\n if (nextHeaders) {\n ctx.headers = nextHeaders;\n // Invalidate any sealed snapshot of the pre-override headers. A middleware\n // that read `headers()` before returning the override (e.g. clerkMiddleware)\n // would otherwise leak the pre-override view into the Server Component.\n ctx.readonlyHeaders = undefined;\n const nextCookieHeader = nextHeaders.get(\"cookie\");\n if (previousCookieHeader !== nextCookieHeader) {\n rebuildCookiesFromHeader(ctx, nextCookieHeader);\n ctx.readonlyCookies = undefined;\n ctx.mutableCookies = undefined;\n }\n }\n\n if (mergeMiddlewareSetCookies(ctx, middlewareSetCookieHeader)) {\n ctx.readonlyCookies = undefined;\n ctx.mutableCookies = undefined;\n }\n}\n\n/** Methods on `Headers` that mutate state. Hoisted to module scope — static. */\nconst _HEADERS_MUTATING_METHODS = new Set([\"set\", \"delete\", \"append\"]);\n\nclass ReadonlyHeadersError extends Error {\n constructor() {\n super(\n \"Headers cannot be modified. Read more: https://nextjs.org/docs/app/api-reference/functions/headers\",\n );\n }\n\n static callable(): never {\n throw new ReadonlyHeadersError();\n }\n}\n\n// Keep this error message in sync with server.ts. The two RequestCookies\n// adapters are separate until the next/headers and NextRequest cookie paths\n// share one implementation.\nclass ReadonlyRequestCookiesError extends Error {\n constructor() {\n super(\n \"Cookies can only be modified in a Server Action or Route Handler. Read more: https://nextjs.org/docs/app/api-reference/functions/cookies#options\",\n );\n }\n\n static callable(): never {\n throw new ReadonlyRequestCookiesError();\n }\n}\n\nfunction _decorateRequestApiPromise<T extends object>(\n promise: Promise<T>,\n target: T,\n): Promise<T> & T {\n return new Proxy(promise as Promise<T> & T, {\n get(promiseTarget, prop) {\n if (prop in promiseTarget) {\n const value = Reflect.get(promiseTarget, prop, promiseTarget);\n return typeof value === \"function\" ? value.bind(promiseTarget) : value;\n }\n\n const value = Reflect.get(target, prop, target);\n return typeof value === \"function\" ? value.bind(target) : value;\n },\n has(promiseTarget, prop) {\n return prop in promiseTarget || prop in target;\n },\n ownKeys(promiseTarget) {\n return Array.from(new Set([...Reflect.ownKeys(promiseTarget), ...Reflect.ownKeys(target)]));\n },\n getOwnPropertyDescriptor(promiseTarget, prop) {\n return (\n Reflect.getOwnPropertyDescriptor(promiseTarget, prop) ??\n Reflect.getOwnPropertyDescriptor(target, prop)\n );\n },\n });\n}\n\n// React.use() tracks thenables by identity, so request APIs must reuse the\n// same decorated promise for the same underlying request view.\nconst _decoratedHeadersPromises = new WeakMap<Headers, Promise<Headers> & Headers>();\nconst _decoratedCookiesPromises = new WeakMap<\n RequestCookies,\n Promise<RequestCookies> & RequestCookies\n>();\n\nfunction _getOrCreateDecoratedRequestApiPromise<T extends object>(\n cache: WeakMap<T, Promise<T> & T>,\n target: T,\n): Promise<T> & T {\n const cached = cache.get(target);\n if (cached) return cached;\n\n const promise = _decorateRequestApiPromise(Promise.resolve(target), target);\n cache.set(target, promise);\n return promise;\n}\n\nfunction _decorateRejectedRequestApiPromise<T extends object>(error: unknown): Promise<T> & T {\n const normalizedError = error instanceof Error ? error : new Error(String(error));\n const promise = Promise.reject(normalizedError) as Promise<T>;\n // Mark the rejection as handled so legacy sync access does not trigger\n // spurious unhandled rejection noise before callers await/catch it.\n promise.catch(() => {});\n\n const throwingTarget = new Proxy({} as T, {\n get(_target, prop) {\n if (prop === \"then\" || prop === \"catch\" || prop === \"finally\") {\n return undefined;\n }\n throw normalizedError;\n },\n });\n\n return _decorateRequestApiPromise(promise, throwingTarget);\n}\n\nfunction _sealHeaders(headers: Headers): Headers {\n return new Proxy(headers, {\n get(target, prop) {\n if (typeof prop === \"string\" && _HEADERS_MUTATING_METHODS.has(prop)) {\n throw new ReadonlyHeadersError();\n }\n\n const value = Reflect.get(target, prop, target);\n return typeof value === \"function\" ? value.bind(target) : value;\n },\n }) as Headers;\n}\n\nfunction _wrapMutableCookies(cookies: RequestCookies): RequestCookies {\n return new Proxy(cookies, {\n get(target, prop) {\n if (prop === \"set\" || prop === \"delete\") {\n return (...args: unknown[]) => {\n if (!_areCookiesMutableInCurrentPhase()) {\n throw new ReadonlyRequestCookiesError();\n }\n\n return (Reflect.get(target, prop, target) as (...callArgs: unknown[]) => unknown).apply(\n target,\n args,\n );\n };\n }\n\n const value = Reflect.get(target, prop, target);\n return typeof value === \"function\" ? value.bind(target) : value;\n },\n }) as RequestCookies;\n}\n\nfunction _sealCookies(cookies: RequestCookies): RequestCookies {\n return new Proxy(cookies, {\n get(target, prop) {\n if (prop === \"set\" || prop === \"delete\") {\n throw new ReadonlyRequestCookiesError();\n }\n\n const value = Reflect.get(target, prop, target);\n return typeof value === \"function\" ? value.bind(target) : value;\n },\n }) as RequestCookies;\n}\n\nfunction _getMutableCookies(ctx: HeadersContext): RequestCookies {\n if (!ctx.mutableCookies) {\n ctx.mutableCookies = _wrapMutableCookies(new RequestCookies(ctx.cookies));\n }\n\n return ctx.mutableCookies;\n}\n\nfunction _getReadonlyCookies(ctx: HeadersContext): RequestCookies {\n if (!ctx.readonlyCookies) {\n // Keep a separate readonly wrapper so render-path reads avoid the\n // mutable phase-checking proxy while still reflecting the shared cookie map.\n ctx.readonlyCookies = _sealCookies(new RequestCookies(ctx.cookies));\n }\n\n return ctx.readonlyCookies;\n}\n\nfunction _getReadonlyHeaders(ctx: HeadersContext): Headers {\n if (!ctx.readonlyHeaders) {\n ctx.readonlyHeaders = _sealHeaders(ctx.headers);\n }\n\n return ctx.readonlyHeaders;\n}\n\n/**\n * Create a HeadersContext from a standard Request object.\n *\n * Performance note: In Workerd (Cloudflare Workers), `new Headers(request.headers)`\n * copies the entire header map across the V8/C++ boundary, which shows up as\n * ~815 ms self-time in production profiles when requests carry many headers.\n * We defer this copy with a lazy proxy:\n *\n * - Reads (`get`, `has`, `entries`, …) are forwarded directly to the original\n * immutable `request.headers` — zero copy cost on the hot path.\n * - The first mutating call (`set`, `delete`, `append`) materialises\n * `new Headers(request.headers)` once, then applies the mutation to the copy.\n * All subsequent operations go to the copy.\n *\n * This means the ~815 ms copy only occurs when middleware actually rewrites\n * request headers via `NextResponse.next({ request: { headers } })`, which is\n * uncommon. Pure read requests (the vast majority) pay zero copy cost.\n *\n * Cookie parsing is also deferred: the `cookie` header string is not split\n * until the first call to `cookies()` or `draftMode()`.\n */\nexport function headersContextFromRequest(\n request: Request,\n options?: HeadersContextFromRequestOptions,\n): HeadersContext {\n // ---------------------------------------------------------------------------\n // Lazy mutable Headers proxy\n // ---------------------------------------------------------------------------\n // `_mutable` holds the materialised copy once a write is needed.\n let _mutable: Headers | null = null;\n\n const headersProxy = new Proxy(request.headers, {\n get(target, prop: string | symbol) {\n // Route to the materialised copy if it exists.\n const src = _mutable ?? target;\n\n // Intercept mutating methods: materialise on first write.\n if (typeof prop === \"string\" && _HEADERS_MUTATING_METHODS.has(prop)) {\n return (...args: unknown[]) => {\n if (!_mutable) {\n _mutable = new Headers(target);\n }\n return (_mutable[prop as \"set\" | \"delete\" | \"append\"] as (...a: unknown[]) => unknown)(\n ...args,\n );\n };\n }\n\n // Non-mutating method or property: bind to current source.\n const value = Reflect.get(src, prop, src);\n return typeof value === \"function\" ? value.bind(src) : value;\n },\n }) as Headers;\n\n // ---------------------------------------------------------------------------\n // Lazy cookie map\n // ---------------------------------------------------------------------------\n // Parsing cookies requires splitting on `;` and `=`, which is cheap but\n // still unnecessary overhead if `cookies()` is never called for this request.\n let _cookies: Map<string, string> | null = null;\n\n function getCookies(): Map<string, string> {\n if (_cookies) return _cookies;\n // Read from the proxy so middleware-modified cookie headers are respected.\n const cookieHeader = headersProxy.get(\"cookie\") || \"\";\n _cookies = parseCookieHeader(cookieHeader);\n return _cookies;\n }\n\n // Expose cookies as a lazy getter that memoises on first access.\n const ctx = {\n headers: headersProxy,\n get cookies(): Map<string, string> {\n return getCookies();\n },\n draftModeSecret: options?.draftModeSecret,\n } satisfies HeadersContext;\n\n return ctx;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Read-only Headers instance from the incoming request.\n * Returns a Promise in Next.js 15+ style (but resolves synchronously since\n * the context is already available).\n */\nexport function headers(): Promise<Headers> & Headers {\n markRenderRequestApiUsage(\"headers\");\n try {\n throwIfInsideCacheScope(\"headers()\");\n } catch (error) {\n return _decorateRejectedRequestApiPromise<Headers>(error);\n }\n\n const state = _getState();\n if (!state.headersContext) {\n return _decorateRejectedRequestApiPromise<Headers>(\n new Error(\n \"headers() can only be called from a Server Component, Route Handler, \" +\n \"or Server Action. Make sure you're not calling it from a Client Component.\",\n ),\n );\n }\n\n if (state.headersContext.accessError) {\n return _decorateRejectedRequestApiPromise<Headers>(state.headersContext.accessError);\n }\n\n markDynamicUsage();\n const readonlyHeaders = _getReadonlyHeaders(state.headersContext);\n return _getOrCreateDecoratedRequestApiPromise(_decoratedHeadersPromises, readonlyHeaders);\n}\n\n/**\n * Cookie jar from the incoming request.\n * Returns a ReadonlyRequestCookies-like object.\n */\nexport function cookies(): Promise<RequestCookies> & RequestCookies {\n markRenderRequestApiUsage(\"cookies\");\n try {\n throwIfInsideCacheScope(\"cookies()\");\n } catch (error) {\n return _decorateRejectedRequestApiPromise<RequestCookies>(error);\n }\n\n const state = _getState();\n if (!state.headersContext) {\n return _decorateRejectedRequestApiPromise<RequestCookies>(\n new Error(\n \"cookies() can only be called from a Server Component, Route Handler, or Server Action.\",\n ),\n );\n }\n\n if (state.headersContext.accessError) {\n return _decorateRejectedRequestApiPromise<RequestCookies>(state.headersContext.accessError);\n }\n\n markDynamicUsage();\n const cookieStore = _areCookiesMutableInCurrentPhase()\n ? _getMutableCookies(state.headersContext)\n : _getReadonlyCookies(state.headersContext);\n\n return _getOrCreateDecoratedRequestApiPromise(_decoratedCookiesPromises, cookieStore);\n}\n\n// ---------------------------------------------------------------------------\n// Writable cookie accumulator for Route Handlers / Server Actions\n// ---------------------------------------------------------------------------\n\n/** Accumulated Set-Cookie headers from cookies().set() / .delete() calls */\n// (stored on _state)\n\n/**\n * Get and clear all pending Set-Cookie headers generated by cookies().set()/delete().\n * Called by the framework after rendering to attach headers to the response.\n */\nexport function getAndClearPendingCookies(): string[] {\n const state = _getState();\n const cookies = state.pendingSetCookies;\n state.pendingSetCookies = [];\n return cookies;\n}\n\n// Draft mode cookie name (matches Next.js convention)\nconst DRAFT_MODE_COOKIE = \"__prerender_bypass\";\nconst DRAFT_MODE_EXPIRED_DATE = new Date(0).toUTCString();\n\n// Store for Set-Cookie headers generated by draftMode().enable()/disable()\n// (stored on _state)\n\n/**\n * Get any Set-Cookie header generated by draftMode().enable()/disable().\n * Called by the framework after rendering to attach the header to the response.\n */\nexport function getDraftModeCookieHeader(): string | null {\n const state = _getState();\n const header = state.draftModeCookieHeader;\n state.draftModeCookieHeader = null;\n return header;\n}\n\nfunction validateDraftModeSecret(secret: string): string {\n if (secret.length === 0) {\n throw new Error(\"[vinext] draft mode secret must be a non-empty string.\");\n }\n return secret;\n}\n\nfunction createDraftModeSecret(): string {\n const crypto = globalThis.crypto;\n if (crypto && typeof crypto.randomUUID === \"function\") {\n return crypto.randomUUID();\n }\n\n throw new Error(\n \"[vinext] draft mode secret is not initialized. \" +\n \"This should be initialized by the server entry before handling requests.\",\n );\n}\n\nfunction ensureContextDraftModeSecret(ctx: HeadersContext): string {\n if (ctx.draftModeSecret !== undefined) {\n return validateDraftModeSecret(ctx.draftModeSecret);\n }\n\n const secret = createDraftModeSecret();\n ctx.draftModeSecret = secret;\n return secret;\n}\n\nexport function isDraftModeRequest(request: Request, draftModeSecret: string): boolean {\n const cookieHeader = request.headers.get(\"cookie\");\n if (!cookieHeader) return false;\n return (\n parseCookieHeader(cookieHeader).get(DRAFT_MODE_COOKIE) ===\n validateDraftModeSecret(draftModeSecret)\n );\n}\n\ntype DraftModeResult = {\n readonly isEnabled: boolean;\n enable(): void;\n disable(): void;\n};\n\nfunction draftModeCookieAttributes(): string {\n if (typeof process !== \"undefined\" && process.env?.NODE_ENV === \"development\") {\n return \"Path=/; HttpOnly; SameSite=Lax\";\n }\n return \"Path=/; HttpOnly; SameSite=None; Secure\";\n}\n\nfunction createDraftModeScopeError(expression: string): Error {\n return new Error(\n `${expression} can only be called from a Server Component, Route Handler, or Server Action.`,\n );\n}\n\nfunction requireActiveDraftModeContext(\n state: VinextHeadersShimState,\n expectedContext: HeadersContext,\n expression: string,\n): HeadersContext {\n const currentContext = state.headersContext;\n if (currentContext !== expectedContext) {\n throw createDraftModeScopeError(expression);\n }\n if (currentContext.accessError) {\n throw currentContext.accessError;\n }\n return currentContext;\n}\n\n/**\n * Draft mode — check/toggle via a `__prerender_bypass` cookie.\n *\n * - `isEnabled`: true if the bypass cookie is present in the request\n * - `enable()`: sets the bypass cookie (for Route Handlers)\n * - `disable()`: clears the bypass cookie\n *\n * Unlike `headers()` / `cookies()`, calling `draftMode()` itself is allowed\n * inside `\"use cache\"` and `unstable_cache()` scopes — reads of `isEnabled`\n * are non-dynamic and supported in cached functions. Only the mutating\n * `enable()` / `disable()` methods throw when invoked inside a cache scope.\n * Ported from Next.js: packages/next/src/server/request/draft-mode.ts\n * (`getDraftModeProviderForCacheScope` + `trackDynamicDraftMode`).\n */\nexport async function draftMode(): Promise<DraftModeResult> {\n markRenderRequestApiUsage(\"draftMode\");\n\n const state = _getState();\n const context = state.headersContext;\n if (!context) {\n throw createDraftModeScopeError(\"draftMode()\");\n }\n if (context.accessError) {\n throw context.accessError;\n }\n // Reading `draftMode()` itself is not dynamic — `isEnabled` is a plain\n // getter and merely calling `draftMode()` does not require bailing out\n // of static prerendering. Only `enable()`/`disable()` mutate state and\n // must be tracked as dynamic, mirroring Next.js's `trackDynamicDraftMode`\n // (see .nextjs-ref/packages/next/src/server/request/draft-mode.ts:152-165).\n const secret = ensureContextDraftModeSecret(context);\n\n return {\n get isEnabled(): boolean {\n return context.cookies.get(DRAFT_MODE_COOKIE) === secret;\n },\n enable(): void {\n // Mutating draft mode inside a cache scope would freeze a Set-Cookie\n // side-effect into the cached entry, so Next.js throws here. Match that.\n throwIfInsideCacheScope(\"draftMode().enable()\");\n const activeContext = requireActiveDraftModeContext(state, context, \"draftMode().enable()\");\n markDynamicUsage();\n activeContext.cookies.set(DRAFT_MODE_COOKIE, secret);\n state.draftModeCookieHeader = `${DRAFT_MODE_COOKIE}=${secret}; ${draftModeCookieAttributes()}`;\n },\n disable(): void {\n throwIfInsideCacheScope(\"draftMode().disable()\");\n const activeContext = requireActiveDraftModeContext(state, context, \"draftMode().disable()\");\n markDynamicUsage();\n activeContext.cookies.delete(DRAFT_MODE_COOKIE);\n state.draftModeCookieHeader = `${DRAFT_MODE_COOKIE}=; ${draftModeCookieAttributes()}; Expires=${DRAFT_MODE_EXPIRED_DATE}`;\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// RequestCookies implementation\n// ---------------------------------------------------------------------------\n\nclass RequestCookies {\n private _cookies: Map<string, string>;\n\n constructor(cookies: Map<string, string>) {\n this._cookies = cookies;\n }\n\n get(name: string): { name: string; value: string } | undefined {\n const value = this._cookies.get(name);\n if (value === undefined) return undefined;\n return { name, value };\n }\n\n getAll(nameOrOptions?: string | { name: string }): Array<{ name: string; value: string }> {\n const name = typeof nameOrOptions === \"string\" ? nameOrOptions : nameOrOptions?.name;\n const result: Array<{ name: string; value: string }> = [];\n for (const [cookieName, value] of this._cookies) {\n if (name === undefined || cookieName === name) {\n result.push({ name: cookieName, value });\n }\n }\n return result;\n }\n\n has(name: string): boolean {\n return this._cookies.has(name);\n }\n\n /**\n * Set a cookie. In Route Handlers and Server Actions, this produces\n * a Set-Cookie header on the response.\n */\n set(\n nameOrOptions:\n | string\n | {\n name: string;\n value: string;\n path?: string;\n domain?: string;\n maxAge?: number;\n expires?: Date;\n httpOnly?: boolean;\n secure?: boolean;\n sameSite?: \"Strict\" | \"Lax\" | \"None\";\n },\n value?: string,\n options?: {\n path?: string;\n domain?: string;\n maxAge?: number;\n expires?: Date;\n httpOnly?: boolean;\n secure?: boolean;\n sameSite?: \"Strict\" | \"Lax\" | \"None\";\n },\n ): this {\n let cookieName: string;\n let cookieValue: string;\n let opts: typeof options;\n\n if (typeof nameOrOptions === \"string\") {\n cookieName = nameOrOptions;\n cookieValue = value ?? \"\";\n opts = options;\n } else {\n cookieName = nameOrOptions.name;\n cookieValue = nameOrOptions.value;\n opts = nameOrOptions;\n }\n\n validateCookieName(cookieName);\n\n // Update the local cookie map\n this._cookies.set(cookieName, cookieValue);\n\n _getState().pendingSetCookies.push(serializeSetCookie(cookieName, cookieValue, opts));\n return this;\n }\n\n /**\n * Delete a cookie by emitting an expired Set-Cookie header.\n */\n delete(nameOrOptions: string | { name: string; path?: string; domain?: string }): this {\n const name = typeof nameOrOptions === \"string\" ? nameOrOptions : nameOrOptions.name;\n const path = typeof nameOrOptions === \"string\" ? \"/\" : (nameOrOptions.path ?? \"/\");\n const domain = typeof nameOrOptions === \"string\" ? undefined : nameOrOptions.domain;\n\n validateCookieName(name);\n validateCookieAttributeValue(path, \"Path\");\n if (domain) {\n validateCookieAttributeValue(domain, \"Domain\");\n }\n\n this._cookies.delete(name);\n const parts = [`${name}=`, `Path=${path}`];\n if (domain) parts.push(`Domain=${domain}`);\n parts.push(`Expires=${EXPIRED_COOKIE_DATE}`);\n _getState().pendingSetCookies.push(parts.join(\"; \"));\n return this;\n }\n\n get size(): number {\n return this._cookies.size;\n }\n\n [Symbol.iterator](): IterableIterator<[string, { name: string; value: string }]> {\n const entries = this._cookies.entries();\n const iter: IterableIterator<[string, { name: string; value: string }]> = {\n [Symbol.iterator]() {\n return iter;\n },\n next() {\n const { value, done } = entries.next();\n if (done) return { value: undefined, done: true };\n const [name, val] = value;\n return { value: [name, { name, value: val }], done: false };\n },\n };\n return iter;\n }\n\n toString(): string {\n const parts: string[] = [];\n for (const [name, value] of this._cookies) {\n parts.push(`${name}=${value}`);\n }\n return parts.join(\"; \");\n }\n}\n\n// Re-export types\nexport type { RequestCookies };\n"],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { VinextLinkPrefetchRoute } from "../../client/vinext-next-data.js";
|
|
2
|
+
|
|
3
|
+
//#region src/shims/internal/app-route-detection.d.ts
|
|
4
|
+
declare global {
|
|
5
|
+
interface Window {
|
|
6
|
+
__VINEXT_LINK_PREFETCH_ROUTES__?: VinextLinkPrefetchRoute[];
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Pages Router `components` map shape. Next.js types this loosely (route
|
|
11
|
+
* pattern → `PrivateRouteInfo`), but for the App Router-detected case it
|
|
12
|
+
* stores `{ __appRouter: true }` as a marker (see Next.js source link above).
|
|
13
|
+
* Vinext only writes the marker variant; reads are by test code that checks
|
|
14
|
+
* for `__appRouter: true`.
|
|
15
|
+
*/
|
|
16
|
+
type PagesRouterComponentsMap = Record<string, {
|
|
17
|
+
__appRouter: true;
|
|
18
|
+
} | Record<string, unknown>>;
|
|
19
|
+
/**
|
|
20
|
+
* Get-or-create the Pages Router `components` map. Returns the same object
|
|
21
|
+
* on every call so `router.components` and `window.next.router.components`
|
|
22
|
+
* have referential identity.
|
|
23
|
+
*/
|
|
24
|
+
declare function getPagesRouterComponentsMap(): PagesRouterComponentsMap;
|
|
25
|
+
/**
|
|
26
|
+
* Record `components[pathname] = { __appRouter: true }` on the shared
|
|
27
|
+
* Pages Router map when the href matches an App Router route. No-op when the
|
|
28
|
+
* manifest is absent, the URL is external, or no app route matches.
|
|
29
|
+
*
|
|
30
|
+
* `pathname` is the basePath-stripped path — matching Next.js's
|
|
31
|
+
* `router.components[urlPathname]` key (see the source link in this file's
|
|
32
|
+
* leading comment).
|
|
33
|
+
*/
|
|
34
|
+
declare function markAppRouteDetectedOnPrefetch(href: string, basePath: string): void;
|
|
35
|
+
//#endregion
|
|
36
|
+
export { getPagesRouterComponentsMap, markAppRouteDetectedOnPrefetch };
|
|
37
|
+
//# sourceMappingURL=app-route-detection.d.ts.map
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { stripBasePath } from "../../utils/base-path.js";
|
|
2
|
+
import { createRouteTrieCache, matchRouteWithTrie } from "../../routing/route-matching.js";
|
|
3
|
+
//#region src/shims/internal/app-route-detection.ts
|
|
4
|
+
const appRouteTrieCache = createRouteTrieCache();
|
|
5
|
+
const _COMPONENTS_KEY = Symbol.for("vinext.pagesRouter.components");
|
|
6
|
+
/**
|
|
7
|
+
* Get-or-create the Pages Router `components` map. Returns the same object
|
|
8
|
+
* on every call so `router.components` and `window.next.router.components`
|
|
9
|
+
* have referential identity.
|
|
10
|
+
*/
|
|
11
|
+
function getPagesRouterComponentsMap() {
|
|
12
|
+
const globalState = globalThis;
|
|
13
|
+
let components = globalState[_COMPONENTS_KEY];
|
|
14
|
+
if (!components) {
|
|
15
|
+
components = {};
|
|
16
|
+
globalState[_COMPONENTS_KEY] = components;
|
|
17
|
+
}
|
|
18
|
+
return components;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Resolve a prefetch href to a same-origin pathname (basePath-stripped),
|
|
22
|
+
* suitable as the key used by Next.js for `router.components[urlPathname]`.
|
|
23
|
+
*
|
|
24
|
+
* Returns null for external URLs, malformed URLs, or non-browser contexts.
|
|
25
|
+
*/
|
|
26
|
+
function resolveSameOriginPathname(href, basePath) {
|
|
27
|
+
if (typeof window === "undefined") return null;
|
|
28
|
+
let url;
|
|
29
|
+
try {
|
|
30
|
+
url = new URL(href, window.location.href);
|
|
31
|
+
} catch {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
if (url.origin !== window.location.origin) return null;
|
|
35
|
+
return stripBasePath(url.pathname, basePath);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Returns true when the prefetch href matches any route in the App Router
|
|
39
|
+
* prefetch manifest (static or dynamic). Returns false when the manifest is
|
|
40
|
+
* absent (Pages-Router-only build), the URL is external, or no route matches.
|
|
41
|
+
*/
|
|
42
|
+
function matchesAppRoute(href, basePath) {
|
|
43
|
+
if (typeof window === "undefined") return false;
|
|
44
|
+
const routes = window.__VINEXT_LINK_PREFETCH_ROUTES__;
|
|
45
|
+
if (!routes || routes.length === 0) return false;
|
|
46
|
+
const pathname = resolveSameOriginPathname(href, basePath);
|
|
47
|
+
if (pathname === null) return false;
|
|
48
|
+
return matchRouteWithTrie(pathname, routes, appRouteTrieCache) !== null;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Record `components[pathname] = { __appRouter: true }` on the shared
|
|
52
|
+
* Pages Router map when the href matches an App Router route. No-op when the
|
|
53
|
+
* manifest is absent, the URL is external, or no app route matches.
|
|
54
|
+
*
|
|
55
|
+
* `pathname` is the basePath-stripped path — matching Next.js's
|
|
56
|
+
* `router.components[urlPathname]` key (see the source link in this file's
|
|
57
|
+
* leading comment).
|
|
58
|
+
*/
|
|
59
|
+
function markAppRouteDetectedOnPrefetch(href, basePath) {
|
|
60
|
+
if (typeof window === "undefined") return;
|
|
61
|
+
if (!matchesAppRoute(href, basePath)) return;
|
|
62
|
+
const pathname = resolveSameOriginPathname(href, basePath);
|
|
63
|
+
if (pathname === null) return;
|
|
64
|
+
getPagesRouterComponentsMap()[pathname] = { __appRouter: true };
|
|
65
|
+
}
|
|
66
|
+
//#endregion
|
|
67
|
+
export { getPagesRouterComponentsMap, markAppRouteDetectedOnPrefetch };
|
|
68
|
+
|
|
69
|
+
//# sourceMappingURL=app-route-detection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-route-detection.js","names":[],"sources":["../../../src/shims/internal/app-route-detection.ts"],"sourcesContent":["/**\n * Shared helper for marking an App Router route as \"detected\" on the Pages\n * Router singleton when a `<Link>` or `Router.prefetch` targets it.\n *\n * Ported from Next.js: `packages/next/src/shared/lib/router/router.ts:2525`\n *\n * if (await this._bfl(asPath, resolvedAs, options.locale, true)) {\n * this.components[urlPathname] = { __appRouter: true } as any\n * }\n *\n * Next.js uses a bloom filter (`_bfl`) of App Router routes that the Pages\n * Router cannot handle. When the prefetch target matches the filter, the\n * Pages Router records the route on `this.components` with\n * `{ __appRouter: true }`. The Next.js deploy test\n * test/e2e/app-dir/app/index.test.ts → \"should successfully detect app\n * route during prefetch\"\n * reads this through `window.next.router.components[\"/dashboard\"]`.\n *\n * Vinext does not need a bloom filter — the App Router prefetch route\n * manifest (`__VINEXT_LINK_PREFETCH_ROUTES__`) already lives on the client\n * for Link's App Router auto-prefetch decisions. This helper reuses that\n * manifest and the shared trie matcher to decide whether a prefetch target\n * is an App Router route.\n *\n * Lives in `shims/internal/` so both the Pages Router (`router.ts`) and the\n * Link shim's Pages-mode branch (`link.tsx`) can call it without pulling in\n * the other shim at module init.\n *\n * The components map is stored behind a `Symbol.for` global so the Pages\n * Router (`router.ts`) and the Link shim (`link.tsx`) both write through the\n * same instance even when Vite loads the router shim through a different\n * resolved module ID than the link shim (mirrors the same module-split\n * mitigation used by `navigation.ts`'s GLOBAL_ACCESSORS_KEY).\n *\n * Issue: https://github.com/cloudflare/vinext/issues/1526\n */\nimport type { VinextLinkPrefetchRoute } from \"../../client/vinext-next-data.js\";\nimport { createRouteTrieCache, matchRouteWithTrie } from \"../../routing/route-matching.js\";\nimport { stripBasePath } from \"../../utils/base-path.js\";\n\nconst appRouteTrieCache = createRouteTrieCache<VinextLinkPrefetchRoute>();\n\ndeclare global {\n // oxlint-disable-next-line typescript-eslint/consistent-type-definitions\n interface Window {\n __VINEXT_LINK_PREFETCH_ROUTES__?: VinextLinkPrefetchRoute[];\n }\n}\n\n/**\n * Pages Router `components` map shape. Next.js types this loosely (route\n * pattern → `PrivateRouteInfo`), but for the App Router-detected case it\n * stores `{ __appRouter: true }` as a marker (see Next.js source link above).\n * Vinext only writes the marker variant; reads are by test code that checks\n * for `__appRouter: true`.\n */\ntype PagesRouterComponentsMap = Record<string, { __appRouter: true } | Record<string, unknown>>;\n\nconst _COMPONENTS_KEY = Symbol.for(\"vinext.pagesRouter.components\");\ntype _GlobalWithComponents = typeof globalThis & {\n [_COMPONENTS_KEY]?: PagesRouterComponentsMap;\n};\n\n/**\n * Get-or-create the Pages Router `components` map. Returns the same object\n * on every call so `router.components` and `window.next.router.components`\n * have referential identity.\n */\nexport function getPagesRouterComponentsMap(): PagesRouterComponentsMap {\n const globalState = globalThis as _GlobalWithComponents;\n let components = globalState[_COMPONENTS_KEY];\n if (!components) {\n components = {};\n globalState[_COMPONENTS_KEY] = components;\n }\n return components;\n}\n\n/**\n * Resolve a prefetch href to a same-origin pathname (basePath-stripped),\n * suitable as the key used by Next.js for `router.components[urlPathname]`.\n *\n * Returns null for external URLs, malformed URLs, or non-browser contexts.\n */\nfunction resolveSameOriginPathname(href: string, basePath: string): string | null {\n if (typeof window === \"undefined\") return null;\n let url: URL;\n try {\n url = new URL(href, window.location.href);\n } catch {\n return null;\n }\n if (url.origin !== window.location.origin) return null;\n return stripBasePath(url.pathname, basePath);\n}\n\n/**\n * Returns true when the prefetch href matches any route in the App Router\n * prefetch manifest (static or dynamic). Returns false when the manifest is\n * absent (Pages-Router-only build), the URL is external, or no route matches.\n */\nfunction matchesAppRoute(href: string, basePath: string): boolean {\n if (typeof window === \"undefined\") return false;\n const routes = window.__VINEXT_LINK_PREFETCH_ROUTES__;\n if (!routes || routes.length === 0) return false;\n\n const pathname = resolveSameOriginPathname(href, basePath);\n if (pathname === null) return false;\n\n return matchRouteWithTrie(pathname, routes, appRouteTrieCache) !== null;\n}\n\n/**\n * Record `components[pathname] = { __appRouter: true }` on the shared\n * Pages Router map when the href matches an App Router route. No-op when the\n * manifest is absent, the URL is external, or no app route matches.\n *\n * `pathname` is the basePath-stripped path — matching Next.js's\n * `router.components[urlPathname]` key (see the source link in this file's\n * leading comment).\n */\nexport function markAppRouteDetectedOnPrefetch(href: string, basePath: string): void {\n if (typeof window === \"undefined\") return;\n if (!matchesAppRoute(href, basePath)) return;\n\n const pathname = resolveSameOriginPathname(href, basePath);\n if (pathname === null) return;\n\n getPagesRouterComponentsMap()[pathname] = { __appRouter: true };\n}\n"],"mappings":";;;AAwCA,MAAM,oBAAoB,sBAA+C;AAkBzE,MAAM,kBAAkB,OAAO,IAAI,gCAAgC;;;;;;AAUnE,SAAgB,8BAAwD;CACtE,MAAM,cAAc;CACpB,IAAI,aAAa,YAAY;CAC7B,IAAI,CAAC,YAAY;EACf,aAAa,EAAE;EACf,YAAY,mBAAmB;;CAEjC,OAAO;;;;;;;;AAST,SAAS,0BAA0B,MAAc,UAAiC;CAChF,IAAI,OAAO,WAAW,aAAa,OAAO;CAC1C,IAAI;CACJ,IAAI;EACF,MAAM,IAAI,IAAI,MAAM,OAAO,SAAS,KAAK;SACnC;EACN,OAAO;;CAET,IAAI,IAAI,WAAW,OAAO,SAAS,QAAQ,OAAO;CAClD,OAAO,cAAc,IAAI,UAAU,SAAS;;;;;;;AAQ9C,SAAS,gBAAgB,MAAc,UAA2B;CAChE,IAAI,OAAO,WAAW,aAAa,OAAO;CAC1C,MAAM,SAAS,OAAO;CACtB,IAAI,CAAC,UAAU,OAAO,WAAW,GAAG,OAAO;CAE3C,MAAM,WAAW,0BAA0B,MAAM,SAAS;CAC1D,IAAI,aAAa,MAAM,OAAO;CAE9B,OAAO,mBAAmB,UAAU,QAAQ,kBAAkB,KAAK;;;;;;;;;;;AAYrE,SAAgB,+BAA+B,MAAc,UAAwB;CACnF,IAAI,OAAO,WAAW,aAAa;CACnC,IAAI,CAAC,gBAAgB,MAAM,SAAS,EAAE;CAEtC,MAAM,WAAW,0BAA0B,MAAM,SAAS;CAC1D,IAAI,aAAa,MAAM;CAEvB,6BAA6B,CAAC,YAAY,EAAE,aAAa,MAAM"}
|
package/dist/shims/link.d.ts
CHANGED
|
@@ -21,7 +21,15 @@ type LinkProps = {
|
|
|
21
21
|
* is upgraded to a full prefetch when the user shows navigation intent.
|
|
22
22
|
*/
|
|
23
23
|
unstable_dynamicOnHover?: boolean; /** Whether to pass the href to the child element */
|
|
24
|
-
passHref?: boolean;
|
|
24
|
+
passHref?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Pre-Next.js-13 link behaviour. When true, <Link> expects its child to be
|
|
27
|
+
* an `<a>` (or a component that renders one) and forwards `href`, click,
|
|
28
|
+
* and prefetch handlers to the child via `React.cloneElement` instead of
|
|
29
|
+
* rendering its own wrapping `<a>`. Required when the user wants to
|
|
30
|
+
* style/instrument the anchor themselves.
|
|
31
|
+
*/
|
|
32
|
+
legacyBehavior?: boolean; /** Scroll to top on navigation (default: true) */
|
|
25
33
|
scroll?: boolean;
|
|
26
34
|
/**
|
|
27
35
|
* Pages Router: update the URL without re-running data fetching methods
|
|
@@ -68,7 +76,15 @@ declare const Link: React.ForwardRefExoticComponent<{
|
|
|
68
76
|
* is upgraded to a full prefetch when the user shows navigation intent.
|
|
69
77
|
*/
|
|
70
78
|
unstable_dynamicOnHover?: boolean; /** Whether to pass the href to the child element */
|
|
71
|
-
passHref?: boolean;
|
|
79
|
+
passHref?: boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Pre-Next.js-13 link behaviour. When true, <Link> expects its child to be
|
|
82
|
+
* an `<a>` (or a component that renders one) and forwards `href`, click,
|
|
83
|
+
* and prefetch handlers to the child via `React.cloneElement` instead of
|
|
84
|
+
* rendering its own wrapping `<a>`. Required when the user wants to
|
|
85
|
+
* style/instrument the anchor themselves.
|
|
86
|
+
*/
|
|
87
|
+
legacyBehavior?: boolean; /** Scroll to top on navigation (default: true) */
|
|
72
88
|
scroll?: boolean;
|
|
73
89
|
/**
|
|
74
90
|
* Pages Router: update the URL without re-running data fetching methods
|
package/dist/shims/link.js
CHANGED
|
@@ -3,15 +3,16 @@ import { stripBasePath } from "../utils/base-path.js";
|
|
|
3
3
|
import { createRouteTrieCache, matchRouteWithTrie } from "../routing/route-matching.js";
|
|
4
4
|
import { VINEXT_MOUNTED_SLOTS_HEADER } from "../server/headers.js";
|
|
5
5
|
import { isDangerousScheme, reportBlockedDangerousNavigation } from "./url-safety.js";
|
|
6
|
-
import { appendSearchParamsToUrl, urlQueryToSearchParams } from "../utils/query.js";
|
|
7
6
|
import { AppElementsWire } from "../server/app-elements-wire.js";
|
|
8
7
|
import { APP_RSC_RENDER_MODE_PREFETCH_LOADING_SHELL } from "../server/app-rsc-render-mode.js";
|
|
8
|
+
import "../server/app-elements.js";
|
|
9
9
|
import { addLocalePrefix, getDomainLocaleUrl } from "../utils/domain-locale.js";
|
|
10
10
|
import { prefetchPagesData, resolvePagesDataNavigationTarget } from "./internal/pages-data-target.js";
|
|
11
|
+
import { markAppRouteDetectedOnPrefetch } from "./internal/app-route-detection.js";
|
|
11
12
|
import { isAbsoluteOrProtocolRelativeUrl, normalizePathTrailingSlash, resolveRelativeHref, toBrowserNavigationHref, toSameOriginAppPath, withBasePath } from "./url-utils.js";
|
|
13
|
+
import { appendSearchParamsToUrl, urlQueryToSearchParams } from "../utils/query.js";
|
|
12
14
|
import { getCurrentBrowserLocale } from "./client-locale.js";
|
|
13
15
|
import { getNavigationRuntime, hasAppNavigationRuntime, registerNavigationRuntimeFunctions } from "../client/navigation-runtime.js";
|
|
14
|
-
import "../server/app-elements.js";
|
|
15
16
|
import { createRscRequestHeaders, createRscRequestUrl, stripRscCacheBustingSearchParam, stripRscSuffix } from "../server/app-rsc-cache-busting.js";
|
|
16
17
|
import { getMountedSlotsHeader, getPrefetchCache, getPrefetchInterceptionContext, getPrefetchedUrls, navigateClientSide, prefetchRscResponse } from "./navigation.js";
|
|
17
18
|
import { navigatePagesRouterLink } from "../client/pages-router-link-navigation.js";
|
|
@@ -208,6 +209,7 @@ function prefetchUrl(href, mode, priority = "low") {
|
|
|
208
209
|
const dataTarget = resolvePagesDataNavigationTarget(fullHref, __basePath);
|
|
209
210
|
if (dataTarget) prefetchPagesData(dataTarget);
|
|
210
211
|
else {
|
|
212
|
+
markAppRouteDetectedOnPrefetch(fullHref, __basePath);
|
|
211
213
|
const link = document.createElement("link");
|
|
212
214
|
link.rel = "prefetch";
|
|
213
215
|
link.href = fullHref;
|
|
@@ -334,8 +336,10 @@ function applyLocaleToHref(href, locale) {
|
|
|
334
336
|
}
|
|
335
337
|
return addLocalePrefix(href, resolvedLocale, defaultLocale);
|
|
336
338
|
}
|
|
337
|
-
const Link = forwardRef(function Link({ href, as, replace = false, prefetch: prefetchProp, scroll = true, shallow = false, children, onClick, onMouseEnter, onTouchStart, onNavigate, unstable_dynamicOnHover = false, ...rest }, forwardedRef) {
|
|
339
|
+
const Link = forwardRef(function Link({ href, as, replace = false, prefetch: prefetchProp, scroll = true, shallow = false, children: childrenProp, onClick, onMouseEnter, onTouchStart, onNavigate, unstable_dynamicOnHover = false, legacyBehavior = false, passHref = false, ...rest }, forwardedRef) {
|
|
338
340
|
const { locale, ...restWithoutLocale } = rest;
|
|
341
|
+
let children = childrenProp;
|
|
342
|
+
if (legacyBehavior && (typeof childrenProp === "string" || typeof childrenProp === "number")) children = React.createElement("a", null, childrenProp);
|
|
339
343
|
const rawResolvedHref = as ?? resolveHref(href);
|
|
340
344
|
const resolvedHref = typeof rawResolvedHref === "string" ? warnAndNormalizeRepeatedSlashesInHref(rawResolvedHref) : rawResolvedHref;
|
|
341
345
|
const isDangerous = typeof resolvedHref === "string" && isDangerousScheme(resolvedHref);
|
|
@@ -422,8 +426,8 @@ const Link = forwardRef(function Link({ href, as, replace = false, prefetch: pre
|
|
|
422
426
|
onTouchStart?.(e);
|
|
423
427
|
prefetchOnIntent();
|
|
424
428
|
}, [onTouchStart, prefetchOnIntent]);
|
|
425
|
-
const handleClick = async (e) => {
|
|
426
|
-
if (onClick) onClick(e);
|
|
429
|
+
const handleClick = async (e, options = {}) => {
|
|
430
|
+
if (!options.skipLinkOnClick && onClick) onClick(e);
|
|
427
431
|
if (e.defaultPrevented) return;
|
|
428
432
|
if (e.currentTarget.hasAttribute("download")) return;
|
|
429
433
|
if (e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
|
|
@@ -481,7 +485,7 @@ const Link = forwardRef(function Link({ href, as, replace = false, prefetch: pre
|
|
|
481
485
|
window.dispatchEvent(new PopStateEvent("popstate"));
|
|
482
486
|
}
|
|
483
487
|
};
|
|
484
|
-
const
|
|
488
|
+
const anchorProps = restWithoutLocale;
|
|
485
489
|
const linkStatusValue = React.useMemo(() => ({ pending }), [pending]);
|
|
486
490
|
if (isDangerous) {
|
|
487
491
|
if (process.env.NODE_ENV !== "production") console.warn(`<Link> blocked dangerous href: ${resolvedHref}`);
|
|
@@ -489,6 +493,26 @@ const Link = forwardRef(function Link({ href, as, replace = false, prefetch: pre
|
|
|
489
493
|
if (onClick) onClick(event);
|
|
490
494
|
reportBlockedDangerousNavigation();
|
|
491
495
|
};
|
|
496
|
+
if (legacyBehavior) {
|
|
497
|
+
const child = React.Children.only(children);
|
|
498
|
+
const childOnClick = child.props.onClick;
|
|
499
|
+
const childRef = child.props.ref;
|
|
500
|
+
const setDangerousRefs = (node) => {
|
|
501
|
+
internalRef.current = node;
|
|
502
|
+
if (typeof childRef === "function") childRef(node);
|
|
503
|
+
else if (childRef) childRef.current = node;
|
|
504
|
+
};
|
|
505
|
+
return /* @__PURE__ */ jsx(LinkStatusContext.Provider, {
|
|
506
|
+
value: linkStatusValue,
|
|
507
|
+
children: React.cloneElement(child, {
|
|
508
|
+
ref: setDangerousRefs,
|
|
509
|
+
onClick: (event) => {
|
|
510
|
+
if (childOnClick) childOnClick(event);
|
|
511
|
+
reportBlockedDangerousNavigation();
|
|
512
|
+
}
|
|
513
|
+
})
|
|
514
|
+
});
|
|
515
|
+
}
|
|
492
516
|
return /* @__PURE__ */ jsx(LinkStatusContext.Provider, {
|
|
493
517
|
value: linkStatusValue,
|
|
494
518
|
children: /* @__PURE__ */ jsx("a", {
|
|
@@ -501,6 +525,46 @@ const Link = forwardRef(function Link({ href, as, replace = false, prefetch: pre
|
|
|
501
525
|
})
|
|
502
526
|
});
|
|
503
527
|
}
|
|
528
|
+
if (legacyBehavior) {
|
|
529
|
+
const child = React.Children.only(children);
|
|
530
|
+
if (process.env.NODE_ENV !== "production") {
|
|
531
|
+
if (onClick) console.warn(`"onClick" was passed to <Link> with \`href\` of \`${resolveHref(href)}\` but "legacyBehavior" was set. The legacy behavior requires onClick be set on the child of next/link`);
|
|
532
|
+
if (onMouseEnter) console.warn(`"onMouseEnter" was passed to <Link> with \`href\` of \`${resolveHref(href)}\` but "legacyBehavior" was set. The legacy behavior requires onMouseEnter be set on the child of next/link`);
|
|
533
|
+
}
|
|
534
|
+
const childPropsExisting = child.props;
|
|
535
|
+
const childHasOwnHref = child.type === "a" ? "href" in childPropsExisting : false;
|
|
536
|
+
const shouldForwardHref = passHref || child.type === "a" && !childHasOwnHref;
|
|
537
|
+
const childOnClick = childPropsExisting.onClick;
|
|
538
|
+
const childOnMouseEnter = childPropsExisting.onMouseEnter;
|
|
539
|
+
const childOnTouchStart = childPropsExisting.onTouchStart;
|
|
540
|
+
const childRef = childPropsExisting.ref;
|
|
541
|
+
const setLegacyRefs = (node) => {
|
|
542
|
+
internalRef.current = node;
|
|
543
|
+
if (typeof childRef === "function") childRef(node);
|
|
544
|
+
else if (childRef) childRef.current = node;
|
|
545
|
+
};
|
|
546
|
+
const clonedProps = {
|
|
547
|
+
ref: setLegacyRefs,
|
|
548
|
+
onClick: (event) => {
|
|
549
|
+
if (childOnClick) childOnClick(event);
|
|
550
|
+
if (event.defaultPrevented) return;
|
|
551
|
+
handleClick(event, { skipLinkOnClick: true });
|
|
552
|
+
},
|
|
553
|
+
onMouseEnter: (event) => {
|
|
554
|
+
if (childOnMouseEnter) childOnMouseEnter(event);
|
|
555
|
+
prefetchOnIntent();
|
|
556
|
+
},
|
|
557
|
+
onTouchStart: (event) => {
|
|
558
|
+
if (childOnTouchStart) childOnTouchStart(event);
|
|
559
|
+
prefetchOnIntent();
|
|
560
|
+
}
|
|
561
|
+
};
|
|
562
|
+
if (shouldForwardHref) clonedProps.href = fullHref;
|
|
563
|
+
return /* @__PURE__ */ jsx(LinkStatusContext.Provider, {
|
|
564
|
+
value: linkStatusValue,
|
|
565
|
+
children: React.cloneElement(child, clonedProps)
|
|
566
|
+
});
|
|
567
|
+
}
|
|
504
568
|
return /* @__PURE__ */ jsx(LinkStatusContext.Provider, {
|
|
505
569
|
value: linkStatusValue,
|
|
506
570
|
children: /* @__PURE__ */ jsx("a", {
|