UNPKG

next

Version:

The React Framework

986 lines (985 loc) • 158 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); 0 && (module.exports = { renderToHTMLOrFlight: null, warmFlightResponse: null }); function _export(target, all) { for(var name in all)Object.defineProperty(target, name, { enumerable: true, get: all[name] }); } _export(exports, { renderToHTMLOrFlight: function() { return renderToHTMLOrFlight; }, warmFlightResponse: function() { return warmFlightResponse; } }); const _jsxruntime = require("react/jsx-runtime"); const _workasyncstorageexternal = require("../app-render/work-async-storage.external"); const _react = /*#__PURE__*/ _interop_require_default(require("react")); const _renderresult = /*#__PURE__*/ _interop_require_default(require("../render-result")); const _nodewebstreamshelper = require("../stream-utils/node-web-streams-helper"); const _internalutils = require("../internal-utils"); const _approuterheaders = require("../../client/components/app-router-headers"); const _metadatacontext = require("../../lib/metadata/metadata-context"); const _requeststore = require("../async-storage/request-store"); const _workstore = require("../async-storage/work-store"); const _httpaccessfallback = require("../../client/components/http-access-fallback/http-access-fallback"); const _redirect = require("../../client/components/redirect"); const _redirecterror = require("../../client/components/redirect-error"); const _implicittags = require("../lib/implicit-tags"); const _constants = require("../lib/trace/constants"); const _tracer = require("../lib/trace/tracer"); const _flightrenderresult = require("./flight-render-result"); const _createerrorhandler = require("./create-error-handler"); const _getshortdynamicparamtype = require("./get-short-dynamic-param-type"); const _getsegmentparam = require("./get-segment-param"); const _getscriptnoncefromheader = require("./get-script-nonce-from-header"); const _parseandvalidateflightrouterstate = require("./parse-and-validate-flight-router-state"); const _createflightrouterstatefromloadertree = require("./create-flight-router-state-from-loader-tree"); const _actionhandler = require("./action-handler"); const _bailouttocsr = require("../../shared/lib/lazy-dynamic/bailout-to-csr"); const _log = require("../../build/output/log"); const _requestcookies = require("../web/spec-extension/adapters/request-cookies"); const _serverinsertedhtml = require("./server-inserted-html"); const _requiredscripts = require("./required-scripts"); const _addpathprefix = require("../../shared/lib/router/utils/add-path-prefix"); const _makegetserverinsertedhtml = require("./make-get-server-inserted-html"); const _walktreewithflightrouterstate = require("./walk-tree-with-flight-router-state"); const _createcomponenttree = require("./create-component-tree"); const _getassetquerystring = require("./get-asset-query-string"); const _encryptionutils = require("./encryption-utils"); const _postponedstate = require("./postponed-state"); const _hooksservercontext = require("../../client/components/hooks-server-context"); const _useflightresponse = require("./use-flight-response"); const _staticgenerationbailout = require("../../client/components/static-generation-bailout"); const _formatservererror = require("../../lib/format-server-error"); const _dynamicrendering = require("./dynamic-rendering"); const _clientcomponentrendererlogger = require("../client-component-renderer-logger"); const _actionutils = require("./action-utils"); const _helpers = require("../base-http/helpers"); const _routeregex = require("../../shared/lib/router/utils/route-regex"); const _parserelativeurl = require("../../shared/lib/router/utils/parse-relative-url"); const _approuter = /*#__PURE__*/ _interop_require_default(require("../../client/components/app-router")); const _serveractionrequestmeta = require("../lib/server-action-request-meta"); const _createinitialrouterstate = require("../../client/components/router-reducer/create-initial-router-state"); const _approuterinstance = require("../../client/components/app-router-instance"); const _utils = require("../instrumentation/utils"); const _segment = require("../../shared/lib/segment"); const _apprenderprerenderutils = require("./app-render-prerender-utils"); const _prospectiverenderutils = require("./prospective-render-utils"); const _apprenderrenderutils = require("./app-render-render-utils"); const _scheduler = require("../../lib/scheduler"); const _workunitasyncstorageexternal = require("./work-unit-async-storage.external"); const _cachesignal = require("./cache-signal"); const _utils1 = require("../lib/trace/utils"); const _invarianterror = require("../../shared/lib/invariant-error"); require("./clean-async-snapshot.external"); const _constants1 = require("../../lib/constants"); const _createcomponentstylesandscripts = require("./create-component-styles-and-scripts"); const _parseloadertree = require("./parse-loader-tree"); const _resumedatacache = require("../resume-data-cache/resume-data-cache"); const _iserror = /*#__PURE__*/ _interop_require_default(require("../../lib/is-error")); const _usecacheerrors = require("../use-cache/use-cache-errors"); const _createserverinsertedmetadata = require("./metadata-insertion/create-server-inserted-metadata"); const _serverutils = require("../server-utils"); const _revalidationutils = require("../revalidation-utils"); function _interop_require_default(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const flightDataPathHeadKey = 'h'; function parseRequestHeaders(headers, options) { const isDevWarmupRequest = options.isDevWarmup === true; // dev warmup requests are treated as prefetch RSC requests const isPrefetchRequest = isDevWarmupRequest || headers[_approuterheaders.NEXT_ROUTER_PREFETCH_HEADER.toLowerCase()] !== undefined; const isHmrRefresh = headers[_approuterheaders.NEXT_HMR_REFRESH_HEADER.toLowerCase()] !== undefined; // dev warmup requests are treated as prefetch RSC requests const isRSCRequest = isDevWarmupRequest || headers[_approuterheaders.RSC_HEADER.toLowerCase()] !== undefined; const shouldProvideFlightRouterState = isRSCRequest && (!isPrefetchRequest || !options.isRoutePPREnabled); const flightRouterState = shouldProvideFlightRouterState ? (0, _parseandvalidateflightrouterstate.parseAndValidateFlightRouterState)(headers[_approuterheaders.NEXT_ROUTER_STATE_TREE_HEADER.toLowerCase()]) : undefined; // Checks if this is a prefetch of the Route Tree by the Segment Cache const isRouteTreePrefetchRequest = headers[_approuterheaders.NEXT_ROUTER_SEGMENT_PREFETCH_HEADER.toLowerCase()] === '/_tree'; const csp = headers['content-security-policy'] || headers['content-security-policy-report-only']; const nonce = typeof csp === 'string' ? (0, _getscriptnoncefromheader.getScriptNonceFromHeader)(csp) : undefined; const previouslyRevalidatedTags = (0, _serverutils.getPreviouslyRevalidatedTags)(headers, options.previewModeId); return { flightRouterState, isPrefetchRequest, isRouteTreePrefetchRequest, isHmrRefresh, isRSCRequest, isDevWarmupRequest, nonce, previouslyRevalidatedTags }; } function createNotFoundLoaderTree(loaderTree) { // Align the segment with parallel-route-default in next-app-loader const components = loaderTree[2]; return [ '', { children: [ _segment.PAGE_SEGMENT_KEY, {}, { page: components['not-found'] } ] }, components ]; } function createDivergedMetadataComponents(Metadata, serveStreamingMetadata) { function EmptyMetadata() { return null; } const StreamingMetadata = serveStreamingMetadata ? Metadata : null; const StaticMetadata = serveStreamingMetadata ? EmptyMetadata : Metadata; return { StaticMetadata, StreamingMetadata }; } /** * Returns a function that parses the dynamic segment and return the associated value. */ function makeGetDynamicParamFromSegment(params, pagePath, fallbackRouteParams) { return function getDynamicParamFromSegment(// [slug] / [[slug]] / [...slug] segment) { const segmentParam = (0, _getsegmentparam.getSegmentParam)(segment); if (!segmentParam) { return null; } const key = segmentParam.param; let value = params[key]; if (fallbackRouteParams && fallbackRouteParams.has(segmentParam.param)) { value = fallbackRouteParams.get(segmentParam.param); } else if (Array.isArray(value)) { value = value.map((i)=>encodeURIComponent(i)); } else if (typeof value === 'string') { value = encodeURIComponent(value); } if (!value) { const isCatchall = segmentParam.type === 'catchall'; const isOptionalCatchall = segmentParam.type === 'optional-catchall'; if (isCatchall || isOptionalCatchall) { const dynamicParamType = _getshortdynamicparamtype.dynamicParamTypes[segmentParam.type]; // handle the case where an optional catchall does not have a value, // e.g. `/dashboard/[[...slug]]` when requesting `/dashboard` if (isOptionalCatchall) { return { param: key, value: null, type: dynamicParamType, treeSegment: [ key, '', dynamicParamType ] }; } // handle the case where a catchall or optional catchall does not have a value, // e.g. `/foo/bar/hello` and `@slot/[...catchall]` or `@slot/[[...catchall]]` is matched value = pagePath.split('/')// remove the first empty string .slice(1)// replace any dynamic params with the actual values .flatMap((pathSegment)=>{ const param = (0, _routeregex.parseParameter)(pathSegment); // if the segment matches a param, return the param value // otherwise, it's a static segment, so just return that return params[param.key] ?? param.key; }); return { param: key, value, type: dynamicParamType, // This value always has to be a string. treeSegment: [ key, value.join('/'), dynamicParamType ] }; } } const type = (0, _getshortdynamicparamtype.getShortDynamicParamType)(segmentParam.type); return { param: key, // The value that is passed to user code. value: value, // The value that is rendered in the router tree. treeSegment: [ key, Array.isArray(value) ? value.join('/') : value, type ], type: type }; }; } function NonIndex({ pagePath, statusCode, isPossibleServerAction }) { const is404Page = pagePath === '/404'; const isInvalidStatusCode = typeof statusCode === 'number' && statusCode > 400; // Only render noindex for page request, skip for server actions // TODO: is this correct if `isPossibleServerAction` is a false positive? if (!isPossibleServerAction && (is404Page || isInvalidStatusCode)) { return /*#__PURE__*/ (0, _jsxruntime.jsx)("meta", { name: "robots", content: "noindex" }); } return null; } /** * This is used by server actions & client-side navigations to generate RSC data from a client-side request. * This function is only called on "dynamic" requests (ie, there wasn't already a static response). * It uses request headers (namely `Next-Router-State-Tree`) to determine where to start rendering. */ async function generateDynamicRSCPayload(ctx, options) { // Flight data that is going to be passed to the browser. // Currently a single item array but in the future multiple patches might be combined in a single request. // We initialize `flightData` to an empty string because the client router knows how to tolerate // it (treating it as an MPA navigation). The only time this function wouldn't generate flight data // is for server actions, if the server action handler instructs this function to skip it. When the server // action reducer sees a falsy value, it'll simply resolve the action with no data. let flightData = ''; const { componentMod: { tree: loaderTree, createMetadataComponents, MetadataBoundary, ViewportBoundary }, getDynamicParamFromSegment, appUsingSizeAdjustment, query, requestId, flightRouterState, workStore, url } = ctx; const serveStreamingMetadata = !!ctx.renderOpts.serveStreamingMetadata; if (!(options == null ? void 0 : options.skipFlight)) { const preloadCallbacks = []; const { ViewportTree, MetadataTree, getViewportReady, getMetadataReady, StreamingMetadataOutlet } = createMetadataComponents({ tree: loaderTree, parsedQuery: query, metadataContext: (0, _metadatacontext.createTrackedMetadataContext)(url.pathname, ctx.renderOpts, workStore), getDynamicParamFromSegment, appUsingSizeAdjustment, workStore, MetadataBoundary, ViewportBoundary, serveStreamingMetadata }); const { StreamingMetadata, StaticMetadata } = createDivergedMetadataComponents(()=>{ return(// Adding requestId as react key to make metadata remount for each render /*#__PURE__*/ (0, _jsxruntime.jsx)(MetadataTree, {}, requestId)); }, serveStreamingMetadata); flightData = (await (0, _walktreewithflightrouterstate.walkTreeWithFlightRouterState)({ ctx, loaderTreeToFilter: loaderTree, parentParams: {}, flightRouterState, // For flight, render metadata inside leaf page rscHead: /*#__PURE__*/ (0, _jsxruntime.jsxs)(_react.default.Fragment, { children: [ /*#__PURE__*/ (0, _jsxruntime.jsx)(NonIndex, { pagePath: ctx.pagePath, statusCode: ctx.res.statusCode, isPossibleServerAction: ctx.isPossibleServerAction }), /*#__PURE__*/ (0, _jsxruntime.jsx)(ViewportTree, {}, requestId), StreamingMetadata ? /*#__PURE__*/ (0, _jsxruntime.jsx)(StreamingMetadata, {}) : null, /*#__PURE__*/ (0, _jsxruntime.jsx)(StaticMetadata, {}) ] }, flightDataPathHeadKey), injectedCSS: new Set(), injectedJS: new Set(), injectedFontPreloadTags: new Set(), rootLayoutIncluded: false, getViewportReady, getMetadataReady, preloadCallbacks, StreamingMetadataOutlet })).map((path)=>path.slice(1)) // remove the '' (root) segment ; } // If we have an action result, then this is a server action response. // We can rely on this because `ActionResult` will always be a promise, even if // the result is falsey. if (options == null ? void 0 : options.actionResult) { return { a: options.actionResult, f: flightData, b: ctx.sharedContext.buildId }; } // Otherwise, it's a regular RSC response. return { b: ctx.sharedContext.buildId, f: flightData, S: workStore.isStaticGeneration }; } function createErrorContext(ctx, renderSource) { return { routerKind: 'App Router', routePath: ctx.pagePath, // TODO: is this correct if `isPossibleServerAction` is a false positive? routeType: ctx.isPossibleServerAction ? 'action' : 'render', renderSource, revalidateReason: (0, _utils.getRevalidateReason)(ctx.workStore) }; } /** * Produces a RenderResult containing the Flight data for the given request. See * `generateDynamicRSCPayload` for information on the contents of the render result. */ async function generateDynamicFlightRenderResult(req, ctx, requestStore, options) { const renderOpts = ctx.renderOpts; function onFlightDataRenderError(err) { return renderOpts.onInstrumentationRequestError == null ? void 0 : renderOpts.onInstrumentationRequestError.call(renderOpts, err, req, createErrorContext(ctx, 'react-server-components-payload')); } const onError = (0, _createerrorhandler.createFlightReactServerErrorHandler)(!!renderOpts.dev, onFlightDataRenderError); const RSCPayload = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(requestStore, generateDynamicRSCPayload, ctx, options); if (// We only want this behavior when running `next dev` renderOpts.dev && // We only want this behavior when we have React's dev builds available process.env.NODE_ENV === 'development' && // We only have a Prerender environment for projects opted into dynamicIO renderOpts.experimental.dynamicIO) { const [resolveValidation, validationOutlet] = createValidationOutlet(); RSCPayload._validation = validationOutlet; spawnDynamicValidationInDev(resolveValidation, ctx.componentMod.tree, ctx, false, ctx.clientReferenceManifest, ctx.workStore.route, requestStore); } // For app dir, use the bundled version of Flight server renderer (renderToReadableStream) // which contains the subset React. const flightReadableStream = _workunitasyncstorageexternal.workUnitAsyncStorage.run(requestStore, ctx.componentMod.renderToReadableStream, RSCPayload, ctx.clientReferenceManifest.clientModules, { onError, temporaryReferences: options == null ? void 0 : options.temporaryReferences }); return new _flightrenderresult.FlightRenderResult(flightReadableStream, { fetchMetrics: ctx.workStore.fetchMetrics }); } /** * Performs a "warmup" render of the RSC payload for a given route. This function is called by the server * prior to an actual render request in Dev mode only. It's purpose is to fill caches so the actual render * can accurately log activity in the right render context (Prerender vs Render). * * At the moment this implementation is mostly a fork of generateDynamicFlightRenderResult */ async function warmupDevRender(req, ctx) { const { clientReferenceManifest, componentMod, getDynamicParamFromSegment, implicitTags, renderOpts, workStore } = ctx; if (!renderOpts.dev) { throw Object.defineProperty(new _invarianterror.InvariantError('generateDynamicFlightRenderResult should never be called in `next start` mode.'), "__NEXT_ERROR_CODE", { value: "E523", enumerable: false, configurable: true }); } const rootParams = (0, _createcomponenttree.getRootParams)(componentMod.tree, getDynamicParamFromSegment); function onFlightDataRenderError(err) { return renderOpts.onInstrumentationRequestError == null ? void 0 : renderOpts.onInstrumentationRequestError.call(renderOpts, err, req, createErrorContext(ctx, 'react-server-components-payload')); } const onError = (0, _createerrorhandler.createFlightReactServerErrorHandler)(true, onFlightDataRenderError); // We're doing a dev warmup, so we should create a new resume data cache so // we can fill it. const prerenderResumeDataCache = (0, _resumedatacache.createPrerenderResumeDataCache)(); const renderController = new AbortController(); const prerenderController = new AbortController(); const cacheSignal = new _cachesignal.CacheSignal(); const prerenderStore = { type: 'prerender', phase: 'render', rootParams, implicitTags, renderSignal: renderController.signal, controller: prerenderController, cacheSignal, dynamicTracking: null, revalidate: _constants1.INFINITE_CACHE, expire: _constants1.INFINITE_CACHE, stale: _constants1.INFINITE_CACHE, tags: [], prerenderResumeDataCache, hmrRefreshHash: req.cookies[_approuterheaders.NEXT_HMR_REFRESH_HASH_COOKIE] }; const rscPayload = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(prerenderStore, generateDynamicRSCPayload, ctx); // For app dir, use the bundled version of Flight server renderer (renderToReadableStream) // which contains the subset React. _workunitasyncstorageexternal.workUnitAsyncStorage.run(prerenderStore, componentMod.renderToReadableStream, rscPayload, clientReferenceManifest.clientModules, { onError, signal: renderController.signal }); // Wait for all caches to be finished filling await cacheSignal.cacheReady(); // We unset the cache so any late over-run renders aren't able to write into this cache prerenderStore.prerenderResumeDataCache = null; // Abort the render renderController.abort(); // We don't really want to return a result here but the stack of functions // that calls into renderToHTML... expects a result. We should refactor this to // lift the warmup pathway outside of renderToHTML... but for now this suffices return new _flightrenderresult.FlightRenderResult('', { fetchMetrics: workStore.fetchMetrics, devRenderResumeDataCache: (0, _resumedatacache.createRenderResumeDataCache)(prerenderResumeDataCache) }); } /** * Crawlers will inadvertently think the canonicalUrl in the RSC payload should be crawled * when our intention is to just seed the router state with the current URL. * This function splits up the pathname so that we can later join it on * when we're ready to consume the path. */ function prepareInitialCanonicalUrl(url) { return (url.pathname + url.search).split('/'); } // This is the data necessary to render <AppRouter /> when no SSR errors are encountered async function getRSCPayload(tree, ctx, is404) { const injectedCSS = new Set(); const injectedJS = new Set(); const injectedFontPreloadTags = new Set(); let missingSlots; // We only track missing parallel slots in development if (process.env.NODE_ENV === 'development') { missingSlots = new Set(); } const { getDynamicParamFromSegment, query, appUsingSizeAdjustment, componentMod: { GlobalError, createMetadataComponents, MetadataBoundary, ViewportBoundary }, url, workStore } = ctx; const initialTree = (0, _createflightrouterstatefromloadertree.createFlightRouterStateFromLoaderTree)(tree, getDynamicParamFromSegment, query); const serveStreamingMetadata = !!ctx.renderOpts.serveStreamingMetadata; const { ViewportTree, MetadataTree, getViewportReady, getMetadataReady, StreamingMetadataOutlet } = createMetadataComponents({ tree, errorType: is404 ? 'not-found' : undefined, parsedQuery: query, metadataContext: (0, _metadatacontext.createTrackedMetadataContext)(url.pathname, ctx.renderOpts, workStore), getDynamicParamFromSegment, appUsingSizeAdjustment, workStore, MetadataBoundary, ViewportBoundary, serveStreamingMetadata }); const preloadCallbacks = []; const { StreamingMetadata, StaticMetadata } = createDivergedMetadataComponents(()=>{ return(// Not add requestId as react key to ensure segment prefetch could result consistently if nothing changed /*#__PURE__*/ (0, _jsxruntime.jsx)(MetadataTree, {})); }, serveStreamingMetadata); const seedData = await (0, _createcomponenttree.createComponentTree)({ ctx, loaderTree: tree, parentParams: {}, injectedCSS, injectedJS, injectedFontPreloadTags, rootLayoutIncluded: false, getViewportReady, getMetadataReady, missingSlots, preloadCallbacks, authInterrupts: ctx.renderOpts.experimental.authInterrupts, StreamingMetadata, StreamingMetadataOutlet }); // When the `vary` response header is present with `Next-URL`, that means there's a chance // it could respond differently if there's an interception route. We provide this information // to `AppRouter` so that it can properly seed the prefetch cache with a prefix, if needed. const varyHeader = ctx.res.getHeader('vary'); const couldBeIntercepted = typeof varyHeader === 'string' && varyHeader.includes(_approuterheaders.NEXT_URL); const initialHead = /*#__PURE__*/ (0, _jsxruntime.jsxs)(_react.default.Fragment, { children: [ /*#__PURE__*/ (0, _jsxruntime.jsx)(NonIndex, { pagePath: ctx.pagePath, statusCode: ctx.res.statusCode, isPossibleServerAction: ctx.isPossibleServerAction }), /*#__PURE__*/ (0, _jsxruntime.jsx)(ViewportTree, {}, ctx.requestId), /*#__PURE__*/ (0, _jsxruntime.jsx)(StaticMetadata, {}) ] }, flightDataPathHeadKey); const globalErrorStyles = await getGlobalErrorStyles(tree, ctx); // Assume the head we're rendering contains only partial data if PPR is // enabled and this is a statically generated response. This is used by the // client Segment Cache after a prefetch to determine if it can skip the // second request to fill in the dynamic data. // // See similar comment in create-component-tree.tsx for more context. const isPossiblyPartialHead = workStore.isStaticGeneration && ctx.renderOpts.experimental.isRoutePPREnabled === true; return { // See the comment above the `Preloads` component (below) for why this is part of the payload P: /*#__PURE__*/ (0, _jsxruntime.jsx)(Preloads, { preloadCallbacks: preloadCallbacks }), b: ctx.sharedContext.buildId, p: ctx.assetPrefix, c: prepareInitialCanonicalUrl(url), i: !!couldBeIntercepted, f: [ [ initialTree, seedData, initialHead, isPossiblyPartialHead ] ], m: missingSlots, G: [ GlobalError, globalErrorStyles ], s: typeof ctx.renderOpts.postponed === 'string', S: workStore.isStaticGeneration }; } /** * Preload calls (such as `ReactDOM.preloadStyle` and `ReactDOM.preloadFont`) need to be called during rendering * in order to create the appropriate preload tags in the DOM, otherwise they're a no-op. Since we invoke * renderToReadableStream with a function that returns component props rather than a component itself, we use * this component to "render " the preload calls. */ function Preloads({ preloadCallbacks }) { preloadCallbacks.forEach((preloadFn)=>preloadFn()); return null; } // This is the data necessary to render <AppRouter /> when an error state is triggered async function getErrorRSCPayload(tree, ctx, ssrError, errorType) { const { getDynamicParamFromSegment, query, appUsingSizeAdjustment, componentMod: { GlobalError, createMetadataComponents, MetadataBoundary, ViewportBoundary }, url, requestId, workStore } = ctx; const serveStreamingMetadata = !!ctx.renderOpts.serveStreamingMetadata; const { MetadataTree, ViewportTree } = createMetadataComponents({ tree, parsedQuery: query, // We create an untracked metadata context here because we can't postpone // again during the error render. metadataContext: (0, _metadatacontext.createMetadataContext)(url.pathname, ctx.renderOpts), errorType, getDynamicParamFromSegment, appUsingSizeAdjustment, workStore, MetadataBoundary, ViewportBoundary, serveStreamingMetadata: serveStreamingMetadata }); const { StreamingMetadata, StaticMetadata } = createDivergedMetadataComponents(()=>/*#__PURE__*/ (0, _jsxruntime.jsx)(_react.default.Fragment, { children: /*#__PURE__*/ (0, _jsxruntime.jsx)(MetadataTree, {}, requestId) }, flightDataPathHeadKey), serveStreamingMetadata); const initialHead = /*#__PURE__*/ (0, _jsxruntime.jsxs)(_react.default.Fragment, { children: [ /*#__PURE__*/ (0, _jsxruntime.jsx)(NonIndex, { pagePath: ctx.pagePath, statusCode: ctx.res.statusCode, isPossibleServerAction: ctx.isPossibleServerAction }), /*#__PURE__*/ (0, _jsxruntime.jsx)(ViewportTree, {}, requestId), process.env.NODE_ENV === 'development' && /*#__PURE__*/ (0, _jsxruntime.jsx)("meta", { name: "next-error", content: "not-found" }), StreamingMetadata ? /*#__PURE__*/ (0, _jsxruntime.jsx)(StreamingMetadata, {}) : null, /*#__PURE__*/ (0, _jsxruntime.jsx)(StaticMetadata, {}) ] }, flightDataPathHeadKey); const initialTree = (0, _createflightrouterstatefromloadertree.createFlightRouterStateFromLoaderTree)(tree, getDynamicParamFromSegment, query); let err = undefined; if (ssrError) { err = (0, _iserror.default)(ssrError) ? ssrError : Object.defineProperty(new Error(ssrError + ''), "__NEXT_ERROR_CODE", { value: "E394", enumerable: false, configurable: true }); } // For metadata notFound error there's no global not found boundary on top // so we create a not found page with AppRouter const seedData = [ initialTree[0], /*#__PURE__*/ (0, _jsxruntime.jsxs)("html", { id: "__next_error__", children: [ /*#__PURE__*/ (0, _jsxruntime.jsxs)("head", { children: [ StreamingMetadata ? /*#__PURE__*/ (0, _jsxruntime.jsx)(StreamingMetadata, {}) : null, /*#__PURE__*/ (0, _jsxruntime.jsx)(StaticMetadata, {}) ] }), /*#__PURE__*/ (0, _jsxruntime.jsx)("body", { children: process.env.NODE_ENV !== 'production' && err ? /*#__PURE__*/ (0, _jsxruntime.jsx)("template", { "data-next-error-message": err.message, "data-next-error-digest": 'digest' in err ? err.digest : '', "data-next-error-stack": err.stack }) : null }) ] }), {}, null, false ]; const globalErrorStyles = await getGlobalErrorStyles(tree, ctx); const isPossiblyPartialHead = workStore.isStaticGeneration && ctx.renderOpts.experimental.isRoutePPREnabled === true; return { b: ctx.sharedContext.buildId, p: ctx.assetPrefix, c: prepareInitialCanonicalUrl(url), m: undefined, i: false, f: [ [ initialTree, seedData, initialHead, isPossiblyPartialHead ] ], G: [ GlobalError, globalErrorStyles ], s: typeof ctx.renderOpts.postponed === 'string', S: workStore.isStaticGeneration }; } // This component must run in an SSR context. It will render the RSC root component function App({ reactServerStream, preinitScripts, clientReferenceManifest, nonce, ServerInsertedHTMLProvider, ServerInsertedMetadataProvider }) { preinitScripts(); const response = _react.default.use((0, _useflightresponse.useFlightStream)(reactServerStream, clientReferenceManifest, nonce)); const initialState = (0, _createinitialrouterstate.createInitialRouterState)({ // This is not used during hydration, so we don't have to pass a // real timestamp. navigatedAt: -1, initialFlightData: response.f, initialCanonicalUrlParts: response.c, initialParallelRoutes: new Map(), // location is not initialized in the SSR render // it's set to window.location during hydration location: null, couldBeIntercepted: response.i, postponed: response.s, prerendered: response.S }); const actionQueue = (0, _approuterinstance.createMutableActionQueue)(initialState, null); const { HeadManagerContext } = require('../../shared/lib/head-manager-context.shared-runtime'); return /*#__PURE__*/ (0, _jsxruntime.jsx)(HeadManagerContext.Provider, { value: { appDir: true, nonce }, children: /*#__PURE__*/ (0, _jsxruntime.jsx)(ServerInsertedMetadataProvider, { children: /*#__PURE__*/ (0, _jsxruntime.jsx)(ServerInsertedHTMLProvider, { children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_approuter.default, { actionQueue: actionQueue, globalErrorComponentAndStyles: response.G, assetPrefix: response.p }) }) }) }); } // @TODO our error stream should be probably just use the same root component. But it was previously // different I don't want to figure out if that is meaningful at this time so just keeping the behavior // consistent for now. function ErrorApp({ reactServerStream, preinitScripts, clientReferenceManifest, ServerInsertedMetadataProvider, ServerInsertedHTMLProvider, nonce }) { preinitScripts(); const response = _react.default.use((0, _useflightresponse.useFlightStream)(reactServerStream, clientReferenceManifest, nonce)); const initialState = (0, _createinitialrouterstate.createInitialRouterState)({ // This is not used during hydration, so we don't have to pass a // real timestamp. navigatedAt: -1, initialFlightData: response.f, initialCanonicalUrlParts: response.c, initialParallelRoutes: new Map(), // location is not initialized in the SSR render // it's set to window.location during hydration location: null, couldBeIntercepted: response.i, postponed: response.s, prerendered: response.S }); const actionQueue = (0, _approuterinstance.createMutableActionQueue)(initialState, null); return /*#__PURE__*/ (0, _jsxruntime.jsx)(ServerInsertedMetadataProvider, { children: /*#__PURE__*/ (0, _jsxruntime.jsx)(ServerInsertedHTMLProvider, { children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_approuter.default, { actionQueue: actionQueue, globalErrorComponentAndStyles: response.G, assetPrefix: response.p }) }) }); } async function renderToHTMLOrFlightImpl(req, res, url, pagePath, query, renderOpts, workStore, parsedRequestHeaders, requestEndedState, postponedState, serverComponentsHmrCache, sharedContext) { const isNotFoundPath = pagePath === '/404'; if (isNotFoundPath) { res.statusCode = 404; } // A unique request timestamp used by development to ensure that it's // consistent and won't change during this request. This is important to // avoid that resources can be deduped by React Float if the same resource is // rendered or preloaded multiple times: `<link href="a.css?v={Date.now()}"/>`. const requestTimestamp = Date.now(); const { serverActionsManifest, ComponentMod, nextFontManifest, serverActions, assetPrefix = '', enableTainting } = renderOpts; // We need to expose the bundled `require` API globally for // react-server-dom-webpack. This is a hack until we find a better way. if (ComponentMod.__next_app__) { const instrumented = (0, _clientcomponentrendererlogger.wrapClientComponentLoader)(ComponentMod); // @ts-ignore globalThis.__next_require__ = instrumented.require; // When we are prerendering if there is a cacheSignal for tracking // cache reads we wrap the loadChunk in this tracking. This allows us // to treat chunk loading with similar semantics as cache reads to avoid // async loading chunks from causing a prerender to abort too early. const __next_chunk_load__ = (...args)=>{ const loadingChunk = instrumented.loadChunk(...args); trackChunkLoading(loadingChunk); return loadingChunk; }; // @ts-expect-error globalThis.__next_chunk_load__ = __next_chunk_load__; } if (process.env.NODE_ENV === 'development') { // reset isr status at start of request const { pathname } = new URL(req.url || '/', 'http://n'); renderOpts.setIsrStatus == null ? void 0 : renderOpts.setIsrStatus.call(renderOpts, pathname, null); } if (// The type check here ensures that `req` is correctly typed, and the // environment variable check provides dead code elimination. process.env.NEXT_RUNTIME !== 'edge' && (0, _helpers.isNodeNextRequest)(req)) { req.originalRequest.on('end', ()=>{ requestEndedState.ended = true; if ('performance' in globalThis) { const metrics = (0, _clientcomponentrendererlogger.getClientComponentLoaderMetrics)({ reset: true }); if (metrics) { (0, _tracer.getTracer)().startSpan(_constants.NextNodeServerSpan.clientComponentLoading, { startTime: metrics.clientComponentLoadStart, attributes: { 'next.clientComponentLoadCount': metrics.clientComponentLoadCount, 'next.span_type': _constants.NextNodeServerSpan.clientComponentLoading } }).end(metrics.clientComponentLoadStart + metrics.clientComponentLoadTimes); } } }); } const metadata = {}; const appUsingSizeAdjustment = !!(nextFontManifest == null ? void 0 : nextFontManifest.appUsingSizeAdjust); // TODO: fix this typescript const clientReferenceManifest = renderOpts.clientReferenceManifest; const serverModuleMap = (0, _actionutils.createServerModuleMap)({ serverActionsManifest }); (0, _encryptionutils.setReferenceManifestsSingleton)({ page: workStore.page, clientReferenceManifest, serverActionsManifest, serverModuleMap }); ComponentMod.patchFetch(); // Pull out the hooks/references from the component. const { tree: loaderTree, taintObjectReference } = ComponentMod; if (enableTainting) { taintObjectReference('Do not pass process.env to client components since it will leak sensitive data', process.env); } workStore.fetchMetrics = []; metadata.fetchMetrics = workStore.fetchMetrics; // don't modify original query object query = { ...query }; (0, _internalutils.stripInternalQueries)(query); const { flightRouterState, isPrefetchRequest, isRSCRequest, isDevWarmupRequest, isHmrRefresh, nonce } = parsedRequestHeaders; /** * The metadata items array created in next-app-loader with all relevant information * that we need to resolve the final metadata. */ let requestId; if (process.env.NEXT_RUNTIME === 'edge') { requestId = crypto.randomUUID(); } else { requestId = require('next/dist/compiled/nanoid').nanoid(); } /** * Dynamic parameters. E.g. when you visit `/dashboard/vercel` which is rendered by `/dashboard/[slug]` the value will be {"slug": "vercel"}. */ const params = renderOpts.params ?? {}; const { isStaticGeneration, fallbackRouteParams } = workStore; const getDynamicParamFromSegment = makeGetDynamicParamFromSegment(params, pagePath, fallbackRouteParams); const isPossibleActionRequest = (0, _serveractionrequestmeta.getIsPossibleServerAction)(req); const implicitTags = await (0, _implicittags.getImplicitTags)(workStore.page, url, fallbackRouteParams); const ctx = { componentMod: ComponentMod, url, renderOpts, workStore, parsedRequestHeaders, getDynamicParamFromSegment, query, isPrefetch: isPrefetchRequest, isPossibleServerAction: isPossibleActionRequest, requestTimestamp, appUsingSizeAdjustment, flightRouterState, requestId, pagePath, clientReferenceManifest, assetPrefix, isNotFoundPath, nonce, res, sharedContext, implicitTags }; (0, _tracer.getTracer)().setRootSpanAttribute('next.route', pagePath); if (isStaticGeneration) { var _metadata_cacheControl; // We're either building or revalidating. In either case we need to // prerender our page rather than render it. const prerenderToStreamWithTracing = (0, _tracer.getTracer)().wrap(_constants.AppRenderSpan.getBodyResult, { spanName: `prerender route (app) ${pagePath}`, attributes: { 'next.route': pagePath } }, prerenderToStream); const response = await prerenderToStreamWithTracing(req, res, ctx, metadata, workStore, loaderTree); // If we're debugging partial prerendering, print all the dynamic API accesses // that occurred during the render. // @TODO move into renderToStream function if (response.dynamicAccess && (0, _dynamicrendering.accessedDynamicData)(response.dynamicAccess) && renderOpts.isDebugDynamicAccesses) { (0, _log.warn)('The following dynamic usage was detected:'); for (const access of (0, _dynamicrendering.formatDynamicAPIAccesses)(response.dynamicAccess)){ (0, _log.warn)(access); } } // If we encountered any unexpected errors during build we fail the // prerendering phase and the build. if (workStore.invalidUsageError) { throw workStore.invalidUsageError; } if (response.digestErrorsMap.size) { const buildFailingError = response.digestErrorsMap.values().next().value; if (buildFailingError) throw buildFailingError; } // Pick first userland SSR error, which is also not a RSC error. if (response.ssrErrors.length) { const buildFailingError = response.ssrErrors.find((err)=>(0, _createerrorhandler.isUserLandError)(err)); if (buildFailingError) throw buildFailingError; } const options = { metadata }; // If we have pending revalidates, wait until they are all resolved. if (workStore.pendingRevalidates || workStore.pendingRevalidateWrites || workStore.pendingRevalidatedTags) { const pendingPromise = (0, _revalidationutils.executeRevalidates)(workStore).finally(()=>{ if (process.env.NEXT_PRIVATE_DEBUG_CACHE) { console.log('pending revalidates promise finished for:', url); } }); if (renderOpts.waitUntil) { renderOpts.waitUntil(pendingPromise); } else { options.waitUntil = pendingPromise; } } if (response.collectedTags) { metadata.fetchTags = response.collectedTags.join(','); } // Let the client router know how long to keep the cached entry around. const staleHeader = String(response.collectedStale); res.setHeader(_approuterheaders.NEXT_ROUTER_STALE_TIME_HEADER, staleHeader); metadata.headers ??= {}; metadata.headers[_approuterheaders.NEXT_ROUTER_STALE_TIME_HEADER] = staleHeader; // If force static is specifically set to false, we should not revalidate // the page. if (workStore.forceStatic === false || response.collectedRevalidate === 0) { metadata.cacheControl = { revalidate: 0, expire: undefined }; } else { // Copy the cache control value onto the render result metadata. metadata.cacheControl = { revalidate: response.collectedRevalidate >= _constants1.INFINITE_CACHE ? false : response.collectedRevalidate, expire: response.collectedExpire >= _constants1.INFINITE_CACHE ? undefined : response.collectedExpire }; } // provide bailout info for debugging if (((_metadata_cacheControl = metadata.cacheControl) == null ? void 0 : _metadata_cacheControl.revalidate) === 0) { metadata.staticBailoutInfo = { description: workStore.dynamicUsageDescription, stack: workStore.dynamicUsageStack }; } return new _renderresult.default(await (0, _nodewebstreamshelper.streamToString)(response.stream), options); } else { // We're rendering dynamically const renderResumeDataCache = renderOpts.devRenderResumeDataCache ?? (postponedState == null ? void 0 : postponedState.renderResumeDataCache); const rootParams = (0, _createcomponenttree.getRootParams)(loaderTree, ctx.getDynamicParamFromSegment); const requestStore = (0, _requeststore.createRequestStoreForRender)(req, res, url, rootParams, implicitTags, renderOpts.onUpdateCookies, renderOpts.previewProps, isHmrRefresh, serverComponentsHmrCache, renderResumeDataCache); if (process.env.NODE_ENV === 'development' && renderOpts.setIsrStatus && // The type check here ensures that `req` is correctly typed, and the // environment variable check provides dead code elimination. process.env.NEXT_RUNTIME !== 'edge' && (0, _helpers.isNodeNextRequest)(req) && !isDevWarmupRequest) { const setIsrStatus = renderOpts.setIsrStatus; req.originalRequest.on('end', ()=>{ if (!requestStore.usedDynamic && !workStore.forceDynamic) { // only node can be ISR so we only need to update the status here const { pathname } = new URL(req.url || '/', 'http://n'); setIsrStatus(pathname, true); } }); } if (isDevWarmupRequest) { return warmupDevRender(req, ctx); } else if (isRSCRequest) { return generateDynamicFlightRenderResult(req, ctx, requestStore); } const renderToStreamWithTracing = (0, _tracer.getTracer)().wrap(_constants.AppRenderSpan.getBodyResult, { spanName: `render route (app) ${pagePath}`, attributes: { 'next.route': pagePath } }, renderToStream); let formState = null; if (isPossibleActionRequest) { // For action requests, we handle them differently with a special render result. const actionRequestResult = await (0, _actionhandler.handleAction)({ req, res, ComponentMod, serverModuleMap, generateFlight: generateDynamicFlightRenderResult, workStore, requestStore, serverActions, ctx }); if (actionRequestResult) { if (actionRequestResult.type === 'not-found') { const notFoundLoaderTree = createNotFoundLoaderTree(loaderTree); res.statusCode = 404; const stream = await renderToStreamWithTracing(requestStore, req, res, ctx, workStore, notFoundLoaderTree, formState, postponedState); return new _renderresult.default(stream, { metadata }); } else if (actionRequestResult.type === 'done') { if (actionRequestResult.result) { actionRequestResult.result.assignMetadata(metadata); return actionRequestResult.result; } else if (actionRequestResult.formState) { formState = actionRequestResult.formState; } } } } const options = { metadata }; const stream = await renderToStreamWithTracing(requestStore, req, res, ctx, workStore, loaderTree, formState, postponedState); if (workStore.invalidUsageError) { throw workStore.invalidUsageError; } // If we have pending revalidates, wait until they are all resolved. if (workStore.pendingRevalidates || workStore.pendingRevalidateWrites || workStore.pendingRevalidatedTags) { const pendingPromise = (0, _revalidationutils.executeRevalidates)(workStore).finally(()=>{ if (process.env.NEXT_PRIVATE_DEBUG_CACHE) { console.log('pending revalidates promise finished for:', url); } }); if (renderOpts.waitUntil) { renderOpts.waitUntil(pendingPromise); } else { options.waitUntil = pendingPromise; } } // Create the new render result for the response. return new _renderresult.default(stream, options); } } const renderToHTMLOrFlight = (req, res, pagePath, query, fallbackRouteParams, renderOpts, serverComponentsHmrCache, isDevWarmup, sharedContext)=>{ var _renderOpts_previewProps; if (!req.url) { throw Object.defineProperty(new Error('Invalid URL'), "__NEXT_ERROR_CODE", { value: "E182", enumerable: false,