vinext 0.0.10 → 0.0.11
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/cli.js +4 -4
- package/dist/cli.js.map +1 -1
- package/dist/config/config-matchers.d.ts +8 -0
- package/dist/config/config-matchers.d.ts.map +1 -1
- package/dist/config/config-matchers.js +163 -42
- package/dist/config/config-matchers.js.map +1 -1
- package/dist/deploy.d.ts.map +1 -1
- package/dist/deploy.js +6 -4
- package/dist/deploy.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +78 -48
- package/dist/index.js.map +1 -1
- package/dist/server/app-dev-server.d.ts.map +1 -1
- package/dist/server/app-dev-server.js +13 -4
- package/dist/server/app-dev-server.js.map +1 -1
- package/dist/server/dev-server.d.ts.map +1 -1
- package/dist/server/dev-server.js +13 -2
- package/dist/server/dev-server.js.map +1 -1
- package/dist/server/middleware-codegen.d.ts.map +1 -1
- package/dist/server/middleware-codegen.js +13 -7
- package/dist/server/middleware-codegen.js.map +1 -1
- package/dist/server/middleware.d.ts.map +1 -1
- package/dist/server/middleware.js +25 -12
- package/dist/server/middleware.js.map +1 -1
- package/dist/server/prod-server.d.ts.map +1 -1
- package/dist/server/prod-server.js +6 -1
- package/dist/server/prod-server.js.map +1 -1
- package/dist/shims/fetch-cache.d.ts.map +1 -1
- package/dist/shims/fetch-cache.js +6 -0
- package/dist/shims/fetch-cache.js.map +1 -1
- package/dist/shims/head.d.ts.map +1 -1
- package/dist/shims/head.js +4 -1
- package/dist/shims/head.js.map +1 -1
- package/dist/shims/headers.d.ts.map +1 -1
- package/dist/shims/headers.js +4 -2
- package/dist/shims/headers.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prod-server.js","sourceRoot":"","sources":["../../src/server/prod-server.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Production server for vinext.\n *\n * Serves the built output from `vinext build`. Handles:\n * - Static asset serving from client build output\n * - Pages Router: SSR rendering + API route handling\n * - App Router: RSC/SSR rendering, route handlers, server actions\n * - Gzip/Brotli compression for text-based responses\n * - Streaming SSR for App Router\n *\n * Build output for Pages Router:\n * - dist/client/ — static assets (JS, CSS, images) + .vite/ssr-manifest.json\n * - dist/server/entry.js — SSR entry point (virtual:vinext-server-entry)\n *\n * Build output for App Router:\n * - dist/client/ — static assets (JS, CSS, images)\n * - dist/server/index.js — RSC entry (default export: handler(Request) → Response)\n * - dist/server/ssr/index.js — SSR entry (imported by RSC entry at runtime)\n */\nimport { createServer, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport { Readable, pipeline } from \"node:stream\";\nimport { pathToFileURL } from \"node:url\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport zlib from \"node:zlib\";\nimport { matchRedirect, matchRewrite, matchHeaders, requestContextFromRequest, isExternalUrl, proxyExternalRequest, sanitizeDestination } from \"../config/config-matchers.js\";\nimport type { RequestContext } from \"../config/config-matchers.js\";\nimport { IMAGE_OPTIMIZATION_PATH, IMAGE_CONTENT_SECURITY_POLICY, parseImageParams, isSafeImageContentType, DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES } from \"./image-optimization.js\";\nimport { normalizePath } from \"./normalize-path.js\";\nimport { computeLazyChunks } from \"../index.js\";\n\n/** Convert a Node.js IncomingMessage into a ReadableStream for Web Request body. */\nfunction readNodeStream(req: IncomingMessage): ReadableStream<Uint8Array> {\n return new ReadableStream({\n start(controller) {\n req.on(\"data\", (chunk: Buffer) => controller.enqueue(new Uint8Array(chunk)));\n req.on(\"end\", () => controller.close());\n req.on(\"error\", (err) => controller.error(err));\n },\n });\n}\n\nexport interface ProdServerOptions {\n /** Port to listen on */\n port?: number;\n /** Host to bind to */\n host?: string;\n /** Path to the build output directory */\n outDir?: string;\n /** Disable compression (default: false) */\n noCompression?: boolean;\n}\n\n/** Content types that benefit from compression. */\nconst COMPRESSIBLE_TYPES = new Set([\n \"text/html\",\n \"text/css\",\n \"text/plain\",\n \"text/xml\",\n \"text/javascript\",\n \"application/javascript\",\n \"application/json\",\n \"application/xml\",\n \"application/xhtml+xml\",\n \"application/rss+xml\",\n \"application/atom+xml\",\n \"image/svg+xml\",\n \"application/manifest+json\",\n \"application/wasm\",\n]);\n\n/** Minimum size threshold for compression (in bytes). Below this, compression overhead isn't worth it. */\nconst COMPRESS_THRESHOLD = 1024;\n\n/**\n * Parse the Accept-Encoding header and return the best supported encoding.\n * Preference order: br > gzip > deflate > identity.\n */\nfunction negotiateEncoding(req: IncomingMessage): \"br\" | \"gzip\" | \"deflate\" | null {\n const accept = req.headers[\"accept-encoding\"];\n if (!accept || typeof accept !== \"string\") return null;\n const lower = accept.toLowerCase();\n if (lower.includes(\"br\")) return \"br\";\n if (lower.includes(\"gzip\")) return \"gzip\";\n if (lower.includes(\"deflate\")) return \"deflate\";\n return null;\n}\n\n/**\n * Create a compression stream for the given encoding.\n */\nfunction createCompressor(encoding: \"br\" | \"gzip\" | \"deflate\"): zlib.BrotliCompress | zlib.Gzip | zlib.Deflate {\n switch (encoding) {\n case \"br\":\n return zlib.createBrotliCompress({\n params: {\n [zlib.constants.BROTLI_PARAM_QUALITY]: 4, // Fast compression (1-11, 4 is a good balance)\n },\n });\n case \"gzip\":\n return zlib.createGzip({ level: 6 }); // Default level, good balance\n case \"deflate\":\n return zlib.createDeflate({ level: 6 });\n }\n}\n\n/**\n * Send a compressed response if the content type is compressible and the\n * client supports compression. Otherwise send uncompressed.\n */\nfunction sendCompressed(\n req: IncomingMessage,\n res: ServerResponse,\n body: string | Buffer,\n contentType: string,\n statusCode: number,\n extraHeaders: Record<string, string> = {},\n compress: boolean = true,\n): void {\n const buf = typeof body === \"string\" ? Buffer.from(body) : body;\n const baseType = contentType.split(\";\")[0].trim();\n const encoding = compress ? negotiateEncoding(req) : null;\n\n if (encoding && COMPRESSIBLE_TYPES.has(baseType) && buf.length >= COMPRESS_THRESHOLD) {\n const compressor = createCompressor(encoding);\n // Merge Accept-Encoding into existing Vary header from extraHeaders instead\n // of overwriting. Preserves Vary values set by the App Router for content\n // negotiation (e.g. \"RSC, Accept\").\n const existingVary = extraHeaders[\"Vary\"] ?? extraHeaders[\"vary\"];\n let varyValue: string;\n if (existingVary) {\n const existing = String(existingVary).toLowerCase();\n varyValue = existing.includes(\"accept-encoding\") ? String(existingVary) : existingVary + \", Accept-Encoding\";\n } else {\n varyValue = \"Accept-Encoding\";\n }\n res.writeHead(statusCode, {\n ...extraHeaders,\n \"Content-Type\": contentType,\n \"Content-Encoding\": encoding,\n Vary: varyValue,\n });\n compressor.end(buf);\n pipeline(compressor, res, () => { /* ignore pipeline errors on closed connections */ });\n } else {\n res.writeHead(statusCode, {\n ...extraHeaders,\n \"Content-Type\": contentType,\n \"Content-Length\": String(buf.length),\n });\n res.end(buf);\n }\n}\n\n/** Content-type lookup for static assets. */\nconst CONTENT_TYPES: Record<string, string> = {\n \".js\": \"application/javascript\",\n \".mjs\": \"application/javascript\",\n \".css\": \"text/css\",\n \".html\": \"text/html\",\n \".json\": \"application/json\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".svg\": \"image/svg+xml\",\n \".ico\": \"image/x-icon\",\n \".woff\": \"font/woff\",\n \".woff2\": \"font/woff2\",\n \".ttf\": \"font/ttf\",\n \".eot\": \"application/vnd.ms-fontobject\",\n \".webp\": \"image/webp\",\n \".avif\": \"image/avif\",\n \".map\": \"application/json\",\n};\n\n/**\n * Try to serve a static file from the client build directory.\n * Returns true if the file was served, false otherwise.\n */\nfunction tryServeStatic(\n req: IncomingMessage,\n res: ServerResponse,\n clientDir: string,\n pathname: string,\n compress: boolean,\n extraHeaders?: Record<string, string>,\n): boolean {\n // Resolve the path and guard against directory traversal (e.g. /../../../etc/passwd)\n const resolvedClient = path.resolve(clientDir);\n let decodedPathname: string;\n try {\n decodedPathname = decodeURIComponent(pathname);\n } catch {\n return false;\n }\n const staticFile = path.resolve(clientDir, \".\" + decodedPathname);\n if (!staticFile.startsWith(resolvedClient + path.sep) && staticFile !== resolvedClient) {\n return false;\n }\n if (\n pathname === \"/\" ||\n !fs.existsSync(staticFile) ||\n !fs.statSync(staticFile).isFile()\n ) {\n return false;\n }\n\n const ext = path.extname(staticFile);\n const ct = CONTENT_TYPES[ext] ?? \"application/octet-stream\";\n const isHashed = pathname.startsWith(\"/assets/\");\n const cacheControl = isHashed\n ? \"public, max-age=31536000, immutable\"\n : \"public, max-age=3600\";\n\n const baseHeaders = {\n \"Content-Type\": ct,\n \"Cache-Control\": cacheControl,\n ...extraHeaders,\n };\n\n const baseType = ct.split(\";\")[0].trim();\n if (compress && COMPRESSIBLE_TYPES.has(baseType)) {\n const encoding = negotiateEncoding(req);\n if (encoding) {\n const fileStream = fs.createReadStream(staticFile);\n const compressor = createCompressor(encoding);\n res.writeHead(200, {\n ...baseHeaders,\n \"Content-Encoding\": encoding,\n Vary: \"Accept-Encoding\",\n });\n pipeline(fileStream, compressor, res, () => { /* ignore */ });\n return true;\n }\n }\n\n res.writeHead(200, baseHeaders);\n fs.createReadStream(staticFile).pipe(res);\n return true;\n}\n\n/**\n * Resolve the host for a request, ignoring X-Forwarded-Host to prevent\n * host header poisoning attacks (open redirects, cache poisoning).\n *\n * X-Forwarded-Host is only trusted when the VINEXT_TRUSTED_HOSTS env var\n * lists the forwarded host value. Without this, an attacker can send\n * X-Forwarded-Host: evil.com and poison any redirect that resolves\n * against request.url.\n *\n * On Cloudflare Workers, X-Forwarded-Host is always set by Cloudflare\n * itself, so this is only a concern for the Node.js prod-server.\n */\nfunction resolveHost(req: IncomingMessage, fallback: string): string {\n const rawForwarded = req.headers[\"x-forwarded-host\"] as string | undefined;\n const hostHeader = req.headers.host;\n\n if (rawForwarded) {\n // X-Forwarded-Host can be comma-separated when passing through\n // multiple proxies — take only the first (client-facing) value.\n const forwardedHost = rawForwarded.split(\",\")[0].trim().toLowerCase();\n if (forwardedHost && trustedHosts.has(forwardedHost)) {\n return forwardedHost;\n }\n }\n\n return hostHeader || fallback;\n}\n\n/** Hosts that are allowed as X-Forwarded-Host values (stored lowercase). */\nconst trustedHosts: Set<string> = new Set(\n (process.env.VINEXT_TRUSTED_HOSTS ?? \"\")\n .split(\",\")\n .map((h) => h.trim().toLowerCase())\n .filter(Boolean),\n);\n\n/**\n * Whether to trust X-Forwarded-Proto from upstream proxies.\n * Enabled when VINEXT_TRUST_PROXY=1 or when VINEXT_TRUSTED_HOSTS is set\n * (having trusted hosts implies a trusted proxy).\n */\nconst trustProxy = process.env.VINEXT_TRUST_PROXY === \"1\" || trustedHosts.size > 0;\n\n/**\n * Convert a Node.js IncomingMessage to a Web Request object.\n */\nfunction nodeToWebRequest(req: IncomingMessage): Request {\n const rawProto = trustProxy\n ? (req.headers[\"x-forwarded-proto\"] as string)?.split(\",\")[0]?.trim()\n : undefined;\n const proto = rawProto === \"https\" || rawProto === \"http\" ? rawProto : \"http\";\n const host = resolveHost(req, \"localhost\");\n const origin = `${proto}://${host}`;\n const url = new URL(req.url ?? \"/\", origin);\n\n const headers = new Headers();\n for (const [key, value] of Object.entries(req.headers)) {\n if (value === undefined) continue;\n if (Array.isArray(value)) {\n for (const v of value) headers.append(key, v);\n } else {\n headers.set(key, value);\n }\n }\n\n const method = req.method ?? \"GET\";\n const hasBody = method !== \"GET\" && method !== \"HEAD\";\n\n const init: RequestInit & { duplex?: string } = {\n method,\n headers,\n };\n\n if (hasBody) {\n // Convert Node.js readable stream to Web ReadableStream for request body.\n // Readable.toWeb() is available since Node.js 17.\n init.body = Readable.toWeb(req) as ReadableStream;\n init.duplex = \"half\"; // Required for streaming request bodies\n }\n\n return new Request(url, init);\n}\n\n/**\n * Stream a Web Response back to a Node.js ServerResponse.\n * Supports streaming compression for SSR responses.\n */\nasync function sendWebResponse(\n webResponse: Response,\n req: IncomingMessage,\n res: ServerResponse,\n compress: boolean,\n): Promise<void> {\n const status = webResponse.status;\n\n // Collect headers, handling multi-value headers (e.g. Set-Cookie)\n const nodeHeaders: Record<string, string | string[]> = {};\n webResponse.headers.forEach((value, key) => {\n const existing = nodeHeaders[key];\n if (existing !== undefined) {\n nodeHeaders[key] = Array.isArray(existing)\n ? [...existing, value]\n : [existing, value];\n } else {\n nodeHeaders[key] = value;\n }\n });\n\n if (!webResponse.body) {\n res.writeHead(status, nodeHeaders);\n res.end();\n return;\n }\n\n // Check if we should compress the response.\n // Skip if the upstream already compressed (avoid double-compression).\n const alreadyEncoded = webResponse.headers.has(\"content-encoding\");\n const contentType = webResponse.headers.get(\"content-type\") ?? \"\";\n const baseType = contentType.split(\";\")[0].trim();\n const encoding = (compress && !alreadyEncoded) ? negotiateEncoding(req) : null;\n const shouldCompress = !!(encoding && COMPRESSIBLE_TYPES.has(baseType));\n\n if (shouldCompress) {\n delete nodeHeaders[\"content-length\"];\n delete nodeHeaders[\"Content-Length\"];\n nodeHeaders[\"Content-Encoding\"] = encoding!;\n // Merge Accept-Encoding into existing Vary header (e.g. \"RSC, Accept\") instead\n // of overwriting. This prevents stripping the Vary values that the App Router\n // sets for content negotiation (RSC stream vs HTML).\n const existingVary = nodeHeaders[\"Vary\"] ?? nodeHeaders[\"vary\"];\n if (existingVary) {\n const existing = String(existingVary).toLowerCase();\n if (!existing.includes(\"accept-encoding\")) {\n nodeHeaders[\"Vary\"] = existingVary + \", Accept-Encoding\";\n }\n } else {\n nodeHeaders[\"Vary\"] = \"Accept-Encoding\";\n }\n }\n\n res.writeHead(status, nodeHeaders);\n\n // HEAD requests: send headers only, skip the body\n if (req.method === \"HEAD\") {\n res.end();\n return;\n }\n\n // Convert Web ReadableStream to Node.js Readable and pipe to response.\n // Readable.fromWeb() is available since Node.js 17.\n const nodeStream = Readable.fromWeb(webResponse.body as import(\"stream/web\").ReadableStream);\n\n if (shouldCompress) {\n const compressor = createCompressor(encoding!);\n pipeline(nodeStream, compressor, res, () => { /* ignore pipeline errors on closed connections */ });\n } else {\n pipeline(nodeStream, res, () => { /* ignore pipeline errors on closed connections */ });\n }\n}\n\n/**\n * Start the production server.\n *\n * Automatically detects whether the build is App Router (dist/server/index.js) or\n * Pages Router (dist/server/entry.js) and configures the appropriate handler.\n */\nexport async function startProdServer(options: ProdServerOptions = {}) {\n const {\n port = process.env.PORT ? parseInt(process.env.PORT) : 3000,\n host = \"0.0.0.0\",\n outDir = path.resolve(\"dist\"),\n noCompression = false,\n } = options;\n\n const compress = !noCompression;\n // Always resolve outDir to absolute to ensure dynamic import() works\n const resolvedOutDir = path.resolve(outDir);\n const clientDir = path.join(resolvedOutDir, \"client\");\n\n // Detect build type\n const rscEntryPath = path.join(resolvedOutDir, \"server\", \"index.js\");\n const serverEntryPath = path.join(resolvedOutDir, \"server\", \"entry.js\");\n const isAppRouter = fs.existsSync(rscEntryPath);\n\n if (!isAppRouter && !fs.existsSync(serverEntryPath)) {\n console.error(`[vinext] No build output found in ${outDir}`);\n console.error(\"Run `vinext build` first.\");\n process.exit(1);\n }\n\n if (isAppRouter) {\n return startAppRouterServer({ port, host, clientDir, rscEntryPath, compress });\n }\n\n return startPagesRouterServer({ port, host, clientDir, serverEntryPath, compress });\n}\n\n// ─── App Router Production Server ─────────────────────────────────────────────\n\ninterface AppRouterServerOptions {\n port: number;\n host: string;\n clientDir: string;\n rscEntryPath: string;\n compress: boolean;\n}\n\n/**\n * Start the App Router production server.\n *\n * The RSC entry (dist/server/index.js) exports a default handler function:\n * handler(request: Request) → Promise<Response>\n *\n * This handler already does everything: route matching, RSC rendering,\n * SSR HTML generation (via import(\"./ssr/index.js\")), route handlers,\n * server actions, ISR caching, 404s, redirects, etc.\n *\n * The production server's job is simply to:\n * 1. Serve static assets from dist/client/\n * 2. Convert Node.js IncomingMessage → Web Request\n * 3. Call the RSC handler\n * 4. Stream the Web Response back (with optional compression)\n */\nasync function startAppRouterServer(options: AppRouterServerOptions) {\n const { port, host, clientDir, rscEntryPath, compress } = options;\n\n // Import the RSC handler (use file:// URL for reliable dynamic import)\n const rscModule = await import(pathToFileURL(rscEntryPath).href);\n const rscHandler: (request: Request) => Promise<Response> = rscModule.default;\n\n if (typeof rscHandler !== \"function\") {\n console.error(\"[vinext] RSC entry does not export a default handler function\");\n process.exit(1);\n }\n\n const server = createServer(async (req, res) => {\n const url = req.url ?? \"/\";\n // Normalize backslashes (browsers treat /\\ as //), then decode and normalize path.\n const rawPathname = url.split(\"?\")[0].replaceAll(\"\\\\\", \"/\");\n const pathname = normalizePath(decodeURIComponent(rawPathname));\n\n // Guard against protocol-relative URL open redirect attacks.\n // Check rawPathname before normalizePath collapses //.\n if (rawPathname.startsWith(\"//\")) {\n res.writeHead(404);\n res.end(\"404 Not Found\");\n return;\n }\n\n // Serve static assets from client build\n if (pathname !== \"/\" && tryServeStatic(req, res, clientDir, pathname, compress)) {\n return;\n }\n\n // Image optimization passthrough (Node.js prod server has no Images binding;\n // serves the original file with cache headers and security headers)\n if (pathname === IMAGE_OPTIMIZATION_PATH) {\n const parsedUrl = new URL(url, \"http://localhost\");\n const defaultAllowedWidths = [...DEFAULT_DEVICE_SIZES, ...DEFAULT_IMAGE_SIZES];\n const params = parseImageParams(parsedUrl, defaultAllowedWidths);\n if (!params) {\n res.writeHead(400);\n res.end(\"Bad Request\");\n return;\n }\n // Block SVG and other unsafe content types by checking the file extension.\n // This must happen before serving to prevent XSS via SVG passthrough.\n const ext = path.extname(params.imageUrl).toLowerCase();\n const ct = CONTENT_TYPES[ext] ?? \"application/octet-stream\";\n if (!isSafeImageContentType(ct)) {\n res.writeHead(400);\n res.end(\"The requested resource is not an allowed image type\");\n return;\n }\n // Serve the original image with CSP and security headers\n const imageSecurityHeaders: Record<string, string> = {\n \"Content-Security-Policy\": IMAGE_CONTENT_SECURITY_POLICY,\n \"X-Content-Type-Options\": \"nosniff\",\n \"Content-Disposition\": \"inline\",\n };\n if (tryServeStatic(req, res, clientDir, params.imageUrl, false, imageSecurityHeaders)) {\n return;\n }\n res.writeHead(404);\n res.end(\"Image not found\");\n return;\n }\n\n try {\n // Convert Node.js request to Web Request and call the RSC handler\n const request = nodeToWebRequest(req);\n const response = await rscHandler(request);\n\n // Stream the Web Response back to the Node.js response\n await sendWebResponse(response, req, res, compress);\n } catch (e) {\n console.error(\"[vinext] Server error:\", e);\n if (!res.headersSent) {\n res.writeHead(500);\n res.end(\"Internal Server Error\");\n }\n }\n });\n\n await new Promise<void>((resolve) => {\n server.listen(port, host, () => {\n const addr = server.address();\n const actualPort = typeof addr === \"object\" && addr ? addr.port : port;\n console.log(`[vinext] Production server running at http://${host}:${actualPort}`);\n resolve();\n });\n });\n\n return server;\n}\n\n// ─── Pages Router Production Server ───────────────────────────────────────────\n\ninterface PagesRouterServerOptions {\n port: number;\n host: string;\n clientDir: string;\n serverEntryPath: string;\n compress: boolean;\n}\n\n/**\n * Start the Pages Router production server.\n *\n * Uses the server entry (dist/server/entry.js) which exports:\n * - renderPage(request, url, manifest) — SSR rendering (Web Request → Response)\n * - handleApiRoute(request, url) — API route handling (Web Request → Response)\n * - runMiddleware(request) — middleware execution\n * - vinextConfig — embedded next.config.js settings\n */\nasync function startPagesRouterServer(options: PagesRouterServerOptions) {\n const { port, host, clientDir, serverEntryPath, compress } = options;\n\n // Load the SSR manifest (maps module URLs to client asset URLs)\n let ssrManifest: Record<string, string[]> = {};\n const manifestPath = path.join(clientDir, \".vite\", \"ssr-manifest.json\");\n if (fs.existsSync(manifestPath)) {\n ssrManifest = JSON.parse(fs.readFileSync(manifestPath, \"utf-8\"));\n }\n\n // Load the build manifest to compute lazy chunks — chunks only reachable via\n // dynamic imports (React.lazy, next/dynamic). These should not be\n // modulepreloaded since they are fetched on demand.\n const buildManifestPath = path.join(clientDir, \".vite\", \"manifest.json\");\n if (fs.existsSync(buildManifestPath)) {\n try {\n const buildManifest = JSON.parse(fs.readFileSync(buildManifestPath, \"utf-8\"));\n const lazyChunks = computeLazyChunks(buildManifest);\n if (lazyChunks.length > 0) {\n (globalThis as any).__VINEXT_LAZY_CHUNKS__ = lazyChunks;\n }\n } catch { /* ignore parse errors */ }\n }\n\n // Import the server entry module (use file:// URL for reliable dynamic import)\n const serverEntry = await import(pathToFileURL(serverEntryPath).href);\n const { renderPage, handleApiRoute: handleApi, runMiddleware, vinextConfig } = serverEntry;\n\n // Extract config values (embedded at build time in the server entry)\n const basePath: string = vinextConfig?.basePath ?? \"\";\n const trailingSlash: boolean = vinextConfig?.trailingSlash ?? false;\n const configRedirects = vinextConfig?.redirects ?? [];\n const configRewrites = vinextConfig?.rewrites ?? { beforeFiles: [], afterFiles: [], fallback: [] };\n const configHeaders = vinextConfig?.headers ?? [];\n // Compute allowed image widths from config (union of deviceSizes + imageSizes)\n const allowedImageWidths: number[] = [\n ...(vinextConfig?.images?.deviceSizes ?? DEFAULT_DEVICE_SIZES),\n ...(vinextConfig?.images?.imageSizes ?? DEFAULT_IMAGE_SIZES),\n ];\n\n const server = createServer(async (req, res) => {\n const rawUrl = req.url ?? \"/\";\n let url = rawUrl;\n // Normalize backslashes (browsers treat /\\ as //), then decode and normalize path.\n const rawPagesPathname = url.split(\"?\")[0].replaceAll(\"\\\\\", \"/\");\n let pathname = normalizePath(decodeURIComponent(rawPagesPathname));\n\n // Guard against protocol-relative URL open redirect attacks.\n // Check rawPagesPathname before normalizePath collapses //.\n if (rawPagesPathname.startsWith(\"//\")) {\n res.writeHead(404);\n res.end(\"404 Not Found\");\n return;\n }\n\n // ── 1. Static assets ──────────────────────────────────────────\n // Serve static files from client build. When basePath is configured,\n // Vite's `base` config ensures assets are under basePath/assets/.\n // We check both with and without basePath.\n const staticLookupPath = basePath && pathname.startsWith(basePath)\n ? pathname.slice(basePath.length) || \"/\"\n : pathname;\n if (\n staticLookupPath !== \"/\" &&\n !staticLookupPath.startsWith(\"/api/\") &&\n tryServeStatic(req, res, clientDir, staticLookupPath, compress)\n ) {\n return;\n }\n\n // ── Image optimization passthrough ──────────────────────────────\n if (pathname === IMAGE_OPTIMIZATION_PATH || staticLookupPath === IMAGE_OPTIMIZATION_PATH) {\n const parsedUrl = new URL(rawUrl, \"http://localhost\");\n const params = parseImageParams(parsedUrl, allowedImageWidths);\n if (!params) {\n res.writeHead(400);\n res.end(\"Bad Request\");\n return;\n }\n // Block SVG and other unsafe content types\n const ext = path.extname(params.imageUrl).toLowerCase();\n const ct = CONTENT_TYPES[ext] ?? \"application/octet-stream\";\n if (!isSafeImageContentType(ct)) {\n res.writeHead(400);\n res.end(\"The requested resource is not an allowed image type\");\n return;\n }\n const imageSecurityHeaders: Record<string, string> = {\n \"Content-Security-Policy\": IMAGE_CONTENT_SECURITY_POLICY,\n \"X-Content-Type-Options\": \"nosniff\",\n \"Content-Disposition\": \"inline\",\n };\n if (tryServeStatic(req, res, clientDir, params.imageUrl, false, imageSecurityHeaders)) {\n return;\n }\n res.writeHead(404);\n res.end(\"Image not found\");\n return;\n }\n\n try {\n // ── 2. Strip basePath ─────────────────────────────────────────\n if (basePath && pathname.startsWith(basePath)) {\n const stripped = pathname.slice(basePath.length) || \"/\";\n const qs = url.includes(\"?\") ? url.slice(url.indexOf(\"?\")) : \"\";\n url = stripped + qs;\n pathname = stripped;\n }\n\n // ── 3. Trailing slash normalization ───────────────────────────\n if (pathname !== \"/\" && !pathname.startsWith(\"/api\")) {\n const hasTrailing = pathname.endsWith(\"/\");\n if (trailingSlash && !hasTrailing) {\n const qs = url.includes(\"?\") ? url.slice(url.indexOf(\"?\")) : \"\";\n res.writeHead(308, { Location: basePath + pathname + \"/\" + qs });\n res.end();\n return;\n } else if (!trailingSlash && hasTrailing) {\n const qs = url.includes(\"?\") ? url.slice(url.indexOf(\"?\")) : \"\";\n res.writeHead(308, { Location: basePath + pathname.replace(/\\/+$/, \"\") + qs });\n res.end();\n return;\n }\n }\n\n // Convert Node.js req to Web Request for the server entry\n const rawProtocol = trustProxy\n ? (req.headers[\"x-forwarded-proto\"] as string)?.split(\",\")[0]?.trim()\n : undefined;\n const protocol = rawProtocol === \"https\" || rawProtocol === \"http\" ? rawProtocol : \"http\";\n const hostHeader = resolveHost(req, `${host}:${port}`);\n const reqHeaders = Object.entries(req.headers).reduce((h, [k, v]) => {\n if (v) h.set(k, Array.isArray(v) ? v.join(\", \") : v);\n return h;\n }, new Headers());\n const method = req.method ?? \"GET\";\n const hasBody = method !== \"GET\" && method !== \"HEAD\";\n const webRequest = new Request(`${protocol}://${hostHeader}${url}`, {\n method,\n headers: reqHeaders,\n body: hasBody ? readNodeStream(req) : undefined,\n // @ts-expect-error — duplex needed for streaming request bodies\n duplex: hasBody ? \"half\" : undefined,\n });\n\n // Build request context for has/missing condition matching\n const reqCtx: RequestContext = requestContextFromRequest(webRequest);\n\n // ── 4. Run middleware ─────────────────────────────────────────\n let resolvedUrl = url;\n const middlewareHeaders: Record<string, string> = {};\n let middlewareRewriteStatus: number | undefined;\n if (typeof runMiddleware === \"function\") {\n const result = await runMiddleware(webRequest);\n\n if (!result.continue) {\n if (result.redirectUrl) {\n res.writeHead(result.redirectStatus ?? 307, {\n Location: result.redirectUrl,\n });\n res.end();\n return;\n }\n if (result.response) {\n // Use arrayBuffer() to handle binary response bodies correctly\n const body = Buffer.from(await result.response.arrayBuffer());\n res.writeHead(result.response.status, Object.fromEntries(result.response.headers));\n res.end(body);\n return;\n }\n }\n\n // Collect middleware response headers to merge into final response\n if (result.responseHeaders) {\n for (const [key, value] of result.responseHeaders) {\n middlewareHeaders[key] = value;\n }\n }\n\n // Apply middleware rewrite\n if (result.rewriteUrl) {\n resolvedUrl = result.rewriteUrl;\n }\n\n // Apply custom status code from middleware rewrite\n // (e.g. NextResponse.rewrite(url, { status: 403 }))\n middlewareRewriteStatus = result.rewriteStatus;\n }\n\n // Unpack x-middleware-request-* headers into the actual request so that\n // renderPage / handleApiRoute see the middleware-modified headers.\n // Also remove them from middlewareHeaders to prevent leaking as response headers.\n const mwReqPrefix = \"x-middleware-request-\";\n for (const key of Object.keys(middlewareHeaders)) {\n if (key.startsWith(mwReqPrefix)) {\n const realName = key.slice(mwReqPrefix.length);\n webRequest.headers.set(realName, middlewareHeaders[key]);\n delete middlewareHeaders[key];\n }\n }\n\n let resolvedPathname = resolvedUrl.split(\"?\")[0];\n\n // ── 5. Apply custom headers from next.config.js ───────────────\n if (configHeaders.length) {\n const matched = matchHeaders(resolvedPathname, configHeaders);\n for (const h of matched) {\n middlewareHeaders[h.key.toLowerCase()] = h.value;\n }\n }\n\n // ── 6. Apply redirects from next.config.js ────────────────────\n if (configRedirects.length) {\n const redirect = matchRedirect(resolvedPathname, configRedirects, reqCtx);\n if (redirect) {\n // Guard against double-prefixing: only add basePath if destination\n // doesn't already start with it.\n // Sanitize the final destination to prevent protocol-relative URL open redirects.\n const dest = sanitizeDestination(\n basePath && !redirect.destination.startsWith(basePath)\n ? basePath + redirect.destination\n : redirect.destination,\n );\n res.writeHead(redirect.permanent ? 308 : 307, { Location: dest });\n res.end();\n return;\n }\n }\n\n // ── 7. Apply beforeFiles rewrites from next.config.js ─────────\n if (configRewrites.beforeFiles?.length) {\n const rewritten = matchRewrite(resolvedPathname, configRewrites.beforeFiles, reqCtx);\n if (rewritten) {\n if (isExternalUrl(rewritten)) {\n const proxyResponse = await proxyExternalRequest(webRequest, rewritten);\n await sendWebResponse(proxyResponse, req, res, compress);\n return;\n }\n resolvedUrl = rewritten;\n resolvedPathname = rewritten.split(\"?\")[0];\n }\n }\n\n // ── 8. API routes ─────────────────────────────────────────────\n if (resolvedPathname.startsWith(\"/api/\") || resolvedPathname === \"/api\") {\n let response: Response;\n if (typeof handleApi === \"function\") {\n response = await handleApi(webRequest, resolvedUrl);\n } else {\n response = new Response(\"404 - API route not found\", { status: 404 });\n }\n\n // Merge middleware + config headers into the response\n const responseBody = Buffer.from(await response.arrayBuffer());\n const ct = response.headers.get(\"content-type\") ?? \"text/html\";\n const responseHeaders: Record<string, string> = { ...middlewareHeaders };\n response.headers.forEach((v, k) => { responseHeaders[k] = v; });\n\n sendCompressed(req, res, responseBody, ct, middlewareRewriteStatus ?? response.status, responseHeaders, compress);\n return;\n }\n\n // ── 9. Apply afterFiles rewrites from next.config.js ──────────\n if (configRewrites.afterFiles?.length) {\n const rewritten = matchRewrite(resolvedPathname, configRewrites.afterFiles, reqCtx);\n if (rewritten) {\n if (isExternalUrl(rewritten)) {\n const proxyResponse = await proxyExternalRequest(webRequest, rewritten);\n await sendWebResponse(proxyResponse, req, res, compress);\n return;\n }\n resolvedUrl = rewritten;\n resolvedPathname = rewritten.split(\"?\")[0];\n }\n }\n\n // ── 10. SSR page rendering ────────────────────────────────────\n let response: Response | undefined;\n if (typeof renderPage === \"function\") {\n response = await renderPage(webRequest, resolvedUrl, ssrManifest);\n\n // ── 11. Fallback rewrites (if SSR returned 404) ─────────────\n if (response && response.status === 404 && configRewrites.fallback?.length) {\n const fallbackRewrite = matchRewrite(resolvedPathname, configRewrites.fallback, reqCtx);\n if (fallbackRewrite) {\n if (isExternalUrl(fallbackRewrite)) {\n const proxyResponse = await proxyExternalRequest(webRequest, fallbackRewrite);\n await sendWebResponse(proxyResponse, req, res, compress);\n return;\n }\n response = await renderPage(webRequest, fallbackRewrite, ssrManifest);\n }\n }\n }\n\n if (!response) {\n res.writeHead(404);\n res.end(\"404 - Not found\");\n return;\n }\n\n // Merge middleware + config headers into the response\n const responseBody = Buffer.from(await response.arrayBuffer());\n const ct = response.headers.get(\"content-type\") ?? \"text/html\";\n const responseHeaders: Record<string, string> = { ...middlewareHeaders };\n response.headers.forEach((v, k) => { responseHeaders[k] = v; });\n\n sendCompressed(req, res, responseBody, ct, middlewareRewriteStatus ?? response.status, responseHeaders, compress);\n } catch (e) {\n console.error(\"[vinext] Server error:\", e);\n res.writeHead(500);\n res.end(\"Internal Server Error\");\n }\n });\n\n await new Promise<void>((resolve) => {\n server.listen(port, host, () => {\n const addr = server.address();\n const actualPort = typeof addr === \"object\" && addr ? addr.port : port;\n console.log(`[vinext] Production server running at http://${host}:${actualPort}`);\n resolve();\n });\n });\n\n return server;\n}\n\n// Export helpers for testing\nexport { sendCompressed, negotiateEncoding, COMPRESSIBLE_TYPES, COMPRESS_THRESHOLD, resolveHost, trustedHosts, trustProxy, nodeToWebRequest };\n"]}
|
|
1
|
+
{"version":3,"file":"prod-server.js","sourceRoot":"","sources":["../../src/server/prod-server.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Production server for vinext.\n *\n * Serves the built output from `vinext build`. Handles:\n * - Static asset serving from client build output\n * - Pages Router: SSR rendering + API route handling\n * - App Router: RSC/SSR rendering, route handlers, server actions\n * - Gzip/Brotli compression for text-based responses\n * - Streaming SSR for App Router\n *\n * Build output for Pages Router:\n * - dist/client/ — static assets (JS, CSS, images) + .vite/ssr-manifest.json\n * - dist/server/entry.js — SSR entry point (virtual:vinext-server-entry)\n *\n * Build output for App Router:\n * - dist/client/ — static assets (JS, CSS, images)\n * - dist/server/index.js — RSC entry (default export: handler(Request) → Response)\n * - dist/server/ssr/index.js — SSR entry (imported by RSC entry at runtime)\n */\nimport { createServer, type IncomingMessage, type ServerResponse } from \"node:http\";\nimport { Readable, pipeline } from \"node:stream\";\nimport { pathToFileURL } from \"node:url\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport zlib from \"node:zlib\";\nimport { matchRedirect, matchRewrite, matchHeaders, requestContextFromRequest, isExternalUrl, proxyExternalRequest, sanitizeDestination } from \"../config/config-matchers.js\";\nimport type { RequestContext } from \"../config/config-matchers.js\";\nimport { IMAGE_OPTIMIZATION_PATH, IMAGE_CONTENT_SECURITY_POLICY, parseImageParams, isSafeImageContentType, DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES } from \"./image-optimization.js\";\nimport { normalizePath } from \"./normalize-path.js\";\nimport { computeLazyChunks } from \"../index.js\";\n\n/** Convert a Node.js IncomingMessage into a ReadableStream for Web Request body. */\nfunction readNodeStream(req: IncomingMessage): ReadableStream<Uint8Array> {\n return new ReadableStream({\n start(controller) {\n req.on(\"data\", (chunk: Buffer) => controller.enqueue(new Uint8Array(chunk)));\n req.on(\"end\", () => controller.close());\n req.on(\"error\", (err) => controller.error(err));\n },\n });\n}\n\nexport interface ProdServerOptions {\n /** Port to listen on */\n port?: number;\n /** Host to bind to */\n host?: string;\n /** Path to the build output directory */\n outDir?: string;\n /** Disable compression (default: false) */\n noCompression?: boolean;\n}\n\n/** Content types that benefit from compression. */\nconst COMPRESSIBLE_TYPES = new Set([\n \"text/html\",\n \"text/css\",\n \"text/plain\",\n \"text/xml\",\n \"text/javascript\",\n \"application/javascript\",\n \"application/json\",\n \"application/xml\",\n \"application/xhtml+xml\",\n \"application/rss+xml\",\n \"application/atom+xml\",\n \"image/svg+xml\",\n \"application/manifest+json\",\n \"application/wasm\",\n]);\n\n/** Minimum size threshold for compression (in bytes). Below this, compression overhead isn't worth it. */\nconst COMPRESS_THRESHOLD = 1024;\n\n/**\n * Parse the Accept-Encoding header and return the best supported encoding.\n * Preference order: br > gzip > deflate > identity.\n */\nfunction negotiateEncoding(req: IncomingMessage): \"br\" | \"gzip\" | \"deflate\" | null {\n const accept = req.headers[\"accept-encoding\"];\n if (!accept || typeof accept !== \"string\") return null;\n const lower = accept.toLowerCase();\n if (lower.includes(\"br\")) return \"br\";\n if (lower.includes(\"gzip\")) return \"gzip\";\n if (lower.includes(\"deflate\")) return \"deflate\";\n return null;\n}\n\n/**\n * Create a compression stream for the given encoding.\n */\nfunction createCompressor(encoding: \"br\" | \"gzip\" | \"deflate\"): zlib.BrotliCompress | zlib.Gzip | zlib.Deflate {\n switch (encoding) {\n case \"br\":\n return zlib.createBrotliCompress({\n params: {\n [zlib.constants.BROTLI_PARAM_QUALITY]: 4, // Fast compression (1-11, 4 is a good balance)\n },\n });\n case \"gzip\":\n return zlib.createGzip({ level: 6 }); // Default level, good balance\n case \"deflate\":\n return zlib.createDeflate({ level: 6 });\n }\n}\n\n/**\n * Send a compressed response if the content type is compressible and the\n * client supports compression. Otherwise send uncompressed.\n */\nfunction sendCompressed(\n req: IncomingMessage,\n res: ServerResponse,\n body: string | Buffer,\n contentType: string,\n statusCode: number,\n extraHeaders: Record<string, string> = {},\n compress: boolean = true,\n): void {\n const buf = typeof body === \"string\" ? Buffer.from(body) : body;\n const baseType = contentType.split(\";\")[0].trim();\n const encoding = compress ? negotiateEncoding(req) : null;\n\n if (encoding && COMPRESSIBLE_TYPES.has(baseType) && buf.length >= COMPRESS_THRESHOLD) {\n const compressor = createCompressor(encoding);\n // Merge Accept-Encoding into existing Vary header from extraHeaders instead\n // of overwriting. Preserves Vary values set by the App Router for content\n // negotiation (e.g. \"RSC, Accept\").\n const existingVary = extraHeaders[\"Vary\"] ?? extraHeaders[\"vary\"];\n let varyValue: string;\n if (existingVary) {\n const existing = String(existingVary).toLowerCase();\n varyValue = existing.includes(\"accept-encoding\") ? String(existingVary) : existingVary + \", Accept-Encoding\";\n } else {\n varyValue = \"Accept-Encoding\";\n }\n res.writeHead(statusCode, {\n ...extraHeaders,\n \"Content-Type\": contentType,\n \"Content-Encoding\": encoding,\n Vary: varyValue,\n });\n compressor.end(buf);\n pipeline(compressor, res, () => { /* ignore pipeline errors on closed connections */ });\n } else {\n res.writeHead(statusCode, {\n ...extraHeaders,\n \"Content-Type\": contentType,\n \"Content-Length\": String(buf.length),\n });\n res.end(buf);\n }\n}\n\n/** Content-type lookup for static assets. */\nconst CONTENT_TYPES: Record<string, string> = {\n \".js\": \"application/javascript\",\n \".mjs\": \"application/javascript\",\n \".css\": \"text/css\",\n \".html\": \"text/html\",\n \".json\": \"application/json\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".gif\": \"image/gif\",\n \".svg\": \"image/svg+xml\",\n \".ico\": \"image/x-icon\",\n \".woff\": \"font/woff\",\n \".woff2\": \"font/woff2\",\n \".ttf\": \"font/ttf\",\n \".eot\": \"application/vnd.ms-fontobject\",\n \".webp\": \"image/webp\",\n \".avif\": \"image/avif\",\n \".map\": \"application/json\",\n};\n\n/**\n * Try to serve a static file from the client build directory.\n * Returns true if the file was served, false otherwise.\n */\nfunction tryServeStatic(\n req: IncomingMessage,\n res: ServerResponse,\n clientDir: string,\n pathname: string,\n compress: boolean,\n extraHeaders?: Record<string, string>,\n): boolean {\n // Resolve the path and guard against directory traversal (e.g. /../../../etc/passwd)\n const resolvedClient = path.resolve(clientDir);\n let decodedPathname: string;\n try {\n decodedPathname = decodeURIComponent(pathname);\n } catch {\n return false;\n }\n const staticFile = path.resolve(clientDir, \".\" + decodedPathname);\n if (!staticFile.startsWith(resolvedClient + path.sep) && staticFile !== resolvedClient) {\n return false;\n }\n if (\n pathname === \"/\" ||\n !fs.existsSync(staticFile) ||\n !fs.statSync(staticFile).isFile()\n ) {\n return false;\n }\n\n const ext = path.extname(staticFile);\n const ct = CONTENT_TYPES[ext] ?? \"application/octet-stream\";\n const isHashed = pathname.startsWith(\"/assets/\");\n const cacheControl = isHashed\n ? \"public, max-age=31536000, immutable\"\n : \"public, max-age=3600\";\n\n const baseHeaders = {\n \"Content-Type\": ct,\n \"Cache-Control\": cacheControl,\n ...extraHeaders,\n };\n\n const baseType = ct.split(\";\")[0].trim();\n if (compress && COMPRESSIBLE_TYPES.has(baseType)) {\n const encoding = negotiateEncoding(req);\n if (encoding) {\n const fileStream = fs.createReadStream(staticFile);\n const compressor = createCompressor(encoding);\n res.writeHead(200, {\n ...baseHeaders,\n \"Content-Encoding\": encoding,\n Vary: \"Accept-Encoding\",\n });\n pipeline(fileStream, compressor, res, () => { /* ignore */ });\n return true;\n }\n }\n\n res.writeHead(200, baseHeaders);\n fs.createReadStream(staticFile).pipe(res);\n return true;\n}\n\n/**\n * Resolve the host for a request, ignoring X-Forwarded-Host to prevent\n * host header poisoning attacks (open redirects, cache poisoning).\n *\n * X-Forwarded-Host is only trusted when the VINEXT_TRUSTED_HOSTS env var\n * lists the forwarded host value. Without this, an attacker can send\n * X-Forwarded-Host: evil.com and poison any redirect that resolves\n * against request.url.\n *\n * On Cloudflare Workers, X-Forwarded-Host is always set by Cloudflare\n * itself, so this is only a concern for the Node.js prod-server.\n */\nfunction resolveHost(req: IncomingMessage, fallback: string): string {\n const rawForwarded = req.headers[\"x-forwarded-host\"] as string | undefined;\n const hostHeader = req.headers.host;\n\n if (rawForwarded) {\n // X-Forwarded-Host can be comma-separated when passing through\n // multiple proxies — take only the first (client-facing) value.\n const forwardedHost = rawForwarded.split(\",\")[0].trim().toLowerCase();\n if (forwardedHost && trustedHosts.has(forwardedHost)) {\n return forwardedHost;\n }\n }\n\n return hostHeader || fallback;\n}\n\n/** Hosts that are allowed as X-Forwarded-Host values (stored lowercase). */\nconst trustedHosts: Set<string> = new Set(\n (process.env.VINEXT_TRUSTED_HOSTS ?? \"\")\n .split(\",\")\n .map((h) => h.trim().toLowerCase())\n .filter(Boolean),\n);\n\n/**\n * Whether to trust X-Forwarded-Proto from upstream proxies.\n * Enabled when VINEXT_TRUST_PROXY=1 or when VINEXT_TRUSTED_HOSTS is set\n * (having trusted hosts implies a trusted proxy).\n */\nconst trustProxy = process.env.VINEXT_TRUST_PROXY === \"1\" || trustedHosts.size > 0;\n\n/**\n * Convert a Node.js IncomingMessage to a Web Request object.\n */\nfunction nodeToWebRequest(req: IncomingMessage): Request {\n const rawProto = trustProxy\n ? (req.headers[\"x-forwarded-proto\"] as string)?.split(\",\")[0]?.trim()\n : undefined;\n const proto = rawProto === \"https\" || rawProto === \"http\" ? rawProto : \"http\";\n const host = resolveHost(req, \"localhost\");\n const origin = `${proto}://${host}`;\n const url = new URL(req.url ?? \"/\", origin);\n\n const headers = new Headers();\n for (const [key, value] of Object.entries(req.headers)) {\n if (value === undefined) continue;\n if (Array.isArray(value)) {\n for (const v of value) headers.append(key, v);\n } else {\n headers.set(key, value);\n }\n }\n\n const method = req.method ?? \"GET\";\n const hasBody = method !== \"GET\" && method !== \"HEAD\";\n\n const init: RequestInit & { duplex?: string } = {\n method,\n headers,\n };\n\n if (hasBody) {\n // Convert Node.js readable stream to Web ReadableStream for request body.\n // Readable.toWeb() is available since Node.js 17.\n init.body = Readable.toWeb(req) as ReadableStream;\n init.duplex = \"half\"; // Required for streaming request bodies\n }\n\n return new Request(url, init);\n}\n\n/**\n * Stream a Web Response back to a Node.js ServerResponse.\n * Supports streaming compression for SSR responses.\n */\nasync function sendWebResponse(\n webResponse: Response,\n req: IncomingMessage,\n res: ServerResponse,\n compress: boolean,\n): Promise<void> {\n const status = webResponse.status;\n\n // Collect headers, handling multi-value headers (e.g. Set-Cookie)\n const nodeHeaders: Record<string, string | string[]> = {};\n webResponse.headers.forEach((value, key) => {\n const existing = nodeHeaders[key];\n if (existing !== undefined) {\n nodeHeaders[key] = Array.isArray(existing)\n ? [...existing, value]\n : [existing, value];\n } else {\n nodeHeaders[key] = value;\n }\n });\n\n if (!webResponse.body) {\n res.writeHead(status, nodeHeaders);\n res.end();\n return;\n }\n\n // Check if we should compress the response.\n // Skip if the upstream already compressed (avoid double-compression).\n const alreadyEncoded = webResponse.headers.has(\"content-encoding\");\n const contentType = webResponse.headers.get(\"content-type\") ?? \"\";\n const baseType = contentType.split(\";\")[0].trim();\n const encoding = (compress && !alreadyEncoded) ? negotiateEncoding(req) : null;\n const shouldCompress = !!(encoding && COMPRESSIBLE_TYPES.has(baseType));\n\n if (shouldCompress) {\n delete nodeHeaders[\"content-length\"];\n delete nodeHeaders[\"Content-Length\"];\n nodeHeaders[\"Content-Encoding\"] = encoding!;\n // Merge Accept-Encoding into existing Vary header (e.g. \"RSC, Accept\") instead\n // of overwriting. This prevents stripping the Vary values that the App Router\n // sets for content negotiation (RSC stream vs HTML).\n const existingVary = nodeHeaders[\"Vary\"] ?? nodeHeaders[\"vary\"];\n if (existingVary) {\n const existing = String(existingVary).toLowerCase();\n if (!existing.includes(\"accept-encoding\")) {\n nodeHeaders[\"Vary\"] = existingVary + \", Accept-Encoding\";\n }\n } else {\n nodeHeaders[\"Vary\"] = \"Accept-Encoding\";\n }\n }\n\n res.writeHead(status, nodeHeaders);\n\n // HEAD requests: send headers only, skip the body\n if (req.method === \"HEAD\") {\n res.end();\n return;\n }\n\n // Convert Web ReadableStream to Node.js Readable and pipe to response.\n // Readable.fromWeb() is available since Node.js 17.\n const nodeStream = Readable.fromWeb(webResponse.body as import(\"stream/web\").ReadableStream);\n\n if (shouldCompress) {\n const compressor = createCompressor(encoding!);\n pipeline(nodeStream, compressor, res, () => { /* ignore pipeline errors on closed connections */ });\n } else {\n pipeline(nodeStream, res, () => { /* ignore pipeline errors on closed connections */ });\n }\n}\n\n/**\n * Start the production server.\n *\n * Automatically detects whether the build is App Router (dist/server/index.js) or\n * Pages Router (dist/server/entry.js) and configures the appropriate handler.\n */\nexport async function startProdServer(options: ProdServerOptions = {}) {\n const {\n port = process.env.PORT ? parseInt(process.env.PORT) : 3000,\n host = \"0.0.0.0\",\n outDir = path.resolve(\"dist\"),\n noCompression = false,\n } = options;\n\n const compress = !noCompression;\n // Always resolve outDir to absolute to ensure dynamic import() works\n const resolvedOutDir = path.resolve(outDir);\n const clientDir = path.join(resolvedOutDir, \"client\");\n\n // Detect build type\n const rscEntryPath = path.join(resolvedOutDir, \"server\", \"index.js\");\n const serverEntryPath = path.join(resolvedOutDir, \"server\", \"entry.js\");\n const isAppRouter = fs.existsSync(rscEntryPath);\n\n if (!isAppRouter && !fs.existsSync(serverEntryPath)) {\n console.error(`[vinext] No build output found in ${outDir}`);\n console.error(\"Run `vinext build` first.\");\n process.exit(1);\n }\n\n if (isAppRouter) {\n return startAppRouterServer({ port, host, clientDir, rscEntryPath, compress });\n }\n\n return startPagesRouterServer({ port, host, clientDir, serverEntryPath, compress });\n}\n\n// ─── App Router Production Server ─────────────────────────────────────────────\n\ninterface AppRouterServerOptions {\n port: number;\n host: string;\n clientDir: string;\n rscEntryPath: string;\n compress: boolean;\n}\n\n/**\n * Start the App Router production server.\n *\n * The RSC entry (dist/server/index.js) exports a default handler function:\n * handler(request: Request) → Promise<Response>\n *\n * This handler already does everything: route matching, RSC rendering,\n * SSR HTML generation (via import(\"./ssr/index.js\")), route handlers,\n * server actions, ISR caching, 404s, redirects, etc.\n *\n * The production server's job is simply to:\n * 1. Serve static assets from dist/client/\n * 2. Convert Node.js IncomingMessage → Web Request\n * 3. Call the RSC handler\n * 4. Stream the Web Response back (with optional compression)\n */\nasync function startAppRouterServer(options: AppRouterServerOptions) {\n const { port, host, clientDir, rscEntryPath, compress } = options;\n\n // Import the RSC handler (use file:// URL for reliable dynamic import)\n const rscModule = await import(pathToFileURL(rscEntryPath).href);\n const rscHandler: (request: Request) => Promise<Response> = rscModule.default;\n\n if (typeof rscHandler !== \"function\") {\n console.error(\"[vinext] RSC entry does not export a default handler function\");\n process.exit(1);\n }\n\n const server = createServer(async (req, res) => {\n const url = req.url ?? \"/\";\n // Normalize backslashes (browsers treat /\\ as //), then decode and normalize path.\n const rawPathname = url.split(\"?\")[0].replaceAll(\"\\\\\", \"/\");\n const pathname = normalizePath(decodeURIComponent(rawPathname));\n\n // Guard against protocol-relative URL open redirect attacks.\n // Check rawPathname before normalizePath collapses //.\n if (rawPathname.startsWith(\"//\")) {\n res.writeHead(404);\n res.end(\"404 Not Found\");\n return;\n }\n\n // Serve static assets from client build\n if (pathname !== \"/\" && tryServeStatic(req, res, clientDir, pathname, compress)) {\n return;\n }\n\n // Image optimization passthrough (Node.js prod server has no Images binding;\n // serves the original file with cache headers and security headers)\n if (pathname === IMAGE_OPTIMIZATION_PATH) {\n const parsedUrl = new URL(url, \"http://localhost\");\n const defaultAllowedWidths = [...DEFAULT_DEVICE_SIZES, ...DEFAULT_IMAGE_SIZES];\n const params = parseImageParams(parsedUrl, defaultAllowedWidths);\n if (!params) {\n res.writeHead(400);\n res.end(\"Bad Request\");\n return;\n }\n // Block SVG and other unsafe content types by checking the file extension.\n // This must happen before serving to prevent XSS via SVG passthrough.\n const ext = path.extname(params.imageUrl).toLowerCase();\n const ct = CONTENT_TYPES[ext] ?? \"application/octet-stream\";\n if (!isSafeImageContentType(ct)) {\n res.writeHead(400);\n res.end(\"The requested resource is not an allowed image type\");\n return;\n }\n // Serve the original image with CSP and security headers\n const imageSecurityHeaders: Record<string, string> = {\n \"Content-Security-Policy\": IMAGE_CONTENT_SECURITY_POLICY,\n \"X-Content-Type-Options\": \"nosniff\",\n \"Content-Disposition\": \"inline\",\n };\n if (tryServeStatic(req, res, clientDir, params.imageUrl, false, imageSecurityHeaders)) {\n return;\n }\n res.writeHead(404);\n res.end(\"Image not found\");\n return;\n }\n\n try {\n // Convert Node.js request to Web Request and call the RSC handler\n const request = nodeToWebRequest(req);\n const response = await rscHandler(request);\n\n // Stream the Web Response back to the Node.js response\n await sendWebResponse(response, req, res, compress);\n } catch (e) {\n console.error(\"[vinext] Server error:\", e);\n if (!res.headersSent) {\n res.writeHead(500);\n res.end(\"Internal Server Error\");\n }\n }\n });\n\n await new Promise<void>((resolve) => {\n server.listen(port, host, () => {\n const addr = server.address();\n const actualPort = typeof addr === \"object\" && addr ? addr.port : port;\n console.log(`[vinext] Production server running at http://${host}:${actualPort}`);\n resolve();\n });\n });\n\n return server;\n}\n\n// ─── Pages Router Production Server ───────────────────────────────────────────\n\ninterface PagesRouterServerOptions {\n port: number;\n host: string;\n clientDir: string;\n serverEntryPath: string;\n compress: boolean;\n}\n\n/**\n * Start the Pages Router production server.\n *\n * Uses the server entry (dist/server/entry.js) which exports:\n * - renderPage(request, url, manifest) — SSR rendering (Web Request → Response)\n * - handleApiRoute(request, url) — API route handling (Web Request → Response)\n * - runMiddleware(request) — middleware execution\n * - vinextConfig — embedded next.config.js settings\n */\nasync function startPagesRouterServer(options: PagesRouterServerOptions) {\n const { port, host, clientDir, serverEntryPath, compress } = options;\n\n // Load the SSR manifest (maps module URLs to client asset URLs)\n let ssrManifest: Record<string, string[]> = {};\n const manifestPath = path.join(clientDir, \".vite\", \"ssr-manifest.json\");\n if (fs.existsSync(manifestPath)) {\n ssrManifest = JSON.parse(fs.readFileSync(manifestPath, \"utf-8\"));\n }\n\n // Load the build manifest to compute lazy chunks — chunks only reachable via\n // dynamic imports (React.lazy, next/dynamic). These should not be\n // modulepreloaded since they are fetched on demand.\n const buildManifestPath = path.join(clientDir, \".vite\", \"manifest.json\");\n if (fs.existsSync(buildManifestPath)) {\n try {\n const buildManifest = JSON.parse(fs.readFileSync(buildManifestPath, \"utf-8\"));\n const lazyChunks = computeLazyChunks(buildManifest);\n if (lazyChunks.length > 0) {\n (globalThis as any).__VINEXT_LAZY_CHUNKS__ = lazyChunks;\n }\n } catch { /* ignore parse errors */ }\n }\n\n // Import the server entry module (use file:// URL for reliable dynamic import)\n const serverEntry = await import(pathToFileURL(serverEntryPath).href);\n const { renderPage, handleApiRoute: handleApi, runMiddleware, vinextConfig } = serverEntry;\n\n // Extract config values (embedded at build time in the server entry)\n const basePath: string = vinextConfig?.basePath ?? \"\";\n const trailingSlash: boolean = vinextConfig?.trailingSlash ?? false;\n const configRedirects = vinextConfig?.redirects ?? [];\n const configRewrites = vinextConfig?.rewrites ?? { beforeFiles: [], afterFiles: [], fallback: [] };\n const configHeaders = vinextConfig?.headers ?? [];\n // Compute allowed image widths from config (union of deviceSizes + imageSizes)\n const allowedImageWidths: number[] = [\n ...(vinextConfig?.images?.deviceSizes ?? DEFAULT_DEVICE_SIZES),\n ...(vinextConfig?.images?.imageSizes ?? DEFAULT_IMAGE_SIZES),\n ];\n\n const server = createServer(async (req, res) => {\n const rawUrl = req.url ?? \"/\";\n let url = rawUrl;\n // Normalize backslashes (browsers treat /\\ as //), then decode and normalize path.\n const rawPagesPathname = url.split(\"?\")[0].replaceAll(\"\\\\\", \"/\");\n let pathname = normalizePath(decodeURIComponent(rawPagesPathname));\n\n // Guard against protocol-relative URL open redirect attacks.\n // Check rawPagesPathname before normalizePath collapses //.\n if (rawPagesPathname.startsWith(\"//\")) {\n res.writeHead(404);\n res.end(\"404 Not Found\");\n return;\n }\n\n // ── 1. Static assets ──────────────────────────────────────────\n // Serve static files from client build. When basePath is configured,\n // Vite's `base` config ensures assets are under basePath/assets/.\n // We check both with and without basePath.\n const staticLookupPath = basePath && pathname.startsWith(basePath)\n ? pathname.slice(basePath.length) || \"/\"\n : pathname;\n if (\n staticLookupPath !== \"/\" &&\n !staticLookupPath.startsWith(\"/api/\") &&\n tryServeStatic(req, res, clientDir, staticLookupPath, compress)\n ) {\n return;\n }\n\n // ── Image optimization passthrough ──────────────────────────────\n if (pathname === IMAGE_OPTIMIZATION_PATH || staticLookupPath === IMAGE_OPTIMIZATION_PATH) {\n const parsedUrl = new URL(rawUrl, \"http://localhost\");\n const params = parseImageParams(parsedUrl, allowedImageWidths);\n if (!params) {\n res.writeHead(400);\n res.end(\"Bad Request\");\n return;\n }\n // Block SVG and other unsafe content types\n const ext = path.extname(params.imageUrl).toLowerCase();\n const ct = CONTENT_TYPES[ext] ?? \"application/octet-stream\";\n if (!isSafeImageContentType(ct)) {\n res.writeHead(400);\n res.end(\"The requested resource is not an allowed image type\");\n return;\n }\n const imageSecurityHeaders: Record<string, string> = {\n \"Content-Security-Policy\": IMAGE_CONTENT_SECURITY_POLICY,\n \"X-Content-Type-Options\": \"nosniff\",\n \"Content-Disposition\": \"inline\",\n };\n if (tryServeStatic(req, res, clientDir, params.imageUrl, false, imageSecurityHeaders)) {\n return;\n }\n res.writeHead(404);\n res.end(\"Image not found\");\n return;\n }\n\n try {\n // ── 2. Strip basePath ─────────────────────────────────────────\n if (basePath && pathname.startsWith(basePath)) {\n const stripped = pathname.slice(basePath.length) || \"/\";\n const qs = url.includes(\"?\") ? url.slice(url.indexOf(\"?\")) : \"\";\n url = stripped + qs;\n pathname = stripped;\n }\n\n // ── 3. Trailing slash normalization ───────────────────────────\n if (pathname !== \"/\" && !pathname.startsWith(\"/api\")) {\n const hasTrailing = pathname.endsWith(\"/\");\n if (trailingSlash && !hasTrailing) {\n const qs = url.includes(\"?\") ? url.slice(url.indexOf(\"?\")) : \"\";\n res.writeHead(308, { Location: basePath + pathname + \"/\" + qs });\n res.end();\n return;\n } else if (!trailingSlash && hasTrailing) {\n const qs = url.includes(\"?\") ? url.slice(url.indexOf(\"?\")) : \"\";\n res.writeHead(308, { Location: basePath + pathname.replace(/\\/+$/, \"\") + qs });\n res.end();\n return;\n }\n }\n\n // Convert Node.js req to Web Request for the server entry\n const rawProtocol = trustProxy\n ? (req.headers[\"x-forwarded-proto\"] as string)?.split(\",\")[0]?.trim()\n : undefined;\n const protocol = rawProtocol === \"https\" || rawProtocol === \"http\" ? rawProtocol : \"http\";\n const hostHeader = resolveHost(req, `${host}:${port}`);\n const reqHeaders = Object.entries(req.headers).reduce((h, [k, v]) => {\n if (v) h.set(k, Array.isArray(v) ? v.join(\", \") : v);\n return h;\n }, new Headers());\n const method = req.method ?? \"GET\";\n const hasBody = method !== \"GET\" && method !== \"HEAD\";\n const webRequest = new Request(`${protocol}://${hostHeader}${url}`, {\n method,\n headers: reqHeaders,\n body: hasBody ? readNodeStream(req) : undefined,\n // @ts-expect-error — duplex needed for streaming request bodies\n duplex: hasBody ? \"half\" : undefined,\n });\n\n // Build request context for has/missing condition matching\n const reqCtx: RequestContext = requestContextFromRequest(webRequest);\n\n // ── 4. Run middleware ─────────────────────────────────────────\n let resolvedUrl = url;\n const middlewareHeaders: Record<string, string> = {};\n let middlewareRewriteStatus: number | undefined;\n if (typeof runMiddleware === \"function\") {\n const result = await runMiddleware(webRequest);\n\n if (!result.continue) {\n if (result.redirectUrl) {\n res.writeHead(result.redirectStatus ?? 307, {\n Location: result.redirectUrl,\n });\n res.end();\n return;\n }\n if (result.response) {\n // Use arrayBuffer() to handle binary response bodies correctly\n const body = Buffer.from(await result.response.arrayBuffer());\n res.writeHead(result.response.status, Object.fromEntries(result.response.headers));\n res.end(body);\n return;\n }\n }\n\n // Collect middleware response headers to merge into final response\n if (result.responseHeaders) {\n for (const [key, value] of result.responseHeaders) {\n middlewareHeaders[key] = value;\n }\n }\n\n // Apply middleware rewrite\n if (result.rewriteUrl) {\n resolvedUrl = result.rewriteUrl;\n }\n\n // Apply custom status code from middleware rewrite\n // (e.g. NextResponse.rewrite(url, { status: 403 }))\n middlewareRewriteStatus = result.rewriteStatus;\n }\n\n // Unpack x-middleware-request-* headers into the actual request so that\n // renderPage / handleApiRoute see the middleware-modified headers.\n // Strip ALL x-middleware-* headers from the response — this prefix is\n // reserved for internal routing signals and must never reach clients.\n // (Matches Next.js behavior where x-middleware-* headers are internal.)\n const mwReqPrefix = \"x-middleware-request-\";\n for (const key of Object.keys(middlewareHeaders)) {\n if (key.startsWith(mwReqPrefix)) {\n const realName = key.slice(mwReqPrefix.length);\n webRequest.headers.set(realName, middlewareHeaders[key]);\n delete middlewareHeaders[key];\n } else if (key.startsWith(\"x-middleware-\")) {\n delete middlewareHeaders[key];\n }\n }\n\n let resolvedPathname = resolvedUrl.split(\"?\")[0];\n\n // ── 5. Apply custom headers from next.config.js ───────────────\n if (configHeaders.length) {\n const matched = matchHeaders(resolvedPathname, configHeaders);\n for (const h of matched) {\n middlewareHeaders[h.key.toLowerCase()] = h.value;\n }\n }\n\n // ── 6. Apply redirects from next.config.js ────────────────────\n if (configRedirects.length) {\n const redirect = matchRedirect(resolvedPathname, configRedirects, reqCtx);\n if (redirect) {\n // Guard against double-prefixing: only add basePath if destination\n // doesn't already start with it.\n // Sanitize the final destination to prevent protocol-relative URL open redirects.\n const dest = sanitizeDestination(\n basePath && !redirect.destination.startsWith(basePath)\n ? basePath + redirect.destination\n : redirect.destination,\n );\n res.writeHead(redirect.permanent ? 308 : 307, { Location: dest });\n res.end();\n return;\n }\n }\n\n // ── 7. Apply beforeFiles rewrites from next.config.js ─────────\n if (configRewrites.beforeFiles?.length) {\n const rewritten = matchRewrite(resolvedPathname, configRewrites.beforeFiles, reqCtx);\n if (rewritten) {\n if (isExternalUrl(rewritten)) {\n const proxyResponse = await proxyExternalRequest(webRequest, rewritten);\n await sendWebResponse(proxyResponse, req, res, compress);\n return;\n }\n resolvedUrl = rewritten;\n resolvedPathname = rewritten.split(\"?\")[0];\n }\n }\n\n // ── 8. API routes ─────────────────────────────────────────────\n if (resolvedPathname.startsWith(\"/api/\") || resolvedPathname === \"/api\") {\n let response: Response;\n if (typeof handleApi === \"function\") {\n response = await handleApi(webRequest, resolvedUrl);\n } else {\n response = new Response(\"404 - API route not found\", { status: 404 });\n }\n\n // Merge middleware + config headers into the response\n const responseBody = Buffer.from(await response.arrayBuffer());\n const ct = response.headers.get(\"content-type\") ?? \"text/html\";\n const responseHeaders: Record<string, string> = { ...middlewareHeaders };\n response.headers.forEach((v, k) => { responseHeaders[k] = v; });\n\n sendCompressed(req, res, responseBody, ct, middlewareRewriteStatus ?? response.status, responseHeaders, compress);\n return;\n }\n\n // ── 9. Apply afterFiles rewrites from next.config.js ──────────\n if (configRewrites.afterFiles?.length) {\n const rewritten = matchRewrite(resolvedPathname, configRewrites.afterFiles, reqCtx);\n if (rewritten) {\n if (isExternalUrl(rewritten)) {\n const proxyResponse = await proxyExternalRequest(webRequest, rewritten);\n await sendWebResponse(proxyResponse, req, res, compress);\n return;\n }\n resolvedUrl = rewritten;\n resolvedPathname = rewritten.split(\"?\")[0];\n }\n }\n\n // ── 10. SSR page rendering ────────────────────────────────────\n let response: Response | undefined;\n if (typeof renderPage === \"function\") {\n response = await renderPage(webRequest, resolvedUrl, ssrManifest);\n\n // ── 11. Fallback rewrites (if SSR returned 404) ─────────────\n if (response && response.status === 404 && configRewrites.fallback?.length) {\n const fallbackRewrite = matchRewrite(resolvedPathname, configRewrites.fallback, reqCtx);\n if (fallbackRewrite) {\n if (isExternalUrl(fallbackRewrite)) {\n const proxyResponse = await proxyExternalRequest(webRequest, fallbackRewrite);\n await sendWebResponse(proxyResponse, req, res, compress);\n return;\n }\n response = await renderPage(webRequest, fallbackRewrite, ssrManifest);\n }\n }\n }\n\n if (!response) {\n res.writeHead(404);\n res.end(\"404 - Not found\");\n return;\n }\n\n // Merge middleware + config headers into the response\n const responseBody = Buffer.from(await response.arrayBuffer());\n const ct = response.headers.get(\"content-type\") ?? \"text/html\";\n const responseHeaders: Record<string, string> = { ...middlewareHeaders };\n response.headers.forEach((v, k) => { responseHeaders[k] = v; });\n\n sendCompressed(req, res, responseBody, ct, middlewareRewriteStatus ?? response.status, responseHeaders, compress);\n } catch (e) {\n console.error(\"[vinext] Server error:\", e);\n res.writeHead(500);\n res.end(\"Internal Server Error\");\n }\n });\n\n await new Promise<void>((resolve) => {\n server.listen(port, host, () => {\n const addr = server.address();\n const actualPort = typeof addr === \"object\" && addr ? addr.port : port;\n console.log(`[vinext] Production server running at http://${host}:${actualPort}`);\n resolve();\n });\n });\n\n return server;\n}\n\n// Export helpers for testing\nexport { sendCompressed, negotiateEncoding, COMPRESSIBLE_TYPES, COMPRESS_THRESHOLD, resolveHost, trustedHosts, trustProxy, nodeToWebRequest };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-cache.d.ts","sourceRoot":"","sources":["../../src/shims/fetch-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;
|
|
1
|
+
{"version":3,"file":"fetch-cache.d.ts","sourceRoot":"","sources":["../../src/shims/fetch-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAgHH,UAAU,gBAAgB;IACxB,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAGD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,WAAW;QACnB,IAAI,CAAC,EAAE,gBAAgB,CAAC;KACzB;CACF;AA0CD;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAEhD;AAsND;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,IAAI,MAAM,IAAI,CAO3C;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAG3E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,UAAU,CAAC,KAAK,CAE1D"}
|
|
@@ -29,6 +29,12 @@ import { AsyncLocalStorage } from "node:async_hooks";
|
|
|
29
29
|
* authenticated response from being served to another user.
|
|
30
30
|
*
|
|
31
31
|
* Checked case-insensitively to match HTTP header semantics.
|
|
32
|
+
*
|
|
33
|
+
* SECURITY NOTE: Only these three headers are keyed. If your application uses
|
|
34
|
+
* custom authentication headers (e.g. "X-Session-Token", "X-Auth-Token"),
|
|
35
|
+
* responses may be incorrectly shared across users. In such cases, use
|
|
36
|
+
* `cache: 'no-store'` on authenticated fetches or add the header to the URL
|
|
37
|
+
* as a query parameter to ensure unique cache keys.
|
|
32
38
|
*/
|
|
33
39
|
const AUTH_HEADERS = ["authorization", "cookie", "x-api-key"];
|
|
34
40
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-cache.js","sourceRoot":"","sources":["../../src/shims/fetch-cache.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Extended fetch() with Next.js caching semantics.\n *\n * Patches `globalThis.fetch` during server rendering to support:\n *\n * fetch(url, { next: { revalidate: 60, tags: ['posts'] } })\n * fetch(url, { cache: 'force-cache' })\n * fetch(url, { cache: 'no-store' })\n *\n * Cached responses are stored via the pluggable CacheHandler, so\n * revalidateTag() and revalidatePath() invalidate fetch-level caches.\n *\n * Usage (in server entry):\n * import { withFetchCache, cleanupFetchCache } from './fetch-cache';\n * const cleanup = withFetchCache();\n * try { ... render ... } finally { cleanup(); }\n *\n * Or use the async helper:\n * await runWithFetchCache(async () => { ... render ... });\n */\n\nimport {\n getCacheHandler,\n type CachedFetchValue,\n} from \"./cache.js\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\n\n// ---------------------------------------------------------------------------\n// Cache key generation\n// ---------------------------------------------------------------------------\n\n/**\n * Headers that carry per-user identity. When any of these are present in a\n * fetch request, they MUST be included in the cache key to prevent one user's\n * authenticated response from being served to another user.\n *\n * Checked case-insensitively to match HTTP header semantics.\n */\nconst AUTH_HEADERS = [\"authorization\", \"cookie\", \"x-api-key\"];\n\n/**\n * Check whether a fetch request includes any per-user authentication headers.\n * Returns the normalized header values (sorted by name) for cache key inclusion,\n * or null if no auth headers are present.\n */\nfunction extractAuthHeaders(input: string | URL | Request, init?: RequestInit): string | null {\n const collected: [string, string][] = [];\n\n // Gather headers from the init object\n if (init?.headers) {\n const headers = init.headers instanceof Headers\n ? init.headers\n : new Headers(init.headers as HeadersInit);\n for (const name of AUTH_HEADERS) {\n const value = headers.get(name);\n if (value) collected.push([name, value]);\n }\n }\n\n // Also check headers from the Request object (if input is a Request)\n if (input instanceof Request && input.headers) {\n for (const name of AUTH_HEADERS) {\n // Don't duplicate if already found in init\n if (collected.some(([n]) => n === name)) continue;\n const value = input.headers.get(name);\n if (value) collected.push([name, value]);\n }\n }\n\n if (collected.length === 0) return null;\n\n // Sort for deterministic key ordering\n collected.sort((a, b) => a[0].localeCompare(b[0]));\n return collected.map(([k, v]) => `${k}=${v}`).join(\"&\");\n}\n\n/**\n * Check whether a fetch request carries any per-user auth headers.\n */\nfunction hasAuthHeaders(input: string | URL | Request, init?: RequestInit): boolean {\n return extractAuthHeaders(input, init) !== null;\n}\n\n/**\n * Generate a deterministic cache key from a fetch request.\n *\n * Key = \"fetch:\" + method + \":\" + URL [+ \"|\" + body] [+ \"|auth:\" + auth_headers].\n *\n * When per-user headers (Authorization, Cookie, X-API-Key) are present,\n * they are included in the cache key so different users get separate cache\n * entries. This prevents authenticated responses from leaking across users.\n */\nfunction buildFetchCacheKey(input: string | URL | Request, init?: RequestInit & { next?: NextFetchOptions }): string {\n let url: string;\n let method = \"GET\";\n let body: string | undefined;\n\n if (typeof input === \"string\") {\n url = input;\n } else if (input instanceof URL) {\n url = input.toString();\n } else {\n // Request object\n url = input.url;\n method = input.method || \"GET\";\n }\n\n if (init?.method) method = init.method;\n if (init?.body && typeof init.body === \"string\") body = init.body;\n\n // Build a stable key from URL + method + body + auth headers\n const parts = [`fetch:${method}:${url}`];\n if (body) parts.push(body);\n\n // Include per-user auth headers in the key to prevent cross-user leakage\n const authPart = extractAuthHeaders(input, init);\n if (authPart) parts.push(`auth:${authPart}`);\n\n return parts.join(\"|\");\n}\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ninterface NextFetchOptions {\n revalidate?: number | false;\n tags?: string[];\n}\n\n// Extend the standard RequestInit to include `next`\ndeclare global {\n interface RequestInit {\n next?: NextFetchOptions;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Patching\n// ---------------------------------------------------------------------------\n\n// Capture the real (unpatched) fetch once, shared across Vite's\n// multi-environment module instances via Symbol.for().\nconst _ORIG_FETCH_KEY = Symbol.for(\"vinext.fetchCache.originalFetch\");\nconst _gFetch = globalThis as unknown as Record<PropertyKey, unknown>;\nconst originalFetch: typeof globalThis.fetch = (_gFetch[_ORIG_FETCH_KEY] ??= globalThis.fetch) as typeof globalThis.fetch;\n\n// ---------------------------------------------------------------------------\n// AsyncLocalStorage for request-scoped fetch cache state.\n// Uses Symbol.for() on globalThis so the storage is shared across Vite's\n// multi-environment module instances.\n// ---------------------------------------------------------------------------\ninterface FetchCacheState {\n currentRequestTags: string[];\n}\n\nconst _ALS_KEY = Symbol.for(\"vinext.fetchCache.als\");\nconst _FALLBACK_KEY = Symbol.for(\"vinext.fetchCache.fallback\");\nconst _g = globalThis as unknown as Record<PropertyKey, unknown>;\nconst _als = (_g[_ALS_KEY] ??= new AsyncLocalStorage<FetchCacheState>()) as AsyncLocalStorage<FetchCacheState>;\n\nconst _fallbackState = (_g[_FALLBACK_KEY] ??= {\n currentRequestTags: [],\n} satisfies FetchCacheState) as FetchCacheState;\n\nfunction _getState(): FetchCacheState {\n return _als.getStore() ?? _fallbackState;\n}\n\n/**\n * Reset the fallback state for a new request. Used by `withFetchCache()`\n * in single-threaded contexts where ALS.run() isn't used.\n */\nfunction _resetFallbackState(): void {\n _fallbackState.currentRequestTags = [];\n}\n\n/**\n * Get tags collected during the current render pass.\n * Useful for associating page-level cache entries with all the\n * fetch tags used during rendering.\n */\nexport function getCollectedFetchTags(): string[] {\n return [..._getState().currentRequestTags];\n}\n\n/**\n * Create a patched fetch function with Next.js caching semantics.\n *\n * The patched fetch:\n * 1. Checks `cache` and `next` options to determine caching behavior\n * 2. On cache hit, returns the cached response without hitting the network\n * 3. On cache miss, fetches from network, stores in cache, returns response\n * 4. Respects `next.revalidate` for TTL-based revalidation\n * 5. Respects `next.tags` for tag-based invalidation via revalidateTag()\n */\nfunction createPatchedFetch(): typeof globalThis.fetch {\n return async function patchedFetch(\n input: string | URL | Request,\n init?: RequestInit,\n ): Promise<Response> {\n const nextOpts = init?.next as NextFetchOptions | undefined;\n const cacheDirective = init?.cache;\n\n // Determine caching behavior:\n // - cache: 'no-store' → skip cache entirely\n // - cache: 'force-cache' → cache indefinitely (revalidate = Infinity)\n // - next.revalidate: false → same as 'no-store'\n // - next.revalidate: 0 → same as 'no-store'\n // - next.revalidate: N → cache for N seconds\n // - No cache/next options → default behavior (no caching, pass-through)\n\n // If no caching options at all, just pass through to original fetch\n if (!nextOpts && !cacheDirective) {\n return originalFetch(input, init);\n }\n\n // Explicit no-store or no-cache — bypass cache entirely\n if (cacheDirective === \"no-store\" || cacheDirective === \"no-cache\" || nextOpts?.revalidate === false || nextOpts?.revalidate === 0) {\n // Strip the `next` property before passing to real fetch\n const cleanInit = stripNextFromInit(init);\n return originalFetch(input, cleanInit);\n }\n\n // Safety: when per-user auth headers are present and the developer hasn't\n // explicitly opted into caching with `cache: 'force-cache'` or an explicit\n // `next.revalidate`, skip caching to prevent accidental cross-user data\n // leakage. Developers who understand the implications can still force\n // caching by using `cache: 'force-cache'` or `next: { revalidate: N }`.\n const hasExplicitCacheOpt =\n cacheDirective === \"force-cache\" ||\n (typeof nextOpts?.revalidate === \"number\" && nextOpts.revalidate > 0);\n if (!hasExplicitCacheOpt && hasAuthHeaders(input, init)) {\n const cleanInit = stripNextFromInit(init);\n return originalFetch(input, cleanInit);\n }\n\n // Determine revalidation period\n let revalidateSeconds: number;\n if (cacheDirective === \"force-cache\") {\n // force-cache means cache indefinitely (we use a very large number)\n revalidateSeconds = nextOpts?.revalidate && typeof nextOpts.revalidate === \"number\"\n ? nextOpts.revalidate\n : 31536000; // 1 year\n } else if (typeof nextOpts?.revalidate === \"number\" && nextOpts.revalidate > 0) {\n revalidateSeconds = nextOpts.revalidate;\n } else {\n // Has `next` options but no explicit revalidate — Next.js defaults to\n // caching when `next` is present (force-cache behavior).\n // If only tags are specified, cache indefinitely.\n if (nextOpts?.tags && nextOpts.tags.length > 0) {\n revalidateSeconds = 31536000;\n } else {\n // next: {} with no revalidate or tags — pass through\n const cleanInit = stripNextFromInit(init);\n return originalFetch(input, cleanInit);\n }\n }\n\n const tags = nextOpts?.tags ?? [];\n const cacheKey = buildFetchCacheKey(input, init);\n const handler = getCacheHandler();\n\n // Collect tags for this render pass\n const reqTags = _getState().currentRequestTags;\n if (tags.length > 0) {\n for (const tag of tags) {\n if (!reqTags.includes(tag)) {\n reqTags.push(tag);\n }\n }\n }\n\n // Try cache first\n try {\n const cached = await handler.get(cacheKey, { kind: \"FETCH\", tags });\n if (cached?.value && cached.value.kind === \"FETCH\" && cached.cacheState !== \"stale\") {\n const cachedData = cached.value.data;\n // Reconstruct a Response from the cached data\n return new Response(cachedData.body, {\n status: cachedData.status ?? 200,\n headers: cachedData.headers,\n });\n }\n\n // Stale entry — we could do stale-while-revalidate here, but for fetch()\n // the simpler approach is to just re-fetch (the page-level ISR handles SWR).\n // However, if we have a stale entry, return it and trigger background refetch.\n if (cached?.value && cached.value.kind === \"FETCH\" && cached.cacheState === \"stale\") {\n const staleData = cached.value.data;\n\n // Background refetch\n const cleanInit = stripNextFromInit(init);\n originalFetch(input, cleanInit).then(async (freshResp) => {\n const freshBody = await freshResp.text();\n const freshHeaders: Record<string, string> = {};\n freshResp.headers.forEach((v, k) => { freshHeaders[k] = v; });\n\n const freshValue: CachedFetchValue = {\n kind: \"FETCH\",\n data: {\n headers: freshHeaders,\n body: freshBody,\n url: typeof input === \"string\" ? input : input instanceof URL ? input.toString() : input.url,\n status: freshResp.status,\n },\n tags,\n revalidate: revalidateSeconds,\n };\n await handler.set(cacheKey, freshValue, {\n fetchCache: true,\n tags,\n revalidate: revalidateSeconds,\n });\n }).catch((err) => {\n console.error(\"[vinext] fetch cache background revalidation failed:\", err);\n });\n\n // Return stale data immediately\n return new Response(staleData.body, {\n status: staleData.status ?? 200,\n headers: staleData.headers,\n });\n }\n } catch (cacheErr) {\n // Cache read failed — fall through to network\n console.error(\"[vinext] fetch cache read error:\", cacheErr);\n }\n\n // Cache miss — fetch from network\n const cleanInit = stripNextFromInit(init);\n const response = await originalFetch(input, cleanInit);\n\n // Only cache successful responses (2xx)\n if (response.ok) {\n // Clone before reading body\n const cloned = response.clone();\n const body = await cloned.text();\n const headers: Record<string, string> = {};\n cloned.headers.forEach((v, k) => { headers[k] = v; });\n\n const cacheValue: CachedFetchValue = {\n kind: \"FETCH\",\n data: {\n headers,\n body,\n url: typeof input === \"string\" ? input : input instanceof URL ? input.toString() : input.url,\n status: cloned.status,\n },\n tags,\n revalidate: revalidateSeconds,\n };\n\n // Store in cache (fire-and-forget)\n handler.set(cacheKey, cacheValue, {\n fetchCache: true,\n tags,\n revalidate: revalidateSeconds,\n }).catch((err) => {\n console.error(\"[vinext] fetch cache write error:\", err);\n });\n }\n\n return response;\n } as typeof globalThis.fetch;\n}\n\n/**\n * Strip the `next` property from RequestInit before passing to real fetch.\n * The `next` property is not a standard fetch option and would cause warnings\n * in some environments.\n */\nfunction stripNextFromInit(init?: RequestInit): RequestInit | undefined {\n if (!init) return init;\n if (!(\"next\" in init)) return init;\n const { next: _next, ...rest } = init as RequestInit & { next?: unknown };\n return Object.keys(rest).length > 0 ? rest : undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n// ---------------------------------------------------------------------------\n// Fetch patching — install once, not per-request.\n// The patched fetch uses _getState() internally, which reads from ALS\n// (concurrent) or _fallbackState (single-threaded), so per-request\n// isolation is handled at the state level, not by swapping globalThis.fetch.\n// ---------------------------------------------------------------------------\n\nconst _PATCH_KEY = Symbol.for(\"vinext.fetchCache.patchInstalled\");\n\nfunction _ensurePatchInstalled(): void {\n if (_g[_PATCH_KEY]) return;\n _g[_PATCH_KEY] = true;\n globalThis.fetch = createPatchedFetch();\n}\n\n/**\n * Install the patched fetch and reset per-request tag state.\n * Returns a cleanup function that clears tags.\n *\n * @deprecated Prefer `runWithFetchCache()` which uses `AsyncLocalStorage.run()`\n * for proper per-request isolation in concurrent environments.\n *\n * Usage:\n * const cleanup = withFetchCache();\n * try { await render(); } finally { cleanup(); }\n */\nexport function withFetchCache(): () => void {\n _ensurePatchInstalled();\n _resetFallbackState();\n\n return () => {\n _resetFallbackState();\n };\n}\n\n/**\n * Run an async function with patched fetch caching enabled.\n * Uses `AsyncLocalStorage.run()` for proper per-request isolation\n * of collected fetch tags in concurrent server environments.\n */\nexport async function runWithFetchCache<T>(fn: () => Promise<T>): Promise<T> {\n _ensurePatchInstalled();\n return _als.run({ currentRequestTags: [] }, fn);\n}\n\n/**\n * Get the original (unpatched) fetch function.\n * Useful for internal code that should bypass caching.\n */\nexport function getOriginalFetch(): typeof globalThis.fetch {\n return originalFetch;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"fetch-cache.js","sourceRoot":"","sources":["../../src/shims/fetch-cache.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Extended fetch() with Next.js caching semantics.\n *\n * Patches `globalThis.fetch` during server rendering to support:\n *\n * fetch(url, { next: { revalidate: 60, tags: ['posts'] } })\n * fetch(url, { cache: 'force-cache' })\n * fetch(url, { cache: 'no-store' })\n *\n * Cached responses are stored via the pluggable CacheHandler, so\n * revalidateTag() and revalidatePath() invalidate fetch-level caches.\n *\n * Usage (in server entry):\n * import { withFetchCache, cleanupFetchCache } from './fetch-cache';\n * const cleanup = withFetchCache();\n * try { ... render ... } finally { cleanup(); }\n *\n * Or use the async helper:\n * await runWithFetchCache(async () => { ... render ... });\n */\n\nimport {\n getCacheHandler,\n type CachedFetchValue,\n} from \"./cache.js\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\n\n// ---------------------------------------------------------------------------\n// Cache key generation\n// ---------------------------------------------------------------------------\n\n/**\n * Headers that carry per-user identity. When any of these are present in a\n * fetch request, they MUST be included in the cache key to prevent one user's\n * authenticated response from being served to another user.\n *\n * Checked case-insensitively to match HTTP header semantics.\n *\n * SECURITY NOTE: Only these three headers are keyed. If your application uses\n * custom authentication headers (e.g. \"X-Session-Token\", \"X-Auth-Token\"),\n * responses may be incorrectly shared across users. In such cases, use\n * `cache: 'no-store'` on authenticated fetches or add the header to the URL\n * as a query parameter to ensure unique cache keys.\n */\nconst AUTH_HEADERS = [\"authorization\", \"cookie\", \"x-api-key\"];\n\n/**\n * Check whether a fetch request includes any per-user authentication headers.\n * Returns the normalized header values (sorted by name) for cache key inclusion,\n * or null if no auth headers are present.\n */\nfunction extractAuthHeaders(input: string | URL | Request, init?: RequestInit): string | null {\n const collected: [string, string][] = [];\n\n // Gather headers from the init object\n if (init?.headers) {\n const headers = init.headers instanceof Headers\n ? init.headers\n : new Headers(init.headers as HeadersInit);\n for (const name of AUTH_HEADERS) {\n const value = headers.get(name);\n if (value) collected.push([name, value]);\n }\n }\n\n // Also check headers from the Request object (if input is a Request)\n if (input instanceof Request && input.headers) {\n for (const name of AUTH_HEADERS) {\n // Don't duplicate if already found in init\n if (collected.some(([n]) => n === name)) continue;\n const value = input.headers.get(name);\n if (value) collected.push([name, value]);\n }\n }\n\n if (collected.length === 0) return null;\n\n // Sort for deterministic key ordering\n collected.sort((a, b) => a[0].localeCompare(b[0]));\n return collected.map(([k, v]) => `${k}=${v}`).join(\"&\");\n}\n\n/**\n * Check whether a fetch request carries any per-user auth headers.\n */\nfunction hasAuthHeaders(input: string | URL | Request, init?: RequestInit): boolean {\n return extractAuthHeaders(input, init) !== null;\n}\n\n/**\n * Generate a deterministic cache key from a fetch request.\n *\n * Key = \"fetch:\" + method + \":\" + URL [+ \"|\" + body] [+ \"|auth:\" + auth_headers].\n *\n * When per-user headers (Authorization, Cookie, X-API-Key) are present,\n * they are included in the cache key so different users get separate cache\n * entries. This prevents authenticated responses from leaking across users.\n */\nfunction buildFetchCacheKey(input: string | URL | Request, init?: RequestInit & { next?: NextFetchOptions }): string {\n let url: string;\n let method = \"GET\";\n let body: string | undefined;\n\n if (typeof input === \"string\") {\n url = input;\n } else if (input instanceof URL) {\n url = input.toString();\n } else {\n // Request object\n url = input.url;\n method = input.method || \"GET\";\n }\n\n if (init?.method) method = init.method;\n if (init?.body && typeof init.body === \"string\") body = init.body;\n\n // Build a stable key from URL + method + body + auth headers\n const parts = [`fetch:${method}:${url}`];\n if (body) parts.push(body);\n\n // Include per-user auth headers in the key to prevent cross-user leakage\n const authPart = extractAuthHeaders(input, init);\n if (authPart) parts.push(`auth:${authPart}`);\n\n return parts.join(\"|\");\n}\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ninterface NextFetchOptions {\n revalidate?: number | false;\n tags?: string[];\n}\n\n// Extend the standard RequestInit to include `next`\ndeclare global {\n interface RequestInit {\n next?: NextFetchOptions;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Patching\n// ---------------------------------------------------------------------------\n\n// Capture the real (unpatched) fetch once, shared across Vite's\n// multi-environment module instances via Symbol.for().\nconst _ORIG_FETCH_KEY = Symbol.for(\"vinext.fetchCache.originalFetch\");\nconst _gFetch = globalThis as unknown as Record<PropertyKey, unknown>;\nconst originalFetch: typeof globalThis.fetch = (_gFetch[_ORIG_FETCH_KEY] ??= globalThis.fetch) as typeof globalThis.fetch;\n\n// ---------------------------------------------------------------------------\n// AsyncLocalStorage for request-scoped fetch cache state.\n// Uses Symbol.for() on globalThis so the storage is shared across Vite's\n// multi-environment module instances.\n// ---------------------------------------------------------------------------\ninterface FetchCacheState {\n currentRequestTags: string[];\n}\n\nconst _ALS_KEY = Symbol.for(\"vinext.fetchCache.als\");\nconst _FALLBACK_KEY = Symbol.for(\"vinext.fetchCache.fallback\");\nconst _g = globalThis as unknown as Record<PropertyKey, unknown>;\nconst _als = (_g[_ALS_KEY] ??= new AsyncLocalStorage<FetchCacheState>()) as AsyncLocalStorage<FetchCacheState>;\n\nconst _fallbackState = (_g[_FALLBACK_KEY] ??= {\n currentRequestTags: [],\n} satisfies FetchCacheState) as FetchCacheState;\n\nfunction _getState(): FetchCacheState {\n return _als.getStore() ?? _fallbackState;\n}\n\n/**\n * Reset the fallback state for a new request. Used by `withFetchCache()`\n * in single-threaded contexts where ALS.run() isn't used.\n */\nfunction _resetFallbackState(): void {\n _fallbackState.currentRequestTags = [];\n}\n\n/**\n * Get tags collected during the current render pass.\n * Useful for associating page-level cache entries with all the\n * fetch tags used during rendering.\n */\nexport function getCollectedFetchTags(): string[] {\n return [..._getState().currentRequestTags];\n}\n\n/**\n * Create a patched fetch function with Next.js caching semantics.\n *\n * The patched fetch:\n * 1. Checks `cache` and `next` options to determine caching behavior\n * 2. On cache hit, returns the cached response without hitting the network\n * 3. On cache miss, fetches from network, stores in cache, returns response\n * 4. Respects `next.revalidate` for TTL-based revalidation\n * 5. Respects `next.tags` for tag-based invalidation via revalidateTag()\n */\nfunction createPatchedFetch(): typeof globalThis.fetch {\n return async function patchedFetch(\n input: string | URL | Request,\n init?: RequestInit,\n ): Promise<Response> {\n const nextOpts = init?.next as NextFetchOptions | undefined;\n const cacheDirective = init?.cache;\n\n // Determine caching behavior:\n // - cache: 'no-store' → skip cache entirely\n // - cache: 'force-cache' → cache indefinitely (revalidate = Infinity)\n // - next.revalidate: false → same as 'no-store'\n // - next.revalidate: 0 → same as 'no-store'\n // - next.revalidate: N → cache for N seconds\n // - No cache/next options → default behavior (no caching, pass-through)\n\n // If no caching options at all, just pass through to original fetch\n if (!nextOpts && !cacheDirective) {\n return originalFetch(input, init);\n }\n\n // Explicit no-store or no-cache — bypass cache entirely\n if (cacheDirective === \"no-store\" || cacheDirective === \"no-cache\" || nextOpts?.revalidate === false || nextOpts?.revalidate === 0) {\n // Strip the `next` property before passing to real fetch\n const cleanInit = stripNextFromInit(init);\n return originalFetch(input, cleanInit);\n }\n\n // Safety: when per-user auth headers are present and the developer hasn't\n // explicitly opted into caching with `cache: 'force-cache'` or an explicit\n // `next.revalidate`, skip caching to prevent accidental cross-user data\n // leakage. Developers who understand the implications can still force\n // caching by using `cache: 'force-cache'` or `next: { revalidate: N }`.\n const hasExplicitCacheOpt =\n cacheDirective === \"force-cache\" ||\n (typeof nextOpts?.revalidate === \"number\" && nextOpts.revalidate > 0);\n if (!hasExplicitCacheOpt && hasAuthHeaders(input, init)) {\n const cleanInit = stripNextFromInit(init);\n return originalFetch(input, cleanInit);\n }\n\n // Determine revalidation period\n let revalidateSeconds: number;\n if (cacheDirective === \"force-cache\") {\n // force-cache means cache indefinitely (we use a very large number)\n revalidateSeconds = nextOpts?.revalidate && typeof nextOpts.revalidate === \"number\"\n ? nextOpts.revalidate\n : 31536000; // 1 year\n } else if (typeof nextOpts?.revalidate === \"number\" && nextOpts.revalidate > 0) {\n revalidateSeconds = nextOpts.revalidate;\n } else {\n // Has `next` options but no explicit revalidate — Next.js defaults to\n // caching when `next` is present (force-cache behavior).\n // If only tags are specified, cache indefinitely.\n if (nextOpts?.tags && nextOpts.tags.length > 0) {\n revalidateSeconds = 31536000;\n } else {\n // next: {} with no revalidate or tags — pass through\n const cleanInit = stripNextFromInit(init);\n return originalFetch(input, cleanInit);\n }\n }\n\n const tags = nextOpts?.tags ?? [];\n const cacheKey = buildFetchCacheKey(input, init);\n const handler = getCacheHandler();\n\n // Collect tags for this render pass\n const reqTags = _getState().currentRequestTags;\n if (tags.length > 0) {\n for (const tag of tags) {\n if (!reqTags.includes(tag)) {\n reqTags.push(tag);\n }\n }\n }\n\n // Try cache first\n try {\n const cached = await handler.get(cacheKey, { kind: \"FETCH\", tags });\n if (cached?.value && cached.value.kind === \"FETCH\" && cached.cacheState !== \"stale\") {\n const cachedData = cached.value.data;\n // Reconstruct a Response from the cached data\n return new Response(cachedData.body, {\n status: cachedData.status ?? 200,\n headers: cachedData.headers,\n });\n }\n\n // Stale entry — we could do stale-while-revalidate here, but for fetch()\n // the simpler approach is to just re-fetch (the page-level ISR handles SWR).\n // However, if we have a stale entry, return it and trigger background refetch.\n if (cached?.value && cached.value.kind === \"FETCH\" && cached.cacheState === \"stale\") {\n const staleData = cached.value.data;\n\n // Background refetch\n const cleanInit = stripNextFromInit(init);\n originalFetch(input, cleanInit).then(async (freshResp) => {\n const freshBody = await freshResp.text();\n const freshHeaders: Record<string, string> = {};\n freshResp.headers.forEach((v, k) => { freshHeaders[k] = v; });\n\n const freshValue: CachedFetchValue = {\n kind: \"FETCH\",\n data: {\n headers: freshHeaders,\n body: freshBody,\n url: typeof input === \"string\" ? input : input instanceof URL ? input.toString() : input.url,\n status: freshResp.status,\n },\n tags,\n revalidate: revalidateSeconds,\n };\n await handler.set(cacheKey, freshValue, {\n fetchCache: true,\n tags,\n revalidate: revalidateSeconds,\n });\n }).catch((err) => {\n console.error(\"[vinext] fetch cache background revalidation failed:\", err);\n });\n\n // Return stale data immediately\n return new Response(staleData.body, {\n status: staleData.status ?? 200,\n headers: staleData.headers,\n });\n }\n } catch (cacheErr) {\n // Cache read failed — fall through to network\n console.error(\"[vinext] fetch cache read error:\", cacheErr);\n }\n\n // Cache miss — fetch from network\n const cleanInit = stripNextFromInit(init);\n const response = await originalFetch(input, cleanInit);\n\n // Only cache successful responses (2xx)\n if (response.ok) {\n // Clone before reading body\n const cloned = response.clone();\n const body = await cloned.text();\n const headers: Record<string, string> = {};\n cloned.headers.forEach((v, k) => { headers[k] = v; });\n\n const cacheValue: CachedFetchValue = {\n kind: \"FETCH\",\n data: {\n headers,\n body,\n url: typeof input === \"string\" ? input : input instanceof URL ? input.toString() : input.url,\n status: cloned.status,\n },\n tags,\n revalidate: revalidateSeconds,\n };\n\n // Store in cache (fire-and-forget)\n handler.set(cacheKey, cacheValue, {\n fetchCache: true,\n tags,\n revalidate: revalidateSeconds,\n }).catch((err) => {\n console.error(\"[vinext] fetch cache write error:\", err);\n });\n }\n\n return response;\n } as typeof globalThis.fetch;\n}\n\n/**\n * Strip the `next` property from RequestInit before passing to real fetch.\n * The `next` property is not a standard fetch option and would cause warnings\n * in some environments.\n */\nfunction stripNextFromInit(init?: RequestInit): RequestInit | undefined {\n if (!init) return init;\n if (!(\"next\" in init)) return init;\n const { next: _next, ...rest } = init as RequestInit & { next?: unknown };\n return Object.keys(rest).length > 0 ? rest : undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n// ---------------------------------------------------------------------------\n// Fetch patching — install once, not per-request.\n// The patched fetch uses _getState() internally, which reads from ALS\n// (concurrent) or _fallbackState (single-threaded), so per-request\n// isolation is handled at the state level, not by swapping globalThis.fetch.\n// ---------------------------------------------------------------------------\n\nconst _PATCH_KEY = Symbol.for(\"vinext.fetchCache.patchInstalled\");\n\nfunction _ensurePatchInstalled(): void {\n if (_g[_PATCH_KEY]) return;\n _g[_PATCH_KEY] = true;\n globalThis.fetch = createPatchedFetch();\n}\n\n/**\n * Install the patched fetch and reset per-request tag state.\n * Returns a cleanup function that clears tags.\n *\n * @deprecated Prefer `runWithFetchCache()` which uses `AsyncLocalStorage.run()`\n * for proper per-request isolation in concurrent environments.\n *\n * Usage:\n * const cleanup = withFetchCache();\n * try { await render(); } finally { cleanup(); }\n */\nexport function withFetchCache(): () => void {\n _ensurePatchInstalled();\n _resetFallbackState();\n\n return () => {\n _resetFallbackState();\n };\n}\n\n/**\n * Run an async function with patched fetch caching enabled.\n * Uses `AsyncLocalStorage.run()` for proper per-request isolation\n * of collected fetch tags in concurrent server environments.\n */\nexport async function runWithFetchCache<T>(fn: () => Promise<T>): Promise<T> {\n _ensurePatchInstalled();\n return _als.run({ currentRequestTags: [] }, fn);\n}\n\n/**\n * Get the original (unpatched) fetch function.\n * Useful for internal code that should bypass caching.\n */\nexport function getOriginalFetch(): typeof globalThis.fetch {\n return originalFetch;\n}\n"]}
|
package/dist/shims/head.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"head.d.ts","sourceRoot":"","sources":["../../src/shims/head.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAA8C,MAAM,OAAO,CAAC;AAEnE,UAAU,SAAS;IACjB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAWD;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,SAAS,EAAE;IACrD,kBAAkB,EAAE,MAAM,MAAM,EAAE,CAAC;IACnC,YAAY,EAAE,MAAM,IAAI,CAAC;CAC1B,GAAG,IAAI,CAGP;AAED,wDAAwD;AACxD,wBAAgB,YAAY,IAAI,IAAI,CAEnC;AAED,kDAAkD;AAClD,wBAAgB,cAAc,IAAI,MAAM,CAEvC;
|
|
1
|
+
{"version":3,"file":"head.d.ts","sourceRoot":"","sources":["../../src/shims/head.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAA8C,MAAM,OAAO,CAAC;AAEnE,UAAU,SAAS;IACjB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAWD;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,SAAS,EAAE;IACrD,kBAAkB,EAAE,MAAM,MAAM,EAAE,CAAC;IACnC,YAAY,EAAE,MAAM,IAAI,CAAC;CAC1B,GAAG,IAAI,CAGP;AAED,wDAAwD;AACxD,wBAAgB,YAAY,IAAI,IAAI,CAEnC;AAED,kDAAkD;AAClD,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAmED,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE5C;AAID,iBAAS,IAAI,CAAC,EAAE,QAAQ,EAAE,EAAE,SAAS,GAAG,IAAI,CAqD3C;AAED,eAAe,IAAI,CAAC"}
|
package/dist/shims/head.js
CHANGED
|
@@ -59,7 +59,10 @@ function reactElementToHTML(child) {
|
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
else if (key === "dangerouslySetInnerHTML") {
|
|
62
|
-
// Intentionally raw — developer explicitly opted in
|
|
62
|
+
// Intentionally raw — developer explicitly opted in.
|
|
63
|
+
// SECURITY NOTE: This injects raw HTML during SSR. The client-side
|
|
64
|
+
// path (line ~148) skips dangerouslySetInnerHTML for safety. Developers
|
|
65
|
+
// must never pass unsanitized user input here — it is a stored XSS vector.
|
|
63
66
|
const html = value;
|
|
64
67
|
if (html?.__html)
|
|
65
68
|
innerHTML = html.__html;
|
package/dist/shims/head.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"head.js","sourceRoot":"","sources":["../../src/shims/head.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * next/head shim\n *\n * In the Pages Router, <Head> manages document <head> elements.\n * - On the server: collects elements into a module-level array that the\n * dev-server reads after render and injects into the HTML <head>.\n * - On the client: uses useEffect + DOM manipulation.\n */\nimport React, { useEffect, Children, isValidElement } from \"react\";\n\ninterface HeadProps {\n children?: React.ReactNode;\n}\n\n// --- SSR head collection ---\n// State uses a registration pattern so this module can be bundled for the\n// browser. The ALS-backed implementation lives in head-state.ts (server-only).\n\nlet _ssrHeadElements: string[] = [];\n\nlet _getSSRHeadElements = (): string[] => _ssrHeadElements;\nlet _resetSSRHeadImpl = (): void => { _ssrHeadElements = []; };\n\n/**\n * Register ALS-backed state accessors. Called by head-state.ts on import.\n * @internal\n */\nexport function _registerHeadStateAccessors(accessors: {\n getSSRHeadElements: () => string[];\n resetSSRHead: () => void;\n}): void {\n _getSSRHeadElements = accessors.getSSRHeadElements;\n _resetSSRHeadImpl = accessors.resetSSRHead;\n}\n\n/** Reset the SSR head collector. Call before render. */\nexport function resetSSRHead(): void {\n _resetSSRHeadImpl();\n}\n\n/** Get collected head HTML. Call after render. */\nexport function getSSRHeadHTML(): string {\n return _getSSRHeadElements().join(\"\\n \");\n}\n\n/**\n * Tags allowed inside <head>. Anything else is silently dropped.\n * This prevents injection of dangerous elements like <iframe>, <object>, etc.\n */\nconst ALLOWED_HEAD_TAGS = new Set([\n \"title\", \"meta\", \"link\", \"style\", \"script\", \"base\", \"noscript\",\n]);\n\n/**\n * Convert a React element to an HTML string for SSR head injection.\n * Returns an empty string for disallowed tag types.\n */\nfunction reactElementToHTML(child: React.ReactElement): string {\n const tag = child.type as string;\n\n if (!ALLOWED_HEAD_TAGS.has(tag)) {\n if (process.env.NODE_ENV !== \"production\") {\n console.warn(\n `[vinext] <Head> ignoring disallowed tag <${tag}>. ` +\n `Only ${[...ALLOWED_HEAD_TAGS].join(\", \")} are allowed.`,\n );\n }\n return \"\";\n }\n\n const props = child.props as Record<string, unknown>;\n const attrs: string[] = [];\n let innerHTML = \"\";\n\n for (const [key, value] of Object.entries(props)) {\n if (key === \"children\") {\n if (typeof value === \"string\") {\n innerHTML = escapeHTML(value);\n }\n } else if (key === \"dangerouslySetInnerHTML\") {\n // Intentionally raw — developer explicitly opted in\n const html = value as { __html: string };\n if (html?.__html) innerHTML = html.__html;\n } else if (key === \"className\") {\n attrs.push(`class=\"${escapeAttr(String(value))}\"`);\n } else if (typeof value === \"string\") {\n attrs.push(`${key}=\"${escapeAttr(value)}\"`);\n } else if (typeof value === \"boolean\" && value) {\n attrs.push(key);\n }\n }\n\n const attrStr = attrs.length ? \" \" + attrs.join(\" \") : \"\";\n\n // Self-closing tags\n const selfClosing = [\"meta\", \"link\", \"base\"];\n if (selfClosing.includes(tag)) {\n return `<${tag}${attrStr} data-vinext-head=\"true\" />`;\n }\n\n return `<${tag}${attrStr} data-vinext-head=\"true\">${innerHTML}</${tag}>`;\n}\n\nfunction escapeHTML(s: string): string {\n return s.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\");\n}\n\nexport function escapeAttr(s: string): string {\n return s.replace(/&/g, \"&\").replace(/\"/g, \""\").replace(/</g, \"<\").replace(/>/g, \">\");\n}\n\n// --- Component ---\n\nfunction Head({ children }: HeadProps): null {\n // SSR path: collect elements for later injection\n if (typeof window === \"undefined\") {\n Children.forEach(children, (child) => {\n if (!isValidElement(child)) return;\n if (typeof child.type !== \"string\") return;\n const html = reactElementToHTML(child);\n if (html) _getSSRHeadElements().push(html);\n });\n return null;\n }\n\n // Client path: useEffect DOM manipulation (runs after hydration)\n // eslint-disable-next-line react-hooks/rules-of-hooks\n useEffect(() => {\n const elements: Element[] = [];\n\n // Remove previous vinext-managed head elements\n document\n .querySelectorAll(\"[data-vinext-head]\")\n .forEach((el) => el.remove());\n\n Children.forEach(children, (child) => {\n if (!isValidElement(child)) return;\n if (typeof child.type !== \"string\") return;\n if (!ALLOWED_HEAD_TAGS.has(child.type)) return;\n\n const domEl = document.createElement(child.type);\n const props = child.props as Record<string, unknown>;\n\n for (const [key, value] of Object.entries(props)) {\n if (key === \"children\" && typeof value === \"string\") {\n domEl.textContent = value;\n } else if (key === \"dangerouslySetInnerHTML\") {\n // skip for safety\n } else if (key === \"className\") {\n domEl.setAttribute(\"class\", String(value));\n } else if (key !== \"children\" && typeof value === \"string\") {\n domEl.setAttribute(key, value);\n }\n }\n\n domEl.setAttribute(\"data-vinext-head\", \"true\");\n document.head.appendChild(domEl);\n elements.push(domEl);\n });\n\n return () => {\n elements.forEach((el) => el.remove());\n };\n }, [children]);\n\n return null;\n}\n\nexport default Head;\n"]}
|
|
1
|
+
{"version":3,"file":"head.js","sourceRoot":"","sources":["../../src/shims/head.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * next/head shim\n *\n * In the Pages Router, <Head> manages document <head> elements.\n * - On the server: collects elements into a module-level array that the\n * dev-server reads after render and injects into the HTML <head>.\n * - On the client: uses useEffect + DOM manipulation.\n */\nimport React, { useEffect, Children, isValidElement } from \"react\";\n\ninterface HeadProps {\n children?: React.ReactNode;\n}\n\n// --- SSR head collection ---\n// State uses a registration pattern so this module can be bundled for the\n// browser. The ALS-backed implementation lives in head-state.ts (server-only).\n\nlet _ssrHeadElements: string[] = [];\n\nlet _getSSRHeadElements = (): string[] => _ssrHeadElements;\nlet _resetSSRHeadImpl = (): void => { _ssrHeadElements = []; };\n\n/**\n * Register ALS-backed state accessors. Called by head-state.ts on import.\n * @internal\n */\nexport function _registerHeadStateAccessors(accessors: {\n getSSRHeadElements: () => string[];\n resetSSRHead: () => void;\n}): void {\n _getSSRHeadElements = accessors.getSSRHeadElements;\n _resetSSRHeadImpl = accessors.resetSSRHead;\n}\n\n/** Reset the SSR head collector. Call before render. */\nexport function resetSSRHead(): void {\n _resetSSRHeadImpl();\n}\n\n/** Get collected head HTML. Call after render. */\nexport function getSSRHeadHTML(): string {\n return _getSSRHeadElements().join(\"\\n \");\n}\n\n/**\n * Tags allowed inside <head>. Anything else is silently dropped.\n * This prevents injection of dangerous elements like <iframe>, <object>, etc.\n */\nconst ALLOWED_HEAD_TAGS = new Set([\n \"title\", \"meta\", \"link\", \"style\", \"script\", \"base\", \"noscript\",\n]);\n\n/**\n * Convert a React element to an HTML string for SSR head injection.\n * Returns an empty string for disallowed tag types.\n */\nfunction reactElementToHTML(child: React.ReactElement): string {\n const tag = child.type as string;\n\n if (!ALLOWED_HEAD_TAGS.has(tag)) {\n if (process.env.NODE_ENV !== \"production\") {\n console.warn(\n `[vinext] <Head> ignoring disallowed tag <${tag}>. ` +\n `Only ${[...ALLOWED_HEAD_TAGS].join(\", \")} are allowed.`,\n );\n }\n return \"\";\n }\n\n const props = child.props as Record<string, unknown>;\n const attrs: string[] = [];\n let innerHTML = \"\";\n\n for (const [key, value] of Object.entries(props)) {\n if (key === \"children\") {\n if (typeof value === \"string\") {\n innerHTML = escapeHTML(value);\n }\n } else if (key === \"dangerouslySetInnerHTML\") {\n // Intentionally raw — developer explicitly opted in.\n // SECURITY NOTE: This injects raw HTML during SSR. The client-side\n // path (line ~148) skips dangerouslySetInnerHTML for safety. Developers\n // must never pass unsanitized user input here — it is a stored XSS vector.\n const html = value as { __html: string };\n if (html?.__html) innerHTML = html.__html;\n } else if (key === \"className\") {\n attrs.push(`class=\"${escapeAttr(String(value))}\"`);\n } else if (typeof value === \"string\") {\n attrs.push(`${key}=\"${escapeAttr(value)}\"`);\n } else if (typeof value === \"boolean\" && value) {\n attrs.push(key);\n }\n }\n\n const attrStr = attrs.length ? \" \" + attrs.join(\" \") : \"\";\n\n // Self-closing tags\n const selfClosing = [\"meta\", \"link\", \"base\"];\n if (selfClosing.includes(tag)) {\n return `<${tag}${attrStr} data-vinext-head=\"true\" />`;\n }\n\n return `<${tag}${attrStr} data-vinext-head=\"true\">${innerHTML}</${tag}>`;\n}\n\nfunction escapeHTML(s: string): string {\n return s.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\");\n}\n\nexport function escapeAttr(s: string): string {\n return s.replace(/&/g, \"&\").replace(/\"/g, \""\").replace(/</g, \"<\").replace(/>/g, \">\");\n}\n\n// --- Component ---\n\nfunction Head({ children }: HeadProps): null {\n // SSR path: collect elements for later injection\n if (typeof window === \"undefined\") {\n Children.forEach(children, (child) => {\n if (!isValidElement(child)) return;\n if (typeof child.type !== \"string\") return;\n const html = reactElementToHTML(child);\n if (html) _getSSRHeadElements().push(html);\n });\n return null;\n }\n\n // Client path: useEffect DOM manipulation (runs after hydration)\n // eslint-disable-next-line react-hooks/rules-of-hooks\n useEffect(() => {\n const elements: Element[] = [];\n\n // Remove previous vinext-managed head elements\n document\n .querySelectorAll(\"[data-vinext-head]\")\n .forEach((el) => el.remove());\n\n Children.forEach(children, (child) => {\n if (!isValidElement(child)) return;\n if (typeof child.type !== \"string\") return;\n if (!ALLOWED_HEAD_TAGS.has(child.type)) return;\n\n const domEl = document.createElement(child.type);\n const props = child.props as Record<string, unknown>;\n\n for (const [key, value] of Object.entries(props)) {\n if (key === \"children\" && typeof value === \"string\") {\n domEl.textContent = value;\n } else if (key === \"dangerouslySetInnerHTML\") {\n // skip for safety\n } else if (key === \"className\") {\n domEl.setAttribute(\"class\", String(value));\n } else if (key !== \"children\" && typeof value === \"string\") {\n domEl.setAttribute(key, value);\n }\n }\n\n domEl.setAttribute(\"data-vinext-head\", \"true\");\n document.head.appendChild(domEl);\n elements.push(domEl);\n });\n\n return () => {\n elements.forEach((el) => el.remove());\n };\n }, [children]);\n\n return null;\n}\n\nexport default Head;\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"headers.d.ts","sourceRoot":"","sources":["../../src/shims/headers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAQH,UAAU,cAAc;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAiCD;;;;GAIG;AAGH;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAK7C;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI,GAAG,IAAI,CA4BlE;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,GAAG,EAAE,cAAc,EACnB,EAAE,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GACvB,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAShB;AAED;;;;;;;;GAQG;AACH,wBAAgB,6BAA6B,CAC3C,yBAAyB,EAAE,OAAO,GACjC,IAAI,CAyBN;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,GAAG,cAAc,CAa1E;AAMD;;;;GAIG;AACH,wBAAsB,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,CAUhD;AAED;;;GAGG;AACH,wBAAsB,OAAO,IAAI,OAAO,CAAC,cAAc,CAAC,CAUvD;AAMD,4EAA4E;AAG5E;;;GAGG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,EAAE,CAKpD;AAsBD;;;GAGG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,GAAG,IAAI,CAKxD;AAED,UAAU,eAAe;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,IAAI,IAAI,CAAC;IACf,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;;;GAMG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,eAAe,CAAC,
|
|
1
|
+
{"version":3,"file":"headers.d.ts","sourceRoot":"","sources":["../../src/shims/headers.ts"],"names":[],"mappings":"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"}
|
package/dist/shims/headers.js
CHANGED
|
@@ -249,15 +249,17 @@ export async function draftMode() {
|
|
|
249
249
|
if (state.headersContext) {
|
|
250
250
|
state.headersContext.cookies.set(DRAFT_MODE_COOKIE, secret);
|
|
251
251
|
}
|
|
252
|
+
const secure = typeof process !== "undefined" && process.env?.NODE_ENV === "production" ? "; Secure" : "";
|
|
252
253
|
state.draftModeCookieHeader =
|
|
253
|
-
`${DRAFT_MODE_COOKIE}=${secret}; Path=/; HttpOnly; SameSite=Lax`;
|
|
254
|
+
`${DRAFT_MODE_COOKIE}=${secret}; Path=/; HttpOnly; SameSite=Lax${secure}`;
|
|
254
255
|
},
|
|
255
256
|
disable() {
|
|
256
257
|
if (state.headersContext) {
|
|
257
258
|
state.headersContext.cookies.delete(DRAFT_MODE_COOKIE);
|
|
258
259
|
}
|
|
260
|
+
const secure = typeof process !== "undefined" && process.env?.NODE_ENV === "production" ? "; Secure" : "";
|
|
259
261
|
state.draftModeCookieHeader =
|
|
260
|
-
`${DRAFT_MODE_COOKIE}=; Path=/; HttpOnly; SameSite=Lax; Max-Age=0`;
|
|
262
|
+
`${DRAFT_MODE_COOKIE}=; Path=/; HttpOnly; SameSite=Lax${secure}; Max-Age=0`;
|
|
261
263
|
},
|
|
262
264
|
};
|
|
263
265
|
}
|