Spaces:
Running
Running
| ; | |
| Object.defineProperty(exports, "__esModule", { | |
| value: true | |
| }); | |
| 0 && (module.exports = { | |
| AppRouteRouteModule: null, | |
| WrappedNextRouterError: null, | |
| default: null, | |
| hasNonStaticMethods: null | |
| }); | |
| function _export(target, all) { | |
| for(var name in all)Object.defineProperty(target, name, { | |
| enumerable: true, | |
| get: all[name] | |
| }); | |
| } | |
| _export(exports, { | |
| AppRouteRouteModule: function() { | |
| return AppRouteRouteModule; | |
| }, | |
| WrappedNextRouterError: function() { | |
| return WrappedNextRouterError; | |
| }, | |
| default: function() { | |
| return _default; | |
| }, | |
| hasNonStaticMethods: function() { | |
| return hasNonStaticMethods; | |
| } | |
| }); | |
| const _routemodule = require("../route-module"); | |
| const _requeststore = require("../../async-storage/request-store"); | |
| const _workstore = require("../../async-storage/work-store"); | |
| const _http = require("../../web/http"); | |
| const _implicittags = require("../../lib/implicit-tags"); | |
| const _patchfetch = require("../../lib/patch-fetch"); | |
| const _tracer = require("../../lib/trace/tracer"); | |
| const _constants = require("../../lib/trace/constants"); | |
| const _log = /*#__PURE__*/ _interop_require_wildcard(require("../../../build/output/log")); | |
| const _autoimplementmethods = require("./helpers/auto-implement-methods"); | |
| const _requestcookies = require("../../web/spec-extension/adapters/request-cookies"); | |
| const _headers = require("../../web/spec-extension/adapters/headers"); | |
| const _parsedurlquerytoparams = require("./helpers/parsed-url-query-to-params"); | |
| const _prospectiverenderutils = require("../../app-render/prospective-render-utils"); | |
| const _hooksservercontext = /*#__PURE__*/ _interop_require_wildcard(require("../../../client/components/hooks-server-context")); | |
| const _workasyncstorageexternal = require("../../app-render/work-async-storage.external"); | |
| const _workunitasyncstorageexternal = require("../../app-render/work-unit-async-storage.external"); | |
| const _actionasyncstorageexternal = require("../../app-render/action-async-storage.external"); | |
| const _sharedmodules = /*#__PURE__*/ _interop_require_wildcard(require("./shared-modules")); | |
| const _serveractionrequestmeta = require("../../lib/server-action-request-meta"); | |
| const _cookies = require("next/dist/compiled/@edge-runtime/cookies"); | |
| const _cleanurl = require("./helpers/clean-url"); | |
| const _staticgenerationbailout = require("../../../client/components/static-generation-bailout"); | |
| const _isstaticgenenabled = require("./helpers/is-static-gen-enabled"); | |
| const _dynamicrendering = require("../../app-render/dynamic-rendering"); | |
| const _reflect = require("../../web/spec-extension/adapters/reflect"); | |
| const _cachesignal = require("../../app-render/cache-signal"); | |
| const _scheduler = require("../../../lib/scheduler"); | |
| const _params = require("../../request/params"); | |
| const _redirect = require("../../../client/components/redirect"); | |
| const _redirecterror = require("../../../client/components/redirect-error"); | |
| const _httpaccessfallback = require("../../../client/components/http-access-fallback/http-access-fallback"); | |
| const _redirectstatuscode = require("../../../client/components/redirect-status-code"); | |
| const _constants1 = require("../../../lib/constants"); | |
| const _revalidationutils = require("../../revalidation-utils"); | |
| const _trackmoduleloadingexternal = require("../../app-render/module-loading/track-module-loading.external"); | |
| const _invarianterror = require("../../../shared/lib/invariant-error"); | |
| const _resumedatacache = require("../../resume-data-cache/resume-data-cache"); | |
| 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 = { | |
| __proto__: null | |
| }; | |
| 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; | |
| } | |
| class WrappedNextRouterError { | |
| constructor(error, headers){ | |
| this.error = error; | |
| this.headers = headers; | |
| } | |
| } | |
| class AppRouteRouteModule extends _routemodule.RouteModule { | |
| static #_ = this.sharedModules = _sharedmodules; | |
| constructor({ userland, definition, distDir, relativeProjectDir, resolvedPagePath, nextConfigOutput }){ | |
| super({ | |
| userland, | |
| definition, | |
| distDir, | |
| relativeProjectDir | |
| }), /** | |
| * A reference to the request async storage. | |
| */ this.workUnitAsyncStorage = _workunitasyncstorageexternal.workUnitAsyncStorage, /** | |
| * A reference to the static generation async storage. | |
| */ this.workAsyncStorage = _workasyncstorageexternal.workAsyncStorage, /** | |
| * An interface to call server hooks which interact with the underlying | |
| * storage. | |
| */ this.serverHooks = _hooksservercontext, /** | |
| * A reference to the mutation related async storage, such as mutations of | |
| * cookies. | |
| */ this.actionAsyncStorage = _actionasyncstorageexternal.actionAsyncStorage; | |
| this.resolvedPagePath = resolvedPagePath; | |
| this.nextConfigOutput = nextConfigOutput; | |
| // Automatically implement some methods if they aren't implemented by the | |
| // userland module. | |
| this.methods = (0, _autoimplementmethods.autoImplementMethods)(userland); | |
| // Get the non-static methods for this route. | |
| this.hasNonStaticMethods = hasNonStaticMethods(userland); | |
| // Get the dynamic property from the userland module. | |
| this.dynamic = this.userland.dynamic; | |
| if (this.nextConfigOutput === 'export') { | |
| if (this.dynamic === 'force-dynamic') { | |
| throw Object.defineProperty(new Error(`export const dynamic = "force-dynamic" on page "${definition.pathname}" cannot be used with "output: export". See more info here: https://nextjs.org/docs/advanced-features/static-html-export`), "__NEXT_ERROR_CODE", { | |
| value: "E278", | |
| enumerable: false, | |
| configurable: true | |
| }); | |
| } else if (!(0, _isstaticgenenabled.isStaticGenEnabled)(this.userland) && this.userland['GET']) { | |
| throw Object.defineProperty(new Error(`export const dynamic = "force-static"/export const revalidate not configured on route "${definition.pathname}" with "output: export". See more info here: https://nextjs.org/docs/advanced-features/static-html-export`), "__NEXT_ERROR_CODE", { | |
| value: "E301", | |
| enumerable: false, | |
| configurable: true | |
| }); | |
| } else { | |
| this.dynamic = 'error'; | |
| } | |
| } | |
| // We only warn in development after here, so return if we're not in | |
| // development. | |
| if (process.env.NODE_ENV === 'development') { | |
| // Print error in development if the exported handlers are in lowercase, only | |
| // uppercase handlers are supported. | |
| const lowercased = _http.HTTP_METHODS.map((method)=>method.toLowerCase()); | |
| for (const method of lowercased){ | |
| if (method in this.userland) { | |
| _log.error(`Detected lowercase method '${method}' in '${this.resolvedPagePath}'. Export the uppercase '${method.toUpperCase()}' method name to fix this error.`); | |
| } | |
| } | |
| // Print error if the module exports a default handler, they must use named | |
| // exports for each HTTP method. | |
| if ('default' in this.userland) { | |
| _log.error(`Detected default export in '${this.resolvedPagePath}'. Export a named export for each HTTP method instead.`); | |
| } | |
| // If there is no methods exported by this module, then return a not found | |
| // response. | |
| if (!_http.HTTP_METHODS.some((method)=>method in this.userland)) { | |
| _log.error(`No HTTP methods exported in '${this.resolvedPagePath}'. Export a named export for each HTTP method.`); | |
| } | |
| } | |
| } | |
| /** | |
| * Resolves the handler function for the given method. | |
| * | |
| * @param method the requested method | |
| * @returns the handler function for the given method | |
| */ resolve(method) { | |
| // Ensure that the requested method is a valid method (to prevent RCE's). | |
| if (!(0, _http.isHTTPMethod)(method)) return ()=>new Response(null, { | |
| status: 400 | |
| }); | |
| // Return the handler. | |
| return this.methods[method]; | |
| } | |
| async do(handler, actionStore, workStore, // @TODO refactor to not take this argument but instead construct the RequestStore | |
| // inside this function. Right now we get passed a RequestStore even when | |
| // we're going to do a prerender. We should probably just split do up into prexecute and execute | |
| requestStore, implicitTags, request, context) { | |
| const isStaticGeneration = workStore.isStaticGeneration; | |
| const cacheComponentsEnabled = !!context.renderOpts.cacheComponents; | |
| // Patch the global fetch. | |
| (0, _patchfetch.patchFetch)({ | |
| workAsyncStorage: this.workAsyncStorage, | |
| workUnitAsyncStorage: this.workUnitAsyncStorage | |
| }); | |
| const handlerContext = { | |
| params: context.params ? (0, _params.createServerParamsForRoute)((0, _parsedurlquerytoparams.parsedUrlQueryToParams)(context.params), workStore) : undefined | |
| }; | |
| const resolvePendingRevalidations = ()=>{ | |
| context.renderOpts.pendingWaitUntil = (0, _revalidationutils.executeRevalidates)(workStore).finally(()=>{ | |
| if (process.env.NEXT_PRIVATE_DEBUG_CACHE) { | |
| console.log('pending revalidates promise finished for:', requestStore.url); | |
| } | |
| }); | |
| }; | |
| let prerenderStore = null; | |
| let res; | |
| try { | |
| if (isStaticGeneration) { | |
| const userlandRevalidate = this.userland.revalidate; | |
| const defaultRevalidate = // If the static generation store does not have a revalidate value | |
| // set, then we should set it the revalidate value from the userland | |
| // module or default to false. | |
| userlandRevalidate === false || userlandRevalidate === undefined ? _constants1.INFINITE_CACHE : userlandRevalidate; | |
| if (cacheComponentsEnabled) { | |
| /** | |
| * When we are attempting to statically prerender the GET handler of a route.ts module | |
| * and cacheComponents is on we follow a similar pattern to rendering. | |
| * | |
| * We first run the handler letting caches fill. If something synchronously dynamic occurs | |
| * during this prospective render then we can infer it will happen on every render and we | |
| * just bail out of prerendering. | |
| * | |
| * Next we run the handler again and we check if we get a result back in a microtask. | |
| * Next.js expects the return value to be a Response or a Thenable that resolves to a Response. | |
| * Unfortunately Response's do not allow for accessing the response body synchronously or in | |
| * a microtask so we need to allow one more task to unwrap the response body. This is a slightly | |
| * different semantic than what we have when we render and it means that certain tasks can still | |
| * execute before a prerender completes such as a carefully timed setImmediate. | |
| * | |
| * Functionally though IO should still take longer than the time it takes to unwrap the response body | |
| * so our heuristic of excluding any IO should be preserved. | |
| */ const prospectiveController = new AbortController(); | |
| let prospectiveRenderIsDynamic = false; | |
| const cacheSignal = new _cachesignal.CacheSignal(); | |
| let dynamicTracking = (0, _dynamicrendering.createDynamicTrackingState)(undefined); | |
| // TODO: Route handlers are never resumed, so it's counter-intuitive | |
| // to use an RDC here. However, we need the data cache to store cached | |
| // results in memory during the prospective prerender, so that they | |
| // can be retrieved during the final prerender within microtasks. This | |
| // is crucial when doing revalidations of a deployed route handler, | |
| // where the default cache handler does not do any in-memory caching. | |
| // We should replace the `prerenderResumeDataCache` and | |
| // `renderResumeDataCache` with a single `dataCache` property that is | |
| // conceptually not tied to resuming, and also avoids the unnecessary | |
| // complexity of using a mutable and an immutable resume data cache. | |
| const prerenderResumeDataCache = (0, _resumedatacache.createPrerenderResumeDataCache)(); | |
| const prospectiveRoutePrerenderStore = prerenderStore = { | |
| type: 'prerender', | |
| phase: 'action', | |
| // This replicates prior behavior where rootParams is empty in routes | |
| // TODO we need to make this have the proper rootParams for this route | |
| rootParams: {}, | |
| fallbackRouteParams: null, | |
| implicitTags, | |
| renderSignal: prospectiveController.signal, | |
| controller: prospectiveController, | |
| cacheSignal, | |
| // During prospective render we don't use a controller | |
| // because we need to let all caches fill. | |
| dynamicTracking, | |
| allowEmptyStaticShell: false, | |
| revalidate: defaultRevalidate, | |
| expire: _constants1.INFINITE_CACHE, | |
| stale: _constants1.INFINITE_CACHE, | |
| tags: [ | |
| ...implicitTags.tags | |
| ], | |
| prerenderResumeDataCache, | |
| renderResumeDataCache: null, | |
| hmrRefreshHash: undefined | |
| }; | |
| let prospectiveResult; | |
| try { | |
| prospectiveResult = this.workUnitAsyncStorage.run(prospectiveRoutePrerenderStore, handler, request, handlerContext); | |
| } catch (err) { | |
| if (prospectiveController.signal.aborted) { | |
| // the route handler called an API which is always dynamic | |
| // there is no need to try again | |
| prospectiveRenderIsDynamic = true; | |
| } else if (process.env.NEXT_DEBUG_BUILD || process.env.__NEXT_VERBOSE_LOGGING) { | |
| (0, _prospectiverenderutils.printDebugThrownValueForProspectiveRender)(err, workStore.route, _prospectiverenderutils.Phase.ProspectiveRender); | |
| } | |
| } | |
| if (typeof prospectiveResult === 'object' && prospectiveResult !== null && typeof prospectiveResult.then === 'function') { | |
| // The handler returned a Thenable. We'll listen for rejections to determine | |
| // if the route is erroring for dynamic reasons. | |
| ; | |
| prospectiveResult.then(()=>{}, (err)=>{ | |
| if (prospectiveController.signal.aborted) { | |
| // the route handler called an API which is always dynamic | |
| // there is no need to try again | |
| prospectiveRenderIsDynamic = true; | |
| } else if (process.env.NEXT_DEBUG_BUILD) { | |
| (0, _prospectiverenderutils.printDebugThrownValueForProspectiveRender)(err, workStore.route, _prospectiverenderutils.Phase.ProspectiveRender); | |
| } | |
| }); | |
| } | |
| (0, _trackmoduleloadingexternal.trackPendingModules)(cacheSignal); | |
| await cacheSignal.cacheReady(); | |
| if (prospectiveRenderIsDynamic) { | |
| // the route handler called an API which is always dynamic | |
| // there is no need to try again | |
| const dynamicReason = (0, _dynamicrendering.getFirstDynamicReason)(dynamicTracking); | |
| if (dynamicReason) { | |
| throw Object.defineProperty(new _hooksservercontext.DynamicServerError(`Route ${workStore.route} couldn't be rendered statically because it used \`${dynamicReason}\`. See more info here: https://nextjs.org/docs/messages/dynamic-server-error`), "__NEXT_ERROR_CODE", { | |
| value: "E558", | |
| enumerable: false, | |
| configurable: true | |
| }); | |
| } else { | |
| console.error('Expected Next.js to keep track of reason for opting out of static rendering but one was not found. This is a bug in Next.js'); | |
| throw Object.defineProperty(new _hooksservercontext.DynamicServerError(`Route ${workStore.route} couldn't be rendered statically because it used a dynamic API. See more info here: https://nextjs.org/docs/messages/dynamic-server-error`), "__NEXT_ERROR_CODE", { | |
| value: "E577", | |
| enumerable: false, | |
| configurable: true | |
| }); | |
| } | |
| } | |
| // TODO start passing this controller to the route handler. We should expose | |
| // it so the handler to abort inflight requests and other operations if we abort | |
| // the prerender. | |
| const finalController = new AbortController(); | |
| dynamicTracking = (0, _dynamicrendering.createDynamicTrackingState)(undefined); | |
| const finalRoutePrerenderStore = prerenderStore = { | |
| type: 'prerender', | |
| phase: 'action', | |
| rootParams: {}, | |
| fallbackRouteParams: null, | |
| implicitTags, | |
| renderSignal: finalController.signal, | |
| controller: finalController, | |
| cacheSignal: null, | |
| dynamicTracking, | |
| allowEmptyStaticShell: false, | |
| revalidate: defaultRevalidate, | |
| expire: _constants1.INFINITE_CACHE, | |
| stale: _constants1.INFINITE_CACHE, | |
| tags: [ | |
| ...implicitTags.tags | |
| ], | |
| prerenderResumeDataCache, | |
| renderResumeDataCache: null, | |
| hmrRefreshHash: undefined | |
| }; | |
| let responseHandled = false; | |
| res = await new Promise((resolve, reject)=>{ | |
| (0, _scheduler.scheduleImmediate)(async ()=>{ | |
| try { | |
| const result = await this.workUnitAsyncStorage.run(finalRoutePrerenderStore, handler, request, handlerContext); | |
| if (responseHandled) { | |
| // we already rejected in the followup task | |
| return; | |
| } else if (!(result instanceof Response)) { | |
| // This is going to error but we let that happen below | |
| resolve(result); | |
| return; | |
| } | |
| responseHandled = true; | |
| let bodyHandled = false; | |
| result.arrayBuffer().then((body)=>{ | |
| if (!bodyHandled) { | |
| bodyHandled = true; | |
| resolve(new Response(body, { | |
| headers: result.headers, | |
| status: result.status, | |
| statusText: result.statusText | |
| })); | |
| } | |
| }, reject); | |
| (0, _scheduler.scheduleImmediate)(()=>{ | |
| if (!bodyHandled) { | |
| bodyHandled = true; | |
| finalController.abort(); | |
| reject(createCacheComponentsError(workStore.route)); | |
| } | |
| }); | |
| } catch (err) { | |
| reject(err); | |
| } | |
| }); | |
| (0, _scheduler.scheduleImmediate)(()=>{ | |
| if (!responseHandled) { | |
| responseHandled = true; | |
| finalController.abort(); | |
| reject(createCacheComponentsError(workStore.route)); | |
| } | |
| }); | |
| }); | |
| if (finalController.signal.aborted) { | |
| // We aborted from within the execution | |
| throw createCacheComponentsError(workStore.route); | |
| } else { | |
| // We didn't abort during the execution. We can abort now as a matter of semantics | |
| // though at the moment nothing actually consumes this signal so it won't halt any | |
| // inflight work. | |
| finalController.abort(); | |
| } | |
| } else { | |
| prerenderStore = { | |
| type: 'prerender-legacy', | |
| phase: 'action', | |
| rootParams: {}, | |
| implicitTags, | |
| revalidate: defaultRevalidate, | |
| expire: _constants1.INFINITE_CACHE, | |
| stale: _constants1.INFINITE_CACHE, | |
| tags: [ | |
| ...implicitTags.tags | |
| ] | |
| }; | |
| res = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(prerenderStore, handler, request, handlerContext); | |
| } | |
| } else { | |
| res = await _workunitasyncstorageexternal.workUnitAsyncStorage.run(requestStore, handler, request, handlerContext); | |
| } | |
| } catch (err) { | |
| if ((0, _redirecterror.isRedirectError)(err)) { | |
| const url = (0, _redirect.getURLFromRedirectError)(err); | |
| if (!url) { | |
| throw Object.defineProperty(new Error('Invariant: Unexpected redirect url format'), "__NEXT_ERROR_CODE", { | |
| value: "E399", | |
| enumerable: false, | |
| configurable: true | |
| }); | |
| } | |
| // We need to capture any headers that should be sent on | |
| // the response. | |
| const headers = new Headers({ | |
| Location: url | |
| }); | |
| // Let's append any cookies that were added by the | |
| // cookie API. | |
| // TODO leaving the gate here b/c it indicates that we might not actually want to do this | |
| // on every `do` call. During prerender there should be no mutableCookies because | |
| (0, _requestcookies.appendMutableCookies)(headers, requestStore.mutableCookies); | |
| resolvePendingRevalidations(); | |
| // Return the redirect response. | |
| return new Response(null, { | |
| // If we're in an action, we want to use a 303 redirect as we don't | |
| // want the POST request to follow the redirect, as it could result in | |
| // erroneous re-submissions. | |
| status: actionStore.isAction ? _redirectstatuscode.RedirectStatusCode.SeeOther : (0, _redirect.getRedirectStatusCodeFromError)(err), | |
| headers | |
| }); | |
| } else if ((0, _httpaccessfallback.isHTTPAccessFallbackError)(err)) { | |
| const httpStatus = (0, _httpaccessfallback.getAccessFallbackHTTPStatus)(err); | |
| return new Response(null, { | |
| status: httpStatus | |
| }); | |
| } | |
| throw err; | |
| } | |
| // Validate that the response is a valid response object. | |
| if (!(res instanceof Response)) { | |
| throw Object.defineProperty(new Error(`No response is returned from route handler '${this.resolvedPagePath}'. Ensure you return a \`Response\` or a \`NextResponse\` in all branches of your handler.`), "__NEXT_ERROR_CODE", { | |
| value: "E325", | |
| enumerable: false, | |
| configurable: true | |
| }); | |
| } | |
| context.renderOpts.fetchMetrics = workStore.fetchMetrics; | |
| resolvePendingRevalidations(); | |
| if (prerenderStore) { | |
| var _prerenderStore_tags; | |
| context.renderOpts.collectedTags = (_prerenderStore_tags = prerenderStore.tags) == null ? void 0 : _prerenderStore_tags.join(','); | |
| context.renderOpts.collectedRevalidate = prerenderStore.revalidate; | |
| context.renderOpts.collectedExpire = prerenderStore.expire; | |
| context.renderOpts.collectedStale = prerenderStore.stale; | |
| } | |
| // It's possible cookies were set in the handler, so we need | |
| // to merge the modified cookies and the returned response | |
| // here. | |
| const headers = new Headers(res.headers); | |
| if ((0, _requestcookies.appendMutableCookies)(headers, requestStore.mutableCookies)) { | |
| return new Response(res.body, { | |
| status: res.status, | |
| statusText: res.statusText, | |
| headers | |
| }); | |
| } | |
| return res; | |
| } | |
| async handle(req, context) { | |
| // Get the handler function for the given method. | |
| const handler = this.resolve(req.method); | |
| // Get the context for the static generation. | |
| const staticGenerationContext = { | |
| page: this.definition.page, | |
| renderOpts: context.renderOpts, | |
| buildId: context.sharedContext.buildId, | |
| previouslyRevalidatedTags: [] | |
| }; | |
| // Add the fetchCache option to the renderOpts. | |
| staticGenerationContext.renderOpts.fetchCache = this.userland.fetchCache; | |
| const actionStore = { | |
| isAppRoute: true, | |
| isAction: (0, _serveractionrequestmeta.getIsPossibleServerAction)(req) | |
| }; | |
| const implicitTags = await (0, _implicittags.getImplicitTags)(this.definition.page, req.nextUrl, // App Routes don't support unknown route params. | |
| null); | |
| const requestStore = (0, _requeststore.createRequestStoreForAPI)(req, req.nextUrl, implicitTags, undefined, context.prerenderManifest.preview); | |
| const workStore = (0, _workstore.createWorkStore)(staticGenerationContext); | |
| // Run the handler with the request AsyncLocalStorage to inject the helper | |
| // support. We set this to `unknown` because the type is not known until | |
| // runtime when we do a instanceof check below. | |
| const response = await this.actionAsyncStorage.run(actionStore, ()=>this.workUnitAsyncStorage.run(requestStore, ()=>this.workAsyncStorage.run(workStore, async ()=>{ | |
| // Check to see if we should bail out of static generation based on | |
| // having non-static methods. | |
| if (this.hasNonStaticMethods) { | |
| if (workStore.isStaticGeneration) { | |
| const err = Object.defineProperty(new _hooksservercontext.DynamicServerError('Route is configured with methods that cannot be statically generated.'), "__NEXT_ERROR_CODE", { | |
| value: "E582", | |
| enumerable: false, | |
| configurable: true | |
| }); | |
| workStore.dynamicUsageDescription = err.message; | |
| workStore.dynamicUsageStack = err.stack; | |
| throw err; | |
| } | |
| } | |
| // We assume we can pass the original request through however we may end up | |
| // proxying it in certain circumstances based on execution type and configuration | |
| let request = req; | |
| // Update the static generation store based on the dynamic property. | |
| switch(this.dynamic){ | |
| case 'force-dynamic': | |
| { | |
| // Routes of generated paths should be dynamic | |
| workStore.forceDynamic = true; | |
| if (workStore.isStaticGeneration) { | |
| const err = Object.defineProperty(new _hooksservercontext.DynamicServerError('Route is configured with dynamic = error which cannot be statically generated.'), "__NEXT_ERROR_CODE", { | |
| value: "E703", | |
| enumerable: false, | |
| configurable: true | |
| }); | |
| workStore.dynamicUsageDescription = err.message; | |
| workStore.dynamicUsageStack = err.stack; | |
| throw err; | |
| } | |
| break; | |
| } | |
| case 'force-static': | |
| // The dynamic property is set to force-static, so we should | |
| // force the page to be static. | |
| workStore.forceStatic = true; | |
| // We also Proxy the request to replace dynamic data on the request | |
| // with empty stubs to allow for safely executing as static | |
| request = new Proxy(req, forceStaticRequestHandlers); | |
| break; | |
| case 'error': | |
| // The dynamic property is set to error, so we should throw an | |
| // error if the page is being statically generated. | |
| workStore.dynamicShouldError = true; | |
| if (workStore.isStaticGeneration) request = new Proxy(req, requireStaticRequestHandlers); | |
| break; | |
| case undefined: | |
| case 'auto': | |
| // We proxy `NextRequest` to track dynamic access, and | |
| // potentially bail out of static generation. | |
| request = proxyNextRequest(req, workStore); | |
| break; | |
| default: | |
| this.dynamic; | |
| } | |
| const tracer = (0, _tracer.getTracer)(); | |
| // Update the root span attribute for the route. | |
| const { pathname } = this.definition; | |
| tracer.setRootSpanAttribute('next.route', pathname); | |
| return tracer.trace(_constants.AppRouteRouteHandlersSpan.runHandler, { | |
| spanName: `executing api route (app) ${pathname}`, | |
| attributes: { | |
| 'next.route': pathname | |
| } | |
| }, async ()=>this.do(handler, actionStore, workStore, requestStore, implicitTags, request, context)); | |
| }))); | |
| // If the handler did't return a valid response, then return the internal | |
| // error response. | |
| if (!(response instanceof Response)) { | |
| // TODO: validate the correct handling behavior, maybe log something? | |
| return new Response(null, { | |
| status: 500 | |
| }); | |
| } | |
| if (response.headers.has('x-middleware-rewrite')) { | |
| throw Object.defineProperty(new Error('NextResponse.rewrite() was used in a app route handler, this is not currently supported. Please remove the invocation to continue.'), "__NEXT_ERROR_CODE", { | |
| value: "E374", | |
| enumerable: false, | |
| configurable: true | |
| }); | |
| } | |
| if (response.headers.get('x-middleware-next') === '1') { | |
| // TODO: move this error into the `NextResponse.next()` function. | |
| throw Object.defineProperty(new Error('NextResponse.next() was used in a app route handler, this is not supported. See here for more info: https://nextjs.org/docs/messages/next-response-next-in-app-route-handler'), "__NEXT_ERROR_CODE", { | |
| value: "E385", | |
| enumerable: false, | |
| configurable: true | |
| }); | |
| } | |
| return response; | |
| } | |
| } | |
| const _default = AppRouteRouteModule; | |
| function hasNonStaticMethods(handlers) { | |
| if (// Order these by how common they are to be used | |
| handlers.POST || handlers.PUT || handlers.DELETE || handlers.PATCH || handlers.OPTIONS) { | |
| return true; | |
| } | |
| return false; | |
| } | |
| // These symbols will be used to stash cached values on Proxied requests without requiring | |
| // additional closures or storage such as WeakMaps. | |
| const nextURLSymbol = Symbol('nextUrl'); | |
| const requestCloneSymbol = Symbol('clone'); | |
| const urlCloneSymbol = Symbol('clone'); | |
| const searchParamsSymbol = Symbol('searchParams'); | |
| const hrefSymbol = Symbol('href'); | |
| const toStringSymbol = Symbol('toString'); | |
| const headersSymbol = Symbol('headers'); | |
| const cookiesSymbol = Symbol('cookies'); | |
| /** | |
| * The general technique with these proxy handlers is to prioritize keeping them static | |
| * by stashing computed values on the Proxy itself. This is safe because the Proxy is | |
| * inaccessible to the consumer since all operations are forwarded | |
| */ const forceStaticRequestHandlers = { | |
| get (target, prop, receiver) { | |
| switch(prop){ | |
| case 'headers': | |
| return target[headersSymbol] || (target[headersSymbol] = _headers.HeadersAdapter.seal(new Headers({}))); | |
| case 'cookies': | |
| return target[cookiesSymbol] || (target[cookiesSymbol] = _requestcookies.RequestCookiesAdapter.seal(new _cookies.RequestCookies(new Headers({})))); | |
| case 'nextUrl': | |
| return target[nextURLSymbol] || (target[nextURLSymbol] = new Proxy(target.nextUrl, forceStaticNextUrlHandlers)); | |
| case 'url': | |
| // we don't need to separately cache this we can just read the nextUrl | |
| // and return the href since we know it will have been stripped of any | |
| // dynamic parts. We access via the receiver to trigger the get trap | |
| return receiver.nextUrl.href; | |
| case 'geo': | |
| case 'ip': | |
| return undefined; | |
| case 'clone': | |
| return target[requestCloneSymbol] || (target[requestCloneSymbol] = ()=>new Proxy(// This is vaguely unsafe but it's required since NextRequest does not implement | |
| // clone. The reason we might expect this to work in this context is the Proxy will | |
| // respond with static-amenable values anyway somewhat restoring the interface. | |
| // @TODO we need to rethink NextRequest and NextURL because they are not sufficientlly | |
| // sophisticated to adequately represent themselves in all contexts. A better approach is | |
| // to probably embed the static generation logic into the class itself removing the need | |
| // for any kind of proxying | |
| target.clone(), forceStaticRequestHandlers)); | |
| default: | |
| return _reflect.ReflectAdapter.get(target, prop, receiver); | |
| } | |
| } | |
| }; | |
| const forceStaticNextUrlHandlers = { | |
| get (target, prop, receiver) { | |
| switch(prop){ | |
| // URL properties | |
| case 'search': | |
| return ''; | |
| case 'searchParams': | |
| return target[searchParamsSymbol] || (target[searchParamsSymbol] = new URLSearchParams()); | |
| case 'href': | |
| return target[hrefSymbol] || (target[hrefSymbol] = (0, _cleanurl.cleanURL)(target.href).href); | |
| case 'toJSON': | |
| case 'toString': | |
| return target[toStringSymbol] || (target[toStringSymbol] = ()=>receiver.href); | |
| // NextUrl properties | |
| case 'url': | |
| // Currently nextURL does not expose url but our Docs indicate that it is an available property | |
| // I am forcing this to undefined here to avoid accidentally exposing a dynamic value later if | |
| // the underlying nextURL ends up adding this property | |
| return undefined; | |
| case 'clone': | |
| return target[urlCloneSymbol] || (target[urlCloneSymbol] = ()=>new Proxy(target.clone(), forceStaticNextUrlHandlers)); | |
| default: | |
| return _reflect.ReflectAdapter.get(target, prop, receiver); | |
| } | |
| } | |
| }; | |
| function proxyNextRequest(request, workStore) { | |
| const nextUrlHandlers = { | |
| get (target, prop, receiver) { | |
| switch(prop){ | |
| case 'search': | |
| case 'searchParams': | |
| case 'url': | |
| case 'href': | |
| case 'toJSON': | |
| case 'toString': | |
| case 'origin': | |
| { | |
| const workUnitStore = _workunitasyncstorageexternal.workUnitAsyncStorage.getStore(); | |
| trackDynamic(workStore, workUnitStore, `nextUrl.${prop}`); | |
| return _reflect.ReflectAdapter.get(target, prop, receiver); | |
| } | |
| case 'clone': | |
| return target[urlCloneSymbol] || (target[urlCloneSymbol] = ()=>new Proxy(target.clone(), nextUrlHandlers)); | |
| default: | |
| return _reflect.ReflectAdapter.get(target, prop, receiver); | |
| } | |
| } | |
| }; | |
| const nextRequestHandlers = { | |
| get (target, prop) { | |
| switch(prop){ | |
| case 'nextUrl': | |
| return target[nextURLSymbol] || (target[nextURLSymbol] = new Proxy(target.nextUrl, nextUrlHandlers)); | |
| case 'headers': | |
| case 'cookies': | |
| case 'url': | |
| case 'body': | |
| case 'blob': | |
| case 'json': | |
| case 'text': | |
| case 'arrayBuffer': | |
| case 'formData': | |
| { | |
| const workUnitStore = _workunitasyncstorageexternal.workUnitAsyncStorage.getStore(); | |
| trackDynamic(workStore, workUnitStore, `request.${prop}`); | |
| // The receiver arg is intentionally the same as the target to fix an issue with | |
| // edge runtime, where attempting to access internal slots with the wrong `this` context | |
| // results in an error. | |
| return _reflect.ReflectAdapter.get(target, prop, target); | |
| } | |
| case 'clone': | |
| return target[requestCloneSymbol] || (target[requestCloneSymbol] = ()=>new Proxy(// This is vaguely unsafe but it's required since NextRequest does not implement | |
| // clone. The reason we might expect this to work in this context is the Proxy will | |
| // respond with static-amenable values anyway somewhat restoring the interface. | |
| // @TODO we need to rethink NextRequest and NextURL because they are not sufficientlly | |
| // sophisticated to adequately represent themselves in all contexts. A better approach is | |
| // to probably embed the static generation logic into the class itself removing the need | |
| // for any kind of proxying | |
| target.clone(), nextRequestHandlers)); | |
| default: | |
| // The receiver arg is intentionally the same as the target to fix an issue with | |
| // edge runtime, where attempting to access internal slots with the wrong `this` context | |
| // results in an error. | |
| return _reflect.ReflectAdapter.get(target, prop, target); | |
| } | |
| } | |
| }; | |
| return new Proxy(request, nextRequestHandlers); | |
| } | |
| const requireStaticRequestHandlers = { | |
| get (target, prop, receiver) { | |
| switch(prop){ | |
| case 'nextUrl': | |
| return target[nextURLSymbol] || (target[nextURLSymbol] = new Proxy(target.nextUrl, requireStaticNextUrlHandlers)); | |
| case 'headers': | |
| case 'cookies': | |
| case 'url': | |
| case 'body': | |
| case 'blob': | |
| case 'json': | |
| case 'text': | |
| case 'arrayBuffer': | |
| case 'formData': | |
| throw Object.defineProperty(new _staticgenerationbailout.StaticGenBailoutError(`Route ${target.nextUrl.pathname} with \`dynamic = "error"\` couldn't be rendered statically because it used \`request.${prop}\`.`), "__NEXT_ERROR_CODE", { | |
| value: "E611", | |
| enumerable: false, | |
| configurable: true | |
| }); | |
| case 'clone': | |
| return target[requestCloneSymbol] || (target[requestCloneSymbol] = ()=>new Proxy(// This is vaguely unsafe but it's required since NextRequest does not implement | |
| // clone. The reason we might expect this to work in this context is the Proxy will | |
| // respond with static-amenable values anyway somewhat restoring the interface. | |
| // @TODO we need to rethink NextRequest and NextURL because they are not sufficientlly | |
| // sophisticated to adequately represent themselves in all contexts. A better approach is | |
| // to probably embed the static generation logic into the class itself removing the need | |
| // for any kind of proxying | |
| target.clone(), requireStaticRequestHandlers)); | |
| default: | |
| return _reflect.ReflectAdapter.get(target, prop, receiver); | |
| } | |
| } | |
| }; | |
| const requireStaticNextUrlHandlers = { | |
| get (target, prop, receiver) { | |
| switch(prop){ | |
| case 'search': | |
| case 'searchParams': | |
| case 'url': | |
| case 'href': | |
| case 'toJSON': | |
| case 'toString': | |
| case 'origin': | |
| throw Object.defineProperty(new _staticgenerationbailout.StaticGenBailoutError(`Route ${target.pathname} with \`dynamic = "error"\` couldn't be rendered statically because it used \`nextUrl.${prop}\`.`), "__NEXT_ERROR_CODE", { | |
| value: "E575", | |
| enumerable: false, | |
| configurable: true | |
| }); | |
| case 'clone': | |
| return target[urlCloneSymbol] || (target[urlCloneSymbol] = ()=>new Proxy(target.clone(), requireStaticNextUrlHandlers)); | |
| default: | |
| return _reflect.ReflectAdapter.get(target, prop, receiver); | |
| } | |
| } | |
| }; | |
| function createCacheComponentsError(route) { | |
| return Object.defineProperty(new _hooksservercontext.DynamicServerError(`Route ${route} couldn't be rendered statically because it used IO that was not cached. See more info here: https://nextjs.org/docs/messages/cache-components`), "__NEXT_ERROR_CODE", { | |
| value: "E727", | |
| enumerable: false, | |
| configurable: true | |
| }); | |
| } | |
| function trackDynamic(store, workUnitStore, expression) { | |
| if (store.dynamicShouldError) { | |
| throw Object.defineProperty(new _staticgenerationbailout.StaticGenBailoutError(`Route ${store.route} with \`dynamic = "error"\` couldn't be rendered statically because it used \`${expression}\`. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering`), "__NEXT_ERROR_CODE", { | |
| value: "E553", | |
| enumerable: false, | |
| configurable: true | |
| }); | |
| } | |
| if (workUnitStore) { | |
| switch(workUnitStore.type){ | |
| case 'cache': | |
| case 'private-cache': | |
| // TODO: Should we allow reading cookies and search params from the | |
| // request for private caches in route handlers? | |
| throw Object.defineProperty(new Error(`Route ${store.route} used "${expression}" inside "use cache". Accessing Dynamic data sources inside a cache scope is not supported. If you need this data inside a cached function use "${expression}" outside of the cached function and pass the required dynamic data in as an argument. See more info here: https://nextjs.org/docs/messages/next-request-in-use-cache`), "__NEXT_ERROR_CODE", { | |
| value: "E178", | |
| enumerable: false, | |
| configurable: true | |
| }); | |
| case 'unstable-cache': | |
| throw Object.defineProperty(new Error(`Route ${store.route} used "${expression}" inside a function cached with "unstable_cache(...)". Accessing Dynamic data sources inside a cache scope is not supported. If you need this data inside a cached function use "${expression}" outside of the cached function and pass the required dynamic data in as an argument. See more info here: https://nextjs.org/docs/app/api-reference/functions/unstable_cache`), "__NEXT_ERROR_CODE", { | |
| value: "E133", | |
| enumerable: false, | |
| configurable: true | |
| }); | |
| case 'prerender': | |
| const error = Object.defineProperty(new Error(`Route ${store.route} used ${expression} without first calling \`await connection()\`. See more info here: https://nextjs.org/docs/messages/next-prerender-sync-request`), "__NEXT_ERROR_CODE", { | |
| value: "E261", | |
| enumerable: false, | |
| configurable: true | |
| }); | |
| return (0, _dynamicrendering.abortAndThrowOnSynchronousRequestDataAccess)(store.route, expression, error, workUnitStore); | |
| case 'prerender-client': | |
| throw Object.defineProperty(new _invarianterror.InvariantError('A client prerender store should not be used for a route handler.'), "__NEXT_ERROR_CODE", { | |
| value: "E720", | |
| enumerable: false, | |
| configurable: true | |
| }); | |
| case 'prerender-runtime': | |
| throw Object.defineProperty(new _invarianterror.InvariantError('A runtime prerender store should not be used for a route handler.'), "__NEXT_ERROR_CODE", { | |
| value: "E767", | |
| enumerable: false, | |
| configurable: true | |
| }); | |
| case 'prerender-ppr': | |
| return (0, _dynamicrendering.postponeWithTracking)(store.route, expression, workUnitStore.dynamicTracking); | |
| case 'prerender-legacy': | |
| workUnitStore.revalidate = 0; | |
| const err = Object.defineProperty(new _hooksservercontext.DynamicServerError(`Route ${store.route} couldn't be rendered statically because it used \`${expression}\`. See more info here: https://nextjs.org/docs/messages/dynamic-server-error`), "__NEXT_ERROR_CODE", { | |
| value: "E558", | |
| enumerable: false, | |
| configurable: true | |
| }); | |
| store.dynamicUsageDescription = expression; | |
| store.dynamicUsageStack = err.stack; | |
| throw err; | |
| case 'request': | |
| if (process.env.NODE_ENV !== 'production') { | |
| // TODO: This is currently not really needed for route handlers, as it | |
| // only controls the ISR status that's shown for pages. | |
| workUnitStore.usedDynamic = true; | |
| } | |
| break; | |
| default: | |
| workUnitStore; | |
| } | |
| } | |
| } | |
| //# sourceMappingURL=module.js.map |