You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
	
	
		
			1235 lines
		
	
	
		
			56 KiB
		
	
	
	
		
			JavaScript
		
	
		
		
			
		
	
	
			1235 lines
		
	
	
		
			56 KiB
		
	
	
	
		
			JavaScript
		
	
| 
											9 months ago
										 | "use strict"; | ||
|  | Object.defineProperty(exports, "__esModule", { | ||
|  |     value: true | ||
|  | }); | ||
|  | Object.defineProperty(exports, "default", { | ||
|  |     enumerable: true, | ||
|  |     get: function() { | ||
|  |         return NextNodeServer; | ||
|  |     } | ||
|  | }); | ||
|  | 0 && __export(require("./base-server")); | ||
|  | require("./node-environment"); | ||
|  | require("./require-hook"); | ||
|  | require("./node-polyfill-crypto"); | ||
|  | const _utils = require("../shared/lib/utils"); | ||
|  | const _fs = /*#__PURE__*/ _interop_require_default(require("fs")); | ||
|  | const _path = require("path"); | ||
|  | const _routematcher = require("../shared/lib/router/utils/route-matcher"); | ||
|  | const _requestmeta = require("./request-meta"); | ||
|  | const _constants = require("../shared/lib/constants"); | ||
|  | const _findpagesdir = require("../lib/find-pages-dir"); | ||
|  | const _node = require("./base-http/node"); | ||
|  | const _sendpayload = require("./send-payload"); | ||
|  | const _parseurl = require("../shared/lib/router/utils/parse-url"); | ||
|  | const _log = /*#__PURE__*/ _interop_require_wildcard(require("../build/output/log")); | ||
|  | const _baseserver = /*#__PURE__*/ _interop_require_wildcard(_export_star(require("./base-server"), exports)); | ||
|  | const _require = require("./require"); | ||
|  | const _denormalizepagepath = require("../shared/lib/page-path/denormalize-page-path"); | ||
|  | const _normalizepagepath = require("../shared/lib/page-path/normalize-page-path"); | ||
|  | const _loadcomponents = require("./load-components"); | ||
|  | const _iserror = /*#__PURE__*/ _interop_require_wildcard(require("../lib/is-error")); | ||
|  | const _utils1 = require("./web/utils"); | ||
|  | const _middlewareroutematcher = require("../shared/lib/router/utils/middleware-route-matcher"); | ||
|  | const _env = require("@next/env"); | ||
|  | const _querystring = require("../shared/lib/router/utils/querystring"); | ||
|  | const _removetrailingslash = require("../shared/lib/router/utils/remove-trailing-slash"); | ||
|  | const _getnextpathnameinfo = require("../shared/lib/router/utils/get-next-pathname-info"); | ||
|  | const _bodystreams = require("./body-streams"); | ||
|  | const _apiutils = require("./api-utils"); | ||
|  | const _responsecache = /*#__PURE__*/ _interop_require_default(require("./response-cache")); | ||
|  | const _incrementalcache = require("./lib/incremental-cache"); | ||
|  | const _apppaths = require("../shared/lib/router/utils/app-paths"); | ||
|  | const _setuphttpagentenv = require("./setup-http-agent-env"); | ||
|  | const _pagesapiroutematch = require("./future/route-matches/pages-api-route-match"); | ||
|  | const _constants1 = require("../lib/constants"); | ||
|  | const _tracer = require("./lib/trace/tracer"); | ||
|  | const _constants2 = require("./lib/trace/constants"); | ||
|  | const _nodefsmethods = require("./lib/node-fs-methods"); | ||
|  | const _routeregex = require("../shared/lib/router/utils/route-regex"); | ||
|  | const _pipereadable = require("./pipe-readable"); | ||
|  | const _mockrequest = require("./lib/mock-request"); | ||
|  | const _approuterheaders = require("../client/components/app-router-headers"); | ||
|  | const _nextrequest = require("./web/spec-extension/adapters/next-request"); | ||
|  | const _routemoduleloader = require("./future/helpers/module-loader/route-module-loader"); | ||
|  | const _loadmanifest = require("./load-manifest"); | ||
|  | const _modulerender = require("./future/route-modules/app-page/module.render"); | ||
|  | const _modulerender1 = require("./future/route-modules/pages/module.render"); | ||
|  | const _interopdefault = require("../lib/interop-default"); | ||
|  | const _formatdynamicimportpath = require("../lib/format-dynamic-import-path"); | ||
|  | function _export_star(from, to) { | ||
|  |     Object.keys(from).forEach(function(k) { | ||
|  |         if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) { | ||
|  |             Object.defineProperty(to, k, { | ||
|  |                 enumerable: true, | ||
|  |                 get: function() { | ||
|  |                     return from[k]; | ||
|  |                 } | ||
|  |             }); | ||
|  |         } | ||
|  |     }); | ||
|  |     return from; | ||
|  | } | ||
|  | function _interop_require_default(obj) { | ||
|  |     return obj && obj.__esModule ? obj : { | ||
|  |         default: obj | ||
|  |     }; | ||
|  | } | ||
|  | function _getRequireWildcardCache(nodeInterop) { | ||
|  |     if (typeof WeakMap !== "function") return null; | ||
|  |     var cacheBabelInterop = new WeakMap(); | ||
|  |     var cacheNodeInterop = new WeakMap(); | ||
|  |     return (_getRequireWildcardCache = function(nodeInterop) { | ||
|  |         return nodeInterop ? cacheNodeInterop : cacheBabelInterop; | ||
|  |     })(nodeInterop); | ||
|  | } | ||
|  | function _interop_require_wildcard(obj, nodeInterop) { | ||
|  |     if (!nodeInterop && obj && obj.__esModule) { | ||
|  |         return obj; | ||
|  |     } | ||
|  |     if (obj === null || typeof obj !== "object" && typeof obj !== "function") { | ||
|  |         return { | ||
|  |             default: obj | ||
|  |         }; | ||
|  |     } | ||
|  |     var cache = _getRequireWildcardCache(nodeInterop); | ||
|  |     if (cache && cache.has(obj)) { | ||
|  |         return cache.get(obj); | ||
|  |     } | ||
|  |     var newObj = {}; | ||
|  |     var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; | ||
|  |     for(var key in obj){ | ||
|  |         if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { | ||
|  |             var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; | ||
|  |             if (desc && (desc.get || desc.set)) { | ||
|  |                 Object.defineProperty(newObj, key, desc); | ||
|  |             } else { | ||
|  |                 newObj[key] = obj[key]; | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  |     newObj.default = obj; | ||
|  |     if (cache) { | ||
|  |         cache.set(obj, newObj); | ||
|  |     } | ||
|  |     return newObj; | ||
|  | } | ||
|  | // For module that can be both CJS or ESM
 | ||
|  | const dynamicImportEsmDefault = process.env.NEXT_MINIMAL ? (id)=>import(/* webpackIgnore: true */ id).then((mod)=>mod.default || mod) : (id)=>import(id).then((mod)=>mod.default || mod); | ||
|  | // For module that will be compiled to CJS, e.g. instrument
 | ||
|  | const dynamicRequire = process.env.NEXT_MINIMAL ? __non_webpack_require__ : require; | ||
|  | function writeStdoutLine(text) { | ||
|  |     process.stdout.write(" " + text + "\n"); | ||
|  | } | ||
|  | function formatRequestUrl(url, maxLength) { | ||
|  |     return maxLength !== undefined && url.length > maxLength ? url.substring(0, maxLength) + ".." : url; | ||
|  | } | ||
|  | const MiddlewareMatcherCache = new WeakMap(); | ||
|  | function getMiddlewareMatcher(info) { | ||
|  |     const stored = MiddlewareMatcherCache.get(info); | ||
|  |     if (stored) { | ||
|  |         return stored; | ||
|  |     } | ||
|  |     if (!Array.isArray(info.matchers)) { | ||
|  |         throw new Error(`Invariant: invalid matchers for middleware ${JSON.stringify(info)}`); | ||
|  |     } | ||
|  |     const matcher = (0, _middlewareroutematcher.getMiddlewareRouteMatcher)(info.matchers); | ||
|  |     MiddlewareMatcherCache.set(info, matcher); | ||
|  |     return matcher; | ||
|  | } | ||
|  | class NextNodeServer extends _baseserver.default { | ||
|  |     constructor(options){ | ||
|  |         // Initialize super class
 | ||
|  |         super(options); | ||
|  |         this.handleNextImageRequest = async (req, res, parsedUrl)=>{ | ||
|  |             if (!parsedUrl.pathname || !parsedUrl.pathname.startsWith("/_next/image")) { | ||
|  |                 return false; | ||
|  |             } | ||
|  |             if (this.minimalMode || this.nextConfig.output === "export" || process.env.NEXT_MINIMAL) { | ||
|  |                 res.statusCode = 400; | ||
|  |                 res.body("Bad Request").send(); | ||
|  |                 return true; | ||
|  |             // the `else` branch is needed for tree-shaking
 | ||
|  |             } else { | ||
|  |                 const { ImageOptimizerCache } = require("./image-optimizer"); | ||
|  |                 const imageOptimizerCache = new ImageOptimizerCache({ | ||
|  |                     distDir: this.distDir, | ||
|  |                     nextConfig: this.nextConfig | ||
|  |                 }); | ||
|  |                 const { getHash, sendResponse, ImageError } = require("./image-optimizer"); | ||
|  |                 if (!this.imageResponseCache) { | ||
|  |                     throw new Error("invariant image optimizer cache was not initialized"); | ||
|  |                 } | ||
|  |                 const imagesConfig = this.nextConfig.images; | ||
|  |                 if (imagesConfig.loader !== "default" || imagesConfig.unoptimized) { | ||
|  |                     await this.render404(req, res); | ||
|  |                     return true; | ||
|  |                 } | ||
|  |                 const paramsResult = ImageOptimizerCache.validateParams(req.originalRequest, parsedUrl.query, this.nextConfig, !!this.renderOpts.dev); | ||
|  |                 if ("errorMessage" in paramsResult) { | ||
|  |                     res.statusCode = 400; | ||
|  |                     res.body(paramsResult.errorMessage).send(); | ||
|  |                     return true; | ||
|  |                 } | ||
|  |                 const cacheKey = ImageOptimizerCache.getCacheKey(paramsResult); | ||
|  |                 try { | ||
|  |                     var _cacheEntry_value; | ||
|  |                     const { getExtension } = require("./serve-static"); | ||
|  |                     const cacheEntry = await this.imageResponseCache.get(cacheKey, async ()=>{ | ||
|  |                         const { buffer, contentType, maxAge } = await this.imageOptimizer(req, res, paramsResult); | ||
|  |                         const etag = getHash([ | ||
|  |                             buffer | ||
|  |                         ]); | ||
|  |                         return { | ||
|  |                             value: { | ||
|  |                                 kind: "IMAGE", | ||
|  |                                 buffer, | ||
|  |                                 etag, | ||
|  |                                 extension: getExtension(contentType) | ||
|  |                             }, | ||
|  |                             revalidate: maxAge | ||
|  |                         }; | ||
|  |                     }, { | ||
|  |                         incrementalCache: imageOptimizerCache | ||
|  |                     }); | ||
|  |                     if ((cacheEntry == null ? void 0 : (_cacheEntry_value = cacheEntry.value) == null ? void 0 : _cacheEntry_value.kind) !== "IMAGE") { | ||
|  |                         throw new Error("invariant did not get entry from image response cache"); | ||
|  |                     } | ||
|  |                     sendResponse(req.originalRequest, res.originalResponse, paramsResult.href, cacheEntry.value.extension, cacheEntry.value.buffer, paramsResult.isStatic, cacheEntry.isMiss ? "MISS" : cacheEntry.isStale ? "STALE" : "HIT", imagesConfig, cacheEntry.revalidate || 0, Boolean(this.renderOpts.dev)); | ||
|  |                     return true; | ||
|  |                 } catch (err) { | ||
|  |                     if (err instanceof ImageError) { | ||
|  |                         res.statusCode = err.statusCode; | ||
|  |                         res.body(err.message).send(); | ||
|  |                         return true; | ||
|  |                     } | ||
|  |                     throw err; | ||
|  |                 } | ||
|  |             } | ||
|  |         }; | ||
|  |         this.handleCatchallRenderRequest = async (req, res, parsedUrl)=>{ | ||
|  |             let { pathname, query } = parsedUrl; | ||
|  |             if (!pathname) { | ||
|  |                 throw new Error("Invariant: pathname is undefined"); | ||
|  |             } | ||
|  |             // This is a catch-all route, there should be no fallbacks so mark it as
 | ||
|  |             // such.
 | ||
|  |             query._nextBubbleNoFallback = "1"; | ||
|  |             try { | ||
|  |                 var _this_i18nProvider; | ||
|  |                 // next.js core assumes page path without trailing slash
 | ||
|  |                 pathname = (0, _removetrailingslash.removeTrailingSlash)(pathname); | ||
|  |                 const options = { | ||
|  |                     i18n: (_this_i18nProvider = this.i18nProvider) == null ? void 0 : _this_i18nProvider.fromQuery(pathname, query) | ||
|  |                 }; | ||
|  |                 const match = await this.matchers.match(pathname, options); | ||
|  |                 // If we don't have a match, try to render it anyways.
 | ||
|  |                 if (!match) { | ||
|  |                     await this.render(req, res, pathname, query, parsedUrl, true); | ||
|  |                     return true; | ||
|  |                 } | ||
|  |                 // Add the match to the request so we don't have to re-run the matcher
 | ||
|  |                 // for the same request.
 | ||
|  |                 (0, _requestmeta.addRequestMeta)(req, "match", match); | ||
|  |                 // TODO-APP: move this to a route handler
 | ||
|  |                 const edgeFunctionsPages = this.getEdgeFunctionsPages(); | ||
|  |                 for (const edgeFunctionsPage of edgeFunctionsPages){ | ||
|  |                     // If the page doesn't match the edge function page, skip it.
 | ||
|  |                     if (edgeFunctionsPage !== match.definition.page) continue; | ||
|  |                     if (this.nextConfig.output === "export") { | ||
|  |                         await this.render404(req, res, parsedUrl); | ||
|  |                         return true; | ||
|  |                     } | ||
|  |                     delete query._nextBubbleNoFallback; | ||
|  |                     delete query[_approuterheaders.NEXT_RSC_UNION_QUERY]; | ||
|  |                     const handled = await this.runEdgeFunction({ | ||
|  |                         req, | ||
|  |                         res, | ||
|  |                         query, | ||
|  |                         params: match.params, | ||
|  |                         page: match.definition.page, | ||
|  |                         match, | ||
|  |                         appPaths: null | ||
|  |                     }); | ||
|  |                     // If we handled the request, we can return early.
 | ||
|  |                     if (handled) return true; | ||
|  |                 } | ||
|  |                 // If the route was detected as being a Pages API route, then handle
 | ||
|  |                 // it.
 | ||
|  |                 // TODO: move this behavior into a route handler.
 | ||
|  |                 if ((0, _pagesapiroutematch.isPagesAPIRouteMatch)(match)) { | ||
|  |                     if (this.nextConfig.output === "export") { | ||
|  |                         await this.render404(req, res, parsedUrl); | ||
|  |                         return true; | ||
|  |                     } | ||
|  |                     delete query._nextBubbleNoFallback; | ||
|  |                     const handled = await this.handleApiRequest(req, res, query, match); | ||
|  |                     if (handled) return true; | ||
|  |                 } | ||
|  |                 await this.render(req, res, pathname, query, parsedUrl, true); | ||
|  |                 return true; | ||
|  |             } catch (err) { | ||
|  |                 if (err instanceof _baseserver.NoFallbackError) { | ||
|  |                     throw err; | ||
|  |                 } | ||
|  |                 try { | ||
|  |                     if (this.renderOpts.dev) { | ||
|  |                         const { formatServerError } = require("../lib/format-server-error"); | ||
|  |                         formatServerError(err); | ||
|  |                         await this.logErrorWithOriginalStack(err); | ||
|  |                     } else { | ||
|  |                         this.logError(err); | ||
|  |                     } | ||
|  |                     res.statusCode = 500; | ||
|  |                     await this.renderError(err, req, res, pathname, query); | ||
|  |                     return true; | ||
|  |                 } catch  {} | ||
|  |                 throw err; | ||
|  |             } | ||
|  |         }; | ||
|  |         this.handleCatchallMiddlewareRequest = async (req, res, parsed)=>{ | ||
|  |             const isMiddlewareInvoke = req.headers["x-middleware-invoke"]; | ||
|  |             if (!isMiddlewareInvoke) { | ||
|  |                 return false; | ||
|  |             } | ||
|  |             const handleFinished = ()=>{ | ||
|  |                 res.setHeader("x-middleware-invoke", "1"); | ||
|  |                 res.body("").send(); | ||
|  |                 return true; | ||
|  |             }; | ||
|  |             const middleware = this.getMiddleware(); | ||
|  |             if (!middleware) { | ||
|  |                 return handleFinished(); | ||
|  |             } | ||
|  |             const initUrl = (0, _requestmeta.getRequestMeta)(req, "initURL"); | ||
|  |             const parsedUrl = (0, _parseurl.parseUrl)(initUrl); | ||
|  |             const pathnameInfo = (0, _getnextpathnameinfo.getNextPathnameInfo)(parsedUrl.pathname, { | ||
|  |                 nextConfig: this.nextConfig, | ||
|  |                 i18nProvider: this.i18nProvider | ||
|  |             }); | ||
|  |             parsedUrl.pathname = pathnameInfo.pathname; | ||
|  |             const normalizedPathname = (0, _removetrailingslash.removeTrailingSlash)(parsed.pathname || ""); | ||
|  |             if (!middleware.match(normalizedPathname, req, parsedUrl.query)) { | ||
|  |                 return handleFinished(); | ||
|  |             } | ||
|  |             let result; | ||
|  |             let bubblingResult = false; | ||
|  |             // Strip the internal headers.
 | ||
|  |             this.stripInternalHeaders(req); | ||
|  |             try { | ||
|  |                 await this.ensureMiddleware(req.url); | ||
|  |                 result = await this.runMiddleware({ | ||
|  |                     request: req, | ||
|  |                     response: res, | ||
|  |                     parsedUrl: parsedUrl, | ||
|  |                     parsed: parsed | ||
|  |                 }); | ||
|  |                 if ("response" in result) { | ||
|  |                     if (isMiddlewareInvoke) { | ||
|  |                         bubblingResult = true; | ||
|  |                         const err = new Error(); | ||
|  |                         err.result = result; | ||
|  |                         err.bubble = true; | ||
|  |                         throw err; | ||
|  |                     } | ||
|  |                     for (const [key, value] of Object.entries((0, _utils1.toNodeOutgoingHttpHeaders)(result.response.headers))){ | ||
|  |                         if (key !== "content-encoding" && value !== undefined) { | ||
|  |                             res.setHeader(key, value); | ||
|  |                         } | ||
|  |                     } | ||
|  |                     res.statusCode = result.response.status; | ||
|  |                     const { originalResponse } = res; | ||
|  |                     if (result.response.body) { | ||
|  |                         await (0, _pipereadable.pipeToNodeResponse)(result.response.body, originalResponse); | ||
|  |                     } else { | ||
|  |                         originalResponse.end(); | ||
|  |                     } | ||
|  |                     return true; | ||
|  |                 } | ||
|  |             } catch (err) { | ||
|  |                 if (bubblingResult) { | ||
|  |                     throw err; | ||
|  |                 } | ||
|  |                 if ((0, _iserror.default)(err) && err.code === "ENOENT") { | ||
|  |                     await this.render404(req, res, parsed); | ||
|  |                     return true; | ||
|  |                 } | ||
|  |                 if (err instanceof _utils.DecodeError) { | ||
|  |                     res.statusCode = 400; | ||
|  |                     await this.renderError(err, req, res, parsed.pathname || ""); | ||
|  |                     return true; | ||
|  |                 } | ||
|  |                 const error = (0, _iserror.getProperError)(err); | ||
|  |                 console.error(error); | ||
|  |                 res.statusCode = 500; | ||
|  |                 await this.renderError(error, req, res, parsed.pathname || ""); | ||
|  |                 return true; | ||
|  |             } | ||
|  |             return result.finished; | ||
|  |         }; | ||
|  |         /** | ||
|  |      * This sets environment variable to be used at the time of SSR by head.tsx. | ||
|  |      * Using this from process.env allows targeting SSR by calling | ||
|  |      * `process.env.__NEXT_OPTIMIZE_CSS`. | ||
|  |      */ if (this.renderOpts.optimizeFonts) { | ||
|  |             process.env.__NEXT_OPTIMIZE_FONTS = JSON.stringify(this.renderOpts.optimizeFonts); | ||
|  |         } | ||
|  |         if (this.renderOpts.optimizeCss) { | ||
|  |             process.env.__NEXT_OPTIMIZE_CSS = JSON.stringify(true); | ||
|  |         } | ||
|  |         if (this.renderOpts.nextScriptWorkers) { | ||
|  |             process.env.__NEXT_SCRIPT_WORKERS = JSON.stringify(true); | ||
|  |         } | ||
|  |         process.env.NEXT_DEPLOYMENT_ID = this.nextConfig.experimental.deploymentId || ""; | ||
|  |         if (!this.minimalMode) { | ||
|  |             this.imageResponseCache = new _responsecache.default(this.minimalMode); | ||
|  |         } | ||
|  |         const { appDocumentPreloading } = this.nextConfig.experimental; | ||
|  |         const isDefaultEnabled = typeof appDocumentPreloading === "undefined"; | ||
|  |         if (!options.dev && (appDocumentPreloading === true || !(this.minimalMode && isDefaultEnabled))) { | ||
|  |             // pre-warm _document and _app as these will be
 | ||
|  |             // needed for most requests
 | ||
|  |             (0, _loadcomponents.loadComponents)({ | ||
|  |                 distDir: this.distDir, | ||
|  |                 page: "/_document", | ||
|  |                 isAppPath: false | ||
|  |             }).catch(()=>{}); | ||
|  |             (0, _loadcomponents.loadComponents)({ | ||
|  |                 distDir: this.distDir, | ||
|  |                 page: "/_app", | ||
|  |                 isAppPath: false | ||
|  |             }).catch(()=>{}); | ||
|  |         } | ||
|  |         if (!options.dev) { | ||
|  |             const { dynamicRoutes = [] } = this.getRoutesManifest() ?? {}; | ||
|  |             this.dynamicRoutes = dynamicRoutes.map((r)=>{ | ||
|  |                 // TODO: can we just re-use the regex from the manifest?
 | ||
|  |                 const regex = (0, _routeregex.getRouteRegex)(r.page); | ||
|  |                 const match = (0, _routematcher.getRouteMatcher)(regex); | ||
|  |                 return { | ||
|  |                     match, | ||
|  |                     page: r.page, | ||
|  |                     re: regex.re | ||
|  |                 }; | ||
|  |             }); | ||
|  |         } | ||
|  |         // ensure options are set when loadConfig isn't called
 | ||
|  |         (0, _setuphttpagentenv.setHttpClientAndAgentOptions)(this.nextConfig); | ||
|  |         // Intercept fetch and other testmode apis.
 | ||
|  |         if (this.serverOptions.experimentalTestProxy) { | ||
|  |             process.env.NEXT_PRIVATE_TEST_PROXY = "true"; | ||
|  |             const { interceptTestApis } = require("next/dist/experimental/testmode/server"); | ||
|  |             interceptTestApis(); | ||
|  |         } | ||
|  |         this.middlewareManifestPath = (0, _path.join)(this.serverDistDir, _constants.MIDDLEWARE_MANIFEST); | ||
|  |     } | ||
|  |     async handleUpgrade() { | ||
|  |     // The web server does not support web sockets, it's only used for HMR in
 | ||
|  |     // development.
 | ||
|  |     } | ||
|  |     async prepareImpl() { | ||
|  |         await super.prepareImpl(); | ||
|  |         if (!this.serverOptions.dev && this.nextConfig.experimental.instrumentationHook) { | ||
|  |             try { | ||
|  |                 const instrumentationHook = await dynamicRequire((0, _path.resolve)(this.serverOptions.dir || ".", this.serverOptions.conf.distDir, "server", _constants1.INSTRUMENTATION_HOOK_FILENAME)); | ||
|  |                 await (instrumentationHook.register == null ? void 0 : instrumentationHook.register.call(instrumentationHook)); | ||
|  |             } catch (err) { | ||
|  |                 if (err.code !== "MODULE_NOT_FOUND") { | ||
|  |                     err.message = `An error occurred while loading instrumentation hook: ${err.message}`; | ||
|  |                     throw err; | ||
|  |                 } | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  |     loadEnvConfig({ dev, forceReload, silent }) { | ||
|  |         (0, _env.loadEnvConfig)(this.dir, dev, silent ? { | ||
|  |             info: ()=>{}, | ||
|  |             error: ()=>{} | ||
|  |         } : _log, forceReload); | ||
|  |     } | ||
|  |     async getIncrementalCache({ requestHeaders, requestProtocol }) { | ||
|  |         const dev = !!this.renderOpts.dev; | ||
|  |         let CacheHandler; | ||
|  |         const { cacheHandler } = this.nextConfig; | ||
|  |         if (cacheHandler) { | ||
|  |             CacheHandler = (0, _interopdefault.interopDefault)(await dynamicImportEsmDefault((0, _formatdynamicimportpath.formatDynamicImportPath)(this.distDir, cacheHandler))); | ||
|  |         } | ||
|  |         // incremental-cache is request specific
 | ||
|  |         // although can have shared caches in module scope
 | ||
|  |         // per-cache handler
 | ||
|  |         return new _incrementalcache.IncrementalCache({ | ||
|  |             fs: this.getCacheFilesystem(), | ||
|  |             dev, | ||
|  |             requestHeaders, | ||
|  |             requestProtocol, | ||
|  |             pagesDir: this.enabledDirectories.pages, | ||
|  |             appDir: this.enabledDirectories.app, | ||
|  |             allowedRevalidateHeaderKeys: this.nextConfig.experimental.allowedRevalidateHeaderKeys, | ||
|  |             minimalMode: this.minimalMode, | ||
|  |             serverDistDir: this.serverDistDir, | ||
|  |             fetchCache: true, | ||
|  |             fetchCacheKeyPrefix: this.nextConfig.experimental.fetchCacheKeyPrefix, | ||
|  |             maxMemoryCacheSize: this.nextConfig.cacheMaxMemorySize, | ||
|  |             flushToDisk: !this.minimalMode && this.nextConfig.experimental.isrFlushToDisk, | ||
|  |             getPrerenderManifest: ()=>this.getPrerenderManifest(), | ||
|  |             CurCacheHandler: CacheHandler, | ||
|  |             experimental: this.renderOpts.experimental | ||
|  |         }); | ||
|  |     } | ||
|  |     getResponseCache() { | ||
|  |         return new _responsecache.default(this.minimalMode); | ||
|  |     } | ||
|  |     getPublicDir() { | ||
|  |         return (0, _path.join)(this.dir, _constants.CLIENT_PUBLIC_FILES_PATH); | ||
|  |     } | ||
|  |     getHasStaticDir() { | ||
|  |         return _fs.default.existsSync((0, _path.join)(this.dir, "static")); | ||
|  |     } | ||
|  |     getPagesManifest() { | ||
|  |         return (0, _loadmanifest.loadManifest)((0, _path.join)(this.serverDistDir, _constants.PAGES_MANIFEST)); | ||
|  |     } | ||
|  |     getAppPathsManifest() { | ||
|  |         if (!this.enabledDirectories.app) return undefined; | ||
|  |         return (0, _loadmanifest.loadManifest)((0, _path.join)(this.serverDistDir, _constants.APP_PATHS_MANIFEST)); | ||
|  |     } | ||
|  |     async hasPage(pathname) { | ||
|  |         var _this_nextConfig_i18n; | ||
|  |         return !!(0, _require.getMaybePagePath)(pathname, this.distDir, (_this_nextConfig_i18n = this.nextConfig.i18n) == null ? void 0 : _this_nextConfig_i18n.locales, this.enabledDirectories.app); | ||
|  |     } | ||
|  |     getBuildId() { | ||
|  |         const buildIdFile = (0, _path.join)(this.distDir, _constants.BUILD_ID_FILE); | ||
|  |         try { | ||
|  |             return _fs.default.readFileSync(buildIdFile, "utf8").trim(); | ||
|  |         } catch (err) { | ||
|  |             if (err.code === "ENOENT") { | ||
|  |                 throw new Error(`Could not find a production build in the '${this.distDir}' directory. Try building your app with 'next build' before starting the production server. https://nextjs.org/docs/messages/production-start-no-build-id`); | ||
|  |             } | ||
|  |             throw err; | ||
|  |         } | ||
|  |     } | ||
|  |     getEnabledDirectories(dev) { | ||
|  |         const dir = dev ? this.dir : this.serverDistDir; | ||
|  |         return { | ||
|  |             app: (0, _findpagesdir.findDir)(dir, "app") ? true : false, | ||
|  |             pages: (0, _findpagesdir.findDir)(dir, "pages") ? true : false | ||
|  |         }; | ||
|  |     } | ||
|  |     sendRenderResult(req, res, options) { | ||
|  |         return (0, _sendpayload.sendRenderResult)({ | ||
|  |             req: req.originalRequest, | ||
|  |             res: res.originalResponse, | ||
|  |             result: options.result, | ||
|  |             type: options.type, | ||
|  |             generateEtags: options.generateEtags, | ||
|  |             poweredByHeader: options.poweredByHeader, | ||
|  |             revalidate: options.revalidate | ||
|  |         }); | ||
|  |     } | ||
|  |     async runApi(req, res, query, match) { | ||
|  |         const edgeFunctionsPages = this.getEdgeFunctionsPages(); | ||
|  |         for (const edgeFunctionsPage of edgeFunctionsPages){ | ||
|  |             if (edgeFunctionsPage === match.definition.pathname) { | ||
|  |                 const handledAsEdgeFunction = await this.runEdgeFunction({ | ||
|  |                     req, | ||
|  |                     res, | ||
|  |                     query, | ||
|  |                     params: match.params, | ||
|  |                     page: match.definition.pathname, | ||
|  |                     appPaths: null | ||
|  |                 }); | ||
|  |                 if (handledAsEdgeFunction) { | ||
|  |                     return true; | ||
|  |                 } | ||
|  |             } | ||
|  |         } | ||
|  |         // The module supports minimal mode, load the minimal module.
 | ||
|  |         const module = await _routemoduleloader.RouteModuleLoader.load(match.definition.filename); | ||
|  |         query = { | ||
|  |             ...query, | ||
|  |             ...match.params | ||
|  |         }; | ||
|  |         delete query.__nextLocale; | ||
|  |         delete query.__nextDefaultLocale; | ||
|  |         delete query.__nextInferredLocaleFromDefault; | ||
|  |         await module.render(req.originalRequest, res.originalResponse, { | ||
|  |             previewProps: this.renderOpts.previewProps, | ||
|  |             revalidate: this.revalidate.bind(this), | ||
|  |             trustHostHeader: this.nextConfig.experimental.trustHostHeader, | ||
|  |             allowedRevalidateHeaderKeys: this.nextConfig.experimental.allowedRevalidateHeaderKeys, | ||
|  |             hostname: this.fetchHostname, | ||
|  |             minimalMode: this.minimalMode, | ||
|  |             dev: this.renderOpts.dev === true, | ||
|  |             query, | ||
|  |             params: match.params, | ||
|  |             page: match.definition.pathname | ||
|  |         }); | ||
|  |         return true; | ||
|  |     } | ||
|  |     async renderHTML(req, res, pathname, query, renderOpts) { | ||
|  |         return (0, _tracer.getTracer)().trace(_constants2.NextNodeServerSpan.renderHTML, async ()=>this.renderHTMLImpl(req, res, pathname, query, renderOpts)); | ||
|  |     } | ||
|  |     async renderHTMLImpl(req, res, pathname, query, renderOpts) { | ||
|  |         if (process.env.NEXT_MINIMAL) { | ||
|  |             throw new Error("Invariant: renderHTML should not be called in minimal mode"); | ||
|  |         // the `else` branch is needed for tree-shaking
 | ||
|  |         } else { | ||
|  |             // Due to the way we pass data by mutating `renderOpts`, we can't extend the
 | ||
|  |             // object here but only updating its `nextFontManifest` field.
 | ||
|  |             // https://github.com/vercel/next.js/blob/df7cbd904c3bd85f399d1ce90680c0ecf92d2752/packages/next/server/render.tsx#L947-L952
 | ||
|  |             renderOpts.nextFontManifest = this.nextFontManifest; | ||
|  |             if (this.enabledDirectories.app && renderOpts.isAppPath) { | ||
|  |                 return (0, _modulerender.lazyRenderAppPage)(req.originalRequest, res.originalResponse, pathname, query, renderOpts); | ||
|  |             } | ||
|  |             // TODO: re-enable this once we've refactored to use implicit matches
 | ||
|  |             // throw new Error('Invariant: render should have used routeModule')
 | ||
|  |             return (0, _modulerender1.lazyRenderPagesPage)(req.originalRequest, res.originalResponse, pathname, query, renderOpts); | ||
|  |         } | ||
|  |     } | ||
|  |     async imageOptimizer(req, res, paramsResult) { | ||
|  |         if (process.env.NEXT_MINIMAL) { | ||
|  |             throw new Error("invariant: imageOptimizer should not be called in minimal mode"); | ||
|  |         } else { | ||
|  |             const { imageOptimizer, fetchExternalImage, fetchInternalImage } = require("./image-optimizer"); | ||
|  |             const handleInternalReq = async (newReq, newRes)=>{ | ||
|  |                 if (newReq.url === req.url) { | ||
|  |                     throw new Error(`Invariant attempted to optimize _next/image itself`); | ||
|  |                 } | ||
|  |                 if (!this.routerServerHandler) { | ||
|  |                     throw new Error(`Invariant missing routerServerHandler`); | ||
|  |                 } | ||
|  |                 await this.routerServerHandler(newReq, newRes); | ||
|  |                 return; | ||
|  |             }; | ||
|  |             const { isAbsolute, href } = paramsResult; | ||
|  |             const imageUpstream = isAbsolute ? await fetchExternalImage(href) : await fetchInternalImage(href, req.originalRequest, res.originalResponse, handleInternalReq); | ||
|  |             return imageOptimizer(imageUpstream, paramsResult, this.nextConfig, this.renderOpts.dev); | ||
|  |         } | ||
|  |     } | ||
|  |     getPagePath(pathname, locales) { | ||
|  |         return (0, _require.getPagePath)(pathname, this.distDir, locales, this.enabledDirectories.app); | ||
|  |     } | ||
|  |     async renderPageComponent(ctx, bubbleNoFallback) { | ||
|  |         const edgeFunctionsPages = this.getEdgeFunctionsPages() || []; | ||
|  |         if (edgeFunctionsPages.length) { | ||
|  |             const appPaths = this.getOriginalAppPaths(ctx.pathname); | ||
|  |             const isAppPath = Array.isArray(appPaths); | ||
|  |             let page = ctx.pathname; | ||
|  |             if (isAppPath) { | ||
|  |                 // When it's an array, we need to pass all parallel routes to the loader.
 | ||
|  |                 page = appPaths[0]; | ||
|  |             } | ||
|  |             for (const edgeFunctionsPage of edgeFunctionsPages){ | ||
|  |                 if (edgeFunctionsPage === page) { | ||
|  |                     await this.runEdgeFunction({ | ||
|  |                         req: ctx.req, | ||
|  |                         res: ctx.res, | ||
|  |                         query: ctx.query, | ||
|  |                         params: ctx.renderOpts.params, | ||
|  |                         page, | ||
|  |                         appPaths | ||
|  |                     }); | ||
|  |                     return null; | ||
|  |                 } | ||
|  |             } | ||
|  |         } | ||
|  |         return super.renderPageComponent(ctx, bubbleNoFallback); | ||
|  |     } | ||
|  |     async findPageComponents({ page, query, params, isAppPath, url }) { | ||
|  |         return (0, _tracer.getTracer)().trace(_constants2.NextNodeServerSpan.findPageComponents, { | ||
|  |             spanName: "resolve page components", | ||
|  |             attributes: { | ||
|  |                 "next.route": isAppPath ? (0, _apppaths.normalizeAppPath)(page) : page | ||
|  |             } | ||
|  |         }, ()=>this.findPageComponentsImpl({ | ||
|  |                 page, | ||
|  |                 query, | ||
|  |                 params, | ||
|  |                 isAppPath, | ||
|  |                 url | ||
|  |             })); | ||
|  |     } | ||
|  |     async findPageComponentsImpl({ page, query, params, isAppPath, url: _url }) { | ||
|  |         const pagePaths = [ | ||
|  |             page | ||
|  |         ]; | ||
|  |         if (query.amp) { | ||
|  |             // try serving a static AMP version first
 | ||
|  |             pagePaths.unshift((isAppPath ? (0, _apppaths.normalizeAppPath)(page) : (0, _normalizepagepath.normalizePagePath)(page)) + ".amp"); | ||
|  |         } | ||
|  |         if (query.__nextLocale) { | ||
|  |             pagePaths.unshift(...pagePaths.map((path)=>`/${query.__nextLocale}${path === "/" ? "" : path}`)); | ||
|  |         } | ||
|  |         for (const pagePath of pagePaths){ | ||
|  |             try { | ||
|  |                 const components = await (0, _loadcomponents.loadComponents)({ | ||
|  |                     distDir: this.distDir, | ||
|  |                     page: pagePath, | ||
|  |                     isAppPath | ||
|  |                 }); | ||
|  |                 if (query.__nextLocale && typeof components.Component === "string" && !pagePath.startsWith(`/${query.__nextLocale}`)) { | ||
|  |                     continue; | ||
|  |                 } | ||
|  |                 return { | ||
|  |                     components, | ||
|  |                     query: { | ||
|  |                         ...!this.renderOpts.isExperimentalCompile && components.getStaticProps ? { | ||
|  |                             amp: query.amp, | ||
|  |                             __nextDataReq: query.__nextDataReq, | ||
|  |                             __nextLocale: query.__nextLocale, | ||
|  |                             __nextDefaultLocale: query.__nextDefaultLocale | ||
|  |                         } : query, | ||
|  |                         // For appDir params is excluded.
 | ||
|  |                         ...(isAppPath ? {} : params) || {} | ||
|  |                     } | ||
|  |                 }; | ||
|  |             } catch (err) { | ||
|  |                 // we should only not throw if we failed to find the page
 | ||
|  |                 // in the pages-manifest
 | ||
|  |                 if (!(err instanceof _utils.PageNotFoundError)) { | ||
|  |                     throw err; | ||
|  |                 } | ||
|  |             } | ||
|  |         } | ||
|  |         return null; | ||
|  |     } | ||
|  |     getFontManifest() { | ||
|  |         return (0, _require.requireFontManifest)(this.distDir); | ||
|  |     } | ||
|  |     getNextFontManifest() { | ||
|  |         return (0, _loadmanifest.loadManifest)((0, _path.join)(this.distDir, "server", _constants.NEXT_FONT_MANIFEST + ".json")); | ||
|  |     } | ||
|  |     getFallback(page) { | ||
|  |         page = (0, _normalizepagepath.normalizePagePath)(page); | ||
|  |         const cacheFs = this.getCacheFilesystem(); | ||
|  |         return cacheFs.readFile((0, _path.join)(this.serverDistDir, "pages", `${page}.html`), "utf8"); | ||
|  |     } | ||
|  |     // Used in development only, overloaded in next-dev-server
 | ||
|  |     async logErrorWithOriginalStack(_err, _type) { | ||
|  |         throw new Error("Invariant: logErrorWithOriginalStack can only be called on the development server"); | ||
|  |     } | ||
|  |     // Used in development only, overloaded in next-dev-server
 | ||
|  |     async ensurePage(_opts) { | ||
|  |         throw new Error("Invariant: ensurePage can only be called on the development server"); | ||
|  |     } | ||
|  |     /** | ||
|  |    * Resolves `API` request, in development builds on demand | ||
|  |    * @param req http request | ||
|  |    * @param res http response | ||
|  |    * @param pathname path of request | ||
|  |    */ async handleApiRequest(req, res, query, match) { | ||
|  |         return this.runApi(req, res, query, match); | ||
|  |     } | ||
|  |     getPrefetchRsc(pathname) { | ||
|  |         return this.getCacheFilesystem().readFile((0, _path.join)(this.serverDistDir, "app", `${pathname}${_constants1.RSC_PREFETCH_SUFFIX}`), "utf8"); | ||
|  |     } | ||
|  |     getCacheFilesystem() { | ||
|  |         return _nodefsmethods.nodeFs; | ||
|  |     } | ||
|  |     normalizeReq(req) { | ||
|  |         return !(req instanceof _node.NodeNextRequest) ? new _node.NodeNextRequest(req) : req; | ||
|  |     } | ||
|  |     normalizeRes(res) { | ||
|  |         return !(res instanceof _node.NodeNextResponse) ? new _node.NodeNextResponse(res) : res; | ||
|  |     } | ||
|  |     getRequestHandler() { | ||
|  |         const handler = this.makeRequestHandler(); | ||
|  |         if (this.serverOptions.experimentalTestProxy) { | ||
|  |             const { wrapRequestHandlerNode } = require("next/dist/experimental/testmode/server"); | ||
|  |             return wrapRequestHandlerNode(handler); | ||
|  |         } | ||
|  |         return handler; | ||
|  |     } | ||
|  |     makeRequestHandler() { | ||
|  |         // This is just optimization to fire prepare as soon as possible. It will be
 | ||
|  |         // properly awaited later. We add the catch here to ensure that it does not
 | ||
|  |         // cause a unhandled promise rejection. The promise rejection wil be
 | ||
|  |         // handled later on via the `await` when the request handler is called.
 | ||
|  |         this.prepare().catch((err)=>{ | ||
|  |             console.error("Failed to prepare server", err); | ||
|  |         }); | ||
|  |         const handler = super.getRequestHandler(); | ||
|  |         return (req, res, parsedUrl)=>{ | ||
|  |             var _this_nextConfig_logging; | ||
|  |             const normalizedReq = this.normalizeReq(req); | ||
|  |             const normalizedRes = this.normalizeRes(res); | ||
|  |             const loggingFetchesConfig = (_this_nextConfig_logging = this.nextConfig.logging) == null ? void 0 : _this_nextConfig_logging.fetches; | ||
|  |             const enabledVerboseLogging = !!loggingFetchesConfig; | ||
|  |             const shouldTruncateUrl = !(loggingFetchesConfig == null ? void 0 : loggingFetchesConfig.fullUrl); | ||
|  |             if (this.renderOpts.dev) { | ||
|  |                 const { bold, green, yellow, red, gray, white } = require("../lib/picocolors"); | ||
|  |                 const _req = req; | ||
|  |                 const _res = res; | ||
|  |                 const origReq = "originalRequest" in _req ? _req.originalRequest : _req; | ||
|  |                 const origRes = "originalResponse" in _res ? _res.originalResponse : _res; | ||
|  |                 const reqStart = Date.now(); | ||
|  |                 const reqCallback = ()=>{ | ||
|  |                     // if we already logged in a render worker
 | ||
|  |                     // don't log again in the router worker.
 | ||
|  |                     // we also don't log for middleware alone
 | ||
|  |                     if (normalizedReq.didInvokePath || origReq.headers["x-middleware-invoke"]) { | ||
|  |                         return; | ||
|  |                     } | ||
|  |                     const reqEnd = Date.now(); | ||
|  |                     const fetchMetrics = normalizedReq.fetchMetrics || []; | ||
|  |                     const reqDuration = reqEnd - reqStart; | ||
|  |                     const getDurationStr = (duration)=>{ | ||
|  |                         let durationStr = duration.toString(); | ||
|  |                         if (duration < 500) { | ||
|  |                             durationStr = green(duration + "ms"); | ||
|  |                         } else if (duration < 2000) { | ||
|  |                             durationStr = yellow(duration + "ms"); | ||
|  |                         } else { | ||
|  |                             durationStr = red(duration + "ms"); | ||
|  |                         } | ||
|  |                         return durationStr; | ||
|  |                     }; | ||
|  |                     if (Array.isArray(fetchMetrics) && fetchMetrics.length) { | ||
|  |                         if (enabledVerboseLogging) { | ||
|  |                             writeStdoutLine(`${white(bold(req.method || "GET"))} ${req.url} ${res.statusCode} in ${getDurationStr(reqDuration)}`); | ||
|  |                         } | ||
|  |                         const calcNestedLevel = (prevMetrics, start)=>{ | ||
|  |                             let nestedLevel = 0; | ||
|  |                             for(let i = 0; i < prevMetrics.length; i++){ | ||
|  |                                 const metric = prevMetrics[i]; | ||
|  |                                 const prevMetric = prevMetrics[i - 1]; | ||
|  |                                 if (metric.end <= start && !(prevMetric && prevMetric.start < metric.end)) { | ||
|  |                                     nestedLevel += 1; | ||
|  |                                 } | ||
|  |                             } | ||
|  |                             return nestedLevel === 0 ? " " : "  │ ".repeat(nestedLevel); | ||
|  |                         }; | ||
|  |                         for(let i = 0; i < fetchMetrics.length; i++){ | ||
|  |                             const metric = fetchMetrics[i]; | ||
|  |                             let { cacheStatus, cacheReason } = metric; | ||
|  |                             let cacheReasonStr = ""; | ||
|  |                             const duration = metric.end - metric.start; | ||
|  |                             if (cacheStatus === "hit") { | ||
|  |                                 cacheStatus = green("HIT"); | ||
|  |                             } else if (cacheStatus === "skip") { | ||
|  |                                 cacheStatus = yellow("SKIP"); | ||
|  |                                 cacheReasonStr = gray(`Cache missed reason: (${white(cacheReason)})`); | ||
|  |                             } else { | ||
|  |                                 cacheStatus = yellow("MISS"); | ||
|  |                             } | ||
|  |                             let url = metric.url; | ||
|  |                             if (url.length > 48) { | ||
|  |                                 const parsed = new URL(url); | ||
|  |                                 const truncatedHost = formatRequestUrl(parsed.host, shouldTruncateUrl ? 16 : undefined); | ||
|  |                                 const truncatedPath = formatRequestUrl(parsed.pathname, shouldTruncateUrl ? 24 : undefined); | ||
|  |                                 const truncatedSearch = formatRequestUrl(parsed.search, shouldTruncateUrl ? 16 : undefined); | ||
|  |                                 url = parsed.protocol + "//" + truncatedHost + truncatedPath + truncatedSearch; | ||
|  |                             } | ||
|  |                             if (enabledVerboseLogging) { | ||
|  |                                 const newLineLeadingChar = "│"; | ||
|  |                                 const nestedIndent = calcNestedLevel(fetchMetrics.slice(0, i + 1), metric.start); | ||
|  |                                 writeStdoutLine(` ${`${newLineLeadingChar}${nestedIndent}${white(bold(metric.method))} ${gray(url)} ${metric.status} in ${getDurationStr(duration)} (cache: ${cacheStatus})`}`); | ||
|  |                                 if (cacheReasonStr) { | ||
|  |                                     const nextNestedIndent = calcNestedLevel(fetchMetrics.slice(0, i + 1), metric.start); | ||
|  |                                     writeStdoutLine(" " + newLineLeadingChar + nextNestedIndent + " " + newLineLeadingChar + "  " + cacheReasonStr); | ||
|  |                                 } | ||
|  |                             } | ||
|  |                         } | ||
|  |                     } else { | ||
|  |                         if (enabledVerboseLogging) { | ||
|  |                             writeStdoutLine(`${white(bold(req.method || "GET"))} ${req.url} ${res.statusCode} in ${getDurationStr(reqDuration)}`); | ||
|  |                         } | ||
|  |                     } | ||
|  |                     origRes.off("close", reqCallback); | ||
|  |                 }; | ||
|  |                 origRes.on("close", reqCallback); | ||
|  |             } | ||
|  |             return handler(normalizedReq, normalizedRes, parsedUrl); | ||
|  |         }; | ||
|  |     } | ||
|  |     async revalidate({ urlPath, revalidateHeaders, opts }) { | ||
|  |         const mocked = (0, _mockrequest.createRequestResponseMocks)({ | ||
|  |             url: urlPath, | ||
|  |             headers: revalidateHeaders | ||
|  |         }); | ||
|  |         const handler = this.getRequestHandler(); | ||
|  |         await handler(new _node.NodeNextRequest(mocked.req), new _node.NodeNextResponse(mocked.res)); | ||
|  |         await mocked.res.hasStreamed; | ||
|  |         if (mocked.res.getHeader("x-nextjs-cache") !== "REVALIDATED" && !(mocked.res.statusCode === 404 && opts.unstable_onlyGenerated)) { | ||
|  |             throw new Error(`Invalid response ${mocked.res.statusCode}`); | ||
|  |         } | ||
|  |     } | ||
|  |     async render(req, res, pathname, query, parsedUrl, internal = false) { | ||
|  |         return super.render(this.normalizeReq(req), this.normalizeRes(res), pathname, query, parsedUrl, internal); | ||
|  |     } | ||
|  |     async renderToHTML(req, res, pathname, query) { | ||
|  |         return super.renderToHTML(this.normalizeReq(req), this.normalizeRes(res), pathname, query); | ||
|  |     } | ||
|  |     async renderErrorToResponseImpl(ctx, err) { | ||
|  |         const { req, res, query } = ctx; | ||
|  |         const is404 = res.statusCode === 404; | ||
|  |         if (is404 && this.enabledDirectories.app) { | ||
|  |             const notFoundPathname = this.renderOpts.dev ? "/not-found" : "/_not-found"; | ||
|  |             if (this.renderOpts.dev) { | ||
|  |                 await this.ensurePage({ | ||
|  |                     page: notFoundPathname, | ||
|  |                     clientOnly: false, | ||
|  |                     url: req.url | ||
|  |                 }).catch(()=>{}); | ||
|  |             } | ||
|  |             if (this.getEdgeFunctionsPages().includes(notFoundPathname)) { | ||
|  |                 await this.runEdgeFunction({ | ||
|  |                     req: req, | ||
|  |                     res: res, | ||
|  |                     query: query || {}, | ||
|  |                     params: {}, | ||
|  |                     page: notFoundPathname, | ||
|  |                     appPaths: null | ||
|  |                 }); | ||
|  |                 return null; | ||
|  |             } | ||
|  |         } | ||
|  |         return super.renderErrorToResponseImpl(ctx, err); | ||
|  |     } | ||
|  |     async renderError(err, req, res, pathname, query, setHeaders) { | ||
|  |         return super.renderError(err, this.normalizeReq(req), this.normalizeRes(res), pathname, query, setHeaders); | ||
|  |     } | ||
|  |     async renderErrorToHTML(err, req, res, pathname, query) { | ||
|  |         return super.renderErrorToHTML(err, this.normalizeReq(req), this.normalizeRes(res), pathname, query); | ||
|  |     } | ||
|  |     async render404(req, res, parsedUrl, setHeaders) { | ||
|  |         return super.render404(this.normalizeReq(req), this.normalizeRes(res), parsedUrl, setHeaders); | ||
|  |     } | ||
|  |     getMiddlewareManifest() { | ||
|  |         if (this.minimalMode) return null; | ||
|  |         const manifest = require(this.middlewareManifestPath); | ||
|  |         return manifest; | ||
|  |     } | ||
|  |     /** Returns the middleware routing item if there is one. */ getMiddleware() { | ||
|  |         var _manifest_middleware; | ||
|  |         const manifest = this.getMiddlewareManifest(); | ||
|  |         const middleware = manifest == null ? void 0 : (_manifest_middleware = manifest.middleware) == null ? void 0 : _manifest_middleware["/"]; | ||
|  |         if (!middleware) { | ||
|  |             return; | ||
|  |         } | ||
|  |         return { | ||
|  |             match: getMiddlewareMatcher(middleware), | ||
|  |             page: "/" | ||
|  |         }; | ||
|  |     } | ||
|  |     getEdgeFunctionsPages() { | ||
|  |         const manifest = this.getMiddlewareManifest(); | ||
|  |         if (!manifest) { | ||
|  |             return []; | ||
|  |         } | ||
|  |         return Object.keys(manifest.functions); | ||
|  |     } | ||
|  |     /** | ||
|  |    * Get information for the edge function located in the provided page | ||
|  |    * folder. If the edge function info can't be found it will throw | ||
|  |    * an error. | ||
|  |    */ getEdgeFunctionInfo(params) { | ||
|  |         const manifest = this.getMiddlewareManifest(); | ||
|  |         if (!manifest) { | ||
|  |             return null; | ||
|  |         } | ||
|  |         let foundPage; | ||
|  |         try { | ||
|  |             foundPage = (0, _denormalizepagepath.denormalizePagePath)((0, _normalizepagepath.normalizePagePath)(params.page)); | ||
|  |         } catch (err) { | ||
|  |             return null; | ||
|  |         } | ||
|  |         let pageInfo = params.middleware ? manifest.middleware[foundPage] : manifest.functions[foundPage]; | ||
|  |         if (!pageInfo) { | ||
|  |             if (!params.middleware) { | ||
|  |                 throw new _utils.PageNotFoundError(foundPage); | ||
|  |             } | ||
|  |             return null; | ||
|  |         } | ||
|  |         return { | ||
|  |             name: pageInfo.name, | ||
|  |             paths: pageInfo.files.map((file)=>(0, _path.join)(this.distDir, file)), | ||
|  |             wasm: (pageInfo.wasm ?? []).map((binding)=>({ | ||
|  |                     ...binding, | ||
|  |                     filePath: (0, _path.join)(this.distDir, binding.filePath) | ||
|  |                 })), | ||
|  |             assets: (pageInfo.assets ?? []).map((binding)=>{ | ||
|  |                 return { | ||
|  |                     ...binding, | ||
|  |                     filePath: (0, _path.join)(this.distDir, binding.filePath) | ||
|  |                 }; | ||
|  |             }) | ||
|  |         }; | ||
|  |     } | ||
|  |     /** | ||
|  |    * Checks if a middleware exists. This method is useful for the development | ||
|  |    * server where we need to check the filesystem. Here we just check the | ||
|  |    * middleware manifest. | ||
|  |    */ async hasMiddleware(pathname) { | ||
|  |         const info = this.getEdgeFunctionInfo({ | ||
|  |             page: pathname, | ||
|  |             middleware: true | ||
|  |         }); | ||
|  |         return Boolean(info && info.paths.length > 0); | ||
|  |     } | ||
|  |     /** | ||
|  |    * A placeholder for a function to be defined in the development server. | ||
|  |    * It will make sure that the root middleware or an edge function has been compiled | ||
|  |    * so that we can run it. | ||
|  |    */ async ensureMiddleware(_url) {} | ||
|  |     async ensureEdgeFunction(_params) {} | ||
|  |     /** | ||
|  |    * This method gets all middleware matchers and execute them when the request | ||
|  |    * matches. It will make sure that each middleware exists and is compiled and | ||
|  |    * ready to be invoked. The development server will decorate it to add warns | ||
|  |    * and errors with rich traces. | ||
|  |    */ async runMiddleware(params) { | ||
|  |         if (process.env.NEXT_MINIMAL) { | ||
|  |             throw new Error("invariant: runMiddleware should not be called in minimal mode"); | ||
|  |         } | ||
|  |         // Middleware is skipped for on-demand revalidate requests
 | ||
|  |         if ((0, _apiutils.checkIsOnDemandRevalidate)(params.request, this.renderOpts.previewProps).isOnDemandRevalidate) { | ||
|  |             return { | ||
|  |                 response: new Response(null, { | ||
|  |                     headers: { | ||
|  |                         "x-middleware-next": "1" | ||
|  |                     } | ||
|  |                 }) | ||
|  |             }; | ||
|  |         } | ||
|  |         let url; | ||
|  |         if (this.nextConfig.skipMiddlewareUrlNormalize) { | ||
|  |             url = (0, _requestmeta.getRequestMeta)(params.request, "initURL"); | ||
|  |         } else { | ||
|  |             // For middleware to "fetch" we must always provide an absolute URL
 | ||
|  |             const query = (0, _querystring.urlQueryToSearchParams)(params.parsed.query).toString(); | ||
|  |             const locale = params.parsed.query.__nextLocale; | ||
|  |             url = `${(0, _requestmeta.getRequestMeta)(params.request, "initProtocol")}://${this.fetchHostname || "localhost"}:${this.port}${locale ? `/${locale}` : ""}${params.parsed.pathname}${query ? `?${query}` : ""}`; | ||
|  |         } | ||
|  |         if (!url.startsWith("http")) { | ||
|  |             throw new Error("To use middleware you must provide a `hostname` and `port` to the Next.js Server"); | ||
|  |         } | ||
|  |         const page = {}; | ||
|  |         const middleware = this.getMiddleware(); | ||
|  |         if (!middleware) { | ||
|  |             return { | ||
|  |                 finished: false | ||
|  |             }; | ||
|  |         } | ||
|  |         if (!await this.hasMiddleware(middleware.page)) { | ||
|  |             return { | ||
|  |                 finished: false | ||
|  |             }; | ||
|  |         } | ||
|  |         await this.ensureMiddleware(params.request.url); | ||
|  |         const middlewareInfo = this.getEdgeFunctionInfo({ | ||
|  |             page: middleware.page, | ||
|  |             middleware: true | ||
|  |         }); | ||
|  |         if (!middlewareInfo) { | ||
|  |             throw new _utils.MiddlewareNotFoundError(); | ||
|  |         } | ||
|  |         const method = (params.request.method || "GET").toUpperCase(); | ||
|  |         const { run } = require("./web/sandbox"); | ||
|  |         const result = await run({ | ||
|  |             distDir: this.distDir, | ||
|  |             name: middlewareInfo.name, | ||
|  |             paths: middlewareInfo.paths, | ||
|  |             edgeFunctionEntry: middlewareInfo, | ||
|  |             request: { | ||
|  |                 headers: params.request.headers, | ||
|  |                 method, | ||
|  |                 nextConfig: { | ||
|  |                     basePath: this.nextConfig.basePath, | ||
|  |                     i18n: this.nextConfig.i18n, | ||
|  |                     trailingSlash: this.nextConfig.trailingSlash | ||
|  |                 }, | ||
|  |                 url: url, | ||
|  |                 page, | ||
|  |                 body: (0, _requestmeta.getRequestMeta)(params.request, "clonableBody"), | ||
|  |                 signal: (0, _nextrequest.signalFromNodeResponse)(params.response.originalResponse) | ||
|  |             }, | ||
|  |             useCache: true, | ||
|  |             onWarning: params.onWarning | ||
|  |         }); | ||
|  |         if (!this.renderOpts.dev) { | ||
|  |             result.waitUntil.catch((error)=>{ | ||
|  |                 console.error(`Uncaught: middleware waitUntil errored`, error); | ||
|  |             }); | ||
|  |         } | ||
|  |         if (!result) { | ||
|  |             this.render404(params.request, params.response, params.parsed); | ||
|  |             return { | ||
|  |                 finished: true | ||
|  |             }; | ||
|  |         } | ||
|  |         for (let [key, value] of result.response.headers){ | ||
|  |             if (key.toLowerCase() !== "set-cookie") continue; | ||
|  |             // Clear existing header.
 | ||
|  |             result.response.headers.delete(key); | ||
|  |             // Append each cookie individually.
 | ||
|  |             const cookies = (0, _utils1.splitCookiesString)(value); | ||
|  |             for (const cookie of cookies){ | ||
|  |                 result.response.headers.append(key, cookie); | ||
|  |             } | ||
|  |             // Add cookies to request meta.
 | ||
|  |             (0, _requestmeta.addRequestMeta)(params.request, "middlewareCookie", cookies); | ||
|  |         } | ||
|  |         return result; | ||
|  |     } | ||
|  |     getPrerenderManifest() { | ||
|  |         var _this_renderOpts, _this_serverOptions; | ||
|  |         if (this._cachedPreviewManifest) { | ||
|  |             return this._cachedPreviewManifest; | ||
|  |         } | ||
|  |         if (((_this_renderOpts = this.renderOpts) == null ? void 0 : _this_renderOpts.dev) || ((_this_serverOptions = this.serverOptions) == null ? void 0 : _this_serverOptions.dev) || process.env.NODE_ENV === "development" || process.env.NEXT_PHASE === _constants.PHASE_PRODUCTION_BUILD) { | ||
|  |             this._cachedPreviewManifest = { | ||
|  |                 version: 4, | ||
|  |                 routes: {}, | ||
|  |                 dynamicRoutes: {}, | ||
|  |                 notFoundRoutes: [], | ||
|  |                 preview: { | ||
|  |                     previewModeId: require("crypto").randomBytes(16).toString("hex"), | ||
|  |                     previewModeSigningKey: require("crypto").randomBytes(32).toString("hex"), | ||
|  |                     previewModeEncryptionKey: require("crypto").randomBytes(32).toString("hex") | ||
|  |                 } | ||
|  |             }; | ||
|  |             return this._cachedPreviewManifest; | ||
|  |         } | ||
|  |         const manifest = (0, _loadmanifest.loadManifest)((0, _path.join)(this.distDir, _constants.PRERENDER_MANIFEST)); | ||
|  |         return this._cachedPreviewManifest = manifest; | ||
|  |     } | ||
|  |     getRoutesManifest() { | ||
|  |         return (0, _tracer.getTracer)().trace(_constants2.NextNodeServerSpan.getRoutesManifest, ()=>{ | ||
|  |             const manifest = (0, _loadmanifest.loadManifest)((0, _path.join)(this.distDir, _constants.ROUTES_MANIFEST)); | ||
|  |             let rewrites = manifest.rewrites ?? { | ||
|  |                 beforeFiles: [], | ||
|  |                 afterFiles: [], | ||
|  |                 fallback: [] | ||
|  |             }; | ||
|  |             if (Array.isArray(rewrites)) { | ||
|  |                 rewrites = { | ||
|  |                     beforeFiles: [], | ||
|  |                     afterFiles: rewrites, | ||
|  |                     fallback: [] | ||
|  |                 }; | ||
|  |             } | ||
|  |             return { | ||
|  |                 ...manifest, | ||
|  |                 rewrites | ||
|  |             }; | ||
|  |         }); | ||
|  |     } | ||
|  |     attachRequestMeta(req, parsedUrl, isUpgradeReq) { | ||
|  |         // Injected in base-server.ts
 | ||
|  |         const protocol = req.headers["x-forwarded-proto"]; | ||
|  |         // When there are hostname and port we build an absolute URL
 | ||
|  |         const initUrl = this.fetchHostname && this.port ? `${protocol}://${this.fetchHostname}:${this.port}${req.url}` : this.nextConfig.experimental.trustHostHeader ? `https://${req.headers.host || "localhost"}${req.url}` : req.url; | ||
|  |         (0, _requestmeta.addRequestMeta)(req, "initURL", initUrl); | ||
|  |         (0, _requestmeta.addRequestMeta)(req, "initQuery", { | ||
|  |             ...parsedUrl.query | ||
|  |         }); | ||
|  |         (0, _requestmeta.addRequestMeta)(req, "initProtocol", protocol); | ||
|  |         if (!isUpgradeReq) { | ||
|  |             (0, _requestmeta.addRequestMeta)(req, "clonableBody", (0, _bodystreams.getCloneableBody)(req.body)); | ||
|  |         } | ||
|  |     } | ||
|  |     async runEdgeFunction(params) { | ||
|  |         if (process.env.NEXT_MINIMAL) { | ||
|  |             throw new Error("Middleware is not supported in minimal mode. Please remove the `NEXT_MINIMAL` environment variable."); | ||
|  |         } | ||
|  |         let edgeInfo; | ||
|  |         const { query, page, match } = params; | ||
|  |         if (!match) await this.ensureEdgeFunction({ | ||
|  |             page, | ||
|  |             appPaths: params.appPaths, | ||
|  |             url: params.req.url | ||
|  |         }); | ||
|  |         edgeInfo = this.getEdgeFunctionInfo({ | ||
|  |             page, | ||
|  |             middleware: false | ||
|  |         }); | ||
|  |         if (!edgeInfo) { | ||
|  |             return null; | ||
|  |         } | ||
|  |         // For edge to "fetch" we must always provide an absolute URL
 | ||
|  |         const isDataReq = !!query.__nextDataReq; | ||
|  |         const initialUrl = new URL((0, _requestmeta.getRequestMeta)(params.req, "initURL") || "/", "http://n"); | ||
|  |         const queryString = (0, _querystring.urlQueryToSearchParams)({ | ||
|  |             ...Object.fromEntries(initialUrl.searchParams), | ||
|  |             ...query, | ||
|  |             ...params.params | ||
|  |         }).toString(); | ||
|  |         if (isDataReq) { | ||
|  |             params.req.headers["x-nextjs-data"] = "1"; | ||
|  |         } | ||
|  |         initialUrl.search = queryString; | ||
|  |         const url = initialUrl.toString(); | ||
|  |         if (!url.startsWith("http")) { | ||
|  |             throw new Error("To use middleware you must provide a `hostname` and `port` to the Next.js Server"); | ||
|  |         } | ||
|  |         const { run } = require("./web/sandbox"); | ||
|  |         const result = await run({ | ||
|  |             distDir: this.distDir, | ||
|  |             name: edgeInfo.name, | ||
|  |             paths: edgeInfo.paths, | ||
|  |             edgeFunctionEntry: edgeInfo, | ||
|  |             request: { | ||
|  |                 headers: params.req.headers, | ||
|  |                 method: params.req.method, | ||
|  |                 nextConfig: { | ||
|  |                     basePath: this.nextConfig.basePath, | ||
|  |                     i18n: this.nextConfig.i18n, | ||
|  |                     trailingSlash: this.nextConfig.trailingSlash | ||
|  |                 }, | ||
|  |                 url, | ||
|  |                 page: { | ||
|  |                     name: params.page, | ||
|  |                     ...params.params && { | ||
|  |                         params: params.params | ||
|  |                     } | ||
|  |                 }, | ||
|  |                 body: (0, _requestmeta.getRequestMeta)(params.req, "clonableBody"), | ||
|  |                 signal: (0, _nextrequest.signalFromNodeResponse)(params.res.originalResponse) | ||
|  |             }, | ||
|  |             useCache: true, | ||
|  |             onWarning: params.onWarning, | ||
|  |             incrementalCache: globalThis.__incrementalCache || (0, _requestmeta.getRequestMeta)(params.req, "incrementalCache") | ||
|  |         }); | ||
|  |         if (result.fetchMetrics) { | ||
|  |             params.req.fetchMetrics = result.fetchMetrics; | ||
|  |         } | ||
|  |         if (!params.res.statusCode || params.res.statusCode < 400) { | ||
|  |             params.res.statusCode = result.response.status; | ||
|  |             params.res.statusMessage = result.response.statusText; | ||
|  |         } | ||
|  |         // TODO: (wyattjoh) investigate improving this
 | ||
|  |         result.response.headers.forEach((value, key)=>{ | ||
|  |             // The append handling is special cased for `set-cookie`.
 | ||
|  |             if (key.toLowerCase() === "set-cookie") { | ||
|  |                 // TODO: (wyattjoh) replace with native response iteration when we can upgrade undici
 | ||
|  |                 for (const cookie of (0, _utils1.splitCookiesString)(value)){ | ||
|  |                     params.res.appendHeader(key, cookie); | ||
|  |                 } | ||
|  |             } else { | ||
|  |                 params.res.appendHeader(key, value); | ||
|  |             } | ||
|  |         }); | ||
|  |         const nodeResStream = params.res.originalResponse; | ||
|  |         if (result.response.body) { | ||
|  |             await (0, _pipereadable.pipeToNodeResponse)(result.response.body, nodeResStream); | ||
|  |         } else { | ||
|  |             nodeResStream.end(); | ||
|  |         } | ||
|  |         return result; | ||
|  |     } | ||
|  |     get serverDistDir() { | ||
|  |         if (this._serverDistDir) { | ||
|  |             return this._serverDistDir; | ||
|  |         } | ||
|  |         const serverDistDir = (0, _path.join)(this.distDir, _constants.SERVER_DIRECTORY); | ||
|  |         this._serverDistDir = serverDistDir; | ||
|  |         return serverDistDir; | ||
|  |     } | ||
|  |     async getFallbackErrorComponents(_url) { | ||
|  |         // Not implemented for production use cases, this is implemented on the
 | ||
|  |         // development server.
 | ||
|  |         return null; | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | //# sourceMappingURL=next-server.js.map
 |