549 lines
27 KiB
JavaScript
549 lines
27 KiB
JavaScript
/**
|
|
* The functions provided by this module are used to communicate certain properties
|
|
* about the currently running code so that Next.js can make decisions on how to handle
|
|
* the current execution in different rendering modes such as pre-rendering, resuming, and SSR.
|
|
*
|
|
* Today Next.js treats all code as potentially static. Certain APIs may only make sense when dynamically rendering.
|
|
* Traditionally this meant deopting the entire render to dynamic however with PPR we can now deopt parts
|
|
* of a React tree as dynamic while still keeping other parts static. There are really two different kinds of
|
|
* Dynamic indications.
|
|
*
|
|
* The first is simply an intention to be dynamic. unstable_noStore is an example of this where
|
|
* the currently executing code simply declares that the current scope is dynamic but if you use it
|
|
* inside unstable_cache it can still be cached. This type of indication can be removed if we ever
|
|
* make the default dynamic to begin with because the only way you would ever be static is inside
|
|
* a cache scope which this indication does not affect.
|
|
*
|
|
* The second is an indication that a dynamic data source was read. This is a stronger form of dynamic
|
|
* because it means that it is inappropriate to cache this at all. using a dynamic data source inside
|
|
* unstable_cache should error. If you want to use some dynamic data inside unstable_cache you should
|
|
* read that data outside the cache and pass it in as an argument to the cached function.
|
|
*/ "use strict";
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
0 && (module.exports = {
|
|
Postpone: null,
|
|
abortAndThrowOnSynchronousRequestDataAccess: null,
|
|
abortOnSynchronousPlatformIOAccess: null,
|
|
accessedDynamicData: null,
|
|
annotateDynamicAccess: null,
|
|
consumeDynamicAccess: null,
|
|
createDynamicTrackingState: null,
|
|
createDynamicValidationState: null,
|
|
createHangingInputAbortSignal: null,
|
|
createPostponedAbortSignal: null,
|
|
formatDynamicAPIAccesses: null,
|
|
getFirstDynamicReason: null,
|
|
isDynamicPostpone: null,
|
|
isPrerenderInterruptedError: null,
|
|
markCurrentScopeAsDynamic: null,
|
|
postponeWithTracking: null,
|
|
throwIfDisallowedDynamic: null,
|
|
throwToInterruptStaticGeneration: null,
|
|
trackAllowedDynamicAccess: null,
|
|
trackDynamicDataInDynamicRender: null,
|
|
trackFallbackParamAccessed: null,
|
|
trackSynchronousPlatformIOAccessInDev: null,
|
|
trackSynchronousRequestDataAccessInDev: null,
|
|
useDynamicRouteParams: null
|
|
});
|
|
function _export(target, all) {
|
|
for(var name in all)Object.defineProperty(target, name, {
|
|
enumerable: true,
|
|
get: all[name]
|
|
});
|
|
}
|
|
_export(exports, {
|
|
Postpone: function() {
|
|
return Postpone;
|
|
},
|
|
abortAndThrowOnSynchronousRequestDataAccess: function() {
|
|
return abortAndThrowOnSynchronousRequestDataAccess;
|
|
},
|
|
abortOnSynchronousPlatformIOAccess: function() {
|
|
return abortOnSynchronousPlatformIOAccess;
|
|
},
|
|
accessedDynamicData: function() {
|
|
return accessedDynamicData;
|
|
},
|
|
annotateDynamicAccess: function() {
|
|
return annotateDynamicAccess;
|
|
},
|
|
consumeDynamicAccess: function() {
|
|
return consumeDynamicAccess;
|
|
},
|
|
createDynamicTrackingState: function() {
|
|
return createDynamicTrackingState;
|
|
},
|
|
createDynamicValidationState: function() {
|
|
return createDynamicValidationState;
|
|
},
|
|
createHangingInputAbortSignal: function() {
|
|
return createHangingInputAbortSignal;
|
|
},
|
|
createPostponedAbortSignal: function() {
|
|
return createPostponedAbortSignal;
|
|
},
|
|
formatDynamicAPIAccesses: function() {
|
|
return formatDynamicAPIAccesses;
|
|
},
|
|
getFirstDynamicReason: function() {
|
|
return getFirstDynamicReason;
|
|
},
|
|
isDynamicPostpone: function() {
|
|
return isDynamicPostpone;
|
|
},
|
|
isPrerenderInterruptedError: function() {
|
|
return isPrerenderInterruptedError;
|
|
},
|
|
markCurrentScopeAsDynamic: function() {
|
|
return markCurrentScopeAsDynamic;
|
|
},
|
|
postponeWithTracking: function() {
|
|
return postponeWithTracking;
|
|
},
|
|
throwIfDisallowedDynamic: function() {
|
|
return throwIfDisallowedDynamic;
|
|
},
|
|
throwToInterruptStaticGeneration: function() {
|
|
return throwToInterruptStaticGeneration;
|
|
},
|
|
trackAllowedDynamicAccess: function() {
|
|
return trackAllowedDynamicAccess;
|
|
},
|
|
trackDynamicDataInDynamicRender: function() {
|
|
return trackDynamicDataInDynamicRender;
|
|
},
|
|
trackFallbackParamAccessed: function() {
|
|
return trackFallbackParamAccessed;
|
|
},
|
|
trackSynchronousPlatformIOAccessInDev: function() {
|
|
return trackSynchronousPlatformIOAccessInDev;
|
|
},
|
|
trackSynchronousRequestDataAccessInDev: function() {
|
|
return trackSynchronousRequestDataAccessInDev;
|
|
},
|
|
useDynamicRouteParams: function() {
|
|
return useDynamicRouteParams;
|
|
}
|
|
});
|
|
const _react = /*#__PURE__*/ _interop_require_default(require("react"));
|
|
const _hooksservercontext = require("../../client/components/hooks-server-context");
|
|
const _staticgenerationbailout = require("../../client/components/static-generation-bailout");
|
|
const _workunitasyncstorageexternal = require("./work-unit-async-storage.external");
|
|
const _workasyncstorageexternal = require("../app-render/work-async-storage.external");
|
|
const _dynamicrenderingutils = require("../dynamic-rendering-utils");
|
|
const _metadataconstants = require("../../lib/metadata/metadata-constants");
|
|
const _scheduler = require("../../lib/scheduler");
|
|
function _interop_require_default(obj) {
|
|
return obj && obj.__esModule ? obj : {
|
|
default: obj
|
|
};
|
|
}
|
|
const hasPostpone = typeof _react.default.unstable_postpone === 'function';
|
|
function createDynamicTrackingState(isDebugDynamicAccesses) {
|
|
return {
|
|
isDebugDynamicAccesses,
|
|
dynamicAccesses: [],
|
|
syncDynamicExpression: undefined,
|
|
syncDynamicErrorWithStack: null
|
|
};
|
|
}
|
|
function createDynamicValidationState() {
|
|
return {
|
|
hasSuspendedDynamic: false,
|
|
hasDynamicMetadata: false,
|
|
hasDynamicViewport: false,
|
|
hasSyncDynamicErrors: false,
|
|
dynamicErrors: []
|
|
};
|
|
}
|
|
function getFirstDynamicReason(trackingState) {
|
|
var _trackingState_dynamicAccesses_;
|
|
return (_trackingState_dynamicAccesses_ = trackingState.dynamicAccesses[0]) == null ? void 0 : _trackingState_dynamicAccesses_.expression;
|
|
}
|
|
function markCurrentScopeAsDynamic(store, workUnitStore, expression) {
|
|
if (workUnitStore) {
|
|
if (workUnitStore.type === 'cache' || workUnitStore.type === 'unstable-cache') {
|
|
// inside cache scopes marking a scope as dynamic has no effect because the outer cache scope
|
|
// creates a cache boundary. This is subtly different from reading a dynamic data source which is
|
|
// forbidden inside a cache scope.
|
|
return;
|
|
}
|
|
}
|
|
// If we're forcing dynamic rendering or we're forcing static rendering, we
|
|
// don't need to do anything here because the entire page is already dynamic
|
|
// or it's static and it should not throw or postpone here.
|
|
if (store.forceDynamic || store.forceStatic) return;
|
|
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) {
|
|
if (workUnitStore.type === 'prerender-ppr') {
|
|
postponeWithTracking(store.route, expression, workUnitStore.dynamicTracking);
|
|
} else if (workUnitStore.type === 'prerender-legacy') {
|
|
workUnitStore.revalidate = 0;
|
|
// We aren't prerendering but we are generating a static page. We need to bail out of static generation
|
|
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: "E550",
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
store.dynamicUsageDescription = expression;
|
|
store.dynamicUsageStack = err.stack;
|
|
throw err;
|
|
} else if (process.env.NODE_ENV === 'development' && workUnitStore && workUnitStore.type === 'request') {
|
|
workUnitStore.usedDynamic = true;
|
|
}
|
|
}
|
|
}
|
|
function trackFallbackParamAccessed(store, expression) {
|
|
const prerenderStore = _workunitasyncstorageexternal.workUnitAsyncStorage.getStore();
|
|
if (!prerenderStore || prerenderStore.type !== 'prerender-ppr') return;
|
|
postponeWithTracking(store.route, expression, prerenderStore.dynamicTracking);
|
|
}
|
|
function throwToInterruptStaticGeneration(expression, store, prerenderStore) {
|
|
// We aren't prerendering but we are generating a static page. We need to bail out of static generation
|
|
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
|
|
});
|
|
prerenderStore.revalidate = 0;
|
|
store.dynamicUsageDescription = expression;
|
|
store.dynamicUsageStack = err.stack;
|
|
throw err;
|
|
}
|
|
function trackDynamicDataInDynamicRender(_store, workUnitStore) {
|
|
if (workUnitStore) {
|
|
if (workUnitStore.type === 'cache' || workUnitStore.type === 'unstable-cache') {
|
|
// inside cache scopes marking a scope as dynamic has no effect because the outer cache scope
|
|
// creates a cache boundary. This is subtly different from reading a dynamic data source which is
|
|
// forbidden inside a cache scope.
|
|
return;
|
|
}
|
|
if (workUnitStore.type === 'prerender' || workUnitStore.type === 'prerender-legacy') {
|
|
workUnitStore.revalidate = 0;
|
|
}
|
|
if (process.env.NODE_ENV === 'development' && workUnitStore.type === 'request') {
|
|
workUnitStore.usedDynamic = true;
|
|
}
|
|
}
|
|
}
|
|
// Despite it's name we don't actually abort unless we have a controller to call abort on
|
|
// There are times when we let a prerender run long to discover caches where we want the semantics
|
|
// of tracking dynamic access without terminating the prerender early
|
|
function abortOnSynchronousDynamicDataAccess(route, expression, prerenderStore) {
|
|
const reason = `Route ${route} needs to bail out of prerendering at this point because it used ${expression}.`;
|
|
const error = createPrerenderInterruptedError(reason);
|
|
prerenderStore.controller.abort(error);
|
|
const dynamicTracking = prerenderStore.dynamicTracking;
|
|
if (dynamicTracking) {
|
|
dynamicTracking.dynamicAccesses.push({
|
|
// When we aren't debugging, we don't need to create another error for the
|
|
// stack trace.
|
|
stack: dynamicTracking.isDebugDynamicAccesses ? new Error().stack : undefined,
|
|
expression
|
|
});
|
|
}
|
|
}
|
|
function abortOnSynchronousPlatformIOAccess(route, expression, errorWithStack, prerenderStore) {
|
|
const dynamicTracking = prerenderStore.dynamicTracking;
|
|
if (dynamicTracking) {
|
|
if (dynamicTracking.syncDynamicErrorWithStack === null) {
|
|
dynamicTracking.syncDynamicExpression = expression;
|
|
dynamicTracking.syncDynamicErrorWithStack = errorWithStack;
|
|
}
|
|
}
|
|
abortOnSynchronousDynamicDataAccess(route, expression, prerenderStore);
|
|
}
|
|
function trackSynchronousPlatformIOAccessInDev(requestStore) {
|
|
// We don't actually have a controller to abort but we do the semantic equivalent by
|
|
// advancing the request store out of prerender mode
|
|
requestStore.prerenderPhase = false;
|
|
}
|
|
function abortAndThrowOnSynchronousRequestDataAccess(route, expression, errorWithStack, prerenderStore) {
|
|
const prerenderSignal = prerenderStore.controller.signal;
|
|
if (prerenderSignal.aborted === false) {
|
|
// TODO it would be better to move this aborted check into the callsite so we can avoid making
|
|
// the error object when it isn't relevant to the aborting of the prerender however
|
|
// since we need the throw semantics regardless of whether we abort it is easier to land
|
|
// this way. See how this was handled with `abortOnSynchronousPlatformIOAccess` for a closer
|
|
// to ideal implementation
|
|
const dynamicTracking = prerenderStore.dynamicTracking;
|
|
if (dynamicTracking) {
|
|
if (dynamicTracking.syncDynamicErrorWithStack === null) {
|
|
dynamicTracking.syncDynamicExpression = expression;
|
|
dynamicTracking.syncDynamicErrorWithStack = errorWithStack;
|
|
if (prerenderStore.validating === true) {
|
|
// We always log Request Access in dev at the point of calling the function
|
|
// So we mark the dynamic validation as not requiring it to be printed
|
|
dynamicTracking.syncDynamicLogged = true;
|
|
}
|
|
}
|
|
}
|
|
abortOnSynchronousDynamicDataAccess(route, expression, prerenderStore);
|
|
}
|
|
throw createPrerenderInterruptedError(`Route ${route} needs to bail out of prerendering at this point because it used ${expression}.`);
|
|
}
|
|
const trackSynchronousRequestDataAccessInDev = trackSynchronousPlatformIOAccessInDev;
|
|
function Postpone({ reason, route }) {
|
|
const prerenderStore = _workunitasyncstorageexternal.workUnitAsyncStorage.getStore();
|
|
const dynamicTracking = prerenderStore && prerenderStore.type === 'prerender-ppr' ? prerenderStore.dynamicTracking : null;
|
|
postponeWithTracking(route, reason, dynamicTracking);
|
|
}
|
|
function postponeWithTracking(route, expression, dynamicTracking) {
|
|
assertPostpone();
|
|
if (dynamicTracking) {
|
|
dynamicTracking.dynamicAccesses.push({
|
|
// When we aren't debugging, we don't need to create another error for the
|
|
// stack trace.
|
|
stack: dynamicTracking.isDebugDynamicAccesses ? new Error().stack : undefined,
|
|
expression
|
|
});
|
|
}
|
|
_react.default.unstable_postpone(createPostponeReason(route, expression));
|
|
}
|
|
function createPostponeReason(route, expression) {
|
|
return `Route ${route} needs to bail out of prerendering at this point because it used ${expression}. ` + `React throws this special object to indicate where. It should not be caught by ` + `your own try/catch. Learn more: https://nextjs.org/docs/messages/ppr-caught-error`;
|
|
}
|
|
function isDynamicPostpone(err) {
|
|
if (typeof err === 'object' && err !== null && typeof err.message === 'string') {
|
|
return isDynamicPostponeReason(err.message);
|
|
}
|
|
return false;
|
|
}
|
|
function isDynamicPostponeReason(reason) {
|
|
return reason.includes('needs to bail out of prerendering at this point because it used') && reason.includes('Learn more: https://nextjs.org/docs/messages/ppr-caught-error');
|
|
}
|
|
if (isDynamicPostponeReason(createPostponeReason('%%%', '^^^')) === false) {
|
|
throw Object.defineProperty(new Error('Invariant: isDynamicPostpone misidentified a postpone reason. This is a bug in Next.js'), "__NEXT_ERROR_CODE", {
|
|
value: "E296",
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
}
|
|
const NEXT_PRERENDER_INTERRUPTED = 'NEXT_PRERENDER_INTERRUPTED';
|
|
function createPrerenderInterruptedError(message) {
|
|
const error = Object.defineProperty(new Error(message), "__NEXT_ERROR_CODE", {
|
|
value: "E394",
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
error.digest = NEXT_PRERENDER_INTERRUPTED;
|
|
return error;
|
|
}
|
|
function isPrerenderInterruptedError(error) {
|
|
return typeof error === 'object' && error !== null && error.digest === NEXT_PRERENDER_INTERRUPTED && 'name' in error && 'message' in error && error instanceof Error;
|
|
}
|
|
function accessedDynamicData(dynamicAccesses) {
|
|
return dynamicAccesses.length > 0;
|
|
}
|
|
function consumeDynamicAccess(serverDynamic, clientDynamic) {
|
|
// We mutate because we only call this once we are no longer writing
|
|
// to the dynamicTrackingState and it's more efficient than creating a new
|
|
// array.
|
|
serverDynamic.dynamicAccesses.push(...clientDynamic.dynamicAccesses);
|
|
return serverDynamic.dynamicAccesses;
|
|
}
|
|
function formatDynamicAPIAccesses(dynamicAccesses) {
|
|
return dynamicAccesses.filter((access)=>typeof access.stack === 'string' && access.stack.length > 0).map(({ expression, stack })=>{
|
|
stack = stack.split('\n')// Remove the "Error: " prefix from the first line of the stack trace as
|
|
// well as the first 4 lines of the stack trace which is the distance
|
|
// from the user code and the `new Error().stack` call.
|
|
.slice(4).filter((line)=>{
|
|
// Exclude Next.js internals from the stack trace.
|
|
if (line.includes('node_modules/next/')) {
|
|
return false;
|
|
}
|
|
// Exclude anonymous functions from the stack trace.
|
|
if (line.includes(' (<anonymous>)')) {
|
|
return false;
|
|
}
|
|
// Exclude Node.js internals from the stack trace.
|
|
if (line.includes(' (node:')) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}).join('\n');
|
|
return `Dynamic API Usage Debug - ${expression}:\n${stack}`;
|
|
});
|
|
}
|
|
function assertPostpone() {
|
|
if (!hasPostpone) {
|
|
throw Object.defineProperty(new Error(`Invariant: React.unstable_postpone is not defined. This suggests the wrong version of React was loaded. This is a bug in Next.js`), "__NEXT_ERROR_CODE", {
|
|
value: "E224",
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
}
|
|
}
|
|
function createPostponedAbortSignal(reason) {
|
|
assertPostpone();
|
|
const controller = new AbortController();
|
|
// We get our hands on a postpone instance by calling postpone and catching the throw
|
|
try {
|
|
_react.default.unstable_postpone(reason);
|
|
} catch (x) {
|
|
controller.abort(x);
|
|
}
|
|
return controller.signal;
|
|
}
|
|
function createHangingInputAbortSignal(workUnitStore) {
|
|
const controller = new AbortController();
|
|
if (workUnitStore.cacheSignal) {
|
|
// If we have a cacheSignal it means we're in a prospective render. If the input
|
|
// we're waiting on is coming from another cache, we do want to wait for it so that
|
|
// we can resolve this cache entry too.
|
|
workUnitStore.cacheSignal.inputReady().then(()=>{
|
|
controller.abort();
|
|
});
|
|
} else {
|
|
// Otherwise we're in the final render and we should already have all our caches
|
|
// filled. We might still be waiting on some microtasks so we wait one tick before
|
|
// giving up. When we give up, we still want to render the content of this cache
|
|
// as deeply as we can so that we can suspend as deeply as possible in the tree
|
|
// or not at all if we don't end up waiting for the input.
|
|
(0, _scheduler.scheduleOnNextTick)(()=>controller.abort());
|
|
}
|
|
return controller.signal;
|
|
}
|
|
function annotateDynamicAccess(expression, prerenderStore) {
|
|
const dynamicTracking = prerenderStore.dynamicTracking;
|
|
if (dynamicTracking) {
|
|
dynamicTracking.dynamicAccesses.push({
|
|
stack: dynamicTracking.isDebugDynamicAccesses ? new Error().stack : undefined,
|
|
expression
|
|
});
|
|
}
|
|
}
|
|
function useDynamicRouteParams(expression) {
|
|
const workStore = _workasyncstorageexternal.workAsyncStorage.getStore();
|
|
if (workStore && workStore.isStaticGeneration && workStore.fallbackRouteParams && workStore.fallbackRouteParams.size > 0) {
|
|
// There are fallback route params, we should track these as dynamic
|
|
// accesses.
|
|
const workUnitStore = _workunitasyncstorageexternal.workUnitAsyncStorage.getStore();
|
|
if (workUnitStore) {
|
|
// We're prerendering with dynamicIO or PPR or both
|
|
if (workUnitStore.type === 'prerender') {
|
|
// We are in a prerender with dynamicIO semantics
|
|
// We are going to hang here and never resolve. This will cause the currently
|
|
// rendering component to effectively be a dynamic hole
|
|
_react.default.use((0, _dynamicrenderingutils.makeHangingPromise)(workUnitStore.renderSignal, expression));
|
|
} else if (workUnitStore.type === 'prerender-ppr') {
|
|
// We're prerendering with PPR
|
|
postponeWithTracking(workStore.route, expression, workUnitStore.dynamicTracking);
|
|
} else if (workUnitStore.type === 'prerender-legacy') {
|
|
throwToInterruptStaticGeneration(expression, workStore, workUnitStore);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
const hasSuspenseRegex = /\n\s+at Suspense \(<anonymous>\)/;
|
|
const hasMetadataRegex = new RegExp(`\\n\\s+at ${_metadataconstants.METADATA_BOUNDARY_NAME}[\\n\\s]`);
|
|
const hasViewportRegex = new RegExp(`\\n\\s+at ${_metadataconstants.VIEWPORT_BOUNDARY_NAME}[\\n\\s]`);
|
|
const hasOutletRegex = new RegExp(`\\n\\s+at ${_metadataconstants.OUTLET_BOUNDARY_NAME}[\\n\\s]`);
|
|
function trackAllowedDynamicAccess(route, componentStack, dynamicValidation, serverDynamic, clientDynamic) {
|
|
if (hasOutletRegex.test(componentStack)) {
|
|
// We don't need to track that this is dynamic. It is only so when something else is also dynamic.
|
|
return;
|
|
} else if (hasMetadataRegex.test(componentStack)) {
|
|
dynamicValidation.hasDynamicMetadata = true;
|
|
return;
|
|
} else if (hasViewportRegex.test(componentStack)) {
|
|
dynamicValidation.hasDynamicViewport = true;
|
|
return;
|
|
} else if (hasSuspenseRegex.test(componentStack)) {
|
|
dynamicValidation.hasSuspendedDynamic = true;
|
|
return;
|
|
} else if (serverDynamic.syncDynamicErrorWithStack || clientDynamic.syncDynamicErrorWithStack) {
|
|
dynamicValidation.hasSyncDynamicErrors = true;
|
|
return;
|
|
} else {
|
|
const message = `Route "${route}": A component accessed data, headers, params, searchParams, or a short-lived cache without a Suspense boundary nor a "use cache" above it. We don't have the exact line number added to error messages yet but you can see which component in the stack below. See more info: https://nextjs.org/docs/messages/next-prerender-missing-suspense`;
|
|
const error = createErrorWithComponentStack(message, componentStack);
|
|
dynamicValidation.dynamicErrors.push(error);
|
|
return;
|
|
}
|
|
}
|
|
function createErrorWithComponentStack(message, componentStack) {
|
|
const error = Object.defineProperty(new Error(message), "__NEXT_ERROR_CODE", {
|
|
value: "E394",
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
error.stack = 'Error: ' + message + componentStack;
|
|
return error;
|
|
}
|
|
function throwIfDisallowedDynamic(route, dynamicValidation, serverDynamic, clientDynamic) {
|
|
let syncError;
|
|
let syncExpression;
|
|
let syncLogged;
|
|
if (serverDynamic.syncDynamicErrorWithStack) {
|
|
syncError = serverDynamic.syncDynamicErrorWithStack;
|
|
syncExpression = serverDynamic.syncDynamicExpression;
|
|
syncLogged = serverDynamic.syncDynamicLogged === true;
|
|
} else if (clientDynamic.syncDynamicErrorWithStack) {
|
|
syncError = clientDynamic.syncDynamicErrorWithStack;
|
|
syncExpression = clientDynamic.syncDynamicExpression;
|
|
syncLogged = clientDynamic.syncDynamicLogged === true;
|
|
} else {
|
|
syncError = null;
|
|
syncExpression = undefined;
|
|
syncLogged = false;
|
|
}
|
|
if (dynamicValidation.hasSyncDynamicErrors && syncError) {
|
|
if (!syncLogged) {
|
|
// In dev we already log errors about sync dynamic access. But during builds we need to ensure
|
|
// the offending sync error is logged before we exit the build
|
|
console.error(syncError);
|
|
}
|
|
// The actual error should have been logged when the sync access ocurred
|
|
throw new _staticgenerationbailout.StaticGenBailoutError();
|
|
}
|
|
const dynamicErrors = dynamicValidation.dynamicErrors;
|
|
if (dynamicErrors.length) {
|
|
for(let i = 0; i < dynamicErrors.length; i++){
|
|
console.error(dynamicErrors[i]);
|
|
}
|
|
throw new _staticgenerationbailout.StaticGenBailoutError();
|
|
}
|
|
if (!dynamicValidation.hasSuspendedDynamic) {
|
|
if (dynamicValidation.hasDynamicMetadata) {
|
|
if (syncError) {
|
|
console.error(syncError);
|
|
throw Object.defineProperty(new _staticgenerationbailout.StaticGenBailoutError(`Route "${route}" has a \`generateMetadata\` that could not finish rendering before ${syncExpression} was used. Follow the instructions in the error for this expression to resolve.`), "__NEXT_ERROR_CODE", {
|
|
value: "E608",
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
}
|
|
throw Object.defineProperty(new _staticgenerationbailout.StaticGenBailoutError(`Route "${route}" has a \`generateMetadata\` that depends on Request data (\`cookies()\`, etc...) or external data (\`fetch(...)\`, etc...) but the rest of the route was static or only used cached data (\`"use cache"\`). If you expected this route to be prerenderable update your \`generateMetadata\` to not use Request data and only use cached external data. Otherwise, add \`await connection()\` somewhere within this route to indicate explicitly it should not be prerendered.`), "__NEXT_ERROR_CODE", {
|
|
value: "E534",
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
} else if (dynamicValidation.hasDynamicViewport) {
|
|
if (syncError) {
|
|
console.error(syncError);
|
|
throw Object.defineProperty(new _staticgenerationbailout.StaticGenBailoutError(`Route "${route}" has a \`generateViewport\` that could not finish rendering before ${syncExpression} was used. Follow the instructions in the error for this expression to resolve.`), "__NEXT_ERROR_CODE", {
|
|
value: "E573",
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
}
|
|
throw Object.defineProperty(new _staticgenerationbailout.StaticGenBailoutError(`Route "${route}" has a \`generateViewport\` that depends on Request data (\`cookies()\`, etc...) or external data (\`fetch(...)\`, etc...) but the rest of the route was static or only used cached data (\`"use cache"\`). If you expected this route to be prerenderable update your \`generateViewport\` to not use Request data and only use cached external data. Otherwise, add \`await connection()\` somewhere within this route to indicate explicitly it should not be prerendered.`), "__NEXT_ERROR_CODE", {
|
|
value: "E590",
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
//# sourceMappingURL=dynamic-rendering.js.map
|