fix update build

This commit is contained in:
2026-07-14 10:40:44 +05:30
parent d8083177ce
commit 3917d58464
1441 changed files with 360224 additions and 66332 deletions

View File

@@ -0,0 +1,15 @@
// This is a minimal import that initializes the node
// environment, it is traced automatically for entries
// and can be used to ensure Node.js APIs are setup
// as expected without require `next-server`
"use strict";
if (process.env.NEXT_RUNTIME !== 'edge') {
// eslint-disable-next-line @next/internal/typechecked-require
require('next/dist/server/node-environment');
// eslint-disable-next-line @next/internal/typechecked-require
require('next/dist/server/require-hook');
// eslint-disable-next-line @next/internal/typechecked-require
require('next/dist/server/node-polyfill-crypto');
}
//# sourceMappingURL=setup-node-env.external.js.map

255
build/node_modules/next/dist/build/define-env.js generated vendored Normal file
View File

@@ -0,0 +1,255 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "getDefineEnv", {
enumerable: true,
get: function() {
return getDefineEnv;
}
});
const _nodepath = /*#__PURE__*/ _interop_require_default(require("node:path"));
const _needsexperimentalreact = require("../lib/needs-experimental-react");
const _ppr = require("../server/lib/experimental/ppr");
const _staticenv = require("../lib/static-env");
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
const DEFINE_ENV_EXPRESSION = Symbol('DEFINE_ENV_EXPRESSION');
/**
* Serializes the DefineEnv config so that it can be inserted into the code by Webpack/Turbopack, JSON stringifies each value.
*/ function serializeDefineEnv(defineEnv) {
const defineEnvStringified = Object.fromEntries(Object.entries(defineEnv).map(([key, value])=>[
key,
typeof value === 'object' && DEFINE_ENV_EXPRESSION in value ? value[DEFINE_ENV_EXPRESSION] : JSON.stringify(value)
]));
return defineEnvStringified;
}
function getImageConfig(config, dev) {
var _config_images, _config_images1, _config_images2;
return {
'process.env.__NEXT_IMAGE_OPTS': {
deviceSizes: config.images.deviceSizes,
imageSizes: config.images.imageSizes,
qualities: config.images.qualities,
path: config.images.path,
loader: config.images.loader,
dangerouslyAllowSVG: config.images.dangerouslyAllowSVG,
unoptimized: config == null ? void 0 : (_config_images = config.images) == null ? void 0 : _config_images.unoptimized,
...dev ? {
// additional config in dev to allow validating on the client
domains: config.images.domains,
remotePatterns: (_config_images1 = config.images) == null ? void 0 : _config_images1.remotePatterns,
localPatterns: (_config_images2 = config.images) == null ? void 0 : _config_images2.localPatterns,
output: config.output
} : {}
}
};
}
function getDefineEnv({ isTurbopack, clientRouterFilters, config, dev, distDir, projectPath, fetchCacheKeyPrefix, hasRewrites, isClient, isEdgeServer, isNodeServer, middlewareMatchers, omitNonDeterministic, rewrites }) {
var _config_experimental, _config_experimental1, _config_experimental_staleTimes, _config_experimental_staleTimes1, _config_experimental_staleTimes2, _config_experimental_staleTimes3, _config_i18n, _config_compiler;
const nextPublicEnv = (0, _staticenv.getNextPublicEnvironmentVariables)();
const nextConfigEnv = (0, _staticenv.getNextConfigEnv)(config);
const isPPREnabled = (0, _ppr.checkIsAppPPREnabled)(config.experimental.ppr);
const isCacheComponentsEnabled = !!config.cacheComponents;
const isUseCacheEnabled = !!config.experimental.useCache;
const defineEnv = {
// internal field to identify the plugin config
__NEXT_DEFINE_ENV: true,
...nextPublicEnv,
...nextConfigEnv,
...!isEdgeServer ? {} : {
EdgeRuntime: /**
* Cloud providers can set this environment variable to allow users
* and library authors to have different implementations based on
* the runtime they are running with, if it's not using `edge-runtime`
*/ process.env.NEXT_EDGE_RUNTIME_PROVIDER ?? 'edge-runtime',
// process should be only { env: {...} } for edge runtime.
// For ignore avoid warn on `process.emit` usage but directly omit it.
'process.emit': false
},
'process.turbopack': isTurbopack,
'process.env.TURBOPACK': isTurbopack,
'process.env.__NEXT_BUNDLER': isTurbopack ? 'Turbopack' : process.env.NEXT_RSPACK ? 'Rspack' : 'Webpack',
// TODO: enforce `NODE_ENV` on `process.env`, and add a test:
'process.env.NODE_ENV': dev || config.experimental.allowDevelopmentBuild ? 'development' : 'production',
'process.env.__NEXT_DEV_SERVER': dev ? '1' : '',
'process.env.NEXT_RUNTIME': isEdgeServer ? 'edge' : isNodeServer ? 'nodejs' : '',
'process.env.NEXT_MINIMAL': '',
'process.env.__NEXT_APP_NAV_FAIL_HANDLING': Boolean(config.experimental.appNavFailHandling),
'process.env.__NEXT_APP_NEW_SCROLL_HANDLER': Boolean(config.experimental.appNewScrollHandler),
'process.env.__NEXT_PPR': isPPREnabled,
'process.env.__NEXT_CACHE_COMPONENTS': isCacheComponentsEnabled,
'process.env.__NEXT_EXPERIMENTAL_CACHED_NAVIGATIONS': Boolean(config.experimental.cachedNavigations),
'process.env.__NEXT_INSTANT_NAV_TOGGLE': !!config.experimental.instantNavigationDevToolsToggle,
'process.env.__NEXT_USE_CACHE': isUseCacheEnabled,
'process.env.NEXT_IMMUTABLE_ASSET_TOKEN': config.experimental.immutableAssetToken || '',
...((_config_experimental = config.experimental) == null ? void 0 : _config_experimental.useSkewCookie) || !config.deploymentId ? {
'process.env.NEXT_DEPLOYMENT_ID': false
} : isClient ? isTurbopack ? {
// This is set at runtime by packages/next/src/client/register-deployment-id-global.ts
'process.env.NEXT_DEPLOYMENT_ID': {
[DEFINE_ENV_EXPRESSION]: 'globalThis.NEXT_DEPLOYMENT_ID'
}
} : {
// For Webpack, we currently don't use the non-inlining globalThis.NEXT_DEPLOYMENT_ID
// approach because we cannot forward this global variable to web workers easily.
'process.env.NEXT_DEPLOYMENT_ID': config.deploymentId || false
} : ((_config_experimental1 = config.experimental) == null ? void 0 : _config_experimental1.runtimeServerDeploymentId) ? {
} : {
'process.env.NEXT_DEPLOYMENT_ID': config.deploymentId || false
},
// Propagates the `__NEXT_EXPERIMENTAL_STATIC_SHELL_DEBUGGING` environment
// variable to the client.
'process.env.__NEXT_EXPERIMENTAL_STATIC_SHELL_DEBUGGING': process.env.__NEXT_EXPERIMENTAL_STATIC_SHELL_DEBUGGING || false,
'process.env.__NEXT_FETCH_CACHE_KEY_PREFIX': fetchCacheKeyPrefix ?? '',
...isTurbopack ? {} : {
'process.env.__NEXT_MIDDLEWARE_MATCHERS': middlewareMatchers ?? []
},
'process.env.__NEXT_MANUAL_CLIENT_BASE_PATH': config.experimental.manualClientBasePath ?? false,
'process.env.__NEXT_CLIENT_ROUTER_DYNAMIC_STALETIME': JSON.stringify(isNaN(Number((_config_experimental_staleTimes = config.experimental.staleTimes) == null ? void 0 : _config_experimental_staleTimes.dynamic)) ? 0 : (_config_experimental_staleTimes1 = config.experimental.staleTimes) == null ? void 0 : _config_experimental_staleTimes1.dynamic),
'process.env.__NEXT_CLIENT_ROUTER_STATIC_STALETIME': JSON.stringify(isNaN(Number((_config_experimental_staleTimes2 = config.experimental.staleTimes) == null ? void 0 : _config_experimental_staleTimes2.static)) ? 5 * 60 // 5 minutes
: (_config_experimental_staleTimes3 = config.experimental.staleTimes) == null ? void 0 : _config_experimental_staleTimes3.static),
'process.env.__NEXT_CLIENT_ROUTER_FILTER_ENABLED': config.experimental.clientRouterFilter ?? true,
'process.env.__NEXT_CLIENT_ROUTER_S_FILTER': (clientRouterFilters == null ? void 0 : clientRouterFilters.staticFilter) ?? false,
'process.env.__NEXT_CLIENT_ROUTER_D_FILTER': (clientRouterFilters == null ? void 0 : clientRouterFilters.dynamicFilter) ?? false,
'process.env.__NEXT_CLIENT_VALIDATE_RSC_REQUEST_HEADERS': Boolean(config.experimental.validateRSCRequestHeaders),
'process.env.__NEXT_DYNAMIC_ON_HOVER': Boolean(config.experimental.dynamicOnHover),
'process.env.__NEXT_PREFETCH_INLINING': Boolean(config.experimental.prefetchInlining),
'process.env.__NEXT_OPTIMISTIC_CLIENT_CACHE': config.experimental.optimisticClientCache ?? true,
'process.env.__NEXT_MIDDLEWARE_PREFETCH': config.experimental.proxyPrefetch ?? 'flexible',
'process.env.__NEXT_CROSS_ORIGIN': config.crossOrigin,
'process.browser': isClient,
'process.env.__NEXT_TEST_MODE': process.env.__NEXT_TEST_MODE ?? false,
// This is used in client/dev-error-overlay/hot-dev-client.js to replace the dist directory
...dev && (isClient ?? isEdgeServer) ? {
'process.env.__NEXT_DIST_DIR': distDir
} : {},
// This is used in devtools to strip the project path in edge runtime,
// as there's only a dummy `dir` value (`.`) as edge runtime doesn't have concept of file system.
...dev && isEdgeServer ? {
'process.env.__NEXT_EDGE_PROJECT_DIR': isTurbopack ? _nodepath.default.relative(process.cwd(), projectPath) : projectPath
} : {},
'process.env.__NEXT_BASE_PATH': config.basePath,
'process.env.__NEXT_CASE_SENSITIVE_ROUTES': Boolean(config.experimental.caseSensitiveRoutes),
'process.env.__NEXT_REWRITES': rewrites,
'process.env.__NEXT_TRAILING_SLASH': config.trailingSlash,
'process.env.__NEXT_DEV_INDICATOR': config.devIndicators !== false,
'process.env.__NEXT_DEV_INDICATOR_POSITION': config.devIndicators === false ? 'bottom-left' // This will not be used as the indicator is disabled.
: config.devIndicators.position ?? 'bottom-left',
'process.env.__NEXT_STRICT_MODE': config.reactStrictMode === null ? false : config.reactStrictMode,
'process.env.__NEXT_STRICT_MODE_APP': // When next.config.js does not have reactStrictMode it's enabled by default.
config.reactStrictMode === null ? true : config.reactStrictMode,
'process.env.__NEXT_OPTIMIZE_CSS': (config.experimental.optimizeCss && !dev) ?? false,
'process.env.__NEXT_SCRIPT_WORKERS': (config.experimental.nextScriptWorkers && !dev) ?? false,
'process.env.__NEXT_SCROLL_RESTORATION': config.experimental.scrollRestoration ?? false,
...getImageConfig(config, dev),
'process.env.__NEXT_ROUTER_BASEPATH': config.basePath,
'process.env.__NEXT_HAS_REWRITES': hasRewrites,
'process.env.__NEXT_CONFIG_OUTPUT': config.output,
'process.env.__NEXT_I18N_SUPPORT': !!config.i18n,
'process.env.__NEXT_I18N_DOMAINS': ((_config_i18n = config.i18n) == null ? void 0 : _config_i18n.domains) ?? false,
'process.env.__NEXT_I18N_CONFIG': config.i18n || '',
'process.env.__NEXT_NO_MIDDLEWARE_URL_NORMALIZE': config.skipProxyUrlNormalize,
'process.env.__NEXT_EXTERNAL_MIDDLEWARE_REWRITE_RESOLVE': config.experimental.externalProxyRewritesResolve ?? false,
'process.env.__NEXT_MANUAL_TRAILING_SLASH': config.skipTrailingSlashRedirect,
'process.env.__NEXT_HAS_WEB_VITALS_ATTRIBUTION': (config.experimental.webVitalsAttribution && config.experimental.webVitalsAttribution.length > 0) ?? false,
'process.env.__NEXT_WEB_VITALS_ATTRIBUTION': config.experimental.webVitalsAttribution ?? false,
'process.env.__NEXT_LINK_NO_TOUCH_START': config.experimental.linkNoTouchStart ?? false,
'process.env.__NEXT_ASSET_PREFIX': config.assetPrefix,
'process.env.__NEXT_EXPERIMENTAL_AUTH_INTERRUPTS': !!config.experimental.authInterrupts,
'process.env.__NEXT_TELEMETRY_DISABLED': Boolean(process.env.NEXT_TELEMETRY_DISABLED),
...isNodeServer || isEdgeServer ? {
// Fix bad-actors in the npm ecosystem (e.g. `node-formidable`)
// This is typically found in unmaintained modules from the
// pre-webpack era (common in server-side code)
'global.GENTLY': false
} : undefined,
...isNodeServer || isEdgeServer ? {
'process.env.__NEXT_EXPERIMENTAL_REACT': (0, _needsexperimentalreact.needsExperimentalReact)(config)
} : undefined,
'process.env.__NEXT_MULTI_ZONE_DRAFT_MODE': config.experimental.multiZoneDraftMode ?? false,
'process.env.__NEXT_TRUST_HOST_HEADER': config.experimental.trustHostHeader ?? false,
'process.env.__NEXT_ALLOWED_REVALIDATE_HEADERS': config.experimental.allowedRevalidateHeaderKeys ?? [],
...isNodeServer || isEdgeServer ? {
'process.env.__NEXT_RELATIVE_DIST_DIR': config.distDir,
'process.env.__NEXT_RELATIVE_PROJECT_DIR': _nodepath.default.relative(process.cwd(), projectPath)
} : {},
'process.env.__NEXT_BROWSER_DEBUG_INFO_IN_TERMINAL': JSON.stringify(config.logging && config.logging.browserToTerminal || false),
'process.env.__NEXT_MCP_SERVER': !!config.experimental.mcpServer,
// The devtools need to know whether or not to show an option to clear the
// bundler cache. This option may be removed later once Turbopack's
// filesystem cache feature is more stable.
//
// This environment value is currently best-effort:
// - It's possible to disable the webpack filesystem cache, but it's
// unlikely for a user to do that.
// - Rspack's filesystem cache is unstable and requires a different
// configuration than webpack to enable (which we don't do).
//
// In the worst case we'll show an option to clear the cache, but it'll be a
// no-op that just restarts the development server.
'process.env.__NEXT_BUNDLER_HAS_PERSISTENT_CACHE': !isTurbopack || (config.experimental.turbopackFileSystemCacheForDev ?? false),
'process.env.__NEXT_REACT_DEBUG_CHANNEL': config.experimental.reactDebugChannel ?? false,
'process.env.__NEXT_TRANSITION_INDICATOR': config.experimental.transitionIndicator ?? false,
'process.env.__NEXT_GESTURE_TRANSITION': config.experimental.gestureTransition ?? false,
'process.env.__NEXT_OPTIMISTIC_ROUTING': config.experimental.optimisticRouting ?? false,
'process.env.__NEXT_VARY_PARAMS': config.experimental.varyParams ?? false,
'process.env.__NEXT_EXPOSE_TESTING_API': dev || config.experimental.exposeTestingApiInProductionBuild === true,
'process.env.__NEXT_CACHE_LIFE': config.cacheLife,
'process.env.__NEXT_CLIENT_PARAM_PARSING_ORIGINS': config.experimental.clientParamParsingOrigins || []
};
const userDefines = ((_config_compiler = config.compiler) == null ? void 0 : _config_compiler.define) ?? {};
for(const key in userDefines){
if (defineEnv.hasOwnProperty(key)) {
throw Object.defineProperty(new Error(`The \`compiler.define\` option is configured to replace the \`${key}\` variable. This variable is either part of a Next.js built-in or is already configured.`), "__NEXT_ERROR_CODE", {
value: "E688",
enumerable: false,
configurable: true
});
}
defineEnv[key] = userDefines[key];
}
if (isNodeServer || isEdgeServer) {
var _config_compiler1;
const userDefinesServer = ((_config_compiler1 = config.compiler) == null ? void 0 : _config_compiler1.defineServer) ?? {};
for(const key in userDefinesServer){
if (defineEnv.hasOwnProperty(key)) {
throw Object.defineProperty(new Error(`The \`compiler.defineServer\` option is configured to replace the \`${key}\` variable. This variable is either part of a Next.js built-in or is already configured.`), "__NEXT_ERROR_CODE", {
value: "E689",
enumerable: false,
configurable: true
});
}
defineEnv[key] = userDefinesServer[key];
}
}
const serializedDefineEnv = serializeDefineEnv(defineEnv);
// we delay inlining these values until after the build
// with flying shuttle enabled so we can update them
// without invalidating entries
if (!dev && omitNonDeterministic) {
// client uses window. instead of leaving process.env
// in case process isn't polyfilled on client already
// since by this point it won't be added by webpack
const safeKey = (key)=>isClient ? `window.${key.split('.').pop()}` : key;
for(const key in nextPublicEnv){
serializedDefineEnv[key] = safeKey(key);
}
for(const key in nextConfigEnv){
serializedDefineEnv[key] = safeKey(key);
}
if (!config.experimental.runtimeServerDeploymentId) {
for (const key of [
'process.env.NEXT_DEPLOYMENT_ID'
]){
serializedDefineEnv[key] = safeKey(key);
}
}
}
return serializedDefineEnv;
}
//# sourceMappingURL=define-env.js.map

View File

@@ -0,0 +1,99 @@
// Time thresholds in seconds
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
durationToString: null,
hrtimeBigIntDurationToString: null,
hrtimeDurationToString: null,
hrtimeToSeconds: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
durationToString: function() {
return durationToString;
},
hrtimeBigIntDurationToString: function() {
return hrtimeBigIntDurationToString;
},
hrtimeDurationToString: function() {
return hrtimeDurationToString;
},
hrtimeToSeconds: function() {
return hrtimeToSeconds;
}
});
const SECONDS_IN_MINUTE = 60;
const MINUTES_THRESHOLD_SECONDS = 120 // 2 minutes
;
const SECONDS_THRESHOLD_HIGH = 40;
const SECONDS_THRESHOLD_LOW = 2;
const MILLISECONDS_PER_SECOND = 1000;
// Time thresholds and conversion factors for nanoseconds
const NANOSECONDS_PER_SECOND = 1000000000;
const NANOSECONDS_PER_MILLISECOND = 1000000;
const NANOSECONDS_PER_MICROSECOND = 1000;
const NANOSECONDS_IN_MINUTE = 60000000000 // 60 * 1_000_000_000
;
const MINUTES_THRESHOLD_NANOSECONDS = 120000000000 // 2 minutes in nanoseconds
;
const SECONDS_THRESHOLD_HIGH_NANOSECONDS = 40000000000 // 40 seconds in nanoseconds
;
const SECONDS_THRESHOLD_LOW_NANOSECONDS = 2000000000 // 2 seconds in nanoseconds
;
const MILLISECONDS_THRESHOLD_NANOSECONDS = 2000000 // 2 milliseconds in nanoseconds
;
function durationToString(compilerDuration) {
if (compilerDuration > MINUTES_THRESHOLD_SECONDS) {
return `${(compilerDuration / SECONDS_IN_MINUTE).toFixed(1)}min`;
} else if (compilerDuration > SECONDS_THRESHOLD_HIGH) {
return `${compilerDuration.toFixed(0)}s`;
} else if (compilerDuration > SECONDS_THRESHOLD_LOW) {
return `${compilerDuration.toFixed(1)}s`;
} else {
return `${(compilerDuration * MILLISECONDS_PER_SECOND).toFixed(0)}ms`;
}
}
/**
* Converts a nanosecond duration to a human-readable string format.
* Formats duration based on magnitude for optimal readability:
* - >= 2 minutes: show in minutes with 1 decimal place (e.g., "2.5min")
* - >= 40 seconds: show in whole seconds (e.g., "45s")
* - >= 2 seconds: show in seconds with 1 decimal place (e.g., "3.2s")
* - >= 2 milliseconds: show in whole milliseconds (e.g., "250ms")
* - < 2 milliseconds: show in whole microseconds (e.g., "500µs")
*
* @param durationBigInt - Duration in nanoseconds as a BigInt
* @returns Formatted duration string with appropriate unit and precision
*/ function durationToStringWithNanoseconds(durationBigInt) {
const duration = Number(durationBigInt);
if (duration >= MINUTES_THRESHOLD_NANOSECONDS) {
return `${(duration / NANOSECONDS_IN_MINUTE).toFixed(1)}min`;
} else if (duration >= SECONDS_THRESHOLD_HIGH_NANOSECONDS) {
return `${(duration / NANOSECONDS_PER_SECOND).toFixed(0)}s`;
} else if (duration >= SECONDS_THRESHOLD_LOW_NANOSECONDS) {
return `${(duration / NANOSECONDS_PER_SECOND).toFixed(1)}s`;
} else if (duration >= MILLISECONDS_THRESHOLD_NANOSECONDS) {
return `${(duration / NANOSECONDS_PER_MILLISECOND).toFixed(0)}ms`;
} else {
return `${(duration / NANOSECONDS_PER_MICROSECOND).toFixed(0)}µs`;
}
}
function hrtimeToSeconds(hrtime) {
// hrtime is a tuple of [seconds, nanoseconds]
return hrtime[0] + hrtime[1] / NANOSECONDS_PER_SECOND;
}
function hrtimeBigIntDurationToString(hrtime) {
return durationToStringWithNanoseconds(hrtime);
}
function hrtimeDurationToString(hrtime) {
return durationToString(hrtimeToSeconds(hrtime));
}
//# sourceMappingURL=duration-to-string.js.map

View File

@@ -0,0 +1,38 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "getSupportedBrowsers", {
enumerable: true,
get: function() {
return getSupportedBrowsers;
}
});
const _browserslist = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/browserslist"));
const _constants = require("../shared/lib/constants");
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
function getSupportedBrowsers(dir, isDevelopment) {
let browsers;
try {
const browsersListConfig = _browserslist.default.loadConfig({
path: dir,
env: isDevelopment ? 'development' : 'production'
});
// Running `browserslist` resolves `extends` and other config features into a list of browsers
if (browsersListConfig && browsersListConfig.length > 0) {
browsers = (0, _browserslist.default)(browsersListConfig);
}
} catch {}
// When user has browserslist use that target
if (browsers && browsers.length > 0) {
return browsers;
}
// Uses modern browsers as the default.
return _constants.MODERN_BROWSERSLIST_TARGET;
}
//# sourceMappingURL=get-supported-browsers.js.map

View File

@@ -0,0 +1,85 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
deregisterHook: null,
registerHook: null,
requireFromString: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
deregisterHook: function() {
return deregisterHook;
},
registerHook: function() {
return registerHook;
},
requireFromString: function() {
return requireFromString;
}
});
const _nodemodule = /*#__PURE__*/ _interop_require_default(require("node:module"));
const _nodefs = require("node:fs");
const _nodepath = require("node:path");
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
const oldJSHook = require.extensions['.js'];
const extensions = [
'.ts',
'.cts',
'.mts',
'.cjs',
'.mjs'
];
function registerHook(swcOptions) {
// lazy require swc since it loads React before even setting NODE_ENV
// resulting loading Development React on Production
const { transformSync } = require('../swc');
require.extensions['.js'] = function(mod, oldFilename) {
try {
return oldJSHook(mod, oldFilename);
} catch (error) {
if (error.code !== 'ERR_REQUIRE_ESM') {
throw error;
}
// calling oldJSHook throws ERR_REQUIRE_ESM, so run _compile manually
// TODO: investigate if we can remove readFileSync
const content = (0, _nodefs.readFileSync)(oldFilename, 'utf8');
const { code } = transformSync(content, swcOptions);
mod._compile(code, oldFilename);
}
};
for (const ext of extensions){
const oldHook = require.extensions[ext] ?? oldJSHook;
require.extensions[ext] = function(mod, oldFilename) {
const _compile = mod._compile;
mod._compile = function(code, filename) {
const swc = transformSync(code, swcOptions);
return _compile.call(this, swc.code, filename);
};
return oldHook(mod, oldFilename);
};
}
}
function deregisterHook() {
require.extensions['.js'] = oldJSHook;
extensions.forEach((ext)=>delete require.extensions[ext]);
}
function requireFromString(code, filename) {
const paths = _nodemodule.default._nodeModulePaths((0, _nodepath.dirname)(filename));
const m = new _nodemodule.default(filename, module.parent);
m.paths = paths;
m._compile(code, filename);
return m.exports;
}
//# sourceMappingURL=require-hook.js.map

View File

@@ -0,0 +1,251 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "transpileConfig", {
enumerable: true,
get: function() {
return transpileConfig;
}
});
const _nodepath = /*#__PURE__*/ _interop_require_default(require("node:path"));
const _nodefs = require("node:fs");
const _nodeurl = require("node:url");
const _commentjson = /*#__PURE__*/ _interop_require_wildcard(require("next/dist/compiled/comment-json"));
const _requirehook = require("./require-hook");
const _log = require("../output/log");
const _utils = require("../../server/lib/utils");
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
function _getRequireWildcardCache(nodeInterop) {
if (typeof WeakMap !== "function") return null;
var cacheBabelInterop = new WeakMap();
var cacheNodeInterop = new WeakMap();
return (_getRequireWildcardCache = function(nodeInterop) {
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
})(nodeInterop);
}
function _interop_require_wildcard(obj, nodeInterop) {
if (!nodeInterop && obj && obj.__esModule) {
return obj;
}
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
return {
default: obj
};
}
var cache = _getRequireWildcardCache(nodeInterop);
if (cache && cache.has(obj)) {
return cache.get(obj);
}
var newObj = {
__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;
}
function resolveSWCOptions(cwd, compilerOptions) {
var _process_versions, _process;
return {
jsc: {
parser: {
syntax: 'typescript'
},
...compilerOptions.paths ? {
paths: compilerOptions.paths
} : {},
...compilerOptions.baseUrl ? {
baseUrl: _nodepath.default.resolve(cwd, compilerOptions.baseUrl)
} : compilerOptions.paths ? {
baseUrl: cwd
} : {}
},
module: {
type: 'commonjs'
},
isModule: 'unknown',
env: {
targets: {
// Setting the Node.js version can reduce unnecessary code generation.
node: ((_process = process) == null ? void 0 : (_process_versions = _process.versions) == null ? void 0 : _process_versions.node) ?? '20.19.0'
}
}
};
}
function resolveExtends(extendsPath, currentConfigDir) {
// Relative paths are resolved relative to the current config's directory
if (extendsPath.startsWith('./') || extendsPath.startsWith('../') || _nodepath.default.isAbsolute(extendsPath)) {
const resolved = _nodepath.default.resolve(currentConfigDir, extendsPath);
// TypeScript allows omitting .json extension
if ((0, _nodefs.existsSync)(resolved)) {
return resolved;
}
if (!resolved.endsWith('.json') && (0, _nodefs.existsSync)(resolved + '.json')) {
return resolved + '.json';
}
return resolved;
}
// Package paths - use require.resolve to find the package
try {
// Try resolving as a direct path within the package
return require.resolve(extendsPath, {
paths: [
currentConfigDir
]
});
} catch {
// If that fails, try appending tsconfig.json for package names like "@tsconfig/node18"
try {
return require.resolve(extendsPath + '/tsconfig.json', {
paths: [
currentConfigDir
]
});
} catch {
// Return the original path and let it fail later with a clear error
return _nodepath.default.resolve(currentConfigDir, extendsPath);
}
}
}
function loadTsConfigFile(configPath, visited) {
const resolvedPath = _nodepath.default.resolve(configPath);
if (visited.has(resolvedPath)) {
return {};
}
visited.add(resolvedPath);
if (!(0, _nodefs.existsSync)(resolvedPath)) {
return {};
}
const configContent = (0, _nodefs.readFileSync)(resolvedPath, 'utf8');
const config = _commentjson.parse(configContent);
const configDir = _nodepath.default.dirname(resolvedPath);
let mergedOptions = {};
// Note that config options from `extends` should get overwritten, not merged
if (config.extends) {
const extendsList = Array.isArray(config.extends) ? config.extends : [
config.extends
];
for (const extendsPath of extendsList){
const parentConfigPath = resolveExtends(extendsPath, configDir);
const parentOptions = loadTsConfigFile(parentConfigPath, visited);
mergedOptions = {
...mergedOptions,
...parentOptions
};
}
}
const currentOptions = config.compilerOptions ?? {};
mergedOptions = {
...mergedOptions,
paths: currentOptions.paths ?? mergedOptions.paths,
baseUrl: currentOptions.baseUrl ?? mergedOptions.baseUrl
};
return mergedOptions;
}
async function loadTsConfig(dir) {
// NOTE: This doesn't fully cover the edge case for setting
// "typescript.tsconfigPath" in next config which is currently
// a restriction.
// It's a chicken-and-egg problem since we need to transpile
// the next config to get that value.
const resolvedTsConfigPath = _nodepath.default.join(dir, 'tsconfig.json');
if (!(0, _nodefs.existsSync)(resolvedTsConfigPath)) {
return {};
}
return loadTsConfigFile(resolvedTsConfigPath, new Set());
}
async function transpileConfig({ nextConfigPath, dir }) {
try {
// envs are passed to the workers and preserve the flag
if (process.env.__NEXT_NODE_NATIVE_TS_LOADER_ENABLED === 'true') {
try {
// Node.js v22.10.0+
// Value is 'strip' or 'transform' based on how the feature is enabled.
// https://nodejs.org/api/process.html#processfeaturestypescript
// TODO: Remove `as any` once we bump @types/node to v22.10.0+
if (process.features.typescript) {
// Run import() here to catch errors and fallback to legacy resolution.
return (await import((0, _nodeurl.pathToFileURL)(nextConfigPath).href)).default;
}
if ((0, _utils.getNodeOptionsArgs)().includes('--no-experimental-strip-types') || process.execArgv.includes('--no-experimental-strip-types')) {
(0, _log.warnOnce)(`Skipped resolving "${_nodepath.default.basename(nextConfigPath)}" using Node.js native TypeScript resolution because it was disabled by the "--no-experimental-strip-types" flag.` + ' Falling back to legacy resolution.' + ' Learn more: https://nextjs.org/docs/app/api-reference/config/typescript#using-nodejs-native-typescript-resolver-for-nextconfigts');
}
// Feature is not enabled, fallback to legacy resolution for current session.
process.env.__NEXT_NODE_NATIVE_TS_LOADER_ENABLED = 'false';
} catch (cause) {
(0, _log.warnOnce)(`Failed to import "${_nodepath.default.basename(nextConfigPath)}" using Node.js native TypeScript resolution.` + ' Falling back to legacy resolution.' + ' Learn more: https://nextjs.org/docs/app/api-reference/config/typescript#using-nodejs-native-typescript-resolver-for-nextconfigts', {
cause
});
// Once failed, fallback to legacy resolution for current session.
process.env.__NEXT_NODE_NATIVE_TS_LOADER_ENABLED = 'false';
}
}
const compilerOptions = await loadTsConfig(dir);
return handleCJS({
dir,
nextConfigPath,
compilerOptions
});
} catch (cause) {
throw Object.defineProperty(new Error(`Failed to transpile "${_nodepath.default.basename(nextConfigPath)}".`, {
cause
}), "__NEXT_ERROR_CODE", {
value: "E797",
enumerable: false,
configurable: true
});
}
}
async function handleCJS({ dir, nextConfigPath, compilerOptions }) {
const swcOptions = resolveSWCOptions(dir, compilerOptions);
let hasRequire = false;
try {
var _config_experimental;
const nextConfigString = (0, _nodefs.readFileSync)(nextConfigPath, 'utf8');
// lazy require swc since it loads React before even setting NODE_ENV
// resulting loading Development React on Production
const { loadBindings } = require('../swc');
const bindings = await loadBindings();
const { code } = await bindings.transform(nextConfigString, swcOptions);
// register require hook only if require exists
if (code.includes('require(')) {
(0, _requirehook.registerHook)(swcOptions);
hasRequire = true;
}
// filename & extension don't matter here
const config = (0, _requirehook.requireFromString)(code, _nodepath.default.resolve(dir, 'next.config.compiled.js'));
// At this point we have already loaded the bindings without this configuration setting due to the `transform` call above.
// Possibly we fell back to wasm in which case, it all works out but if not we need to warn
// that the configuration was ignored.
if ((config == null ? void 0 : (_config_experimental = config.experimental) == null ? void 0 : _config_experimental.useWasmBinary) && !bindings.isWasm) {
(0, _log.warn)('Using a next.config.ts file is incompatible with `experimental.useWasmBinary` unless ' + '`--experimental-next-config-strip-types` is also passed.\nSetting `useWasmBinary` to `false');
config.experimental.useWasmBinary = false;
}
return config;
} catch (error) {
throw error;
} finally{
if (hasRequire) {
(0, _requirehook.deregisterHook)();
}
}
}
//# sourceMappingURL=transpile-config.js.map

84
build/node_modules/next/dist/build/output/format.js generated vendored Normal file
View File

@@ -0,0 +1,84 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
formatExpire: null,
formatRevalidate: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
formatExpire: function() {
return formatExpire;
},
formatRevalidate: function() {
return formatRevalidate;
}
});
const timeUnits = [
{
label: 'y',
seconds: 31536000
},
{
label: 'w',
seconds: 604800
},
{
label: 'd',
seconds: 86400
},
{
label: 'h',
seconds: 3600
},
{
label: 'm',
seconds: 60
},
{
label: 's',
seconds: 1
}
];
function humanReadableTimeRounded(seconds) {
// Find the largest fitting unit.
let candidateIndex = timeUnits.length - 1;
for(let i = 0; i < timeUnits.length; i++){
if (seconds >= timeUnits[i].seconds) {
candidateIndex = i;
break;
}
}
const candidate = timeUnits[candidateIndex];
const value = seconds / candidate.seconds;
const isExact = Number.isInteger(value);
// For days and weeks only, check if using the next smaller unit yields an
// exact result.
if (!isExact && (candidate.label === 'd' || candidate.label === 'w')) {
const nextUnit = timeUnits[candidateIndex + 1];
const nextValue = seconds / nextUnit.seconds;
if (Number.isInteger(nextValue)) {
return `${nextValue}${nextUnit.label}`;
}
}
if (isExact) {
return `${value}${candidate.label}`;
}
return `${Math.round(value)}${candidate.label}`;
}
function formatRevalidate(cacheControl) {
const { revalidate } = cacheControl;
return revalidate ? humanReadableTimeRounded(revalidate) : '';
}
function formatExpire(cacheControl) {
const { expire } = cacheControl;
return expire ? humanReadableTimeRounded(expire) : '';
}
//# sourceMappingURL=format.js.map

135
build/node_modules/next/dist/build/output/log.js generated vendored Normal file
View File

@@ -0,0 +1,135 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
bootstrap: null,
error: null,
errorOnce: null,
event: null,
info: null,
prefixes: null,
ready: null,
trace: null,
wait: null,
warn: null,
warnOnce: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
bootstrap: function() {
return bootstrap;
},
error: function() {
return error;
},
errorOnce: function() {
return errorOnce;
},
event: function() {
return event;
},
info: function() {
return info;
},
prefixes: function() {
return prefixes;
},
ready: function() {
return ready;
},
trace: function() {
return trace;
},
wait: function() {
return wait;
},
warn: function() {
return warn;
},
warnOnce: function() {
return warnOnce;
}
});
const _picocolors = require("../../lib/picocolors");
const _lrucache = require("../../server/lib/lru-cache");
const prefixes = {
wait: (0, _picocolors.white)((0, _picocolors.bold)('○')),
error: (0, _picocolors.red)((0, _picocolors.bold)('')),
warn: (0, _picocolors.yellow)((0, _picocolors.bold)('⚠')),
ready: '▲',
info: (0, _picocolors.white)((0, _picocolors.bold)(' ')),
event: (0, _picocolors.green)((0, _picocolors.bold)('✓')),
trace: (0, _picocolors.magenta)((0, _picocolors.bold)('»'))
};
const LOGGING_METHOD = {
log: 'log',
warn: 'warn',
error: 'error'
};
function prefixedLog(prefixType, ...message) {
if ((message[0] === '' || message[0] === undefined) && message.length === 1) {
message.shift();
}
const consoleMethod = prefixType in LOGGING_METHOD ? LOGGING_METHOD[prefixType] : 'log';
const prefix = prefixes[prefixType];
// If there's no message, don't print the prefix but a new line
if (message.length === 0) {
console[consoleMethod]('');
} else {
// Ensure if there's ANSI escape codes it's concatenated into one string.
// Chrome DevTool can only handle color if it's in one string.
if (message.length === 1 && typeof message[0] === 'string') {
console[consoleMethod](prefix + ' ' + message[0]);
} else {
console[consoleMethod](prefix, ...message);
}
}
}
function bootstrap(message) {
console.log(message);
}
function wait(...message) {
prefixedLog('wait', ...message);
}
function error(...message) {
prefixedLog('error', ...message);
}
function warn(...message) {
prefixedLog('warn', ...message);
}
function ready(...message) {
prefixedLog('ready', ...message);
}
function info(...message) {
prefixedLog('info', ...message);
}
function event(...message) {
prefixedLog('event', ...message);
}
function trace(...message) {
prefixedLog('trace', ...message);
}
const warnOnceCache = new _lrucache.LRUCache(10000, (value)=>value.length);
function warnOnce(...message) {
const key = message.join(' ');
if (!warnOnceCache.has(key)) {
warnOnceCache.set(key, key);
warn(...message);
}
}
const errorOnceCache = new _lrucache.LRUCache(10000, (value)=>value.length);
function errorOnce(...message) {
const key = message.join(' ');
if (!errorOnceCache.has(key)) {
errorOnceCache.set(key, key);
error(...message);
}
}
//# sourceMappingURL=log.js.map

View File

@@ -0,0 +1,162 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
AppSegmentConfigSchemaKeys: null,
parseAppSegmentConfig: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
AppSegmentConfigSchemaKeys: function() {
return AppSegmentConfigSchemaKeys;
},
parseAppSegmentConfig: function() {
return parseAppSegmentConfig;
}
});
const _zod = require("next/dist/compiled/zod");
const _zod1 = require("../../../shared/lib/zod");
const CookieSchema = _zod.z.object({
name: _zod.z.string(),
value: _zod.z.string().or(_zod.z.null())
}).strict();
const RuntimeSampleSchema = _zod.z.object({
cookies: _zod.z.array(CookieSchema).optional(),
headers: _zod.z.array(_zod.z.tuple([
_zod.z.string(),
_zod.z.string().or(_zod.z.null())
])).optional(),
params: _zod.z.record(_zod.z.union([
_zod.z.string(),
_zod.z.array(_zod.z.string())
])).optional(),
searchParams: _zod.z.record(_zod.z.union([
_zod.z.string(),
_zod.z.array(_zod.z.string()),
_zod.z.null()
])).optional()
}).strict();
const InstantConfigStaticSchema = _zod.z.object({
prefetch: _zod.z.literal('static'),
samples: _zod.z.array(RuntimeSampleSchema).min(1).optional(),
from: _zod.z.array(_zod.z.string()).optional(),
unstable_disableValidation: _zod.z.literal(true).optional(),
unstable_disableDevValidation: _zod.z.literal(true).optional(),
unstable_disableBuildValidation: _zod.z.literal(true).optional()
}).strict();
const InstantConfigRuntimeSchema = _zod.z.object({
prefetch: _zod.z.literal('runtime'),
samples: _zod.z.array(RuntimeSampleSchema).min(1),
from: _zod.z.array(_zod.z.string()).optional(),
unstable_disableValidation: _zod.z.literal(true).optional(),
unstable_disableDevValidation: _zod.z.literal(true).optional(),
unstable_disableBuildValidation: _zod.z.literal(true).optional()
}).strict();
const InstantConfigSchema = _zod.z.union([
_zod.z.discriminatedUnion('prefetch', [
InstantConfigStaticSchema,
InstantConfigRuntimeSchema
]),
_zod.z.literal(false)
]);
/**
* The schema for configuration for a page.
*/ const AppSegmentConfigSchema = _zod.z.object({
/**
* The number of seconds to revalidate the page or false to disable revalidation.
*/ revalidate: _zod.z.union([
_zod.z.number().int().nonnegative(),
_zod.z.literal(false)
]).optional(),
/**
* Whether the page supports dynamic parameters.
*/ dynamicParams: _zod.z.boolean().optional(),
/**
* The dynamic behavior of the page.
*/ dynamic: _zod.z.enum([
'auto',
'error',
'force-static',
'force-dynamic'
]).optional(),
/**
* The caching behavior of the page.
*/ fetchCache: _zod.z.enum([
'auto',
'default-cache',
'only-cache',
'force-cache',
'force-no-store',
'default-no-store',
'only-no-store'
]).optional(),
/**
* How this segment should be prefetched.
*/ unstable_instant: InstantConfigSchema.optional(),
/**
* The stale time for dynamic responses in seconds.
* Controls how long the client-side router cache retains dynamic page data.
* Pages only — not allowed in layouts.
*/ unstable_dynamicStaleTime: _zod.z.number().int().nonnegative().optional(),
/**
* The preferred region for the page.
*/ preferredRegion: _zod.z.union([
_zod.z.string(),
_zod.z.array(_zod.z.string())
]).optional(),
/**
* The runtime to use for the page.
*/ runtime: _zod.z.enum([
'edge',
'nodejs'
]).optional(),
/**
* The maximum duration for the page in seconds.
*/ maxDuration: _zod.z.number().int().nonnegative().optional()
});
function parseAppSegmentConfig(data, route) {
const parsed = AppSegmentConfigSchema.safeParse(data, {
errorMap: (issue, ctx)=>{
if (issue.path.length === 1) {
switch(issue.path[0]){
case 'revalidate':
{
return {
message: `Invalid revalidate value ${JSON.stringify(ctx.data)} on "${route}", must be a non-negative number or false`
};
}
case 'unstable_instant':
{
return {
// @TODO replace this link with a link to the docs when they are written
message: `Invalid unstable_instant value ${JSON.stringify(ctx.data)} on "${route}", must be an object with \`prefetch: "static"\` or \`prefetch: "runtime"\`, or \`false\`. Read more at https://nextjs.org/docs/messages/invalid-instant-configuration`
};
}
case 'unstable_dynamicStaleTime':
{
return {
message: `Invalid unstable_dynamicStaleTime value ${JSON.stringify(ctx.data)} on "${route}", must be a non-negative number`
};
}
default:
}
}
return {
message: ctx.defaultError
};
}
});
if (!parsed.success) {
throw (0, _zod1.formatZodError)(`Invalid segment configuration options detected for "${route}". Read more at https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config`, parsed.error);
}
return parsed.data;
}
const AppSegmentConfigSchemaKeys = AppSegmentConfigSchema.keyof().options;
//# sourceMappingURL=app-segment-config.js.map

View File

@@ -0,0 +1,137 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "collectSegments", {
enumerable: true,
get: function() {
return collectSegments;
}
});
const _appsegmentconfig = require("./app-segment-config");
const _invarianterror = require("../../../shared/lib/invariant-error");
const _checks = require("../../../server/route-modules/checks");
const _clientandserverreferences = require("../../../lib/client-and-server-references");
const _getsegmentparam = require("../../../shared/lib/router/utils/get-segment-param");
const _appdirmodule = require("../../../server/lib/app-dir-module");
/**
* Parses the app config and attaches it to the segment.
*/ function attach(segment, userland, route) {
// If the userland is not an object, then we can't do anything with it.
if (typeof userland !== 'object' || userland === null) {
return;
}
// Try to parse the application configuration.
const config = (0, _appsegmentconfig.parseAppSegmentConfig)(userland, route);
// If there was any keys on the config, then attach it to the segment.
if (Object.keys(config).length > 0) {
segment.config = config;
}
if ('generateStaticParams' in userland && typeof userland.generateStaticParams === 'function') {
var _segment_config;
segment.generateStaticParams = userland.generateStaticParams;
// Validate that `generateStaticParams` makes sense in this context.
if (((_segment_config = segment.config) == null ? void 0 : _segment_config.runtime) === 'edge') {
throw Object.defineProperty(new Error('Edge runtime is not supported with `generateStaticParams`.'), "__NEXT_ERROR_CODE", {
value: "E502",
enumerable: false,
configurable: true
});
}
}
}
/**
* Walks the loader tree and collects the generate parameters for each segment.
*
* @param routeModule the app page route module
* @returns the segments for the app page route module
*/ async function collectAppPageSegments(routeModule) {
// We keep track of unique segments, since with parallel routes, it's possible
// to see the same segment multiple times.
const segments = [];
// Queue will store loader trees.
const queue = [
routeModule.userland.loaderTree
];
while(queue.length > 0){
const loaderTree = queue.shift();
const [name, parallelRoutes] = loaderTree;
// Process current node
const { mod: userland, filePath } = await (0, _appdirmodule.getLayoutOrPageModule)(loaderTree);
const isClientComponent = userland && (0, _clientandserverreferences.isClientReference)(userland);
const param = (0, _getsegmentparam.getSegmentParam)(name);
const segment = {
name,
paramName: param == null ? void 0 : param.paramName,
paramType: param == null ? void 0 : param.paramType,
filePath,
config: undefined,
generateStaticParams: undefined
};
// Only server components can have app segment configurations
if (!isClientComponent) {
attach(segment, userland, routeModule.definition.pathname);
}
// If this segment doesn't already exist, then add it to the segments array.
// The list of segments is short so we just use a list traversal to check
// for duplicates and spare us needing to maintain the string key.
if (segments.every((s)=>s.name !== segment.name || s.paramName !== segment.paramName || s.paramType !== segment.paramType || s.filePath !== segment.filePath)) {
segments.push(segment);
}
// Add all parallel routes to the queue
for (const parallelRoute of Object.values(parallelRoutes)){
queue.push(parallelRoute);
}
}
return segments;
}
/**
* Collects the segments for a given app route module.
*
* @param routeModule the app route module
* @returns the segments for the app route module
*/ function collectAppRouteSegments(routeModule) {
// Get the pathname parts, slice off the first element (which is empty).
const parts = routeModule.definition.pathname.split('/').slice(1);
if (parts.length === 0) {
throw Object.defineProperty(new _invarianterror.InvariantError('Expected at least one segment'), "__NEXT_ERROR_CODE", {
value: "E580",
enumerable: false,
configurable: true
});
}
// Generate all the segments.
const segments = parts.map((name)=>{
const param = (0, _getsegmentparam.getSegmentParam)(name);
return {
name,
paramName: param == null ? void 0 : param.paramName,
paramType: param == null ? void 0 : param.paramType,
filePath: undefined,
config: undefined,
generateStaticParams: undefined
};
});
// We know we have at least one, we verified this above. We should get the
// last segment which represents the root route module.
const segment = segments[segments.length - 1];
segment.filePath = routeModule.definition.filename;
// Extract the segment config from the userland module.
attach(segment, routeModule.userland, routeModule.definition.pathname);
return segments;
}
function collectSegments(routeModule) {
if ((0, _checks.isAppRouteRouteModule)(routeModule)) {
return collectAppRouteSegments(routeModule);
}
if ((0, _checks.isAppPageRouteModule)(routeModule)) {
return collectAppPageSegments(routeModule);
}
throw Object.defineProperty(new _invarianterror.InvariantError('Expected a route module to be one of app route or page'), "__NEXT_ERROR_CODE", {
value: "E568",
enumerable: false,
configurable: true
});
}
//# sourceMappingURL=app-segments.js.map

View File

@@ -0,0 +1,52 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "collectRootParamKeys", {
enumerable: true,
get: function() {
return collectRootParamKeys;
}
});
const _getsegmentparam = require("../../../shared/lib/router/utils/get-segment-param");
const _checks = require("../../../server/route-modules/checks");
const _invarianterror = require("../../../shared/lib/invariant-error");
function collectAppPageRootParamKeys(routeModule) {
let rootParams = [];
let current = routeModule.userland.loaderTree;
while(current){
var _getSegmentParam;
const [name, parallelRoutes, modules] = current;
// If this is a dynamic segment, then we collect the param.
const paramName = (_getSegmentParam = (0, _getsegmentparam.getSegmentParam)(name)) == null ? void 0 : _getSegmentParam.paramName;
if (paramName) {
rootParams.push(paramName);
}
// If this has a layout module, then we've found the root layout because
// we return once we found the first layout.
if (typeof modules.layout !== 'undefined') {
return rootParams;
}
// This didn't include a root layout, so we need to continue. We don't need
// to collect from other parallel routes because we can't have a parallel
// route above a root layout.
current = parallelRoutes.children;
}
// If we didn't find a root layout, then we don't have any params.
return [];
}
function collectRootParamKeys(routeModule) {
if ((0, _checks.isAppRouteRouteModule)(routeModule)) {
return [];
}
if ((0, _checks.isAppPageRouteModule)(routeModule)) {
return collectAppPageRootParamKeys(routeModule);
}
throw Object.defineProperty(new _invarianterror.InvariantError('Expected a route module to be one of app route or page'), "__NEXT_ERROR_CODE", {
value: "E568",
enumerable: false,
configurable: true
});
}
//# sourceMappingURL=collect-root-param-keys.js.map

736
build/node_modules/next/dist/build/static-paths/app.js generated vendored Normal file
View File

@@ -0,0 +1,736 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
assignStaticShellMetadata: null,
buildAppStaticPaths: null,
calculateFallbackMode: null,
filterUniqueParams: null,
generateAllParamCombinations: null,
generateRouteStaticParams: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
assignStaticShellMetadata: function() {
return assignStaticShellMetadata;
},
buildAppStaticPaths: function() {
return buildAppStaticPaths;
},
calculateFallbackMode: function() {
return calculateFallbackMode;
},
filterUniqueParams: function() {
return filterUniqueParams;
},
generateAllParamCombinations: function() {
return generateAllParamCombinations;
},
generateRouteStaticParams: function() {
return generateRouteStaticParams;
}
});
const _nodepath = /*#__PURE__*/ _interop_require_default(require("node:path"));
const _runwithafter = require("../../server/after/run-with-after");
const _workstore = require("../../server/async-storage/work-store");
const _fallback = require("../../lib/fallback");
const _utils = require("./utils");
const _escapepathdelimiters = /*#__PURE__*/ _interop_require_default(require("../../shared/lib/router/utils/escape-path-delimiters"));
const _createincrementalcache = require("../../export/helpers/create-incremental-cache");
const _getsegmentparam = require("../../shared/lib/router/utils/get-segment-param");
const _emptygeneratestaticparamserror = require("../../shared/lib/errors/empty-generate-static-params-error");
const _interceptionprefixfromparamtype = require("../../shared/lib/router/utils/interception-prefix-from-param-type");
const _implicittags = require("../../server/lib/implicit-tags");
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
function filterUniqueParams(childrenRouteParams, routeParams) {
// A Map is used to store unique parameter combinations. The key of the Map
// is a string representation of the parameter combination, and the value
// is the actual `Params` object.
const unique = new Map();
// Iterate over each parameter object in the input array.
for (const params of routeParams){
let key = '' // Initialize an empty string to build the unique key for the current `params` object.
;
// Iterate through the `routeParamKeys` (which are assumed to be sorted).
// This consistent order is crucial for generating a stable and unique key
// for each parameter combination.
for (const { paramName: paramKey } of childrenRouteParams){
const value = params[paramKey];
// Construct a part of the key using the parameter key and its value.
// A type prefix (`A:` for Array, `S:` for String, `U:` for undefined) is added to the value
// to prevent collisions. For example, `['a', 'b']` and `'a,b'` would
// otherwise generate the same string representation, leading to incorrect
// deduplication. This ensures that different types with the same string
// representation are treated as distinct.
let valuePart;
if (Array.isArray(value)) {
valuePart = `A:${value.join(',')}`;
} else if (value === undefined) {
valuePart = `U:undefined`;
} else {
valuePart = `S:${value}`;
}
key += `${paramKey}:${valuePart}|`;
}
// If the generated key is not already in the `unique` Map, it means this
// parameter combination is unique so far. Add it to the Map.
if (!unique.has(key)) {
unique.set(key, params);
}
}
// Convert the Map's values (the unique `Params` objects) back into an array
// and return it.
return Array.from(unique.values());
}
function generateAllParamCombinations(childrenRouteParams, routeParams, rootParamKeys) {
// A Map is used to store unique combinations of Route Parameters.
// The key of the Map is a string representation of the Route Parameter
// combination, and the value is the `Params` object containing only
// the Route Parameters.
const combinations = new Map();
// Determine the minimum index where all Root Parameters are included.
// This optimization ensures we only generate combinations that include
// a complete set of Root Parameters, preventing invalid Static Shells.
//
// For example, if rootParamKeys = ['lang', 'region'] and routeParamKeys = ['lang', 'region', 'slug']:
// - 'lang' is at index 0, 'region' is at index 1
// - minIndexForCompleteRootParams = max(0, 1) = 1
// - We'll only generate combinations starting from index 1 (which includes both lang and region)
let minIndexForCompleteRootParams = -1;
if (rootParamKeys.length > 0) {
// Find the index of the last Root Parameter in routeParamKeys.
// This tells us the minimum combination length needed to include all Root Parameters.
for (const rootParamKey of rootParamKeys){
const index = childrenRouteParams.findIndex((param)=>param.paramName === rootParamKey);
if (index === -1) {
// Root Parameter not found in Route Parameters - this shouldn't happen in normal cases
// but we handle it gracefully by treating it as if there are no Root Parameters.
// This allows the function to fall back to generating all sub-combinations.
minIndexForCompleteRootParams = -1;
break;
}
// Track the highest index among all Root Parameters.
// This ensures all Root Parameters are included in any generated combination.
minIndexForCompleteRootParams = Math.max(minIndexForCompleteRootParams, index);
}
}
// Iterate over each Static Parameter object in the input array.
// Each params object represents one potential route combination (e.g., { lang: 'en', region: 'US', slug: 'home' })
for (const params of routeParams){
// Generate all possible prefix combinations for this Static Parameter set.
// For routeParamKeys = ['lang', 'region', 'slug'], we'll generate combinations at:
// - i=0: { lang: 'en' }
// - i=1: { lang: 'en', region: 'US' }
// - i=2: { lang: 'en', region: 'US', slug: 'home' }
//
// The iteration order is crucial for generating stable and unique keys
// for each Route Parameter combination.
for(let i = 0; i < childrenRouteParams.length; i++){
// Skip generating combinations that don't include all Root Parameters.
// This prevents creating invalid Static Shells that are missing required Root Parameters.
//
// For example, if Root Parameters are ['lang', 'region'] and minIndexForCompleteRootParams = 1:
// - Skip i=0 (would only include 'lang', missing 'region')
// - Process i=1 and higher (includes both 'lang' and 'region')
if (minIndexForCompleteRootParams >= 0 && i < minIndexForCompleteRootParams) {
continue;
}
// Initialize data structures for building this specific combination
const combination = {};
const keyParts = [];
let hasAllRootParams = true;
// Build the sub-combination with parameters from index 0 to i (inclusive).
// This creates a prefix of the full parameter set, building up combinations incrementally.
//
// For example, if routeParamKeys = ['lang', 'region', 'slug'] and i = 1:
// - j=0: Add 'lang' parameter
// - j=1: Add 'region' parameter
// Result: { lang: 'en', region: 'US' }
for(let j = 0; j <= i; j++){
const { paramName: routeKey } = childrenRouteParams[j];
// Check if the parameter exists in the original params object and has a defined value.
// This handles cases where generateStaticParams doesn't provide all possible parameters,
// or where some parameters are optional/undefined.
if (!params.hasOwnProperty(routeKey) || params[routeKey] === undefined) {
// If this missing parameter is a Root Parameter, mark the combination as invalid.
// Root Parameters are required for Static Shells, so we can't generate partial combinations without them.
if (rootParamKeys.includes(routeKey)) {
hasAllRootParams = false;
}
break;
}
const value = params[routeKey];
combination[routeKey] = value;
// Construct a unique key part for this parameter to enable deduplication.
// We use type prefixes to prevent collisions between different value types
// that might have the same string representation.
//
// Examples:
// - Array ['foo', 'bar'] becomes "A:foo,bar"
// - String "foo,bar" becomes "S:foo,bar"
// - This prevents collisions between ['foo', 'bar'] and "foo,bar"
let valuePart;
if (Array.isArray(value)) {
valuePart = `A:${value.join(',')}`;
} else {
valuePart = `S:${value}`;
}
keyParts.push(`${routeKey}:${valuePart}`);
}
// Build the final unique key by joining all parameter parts.
// This key is used for deduplication in the combinations Map.
// Format: "lang:S:en|region:S:US|slug:A:home,about"
const currentKey = keyParts.join('|');
// Only add the combination if it meets our criteria:
// 1. hasAllRootParams: Contains all required Root Parameters
// 2. !combinations.has(currentKey): Is not a duplicate of an existing combination
//
// This ensures we only generate valid, unique parameter combinations for Static Shells.
if (hasAllRootParams && !combinations.has(currentKey)) {
combinations.set(currentKey, combination);
}
}
}
// Convert the Map's values back into an array and return the final result.
// The Map ensures all combinations are unique, and we return only the
// parameter objects themselves, discarding the internal deduplication keys.
return Array.from(combinations.values());
}
function calculateFallbackMode(dynamicParams, fallbackRootParams, baseFallbackMode) {
return dynamicParams ? // perform a blocking static render.
fallbackRootParams.length > 0 ? _fallback.FallbackMode.BLOCKING_STATIC_RENDER : baseFallbackMode ?? _fallback.FallbackMode.NOT_FOUND : _fallback.FallbackMode.NOT_FOUND;
}
/**
* Validates the parameters to ensure they're accessible and have the correct
* types.
*
* @param page - The page to validate.
* @param regex - The route regex.
* @param isRoutePPREnabled - Whether the route has partial prerendering enabled.
* @param pathnameSegments - The keys of the parameters.
* @param rootParamKeys - The keys of the root params.
* @param routeParams - The list of parameters to validate.
* @returns The list of validated parameters.
*/ function validateParams(page, isRoutePPREnabled, pathnameSegments, rootParamKeys, routeParams) {
const valid = [];
// Validate that if there are any root params, that the user has provided at
// least one value for them only if we're using partial prerendering.
if (isRoutePPREnabled && rootParamKeys.length > 0) {
if (routeParams.length === 0 || rootParamKeys.some((key)=>routeParams.some((params)=>!(key in params)))) {
if (rootParamKeys.length === 1) {
throw Object.defineProperty(new Error(`A required root parameter (${rootParamKeys[0]}) was not provided in generateStaticParams for ${page}, please provide at least one value.`), "__NEXT_ERROR_CODE", {
value: "E622",
enumerable: false,
configurable: true
});
}
throw Object.defineProperty(new Error(`Required root params (${rootParamKeys.join(', ')}) were not provided in generateStaticParams for ${page}, please provide at least one value for each.`), "__NEXT_ERROR_CODE", {
value: "E621",
enumerable: false,
configurable: true
});
}
}
for (const params of routeParams){
const item = {};
for (const { paramName: key, paramType } of pathnameSegments){
const { repeat, optional } = (0, _getsegmentparam.getParamProperties)(paramType);
let paramValue = params[key];
if (optional && params.hasOwnProperty(key) && (paramValue === null || paramValue === undefined || paramValue === false)) {
paramValue = [];
}
// A parameter is missing, so the rest of the params are not accessible.
// We only support this when the route has partial prerendering enabled.
// This will make it so that the remaining params are marked as missing so
// we can generate a fallback route for them.
if (!paramValue && isRoutePPREnabled) {
break;
}
// Perform validation for the parameter based on whether it's a repeat
// parameter or not.
if (repeat) {
if (!Array.isArray(paramValue)) {
throw Object.defineProperty(new Error(`A required parameter (${key}) was not provided as an array received ${typeof paramValue} in generateStaticParams for ${page}`), "__NEXT_ERROR_CODE", {
value: "E618",
enumerable: false,
configurable: true
});
}
} else {
if (typeof paramValue !== 'string') {
throw Object.defineProperty(new Error(`A required parameter (${key}) was not provided as a string received ${typeof paramValue} in generateStaticParams for ${page}`), "__NEXT_ERROR_CODE", {
value: "E617",
enumerable: false,
configurable: true
});
}
}
item[key] = paramValue;
}
valid.push(item);
}
return valid;
}
function assignStaticShellMetadata(prerenderedRoutes, pathnameSegments, computeRemainingPrerenderableParams) {
// If there are no routes to process, exit early.
if (prerenderedRoutes.length === 0) {
return;
}
// Initialize the root of the Trie. This node represents the starting point
// before any parameters have been considered.
const root = {
children: new Map(),
routes: []
};
// Phase 1: Build the Trie.
// Iterate over each prerendered route and insert it into the Trie.
// Each route's concrete parameter values form a path in the Trie.
for (const route of prerenderedRoutes){
let currentNode = root // Start building the path from the root for each route.
;
// Iterate through the sorted parameter keys. The order of keys is crucial
// for ensuring that routes with the same concrete parameters follow the
// same path in the Trie, regardless of the original order of properties
// in the `params` object.
for (const { paramName: key } of pathnameSegments){
// Check if the current route actually has a concrete value for this parameter.
// If a dynamic segment is not filled (i.e., it's a fallback), it won't have
// this property, and we stop building the path for this route at this point.
if (route.params.hasOwnProperty(key)) {
const value = route.params[key];
// Generate a unique key for the parameter's value. This is critical
// to prevent collisions between different data types that might have
// the same string representation (e.g., `['a', 'b']` vs `'a,b'`).
// A type prefix (`A:` for Array, `S:` for String, `U:` for undefined)
// is added to the value to prevent collisions. This ensures that
// different types with the same string representation are treated as
// distinct.
let valueKey;
if (Array.isArray(value)) {
valueKey = `A:${value.join(',')}`;
} else if (value === undefined) {
valueKey = `U:undefined`;
} else {
valueKey = `S:${value}`;
}
// Look for a child node corresponding to this `valueKey` from the `currentNode`.
let childNode = currentNode.children.get(valueKey);
if (!childNode) {
// If the child node doesn't exist, create a new one and add it to
// the current node's children.
childNode = {
children: new Map(),
routes: []
};
currentNode.children.set(valueKey, childNode);
}
// Move deeper into the Trie to the `childNode` for the next parameter.
currentNode = childNode;
}
}
// After processing all concrete parameters for the route, add the full
// `PrerenderedRoute` object to the `routes` array of the `currentNode`.
// This node represents the unique concrete parameter combination for this route.
currentNode.routes.push(route);
}
// Phase 2: Traverse the Trie to assign the `throwOnEmptyStaticShell` property.
// This is done using an iterative Depth-First Search (DFS) approach with an
// explicit stack to avoid JavaScript's recursion depth limits (stack overflow)
// for very deep routing structures.
const stack = [
root
] // Initialize the stack with the root node.
;
while(stack.length > 0){
const node = stack.pop()// Pop the next node to process from the stack.
;
// `hasChildren` indicates if this node has any more specific concrete
// parameter combinations branching off from it. If true, it means this
// node represents a prefix for other, more specific routes.
const hasChildren = node.children.size > 0;
// If the current node has routes associated with it (meaning, routes whose
// concrete parameters lead to this node's path in the Trie).
if (node.routes.length > 0) {
// Determine the minimum number of fallback parameters among all routes
// that are associated with this current Trie node. This is used to
// identify if a route should not throw on empty static shell relative to another route *at the same level*
// of concrete parameters, but with fewer fallback parameters.
let minFallbacks = Infinity;
for (const r of node.routes){
// `fallbackRouteParams?.length ?? 0` handles cases where `fallbackRouteParams`
// might be `undefined` or `null`, treating them as 0 length.
minFallbacks = Math.min(minFallbacks, r.fallbackRouteParams ? r.fallbackRouteParams.length : 0);
}
// Now, for each `PrerenderedRoute` associated with this node:
for (const route of node.routes){
// A route is ok not to throw on an empty static shell (and thus
// `throwOnEmptyStaticShell` should be `false`) if either of the
// following conditions is met:
// 1. `hasChildren` is true: This node has further concrete parameter children.
// This means the current route is a parent to more specific routes (e.g.,
// `/blog/[slug]` should not throw when concrete routes like `/blog/first-post` exist).
// OR
// 2. `route.fallbackRouteParams.length > minFallbacks`: This route has
// more fallback parameters than another route at the same Trie node.
// This implies the current route is a more general version that should not throw
// compared to a more specific route that has fewer fallback parameters
// (e.g., `/1234/[...slug]` should not throw relative to `/[id]/[...slug]`).
if (hasChildren || route.fallbackRouteParams && route.fallbackRouteParams.length > minFallbacks) {
route.throwOnEmptyStaticShell = false // Should not throw on empty static shell.
;
} else {
route.throwOnEmptyStaticShell = true // Should throw on empty static shell.
;
}
if (computeRemainingPrerenderableParams && route.fallbackRouteParams && route.fallbackRouteParams.length > 0) {
const fallbackRouteParamsByName = new Map(route.fallbackRouteParams.map((param)=>[
param.paramName,
param
]));
const remainingPrerenderableParams = [];
// Only unresolved pathname params that can still be filled by
// generateStaticParams belong here. Once we hit an unresolved param
// that is purely dynamic, the rest of the shell also stays dynamic
// and cannot be completed into a more specific prerendered shell.
for (const segment of pathnameSegments){
if (route.params.hasOwnProperty(segment.paramName)) {
continue;
}
if (!segment.hasGenerateStaticParams) {
break;
}
const fallbackRouteParam = fallbackRouteParamsByName.get(segment.paramName);
if (!fallbackRouteParam) {
break;
}
remainingPrerenderableParams.push(fallbackRouteParam);
}
route.remainingPrerenderableParams = remainingPrerenderableParams.length > 0 ? remainingPrerenderableParams : undefined;
}
}
}
// Add all children of the current node to the stack. This ensures that
// the traversal continues to explore deeper paths in the Trie.
for (const child of node.children.values()){
stack.push(child);
}
}
}
/**
* Calls a single generateStaticParams function within a WorkUnitStore context,
* making root param getters available during static param generation.
*/ async function callGenerateStaticParams(generateStaticParams, workUnitAsyncStorage, parentParams, rootParamKeys, implicitTags) {
const rootParams = {};
for (const key of rootParamKeys){
if (key in parentParams) {
rootParams[key] = parentParams[key];
}
}
const workUnitStore = {
type: 'generate-static-params',
phase: 'render',
implicitTags,
rootParams
};
return workUnitAsyncStorage.run(workUnitStore, generateStaticParams, {
params: parentParams
});
}
async function generateRouteStaticParams(segments, store, workUnitAsyncStorage, isRoutePPREnabled, rootParamKeys) {
// Early return if no segments to process
if (segments.length === 0) return [];
const implicitTags = await (0, _implicittags.getImplicitTags)(store.page, store.page, null);
const queue = [
{
segmentIndex: 0,
params: []
}
];
let currentParams = [];
while(queue.length > 0){
var _current_config;
const { segmentIndex, params } = queue.shift();
// If we've processed all segments, this is our final result
if (segmentIndex >= segments.length) {
currentParams = params;
break;
}
const current = segments[segmentIndex];
// Skip segments without generateStaticParams and continue to next
if (typeof current.generateStaticParams !== 'function') {
queue.push({
segmentIndex: segmentIndex + 1,
params
});
continue;
}
// Configure fetchCache if specified
if (((_current_config = current.config) == null ? void 0 : _current_config.fetchCache) !== undefined) {
store.fetchCache = current.config.fetchCache;
}
const nextParams = [];
// If there are parent params, we need to process them.
if (params.length > 0) {
// Process each parent parameter combination
for (const parentParams of params){
const result = await callGenerateStaticParams(current.generateStaticParams, workUnitAsyncStorage, parentParams, rootParamKeys, implicitTags);
if (result.length > 0) {
// Merge parent params with each result item
for (const item of result){
nextParams.push({
...parentParams,
...item
});
}
} else if (isRoutePPREnabled) {
(0, _emptygeneratestaticparamserror.throwEmptyGenerateStaticParamsError)();
} else {
// No results, just pass through parent params
nextParams.push(parentParams);
}
}
} else {
// No parent params, call generateStaticParams with empty object
const result = await callGenerateStaticParams(current.generateStaticParams, workUnitAsyncStorage, {}, rootParamKeys, implicitTags);
if (result.length === 0 && isRoutePPREnabled) {
(0, _emptygeneratestaticparamserror.throwEmptyGenerateStaticParamsError)();
}
nextParams.push(...result);
}
// Add next segment to work queue
queue.push({
segmentIndex: segmentIndex + 1,
params: nextParams
});
}
return currentParams;
}
function createReplacements(segment, paramValue) {
// Determine the prefix to use for the interception marker.
let prefix;
if (segment.paramType) {
prefix = (0, _interceptionprefixfromparamtype.interceptionPrefixFromParamType)(segment.paramType) ?? '';
} else {
prefix = '';
}
return {
pathname: prefix + (0, _utils.encodeParam)(paramValue, (value)=>// Only escape path delimiters if the value is a string, the following
// version will URL encode the value.
(0, _escapepathdelimiters.default)(value, true)),
encodedPathname: prefix + (0, _utils.encodeParam)(paramValue, // URL encode the value.
encodeURIComponent)
};
}
async function buildAppStaticPaths({ dir, page, route, distDir, cacheComponents, authInterrupts, segments, isrFlushToDisk, cacheHandler, cacheLifeProfiles, requestHeaders, cacheHandlers, cacheMaxMemorySize, fetchCacheKeyPrefix, nextConfigOutput, ComponentMod, isRoutePPREnabled = false, partialFallbacksEnabled = false, buildId, deploymentId, rootParamKeys }) {
if (segments.some((generate)=>{
var _generate_config;
return ((_generate_config = generate.config) == null ? void 0 : _generate_config.dynamicParams) === true;
}) && nextConfigOutput === 'export') {
throw Object.defineProperty(new Error('"dynamicParams: true" cannot be used with "output: export". See more info here: https://nextjs.org/docs/app/building-your-application/deploying/static-exports'), "__NEXT_ERROR_CODE", {
value: "E393",
enumerable: false,
configurable: true
});
}
ComponentMod.patchFetch();
const incrementalCache = await (0, _createincrementalcache.createIncrementalCache)({
dir,
distDir,
cacheHandler,
cacheHandlers,
requestHeaders,
fetchCacheKeyPrefix,
flushToDisk: isrFlushToDisk,
cacheMaxMemorySize
});
// Extract segments that contribute to the pathname.
// For AppPageRouteModule: Traverses the loader tree to find all segments (including
// interception routes in parallel slots) that match the pathname
// For AppRouteRouteModule: Filters the segments array to get non-parallel route params
const pathnameRouteParamSegments = (0, _utils.extractPathnameRouteParamSegments)(ComponentMod.routeModule, segments, route);
const afterRunner = new _runwithafter.AfterRunner();
const store = (0, _workstore.createWorkStore)({
page,
renderOpts: {
incrementalCache,
cacheLifeProfiles,
supportsDynamicResponse: true,
cacheComponents,
experimental: {
authInterrupts
},
waitUntil: afterRunner.context.waitUntil,
onClose: afterRunner.context.onClose,
onAfterTaskError: afterRunner.context.onTaskError
},
buildId,
deploymentId,
previouslyRevalidatedTags: []
});
const routeParams = await ComponentMod.workAsyncStorage.run(store, generateRouteStaticParams, segments, store, ComponentMod.workUnitAsyncStorage, isRoutePPREnabled, rootParamKeys);
const generatedParamNames = new Set();
for (const params of routeParams){
for (const paramName of Object.keys(params)){
generatedParamNames.add(paramName);
}
}
const prerenderablePathSegments = pathnameRouteParamSegments.map((segment)=>({
paramName: segment.paramName,
hasGenerateStaticParams: generatedParamNames.has(segment.paramName)
}));
await afterRunner.executeAfter();
let lastDynamicSegmentHadGenerateStaticParams = false;
for (const segment of segments){
var _segment_config;
// Check to see if there are any missing params for segments that have
// dynamicParams set to false.
if (segment.paramName && segment.paramType && ((_segment_config = segment.config) == null ? void 0 : _segment_config.dynamicParams) === false) {
for (const params of routeParams){
if (segment.paramName in params) continue;
const relative = segment.filePath ? _nodepath.default.relative(dir, segment.filePath) : undefined;
throw Object.defineProperty(new Error(`Segment "${relative}" exports "dynamicParams: false" but the param "${segment.paramName}" is missing from the generated route params.`), "__NEXT_ERROR_CODE", {
value: "E280",
enumerable: false,
configurable: true
});
}
}
if (segment.paramName && segment.paramType && typeof segment.generateStaticParams !== 'function') {
lastDynamicSegmentHadGenerateStaticParams = false;
} else if (typeof segment.generateStaticParams === 'function') {
lastDynamicSegmentHadGenerateStaticParams = true;
}
}
// Determine if all the segments have had their parameters provided.
const hadAllParamsGenerated = pathnameRouteParamSegments.length === 0 || routeParams.length > 0 && routeParams.every((params)=>{
for (const { paramName } of pathnameRouteParamSegments){
if (paramName in params) continue;
return false;
}
return true;
});
// TODO: dynamic params should be allowed to be granular per segment but
// we need additional information stored/leveraged in the prerender
// manifest to allow this behavior.
const dynamicParams = segments.every((segment)=>{
var _segment_config;
return ((_segment_config = segment.config) == null ? void 0 : _segment_config.dynamicParams) !== false;
});
const supportsRoutePreGeneration = hadAllParamsGenerated || !process.env.__NEXT_DEV_SERVER;
const fallbackMode = dynamicParams ? supportsRoutePreGeneration ? isRoutePPREnabled ? _fallback.FallbackMode.PRERENDER : _fallback.FallbackMode.BLOCKING_STATIC_RENDER : undefined : _fallback.FallbackMode.NOT_FOUND;
const prerenderedRoutesByPathname = new Map();
// Convert rootParamKeys to Set for O(1) lookup.
const rootParamSet = new Set(rootParamKeys);
if (hadAllParamsGenerated || isRoutePPREnabled) {
let paramsToProcess = routeParams;
if (isRoutePPREnabled) {
// Discover all unique combinations of the routeParams so we can generate
// routes that won't throw on empty static shell for each of them if
// they're available.
paramsToProcess = generateAllParamCombinations(pathnameRouteParamSegments, routeParams, rootParamKeys);
// Collect all the fallback route params for the segments.
const fallbackRouteParams = [];
for (const segment of segments){
if (!segment.paramName || !segment.paramType) continue;
fallbackRouteParams.push({
paramName: segment.paramName,
paramType: segment.paramType
});
}
// Add the base route, this is the route with all the placeholders as it's
// derived from the `page` string.
prerenderedRoutesByPathname.set(page, {
params: {},
pathname: page,
encodedPathname: page,
fallbackRouteParams,
fallbackMode: calculateFallbackMode(dynamicParams, rootParamKeys, fallbackMode),
fallbackRootParams: rootParamKeys,
throwOnEmptyStaticShell: true
});
}
filterUniqueParams(pathnameRouteParamSegments, validateParams(page, isRoutePPREnabled, pathnameRouteParamSegments, rootParamKeys, paramsToProcess)).forEach((params)=>{
let pathname = page;
let encodedPathname = page;
const fallbackRouteParams = [];
for (const { name, paramName, paramType } of pathnameRouteParamSegments){
const paramValue = params[paramName];
if (!paramValue) {
if (isRoutePPREnabled) {
// Mark remaining params as fallback params.
fallbackRouteParams.push({
paramName,
paramType
});
for(let i = pathnameRouteParamSegments.findIndex((param)=>param.paramName === paramName) + 1; i < pathnameRouteParamSegments.length; i++){
fallbackRouteParams.push({
paramName: pathnameRouteParamSegments[i].paramName,
paramType: pathnameRouteParamSegments[i].paramType
});
}
break;
} else {
// This route is not complete, and we aren't performing a partial
// prerender, so we should return, skipping this route.
return;
}
}
const replacements = createReplacements({
paramType
}, paramValue);
pathname = pathname.replace(name, // We're replacing the segment name with the replacement pathname
// which will include the interception marker prefix if it exists.
replacements.pathname);
encodedPathname = encodedPathname.replace(name, // We're replacing the segment name with the replacement encoded
// pathname which will include the encoded param value.
replacements.encodedPathname);
}
// Resolve all route params from the loader tree if this is from an
// app page. This processes both regular route params and parallel route params.
if ('loaderTree' in ComponentMod.routeModule.userland && Array.isArray(ComponentMod.routeModule.userland.loaderTree)) {
(0, _utils.resolveRouteParamsFromTree)(ComponentMod.routeModule.userland.loaderTree, params, route, fallbackRouteParams);
}
const fallbackRootParams = [];
for (const { paramName } of fallbackRouteParams){
// If the param is a root param then we can add it to the fallback
// root params.
if (rootParamSet.has(paramName)) {
fallbackRootParams.push(paramName);
}
}
pathname = (0, _utils.normalizePathname)(pathname);
prerenderedRoutesByPathname.set(pathname, {
params,
pathname,
encodedPathname: (0, _utils.normalizePathname)(encodedPathname),
fallbackRouteParams,
fallbackMode: calculateFallbackMode(dynamicParams, fallbackRootParams, fallbackMode),
fallbackRootParams,
throwOnEmptyStaticShell: true
});
});
}
const prerenderedRoutes = prerenderedRoutesByPathname.size > 0 || lastDynamicSegmentHadGenerateStaticParams ? [
...prerenderedRoutesByPathname.values()
] : undefined;
// Now we have to set the throwOnEmptyStaticShell for each of the routes.
if (prerenderedRoutes && cacheComponents) {
assignStaticShellMetadata(prerenderedRoutes, prerenderablePathSegments, partialFallbacksEnabled);
}
return {
fallbackMode,
prerenderedRoutes
};
}
//# sourceMappingURL=app.js.map

View File

@@ -0,0 +1,137 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "extractPathnameRouteParamSegmentsFromLoaderTree", {
enumerable: true,
get: function() {
return extractPathnameRouteParamSegmentsFromLoaderTree;
}
});
const _app = require("../../../shared/lib/router/routes/app");
const _parseloadertree = require("../../../shared/lib/router/utils/parse-loader-tree");
const _resolveparamvalue = require("../../../shared/lib/router/utils/resolve-param-value");
/**
* Validates that the static segments in currentPath match the corresponding
* segments in targetSegments. This ensures we only extract dynamic parameters
* that are part of the target pathname structure.
*
* Segments are compared literally - interception markers like "(.)photo" are
* part of the pathname and must match exactly.
*
* @example
* // Matching paths
* currentPath: ['blog', '(.)photo']
* targetSegments: ['blog', '(.)photo', '[id]']
* → Returns true (both static segments match exactly)
*
* @example
* // Non-matching paths
* currentPath: ['blog', '(.)photo']
* targetSegments: ['blog', 'photo', '[id]']
* → Returns false (segments don't match - marker is part of pathname)
*
* @param currentPath - The accumulated path segments from the loader tree
* @param targetSegments - The target pathname split into segments
* @returns true if all static segments match, false otherwise
*/ function validatePrefixMatch(currentPath, route) {
for(let i = 0; i < currentPath.length; i++){
const pathSegment = currentPath[i];
const targetPathSegment = route.segments[i];
// Type mismatch - one is static, one is dynamic
if (pathSegment.type !== targetPathSegment.type) {
return false;
}
// One has an interception marker, the other doesn't.
if (pathSegment.interceptionMarker !== targetPathSegment.interceptionMarker) {
return false;
}
// Both are static but names don't match
if (pathSegment.type === 'static' && targetPathSegment.type === 'static' && pathSegment.name !== targetPathSegment.name) {
return false;
} else if (pathSegment.type === 'dynamic' && targetPathSegment.type === 'dynamic' && pathSegment.param.paramType !== targetPathSegment.param.paramType && pathSegment.param.paramName !== targetPathSegment.param.paramName) {
return false;
}
}
return true;
}
function extractPathnameRouteParamSegmentsFromLoaderTree(loaderTree, route) {
const pathnameRouteParamSegments = [];
const params = {};
// BFS traversal with depth and path tracking
const queue = [
{
tree: loaderTree,
depth: 0,
currentPath: []
}
];
while(queue.length > 0){
const { tree, depth, currentPath } = queue.shift();
const { segment, parallelRoutes } = (0, _parseloadertree.parseLoaderTree)(tree);
// Build the path for the current node
let updatedPath = currentPath;
let nextDepth = depth;
const appSegment = (0, _app.parseAppRouteSegment)(segment);
// Only add to path if it's a real segment that appears in the URL
// Route groups and parallel markers don't contribute to URL pathname
if (appSegment && appSegment.type !== 'route-group' && appSegment.type !== 'parallel-route') {
updatedPath = [
...currentPath,
appSegment
];
nextDepth = depth + 1;
}
// Check if this segment has a param and matches the target pathname at this depth
if ((appSegment == null ? void 0 : appSegment.type) === 'dynamic') {
const { paramName, paramType } = appSegment.param;
// Check if this segment is at the correct depth in the target pathname
// A segment matches if:
// 1. There's a dynamic segment at this depth in the pathname
// 2. The parameter names match (e.g., [id] matches [id], not [category])
// 3. The static segments leading up to this point match (prefix check)
if (depth < route.segments.length) {
const targetSegment = route.segments[depth];
// Match if the target pathname has a dynamic segment at this depth
if (targetSegment.type === 'dynamic') {
// Check that parameter names match exactly
// This prevents [category] from matching against /[id]
if (paramName !== targetSegment.param.paramName) {
continue; // Different param names, skip this segment
}
// Validate that the path leading up to this dynamic segment matches
// the target pathname. This prevents false matches like extracting
// [slug] from "/news/[slug]" when the tree has "/blog/[slug]"
if (validatePrefixMatch(currentPath, route)) {
pathnameRouteParamSegments.push({
name: segment,
paramName,
paramType
});
}
}
}
// Resolve parameter value if it's not already known.
if (!params.hasOwnProperty(paramName)) {
const paramValue = (0, _resolveparamvalue.resolveParamValue)(paramName, paramType, depth, route, params);
if (paramValue !== undefined) {
params[paramName] = paramValue;
}
}
}
// Continue traversing all parallel routes to find matching segments
for (const parallelRoute of Object.values(parallelRoutes)){
queue.push({
tree: parallelRoute,
depth: nextDepth,
currentPath: updatedPath
});
}
}
return {
pathnameRouteParamSegments,
params
};
}
//# sourceMappingURL=extract-pathname-route-param-segments-from-loader-tree.js.map

View File

@@ -0,0 +1,169 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "buildPagesStaticPaths", {
enumerable: true,
get: function() {
return buildPagesStaticPaths;
}
});
const _normalizelocalepath = require("../../shared/lib/i18n/normalize-locale-path");
const _fallback = require("../../lib/fallback");
const _escapepathdelimiters = /*#__PURE__*/ _interop_require_default(require("../../shared/lib/router/utils/escape-path-delimiters"));
const _removetrailingslash = require("../../shared/lib/router/utils/remove-trailing-slash");
const _routematcher = require("../../shared/lib/router/utils/route-matcher");
const _routeregex = require("../../shared/lib/router/utils/route-regex");
const _utils = require("./utils");
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
async function buildPagesStaticPaths({ page, getStaticPaths, configFileName, locales, defaultLocale }) {
const prerenderedRoutesByPathname = new Map();
const _routeRegex = (0, _routeregex.getRouteRegex)(page);
const _routeMatcher = (0, _routematcher.getRouteMatcher)(_routeRegex);
// Get the default list of allowed params.
const routeParameterKeys = Object.keys(_routeMatcher(page));
const staticPathsResult = await getStaticPaths({
// We create a copy here to avoid having the types of `getStaticPaths`
// change. This ensures that users can't mutate this array and have it
// poison the reference.
locales: [
...locales ?? []
],
defaultLocale
});
const expectedReturnVal = `Expected: { paths: [], fallback: boolean }\n` + `See here for more info: https://nextjs.org/docs/messages/invalid-getstaticpaths-value`;
if (!staticPathsResult || typeof staticPathsResult !== 'object' || Array.isArray(staticPathsResult)) {
throw Object.defineProperty(new Error(`Invalid value returned from getStaticPaths in ${page}. Received ${typeof staticPathsResult} ${expectedReturnVal}`), "__NEXT_ERROR_CODE", {
value: "E1004",
enumerable: false,
configurable: true
});
}
const invalidStaticPathKeys = Object.keys(staticPathsResult).filter((key)=>!(key === 'paths' || key === 'fallback'));
if (invalidStaticPathKeys.length > 0) {
throw Object.defineProperty(new Error(`Extra keys returned from getStaticPaths in ${page} (${invalidStaticPathKeys.join(', ')}) ${expectedReturnVal}`), "__NEXT_ERROR_CODE", {
value: "E1047",
enumerable: false,
configurable: true
});
}
if (!(typeof staticPathsResult.fallback === 'boolean' || staticPathsResult.fallback === 'blocking')) {
throw Object.defineProperty(new Error(`The \`fallback\` key must be returned from getStaticPaths in ${page}.\n` + expectedReturnVal), "__NEXT_ERROR_CODE", {
value: "E1034",
enumerable: false,
configurable: true
});
}
const toPrerender = staticPathsResult.paths;
if (!Array.isArray(toPrerender)) {
throw Object.defineProperty(new Error(`Invalid \`paths\` value returned from getStaticPaths in ${page}.\n` + `\`paths\` must be an array of strings or objects of shape { params: [key: string]: string }`), "__NEXT_ERROR_CODE", {
value: "E83",
enumerable: false,
configurable: true
});
}
toPrerender.forEach((entry)=>{
// For a string-provided path, we must make sure it matches the dynamic
// route.
if (typeof entry === 'string') {
entry = (0, _removetrailingslash.removeTrailingSlash)(entry);
const localePathResult = (0, _normalizelocalepath.normalizeLocalePath)(entry, locales);
let cleanedEntry = entry;
if (localePathResult.detectedLocale) {
cleanedEntry = entry.slice(localePathResult.detectedLocale.length + 1);
} else if (defaultLocale) {
entry = `/${defaultLocale}${entry}`;
}
const params = _routeMatcher(cleanedEntry);
if (!params) {
throw Object.defineProperty(new Error(`The provided path \`${cleanedEntry}\` does not match the page: \`${page}\`.`), "__NEXT_ERROR_CODE", {
value: "E481",
enumerable: false,
configurable: true
});
}
// If leveraging the string paths variant the entry should already be
// encoded so we decode the segments ensuring we only escape path
// delimiters
const pathname = entry.split('/').map((segment)=>(0, _escapepathdelimiters.default)(decodeURIComponent(segment), true)).join('/');
if (!prerenderedRoutesByPathname.has(pathname)) {
prerenderedRoutesByPathname.set(pathname, {
params,
pathname,
encodedPathname: entry,
fallbackRouteParams: undefined,
fallbackMode: (0, _fallback.parseStaticPathsResult)(staticPathsResult.fallback),
fallbackRootParams: undefined,
throwOnEmptyStaticShell: undefined
});
}
} else {
const invalidKeys = Object.keys(entry).filter((key)=>key !== 'params' && key !== 'locale');
if (invalidKeys.length) {
throw Object.defineProperty(new Error(`Additional keys were returned from \`getStaticPaths\` in page "${page}". ` + `URL Parameters intended for this dynamic route must be nested under the \`params\` key, i.e.:` + `\n\n\treturn { params: { ${routeParameterKeys.map((k)=>`${k}: ...`).join(', ')} } }` + `\n\nKeys that need to be moved: ${invalidKeys.join(', ')}.\n`), "__NEXT_ERROR_CODE", {
value: "E322",
enumerable: false,
configurable: true
});
}
const { params = {} } = entry;
let builtPage = page;
let encodedBuiltPage = page;
routeParameterKeys.forEach((validParamKey)=>{
const { repeat, optional } = _routeRegex.groups[validParamKey];
let paramValue = params[validParamKey];
if (optional && params.hasOwnProperty(validParamKey) && (paramValue === null || paramValue === undefined || paramValue === false)) {
paramValue = [];
}
if (repeat && !Array.isArray(paramValue) || !repeat && typeof paramValue !== 'string' || typeof paramValue === 'undefined') {
throw Object.defineProperty(new Error(`A required parameter (${validParamKey}) was not provided as ${repeat ? 'an array' : 'a string'} received ${typeof paramValue} in getStaticPaths for ${page}`), "__NEXT_ERROR_CODE", {
value: "E620",
enumerable: false,
configurable: true
});
}
let replaced = `[${repeat ? '...' : ''}${validParamKey}]`;
if (optional) {
replaced = `[${replaced}]`;
}
builtPage = builtPage.replace(replaced, (0, _utils.encodeParam)(paramValue, (value)=>(0, _escapepathdelimiters.default)(value, true)));
encodedBuiltPage = encodedBuiltPage.replace(replaced, (0, _utils.encodeParam)(paramValue, encodeURIComponent));
});
if (!builtPage && !encodedBuiltPage) {
return;
}
if (entry.locale && !(locales == null ? void 0 : locales.includes(entry.locale))) {
throw Object.defineProperty(new Error(`Invalid locale returned from getStaticPaths for ${page}, the locale ${entry.locale} is not specified in ${configFileName}`), "__NEXT_ERROR_CODE", {
value: "E358",
enumerable: false,
configurable: true
});
}
const curLocale = entry.locale || defaultLocale || '';
const pathname = (0, _utils.normalizePathname)(`${curLocale ? `/${curLocale}` : ''}${curLocale && builtPage === '/' ? '' : builtPage}`);
if (!prerenderedRoutesByPathname.has(pathname)) {
prerenderedRoutesByPathname.set(pathname, {
params,
pathname,
encodedPathname: (0, _utils.normalizePathname)(`${curLocale ? `/${curLocale}` : ''}${curLocale && encodedBuiltPage === '/' ? '' : encodedBuiltPage}`),
fallbackRouteParams: undefined,
fallbackMode: (0, _fallback.parseStaticPathsResult)(staticPathsResult.fallback),
fallbackRootParams: undefined,
throwOnEmptyStaticShell: undefined
});
}
}
});
return {
fallbackMode: (0, _fallback.parseStaticPathsResult)(staticPathsResult.fallback),
prerenderedRoutes: [
...prerenderedRoutesByPathname.values()
]
};
}
//# sourceMappingURL=pages.js.map

View File

@@ -0,0 +1,119 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
encodeParam: null,
extractPathnameRouteParamSegments: null,
extractPathnameRouteParamSegmentsFromSegments: null,
normalizePathname: null,
resolveRouteParamsFromTree: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
encodeParam: function() {
return encodeParam;
},
extractPathnameRouteParamSegments: function() {
return extractPathnameRouteParamSegments;
},
extractPathnameRouteParamSegmentsFromSegments: function() {
return extractPathnameRouteParamSegmentsFromSegments;
},
normalizePathname: function() {
return normalizePathname;
},
resolveRouteParamsFromTree: function() {
return resolveRouteParamsFromTree;
}
});
const _checks = require("../../server/route-modules/checks");
const _app = require("../../shared/lib/router/routes/app");
const _parseloadertree = require("../../shared/lib/router/utils/parse-loader-tree");
const _extractpathnamerouteparamsegmentsfromloadertree = require("./app/extract-pathname-route-param-segments-from-loader-tree");
const _resolveparamvalue = require("../../shared/lib/router/utils/resolve-param-value");
function encodeParam(value, encoder) {
let replaceValue;
if (Array.isArray(value)) {
replaceValue = value.map(encoder).join('/');
} else {
replaceValue = encoder(value);
}
return replaceValue;
}
function normalizePathname(pathname) {
return pathname.replace(/\\/g, '/').replace(/(?!^)\/$/, '');
}
function extractPathnameRouteParamSegments(routeModule, segments, route) {
// For AppPageRouteModule, use the loaderTree traversal approach
if ((0, _checks.isAppPageRouteModule)(routeModule)) {
const { pathnameRouteParamSegments } = (0, _extractpathnamerouteparamsegmentsfromloadertree.extractPathnameRouteParamSegmentsFromLoaderTree)(routeModule.userland.loaderTree, route);
return pathnameRouteParamSegments;
}
return extractPathnameRouteParamSegmentsFromSegments(segments);
}
function extractPathnameRouteParamSegmentsFromSegments(segments) {
// TODO: should we consider what values are already present in the page?
// For AppRouteRouteModule, filter the segments array to get the route params
// that contribute to the pathname.
const result = [];
for (const segment of segments){
// Skip segments without param info.
if (!segment.paramName || !segment.paramType) continue;
// Collect all the route param keys that contribute to the pathname.
result.push({
name: segment.name,
paramName: segment.paramName,
paramType: segment.paramType
});
}
return result;
}
function resolveRouteParamsFromTree(loaderTree, params, route, fallbackRouteParams) {
// Stack-based traversal with depth tracking
const stack = [
{
tree: loaderTree,
depth: 0
}
];
while(stack.length > 0){
const { tree, depth } = stack.pop();
const { segment, parallelRoutes } = (0, _parseloadertree.parseLoaderTree)(tree);
const appSegment = (0, _app.parseAppRouteSegment)(segment);
// If this segment is a route parameter, then we should process it if it's
// not already known and is not already marked as a fallback route param.
if ((appSegment == null ? void 0 : appSegment.type) === 'dynamic' && !params.hasOwnProperty(appSegment.param.paramName) && !fallbackRouteParams.some((param)=>param.paramName === appSegment.param.paramName)) {
const { paramName, paramType } = appSegment.param;
const paramValue = (0, _resolveparamvalue.resolveParamValue)(paramName, paramType, depth, route, params);
if (paramValue !== undefined) {
params[paramName] = paramValue;
} else if (paramType !== 'optional-catchall') {
// If we couldn't resolve the param, mark it as a fallback
fallbackRouteParams.push({
paramName,
paramType
});
}
}
// Calculate next depth - increment if this is not a route group and not empty
let nextDepth = depth;
if (appSegment && appSegment.type !== 'route-group' && appSegment.type !== 'parallel-route') {
nextDepth++;
}
// Add all parallel routes to the stack for processing.
for (const parallelRoute of Object.values(parallelRoutes)){
stack.push({
tree: parallelRoute,
depth: nextDepth
});
}
}
}
//# sourceMappingURL=utils.js.map

15
build/node_modules/next/dist/build/swc/helpers.js generated vendored Normal file
View File

@@ -0,0 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "__nextjs_pure", {
enumerable: true,
get: function() {
return __nextjs_pure;
}
});
function __nextjs_pure(expr) {
return expr;
}
//# sourceMappingURL=helpers.js.map

1348
build/node_modules/next/dist/build/swc/index.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,30 @@
/**
* This module provides a way to install SWC bindings without eagerly loading the entire swc/index module.
*
* The swc/index module can transitively load other modules (like webpack-config) that import React,
* and React's entry point checks process.env.NODE_ENV at require time to decide whether to load
* the development or production bundle. By deferring the require of swc/index until this function
* is called, we ensure NODE_ENV is set before React is loaded.
*/ /**
* Loads and caches the native bindings. This is idempotent and should be called early so bindings
* can be accessed synchronously later.
*
* @param useWasmBinary - Whether to use WASM bindings instead of native bindings
*/ "use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "installBindings", {
enumerable: true,
get: function() {
return installBindings;
}
});
async function installBindings(useWasmBinary = false) {
// Lazy require to avoid loading swc/index (and transitively webpack-config/React)
// before NODE_ENV is set
const { loadBindings } = require('./index');
await loadBindings(useWasmBinary);
}
//# sourceMappingURL=install-bindings.js.map

View File

@@ -0,0 +1,76 @@
/*
Copyright (c) 2021 The swc Project Developers
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/ "use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
const _vm = /*#__PURE__*/ _interop_require_default(require("vm"));
const _index = require("./index");
const _options = require("./options");
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
// Jest use the `vm` [Module API](https://nodejs.org/api/vm.html#vm_class_vm_module) for ESM.
// see https://github.com/facebook/jest/issues/9430
const isSupportEsm = 'Module' in _vm.default;
function getJestConfig(jestConfig) {
return 'config' in jestConfig ? jestConfig.config : jestConfig;
}
function isEsm(isEsmProject, filename, jestConfig) {
var _jestConfig_extensionsToTreatAsEsm;
return /\.jsx?$/.test(filename) && isEsmProject || ((_jestConfig_extensionsToTreatAsEsm = jestConfig.extensionsToTreatAsEsm) == null ? void 0 : _jestConfig_extensionsToTreatAsEsm.some((ext)=>filename.endsWith(ext)));
}
const createTransformer = (inputOptions)=>({
process (src, filename, jestOptions) {
const jestConfig = getJestConfig(jestOptions);
const swcTransformOpts = (0, _options.getJestSWCOptions)({
isServer: jestConfig.testEnvironment === 'node' || jestConfig.testEnvironment.includes('jest-environment-node'),
filename,
jsConfig: inputOptions == null ? void 0 : inputOptions.jsConfig,
resolvedBaseUrl: inputOptions == null ? void 0 : inputOptions.resolvedBaseUrl,
pagesDir: inputOptions == null ? void 0 : inputOptions.pagesDir,
serverComponents: inputOptions == null ? void 0 : inputOptions.serverComponents,
modularizeImports: inputOptions == null ? void 0 : inputOptions.modularizeImports,
swcPlugins: inputOptions == null ? void 0 : inputOptions.swcPlugins,
compilerOptions: inputOptions == null ? void 0 : inputOptions.compilerOptions,
imageConfig: inputOptions == null ? void 0 : inputOptions.imageConfig,
serverReferenceHashSalt: '',
esm: isSupportEsm && isEsm(Boolean(inputOptions == null ? void 0 : inputOptions.isEsmProject), filename, jestConfig)
});
return (0, _index.transformSync)(src, {
...swcTransformOpts,
filename
});
}
});
module.exports = {
createTransformer
};
//# sourceMappingURL=jest-transformer.js.map

View File

@@ -0,0 +1,40 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "runLoaderWorkerPool", {
enumerable: true,
get: function() {
return runLoaderWorkerPool;
}
});
const _worker_threads = require("worker_threads");
const loaderWorkers = {};
function getPoolId(cwd, filename) {
return `${cwd}:${filename}`;
}
async function runLoaderWorkerPool(bindings, bindingPath) {
bindings.registerWorkerScheduler((creation)=>{
const { options: { filename, cwd } } = creation;
const poolId = getPoolId(cwd, filename);
const worker = new _worker_threads.Worker(/* turbopackIgnore: true*/ filename, {
workerData: {
bindingPath,
cwd
}
});
// This will cause handing when run in jest worker, but not as a first level thread of nodejs thread
// worker.unref()
const workers = loaderWorkers[poolId] || (loaderWorkers[poolId] = new Map());
workers.set(worker.threadId, worker);
}, (termination)=>{
var _workers_get;
const { options: { filename, cwd }, workerId } = termination;
const poolId = getPoolId(cwd, filename);
const workers = loaderWorkers[poolId];
(_workers_get = workers.get(workerId)) == null ? void 0 : _workers_get.terminate();
workers.delete(workerId);
});
}
//# sourceMappingURL=loaderWorkerPool.js.map

403
build/node_modules/next/dist/build/swc/options.js generated vendored Normal file
View File

@@ -0,0 +1,403 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
getJestSWCOptions: null,
getLoaderSWCOptions: null,
getParserOptions: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
getJestSWCOptions: function() {
return getJestSWCOptions;
},
getLoaderSWCOptions: function() {
return getLoaderSWCOptions;
},
getParserOptions: function() {
return getParserOptions;
}
});
const _path = /*#__PURE__*/ _interop_require_default(require("path"));
const _constants = require("../../lib/constants");
const _utils = require("../utils");
const _escaperegexp = require("../../shared/lib/escape-regexp");
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
const nextDirname = _path.default.dirname(require.resolve('next/package.json'));
const nextDistPath = new RegExp(`${(0, _escaperegexp.escapeStringRegexp)(nextDirname)}[\\/]dist[\\/](shared[\\/]lib|client|pages)`);
const nodeModulesPath = /[\\/]node_modules[\\/]/;
const regeneratorRuntimePath = require.resolve('next/dist/compiled/regenerator-runtime');
function isTypeScriptFile(filename) {
return filename.endsWith('.ts') || filename.endsWith('.tsx');
}
function isCommonJSFile(filename) {
return filename.endsWith('.cjs');
}
// Ensure Next.js internals and .cjs files are output as CJS modules,
// By default all modules are output as ESM or will treated as CJS if next-swc/auto-cjs plugin detects file is CJS.
function shouldOutputCommonJs(filename) {
return isCommonJSFile(filename) || nextDistPath.test(filename);
}
function getParserOptions({ filename, jsConfig, ...rest }) {
var _jsConfig_compilerOptions;
const isTSFile = filename.endsWith('.ts');
const hasTsSyntax = isTypeScriptFile(filename);
const enableDecorators = Boolean(jsConfig == null ? void 0 : (_jsConfig_compilerOptions = jsConfig.compilerOptions) == null ? void 0 : _jsConfig_compilerOptions.experimentalDecorators);
return {
...rest,
syntax: hasTsSyntax ? 'typescript' : 'ecmascript',
dynamicImport: true,
decorators: enableDecorators,
// Exclude regular TypeScript files from React transformation to prevent e.g. generic parameters and angle-bracket type assertion from being interpreted as JSX tags.
[hasTsSyntax ? 'tsx' : 'jsx']: !isTSFile,
importAssertions: true
};
}
function getBaseSWCOptions({ filename, jest, development, hasReactRefresh, globalWindow, esm, modularizeImports, swcPlugins, compilerOptions, resolvedBaseUrl, jsConfig, supportedBrowsers, swcCacheDir, serverComponents, serverReferenceHashSalt, bundleLayer, isCacheComponents, cacheHandlers, useCacheEnabled, taintEnabled, trackDynamicImports, pageExtensions }) {
var _jsConfig_compilerOptions, _jsConfig_compilerOptions1, _jsConfig_compilerOptions2, _jsConfig_compilerOptions3, _jsConfig_compilerOptions4, _jsConfig_experimental;
const isReactServerLayer = (0, _utils.shouldUseReactServerCondition)(bundleLayer);
const isAppRouterPagesLayer = (0, _utils.isWebpackAppPagesLayer)(bundleLayer);
const parserConfig = getParserOptions({
filename,
jsConfig
});
const paths = jsConfig == null ? void 0 : (_jsConfig_compilerOptions = jsConfig.compilerOptions) == null ? void 0 : _jsConfig_compilerOptions.paths;
const enableDecorators = Boolean(jsConfig == null ? void 0 : (_jsConfig_compilerOptions1 = jsConfig.compilerOptions) == null ? void 0 : _jsConfig_compilerOptions1.experimentalDecorators);
const emitDecoratorMetadata = Boolean(jsConfig == null ? void 0 : (_jsConfig_compilerOptions2 = jsConfig.compilerOptions) == null ? void 0 : _jsConfig_compilerOptions2.emitDecoratorMetadata);
const useDefineForClassFields = Boolean(jsConfig == null ? void 0 : (_jsConfig_compilerOptions3 = jsConfig.compilerOptions) == null ? void 0 : _jsConfig_compilerOptions3.useDefineForClassFields);
const plugins = (swcPlugins ?? []).filter(Array.isArray).map(([name, options])=>[
require.resolve(name),
options
]);
return {
jsc: {
...resolvedBaseUrl && paths ? {
baseUrl: resolvedBaseUrl.baseUrl,
paths
} : {},
externalHelpers: !process.versions.pnp && !jest,
parser: parserConfig,
experimental: {
keepImportAttributes: true,
emitAssertForImportAttributes: true,
plugins,
cacheRoot: swcCacheDir
},
transform: {
// Enables https://github.com/swc-project/swc/blob/0359deb4841be743d73db4536d4a22ac797d7f65/crates/swc_ecma_ext_transforms/src/jest.rs
...jest ? {
hidden: {
jest: true
}
} : {},
legacyDecorator: enableDecorators,
decoratorMetadata: emitDecoratorMetadata,
useDefineForClassFields: useDefineForClassFields,
react: {
importSource: (jsConfig == null ? void 0 : (_jsConfig_compilerOptions4 = jsConfig.compilerOptions) == null ? void 0 : _jsConfig_compilerOptions4.jsxImportSource) ?? ((compilerOptions == null ? void 0 : compilerOptions.emotion) && !isReactServerLayer ? '@emotion/react' : 'react'),
runtime: 'automatic',
pragmaFrag: 'React.Fragment',
throwIfNamespace: true,
development: !!development,
useBuiltins: true,
refresh: !!hasReactRefresh
},
optimizer: {
simplify: false,
globals: jest ? undefined : {
typeofs: {
window: globalWindow ? 'object' : 'undefined'
},
envs: {
NODE_ENV: development ? '"development"' : '"production"'
}
}
},
regenerator: {
importPath: regeneratorRuntimePath
}
}
},
sourceMaps: jest ? 'inline' : undefined,
removeConsole: compilerOptions == null ? void 0 : compilerOptions.removeConsole,
// disable "reactRemoveProperties" when "jest" is true
// otherwise the setting from next.config.js will be used
reactRemoveProperties: jest ? false : compilerOptions == null ? void 0 : compilerOptions.reactRemoveProperties,
// Map the k-v map to an array of pairs.
modularizeImports: modularizeImports ? Object.fromEntries(Object.entries(modularizeImports).map(([mod, config])=>[
mod,
{
...config,
transform: typeof config.transform === 'string' ? config.transform : Object.entries(config.transform).map(([key, value])=>[
key,
value
])
}
])) : undefined,
relay: compilerOptions == null ? void 0 : compilerOptions.relay,
// Always transform styled-jsx and error when `client-only` condition is triggered
styledJsx: (compilerOptions == null ? void 0 : compilerOptions.styledJsx) ?? {
useLightningcss: (jsConfig == null ? void 0 : (_jsConfig_experimental = jsConfig.experimental) == null ? void 0 : _jsConfig_experimental.useLightningcss) ?? false
},
// Disable css-in-js libs (without client-only integration) transform on server layer for server components
...!isReactServerLayer && {
emotion: getEmotionOptions(compilerOptions == null ? void 0 : compilerOptions.emotion, development),
styledComponents: getStyledComponentsOptions(compilerOptions == null ? void 0 : compilerOptions.styledComponents, development)
},
serverComponents: serverComponents && !jest ? {
isReactServerLayer,
cacheComponentsEnabled: isCacheComponents,
useCacheEnabled,
taintEnabled,
pageExtensions: pageExtensions || []
} : undefined,
serverActions: isAppRouterPagesLayer && !jest ? {
isReactServerLayer,
isDevelopment: development,
useCacheEnabled,
hashSalt: serverReferenceHashSalt,
cacheKinds: [
'default',
'remote',
'private'
].concat(cacheHandlers ? Object.keys(cacheHandlers) : [])
} : undefined,
// For app router we prefer to bundle ESM,
// On server side of pages router we prefer CJS.
preferEsm: esm,
lintCodemodComments: true,
trackDynamicImports: trackDynamicImports,
debugFunctionName: development,
...supportedBrowsers && supportedBrowsers.length > 0 ? {
cssEnv: {
targets: supportedBrowsers
}
} : {}
};
}
function getStyledComponentsOptions(styledComponentsConfig, development) {
if (!styledComponentsConfig) {
return null;
} else if (typeof styledComponentsConfig === 'object') {
return {
...styledComponentsConfig,
displayName: styledComponentsConfig.displayName ?? Boolean(development)
};
} else {
return {
displayName: Boolean(development)
};
}
}
function getEmotionOptions(emotionConfig, development) {
if (!emotionConfig) {
return null;
}
let autoLabel = !!development;
if (typeof emotionConfig === 'object' && emotionConfig.autoLabel) {
switch(emotionConfig.autoLabel){
case 'never':
autoLabel = false;
break;
case 'always':
autoLabel = true;
break;
case 'dev-only':
break;
default:
emotionConfig.autoLabel;
}
}
return {
enabled: true,
autoLabel,
sourcemap: development,
...typeof emotionConfig === 'object' && {
importMap: emotionConfig.importMap,
labelFormat: emotionConfig.labelFormat,
sourcemap: development && emotionConfig.sourceMap
}
};
}
function getJestSWCOptions({ isServer, filename, esm, modularizeImports, swcPlugins, compilerOptions, jsConfig, resolvedBaseUrl, pagesDir, imageConfig, serverReferenceHashSalt }) {
let baseOptions = getBaseSWCOptions({
filename,
jest: true,
development: false,
hasReactRefresh: false,
globalWindow: !isServer,
modularizeImports,
swcPlugins,
compilerOptions,
jsConfig,
resolvedBaseUrl,
supportedBrowsers: undefined,
esm,
// Don't apply server layer transformations for Jest
// Disable server / client graph assertions for Jest
bundleLayer: undefined,
serverComponents: false,
serverReferenceHashSalt
});
// In production, webpack DefinePlugin replaces process.env.__NEXT_IMAGE_OPTS
// with an object literal at compile time. Emulate that here by enabling
// SWC's optimizer globals.envs so the same compile-time replacement happens
// during Jest transforms.
if (imageConfig) {
var _baseOptions_jsc_transform_optimizer_globals;
baseOptions.jsc.transform.optimizer.globals = {
envs: {
...(_baseOptions_jsc_transform_optimizer_globals = baseOptions.jsc.transform.optimizer.globals) == null ? void 0 : _baseOptions_jsc_transform_optimizer_globals.envs,
__NEXT_IMAGE_OPTS: JSON.stringify(imageConfig)
}
};
}
const useCjsModules = shouldOutputCommonJs(filename);
return {
...baseOptions,
env: {
targets: {
// Targets the current version of Node.js
node: process.versions.node
}
},
module: {
type: esm && !useCjsModules ? 'es6' : 'commonjs'
},
disableNextSsg: true,
pagesDir
};
}
function getLoaderSWCOptions({ // This is not passed yet as "paths" resolving is handled by webpack currently.
// resolvedBaseUrl,
filename, development, isServer, pagesDir, appDir, isPageFile, isCacheComponents, hasReactRefresh, modularizeImports, optimizeServerReact, optimizePackageImports, swcPlugins, compilerOptions, jsConfig, supportedBrowsers, swcCacheDir, relativeFilePathFromRoot, serverComponents, serverReferenceHashSalt, bundleLayer, esm, cacheHandlers, useCacheEnabled, taintEnabled, trackDynamicImports, pageExtensions }) {
let baseOptions = getBaseSWCOptions({
filename,
development,
globalWindow: !isServer,
hasReactRefresh,
modularizeImports,
swcPlugins,
compilerOptions,
jsConfig,
// resolvedBaseUrl,
supportedBrowsers,
swcCacheDir,
bundleLayer,
serverComponents,
serverReferenceHashSalt,
esm: !!esm,
isCacheComponents,
cacheHandlers,
useCacheEnabled,
taintEnabled,
trackDynamicImports,
pageExtensions
});
baseOptions.fontLoaders = {
fontLoaders: [
'next/font/local',
'next/font/google'
],
relativeFilePathFromRoot
};
baseOptions.cjsRequireOptimizer = {
packages: {
'next/server': {
transforms: {
NextRequest: 'next/dist/server/web/spec-extension/request',
NextResponse: 'next/dist/server/web/spec-extension/response',
ImageResponse: 'next/dist/server/web/spec-extension/image-response',
userAgentFromString: 'next/dist/server/web/spec-extension/user-agent',
userAgent: 'next/dist/server/web/spec-extension/user-agent'
}
}
}
};
if (optimizeServerReact && isServer && !development) {
baseOptions.optimizeServerReact = {
optimize_use_state: false
};
}
// Modularize import optimization for barrel files
if (optimizePackageImports) {
baseOptions.autoModularizeImports = {
packages: optimizePackageImports
};
}
const isNodeModules = nodeModulesPath.test(filename);
const isAppBrowserLayer = bundleLayer === _constants.WEBPACK_LAYERS.appPagesBrowser;
const moduleResolutionConfig = shouldOutputCommonJs(filename) ? {
module: {
type: 'commonjs'
}
} : {};
let options;
if (isServer) {
options = {
...baseOptions,
...moduleResolutionConfig,
// Disables getStaticProps/getServerSideProps tree shaking on the server compilation for pages
disableNextSsg: true,
isDevelopment: development,
isServerCompiler: isServer,
pagesDir,
appDir,
preferEsm: !!esm,
isPageFile,
env: {
targets: {
// Targets the current version of Node.js
node: process.versions.node
}
}
};
} else {
options = {
...baseOptions,
...moduleResolutionConfig,
disableNextSsg: !isPageFile,
isDevelopment: development,
isServerCompiler: isServer,
pagesDir,
appDir,
isPageFile,
...supportedBrowsers && supportedBrowsers.length > 0 ? {
env: {
targets: supportedBrowsers
}
} : {}
};
if (!options.env) {
// Matches default @babel/preset-env behavior
options.jsc.target = 'es5';
}
}
// For node_modules in app browser layer, we don't need to do any server side transformation.
// Only keep server actions transform to discover server actions from client components.
if (isAppBrowserLayer && isNodeModules) {
var _options_jsc_transform_optimizer_globals;
options.disableNextSsg = true;
options.isPageFile = false;
options.optimizeServerReact = undefined;
options.cjsRequireOptimizer = undefined;
// Disable optimizer for node_modules in app browser layer, to avoid unnecessary replacement.
// e.g. typeof window could result differently in js worker or browser.
if (((_options_jsc_transform_optimizer_globals = options.jsc.transform.optimizer.globals) == null ? void 0 : _options_jsc_transform_optimizer_globals.typeofs) && !filename.includes(nextDirname)) {
delete options.jsc.transform.optimizer.globals.typeofs.window;
}
}
return options;
}
//# sourceMappingURL=options.js.map

6
build/node_modules/next/dist/build/swc/types.js generated vendored Normal file
View File

@@ -0,0 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
//# sourceMappingURL=types.js.map

1216
build/node_modules/next/dist/build/utils.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

170
build/node_modules/next/dist/cli/next-test.js generated vendored Normal file
View File

@@ -0,0 +1,170 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
SUPPORTED_TEST_RUNNERS_LIST: null,
nextTest: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
SUPPORTED_TEST_RUNNERS_LIST: function() {
return SUPPORTED_TEST_RUNNERS_LIST;
},
nextTest: function() {
return nextTest;
}
});
const _fs = require("fs");
const _getprojectdir = require("../lib/get-project-dir");
const _utils = require("../server/lib/utils");
const _config = /*#__PURE__*/ _interop_require_default(require("../server/config"));
const _constants = require("../shared/lib/constants");
const _hasnecessarydependencies = require("../lib/has-necessary-dependencies");
const _installdependencies = require("../lib/install-dependencies");
const _findup = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/find-up"));
const _findpagesdir = require("../lib/find-pages-dir");
const _verifytypescriptsetup = require("../lib/verify-typescript-setup");
const _path = /*#__PURE__*/ _interop_require_default(require("path"));
const _crossspawn = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/cross-spawn"));
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
const SUPPORTED_TEST_RUNNERS_LIST = [
'playwright'
];
const requiredPackagesByTestRunner = {
playwright: [
{
file: 'playwright',
pkg: '@playwright/test',
exportsRestrict: false
}
]
};
async function nextTest(directory, testRunnerArgs = [], options = {}) {
// The following mess is in order to support an existing Next.js CLI pattern of optionally, passing a project `directory` as the first argument to execute the command on.
// This is problematic for `next test` because as a wrapper around a test runner's `test` command, it needs to pass through any additional arguments and options.
// Thus, `directory` could either be a valid Next.js project directory (that the user intends to run `next test` on), or it is the first argument for the test runner.
// Unfortunately, since many test runners support passing a path (to a test file or directory containing test files), we must check if `directory` is both a valid path and a valid Next.js project.
let baseDir, nextConfig;
try {
// if directory is `undefined` or a valid path this will succeed.
baseDir = (0, _getprojectdir.getProjectDir)(directory, false);
} catch (err) {
// if that failed, then `directory` is not a valid path, so it must have meant to be the first item for `testRunnerArgs`
// @ts-expect-error directory is a string here since `getProjectDir` will succeed if its undefined
testRunnerArgs.unshift(directory);
// intentionally set baseDir to the resolved '.' path
baseDir = (0, _getprojectdir.getProjectDir)();
}
try {
// but, `baseDir` might not be a Next.js project directory, it could be a path-like argument for the test runner (i.e. `playwright test test/foo.spec.js`)
// if this succeeds, it means that `baseDir` is a Next.js project directory
nextConfig = await (0, _config.default)(_constants.PHASE_PRODUCTION_BUILD, baseDir);
} catch (err) {
// if it doesn't, then most likely `baseDir` is not a Next.js project directory
// @ts-expect-error directory is a string here since `getProjectDir` will succeed if its undefined
testRunnerArgs.unshift(directory);
// intentionally set baseDir to the resolved '.' path
baseDir = (0, _getprojectdir.getProjectDir)();
nextConfig = await (0, _config.default)(_constants.PHASE_PRODUCTION_BUILD, baseDir) // let this error bubble up if the `basePath` is still not a valid Next.js project
;
}
// set the test runner. priority is CLI option > next config > default 'playwright'
const configuredTestRunner = (options == null ? void 0 : options.testRunner) ?? // --test-runner='foo'
nextConfig.experimental.defaultTestRunner ?? // { experimental: { defaultTestRunner: 'foo' }}
'playwright';
if (!nextConfig.experimental.testProxy) {
return (0, _utils.printAndExit)(`\`next experimental-test\` requires the \`experimental.testProxy: true\` configuration option.`);
}
// execute test runner specific function
switch(configuredTestRunner){
case 'playwright':
return runPlaywright(baseDir, nextConfig, testRunnerArgs);
default:
return (0, _utils.printAndExit)(`Test runner ${configuredTestRunner} is not supported.`);
}
}
async function checkRequiredDeps(baseDir, testRunner) {
const deps = (0, _hasnecessarydependencies.hasNecessaryDependencies)(baseDir, requiredPackagesByTestRunner[testRunner]);
if (deps.missing.length > 0) {
await (0, _installdependencies.installDependencies)(baseDir, deps.missing, true);
const playwright = (0, _crossspawn.default)(_path.default.join(baseDir, 'node_modules', '.bin', 'playwright'), [
'install'
], {
cwd: baseDir,
shell: false,
stdio: 'inherit',
env: {
...process.env
}
});
return new Promise((resolve, reject)=>{
playwright.on('close', (c)=>resolve(c));
playwright.on('error', (err)=>reject(err));
});
}
}
async function runPlaywright(baseDir, nextConfig, testRunnerArgs) {
await checkRequiredDeps(baseDir, 'playwright');
const playwrightConfigFile = await (0, _findup.default)([
'playwright.config.js',
'playwright.config.ts'
], {
cwd: baseDir
});
if (!playwrightConfigFile) {
const { pagesDir, appDir } = (0, _findpagesdir.findPagesDir)(baseDir);
const { version: typeScriptVersion } = await (0, _verifytypescriptsetup.verifyAndRunTypeScript)({
dir: baseDir,
distDir: nextConfig.distDir,
strictRouteTypes: Boolean(nextConfig.experimental.strictRouteTypes),
shouldRunTypeCheck: false,
tsconfigPath: nextConfig.typescript.tsconfigPath,
typedRoutes: Boolean(nextConfig.typedRoutes),
disableStaticImages: nextConfig.images.disableStaticImages,
hasAppDir: !!appDir,
hasPagesDir: !!pagesDir,
appDir: appDir || undefined,
pagesDir: pagesDir || undefined
});
const isUsingTypeScript = !!typeScriptVersion;
const playwrightConfigFilename = isUsingTypeScript ? 'playwright.config.ts' : 'playwright.config.js';
(0, _fs.writeFileSync)(_path.default.join(baseDir, playwrightConfigFilename), defaultPlaywrightConfig(isUsingTypeScript));
return (0, _utils.printAndExit)(`Successfully generated ${playwrightConfigFilename}. Create your first test and then run \`next experimental-test\`.`, 0);
} else {
const playwright = (0, _crossspawn.default)(_path.default.join(baseDir, 'node_modules', '.bin', 'playwright'), [
'test',
...testRunnerArgs
], {
cwd: baseDir,
shell: false,
stdio: 'inherit',
env: {
...process.env
}
});
return new Promise((resolve, reject)=>{
playwright.on('close', (c)=>resolve(c));
playwright.on('error', (err)=>reject(err));
});
}
}
function defaultPlaywrightConfig(typescript) {
const comment = `/*
* Specify any additional Playwright config options here.
* They will be merged with Next.js' default Playwright config.
* You can access the default config by importing \`defaultPlaywrightConfig\` from \`'next/experimental/testmode/playwright'\`.
*/`;
return typescript ? `import { defineConfig } from 'next/experimental/testmode/playwright';\n\n${comment}\nexport default defineConfig({});` : `const { defineConfig } = require('next/experimental/testmode/playwright');\n\n${comment}\nmodule.exports = defineConfig({});`;
}
//# sourceMappingURL=next-test.js.map

24
build/node_modules/next/dist/client/add-base-path.js generated vendored Normal file
View File

@@ -0,0 +1,24 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "addBasePath", {
enumerable: true,
get: function() {
return addBasePath;
}
});
const _addpathprefix = require("../shared/lib/router/utils/add-path-prefix");
const _normalizetrailingslash = require("./normalize-trailing-slash");
const basePath = process.env.__NEXT_ROUTER_BASEPATH || '';
function addBasePath(path, required) {
return (0, _normalizetrailingslash.normalizePathTrailingSlash)(process.env.__NEXT_MANUAL_CLIENT_BASE_PATH && !required ? path : (0, _addpathprefix.addPathPrefix)(path, basePath));
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=add-base-path.js.map

34
build/node_modules/next/dist/client/app-call-server.js generated vendored Normal file
View File

@@ -0,0 +1,34 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "callServer", {
enumerable: true,
get: function() {
return callServer;
}
});
const _react = require("react");
const _routerreducertypes = require("./components/router-reducer/router-reducer-types");
const _useactionqueue = require("./components/use-action-queue");
async function callServer(actionId, actionArgs) {
return new Promise((resolve, reject)=>{
(0, _react.startTransition)(()=>{
(0, _useactionqueue.dispatchAppRouterAction)({
type: _routerreducertypes.ACTION_SERVER_ACTION,
actionId,
actionArgs,
resolve,
reject
});
});
});
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=app-call-server.js.map

View File

@@ -0,0 +1,39 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "findSourceMapURL", {
enumerable: true,
get: function() {
return findSourceMapURL;
}
});
const basePath = process.env.__NEXT_ROUTER_BASEPATH || '';
const pathname = `${basePath}/__nextjs_source-map`;
const findSourceMapURL = // Source maps are only served by the dev server.
process.env.__NEXT_DEV_SERVER ? function findSourceMapURL(filename) {
if (filename === '') {
return null;
}
if (filename.startsWith(document.location.origin) && filename.includes('/_next/static')) {
// This is a request for a client chunk. This can only happen when
// using Turbopack. In this case, since we control how those source
// maps are generated, we can safely assume that the sourceMappingURL
// is relative to the filename, with an added `.map` extension. The
// browser can just request this file, and it gets served through the
// normal dev server, without the need to route this through
// the `/__nextjs_source-map` dev middleware.
return `${filename}.map`;
}
const url = new URL(pathname, document.location.origin);
url.searchParams.set('filename', filename);
return url.href;
} : undefined;
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=app-find-source-map-url.js.map

29
build/node_modules/next/dist/client/assign-location.js generated vendored Normal file
View File

@@ -0,0 +1,29 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "assignLocation", {
enumerable: true,
get: function() {
return assignLocation;
}
});
const _addbasepath = require("./add-base-path");
function assignLocation(location, url) {
if (location.startsWith('.')) {
const urlBase = url.origin + url.pathname;
return new URL(// In order for a relative path to be added to the current url correctly, the current url must end with a slash
// new URL('./relative', 'https://example.com/subdir').href -> 'https://example.com/relative'
// new URL('./relative', 'https://example.com/subdir/').href -> 'https://example.com/subdir/relative'
(urlBase.endsWith('/') ? urlBase : urlBase + '/') + location);
}
return new URL((0, _addbasepath.addBasePath)(location), url.href);
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=assign-location.js.map

View File

@@ -0,0 +1,78 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "AppRouterAnnouncer", {
enumerable: true,
get: function() {
return AppRouterAnnouncer;
}
});
const _react = require("react");
const _reactdom = require("react-dom");
const ANNOUNCER_TYPE = 'next-route-announcer';
const ANNOUNCER_ID = '__next-route-announcer__';
function getAnnouncerNode() {
const existingAnnouncer = document.getElementsByName(ANNOUNCER_TYPE)[0];
if (existingAnnouncer?.shadowRoot?.childNodes[0]) {
return existingAnnouncer.shadowRoot.childNodes[0];
} else {
const container = document.createElement(ANNOUNCER_TYPE);
container.style.cssText = 'position:absolute';
const announcer = document.createElement('div');
announcer.ariaLive = 'assertive';
announcer.id = ANNOUNCER_ID;
announcer.role = 'alert';
announcer.style.cssText = 'position:absolute;border:0;height:1px;margin:-1px;padding:0;width:1px;clip:rect(0 0 0 0);overflow:hidden;white-space:nowrap;word-wrap:normal';
// Use shadow DOM here to avoid any potential CSS bleed
const shadow = container.attachShadow({
mode: 'open'
});
shadow.appendChild(announcer);
document.body.appendChild(container);
return announcer;
}
}
function AppRouterAnnouncer({ tree }) {
const [portalNode, setPortalNode] = (0, _react.useState)(null);
(0, _react.useEffect)(()=>{
const announcer = getAnnouncerNode();
setPortalNode(announcer);
return ()=>{
const container = document.getElementsByTagName(ANNOUNCER_TYPE)[0];
if (container?.isConnected) {
document.body.removeChild(container);
}
};
}, []);
const [routeAnnouncement, setRouteAnnouncement] = (0, _react.useState)('');
const previousTitle = (0, _react.useRef)(undefined);
(0, _react.useEffect)(()=>{
let currentTitle = '';
if (document.title) {
currentTitle = document.title;
} else {
const pageHeader = document.querySelector('h1');
if (pageHeader) {
currentTitle = pageHeader.innerText || pageHeader.textContent || '';
}
}
// Only announce the title change, but not for the first load because screen
// readers do that automatically.
if (previousTitle.current !== undefined && previousTitle.current !== currentTitle) {
setRouteAnnouncement(currentTitle);
}
previousTitle.current = currentTitle;
}, [
tree
]);
return portalNode ? /*#__PURE__*/ (0, _reactdom.createPortal)(routeAnnouncement, portalNode) : null;
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=app-router-announcer.js.map

View File

@@ -0,0 +1,138 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
ACTION_HEADER: null,
FLIGHT_HEADERS: null,
NEXT_ACTION_NOT_FOUND_HEADER: null,
NEXT_ACTION_REVALIDATED_HEADER: null,
NEXT_DID_POSTPONE_HEADER: null,
NEXT_HMR_REFRESH_HASH_COOKIE: null,
NEXT_HMR_REFRESH_HEADER: null,
NEXT_HTML_REQUEST_ID_HEADER: null,
NEXT_INSTANT_PREFETCH_HEADER: null,
NEXT_INSTANT_TEST_COOKIE: null,
NEXT_IS_PRERENDER_HEADER: null,
NEXT_REQUEST_ID_HEADER: null,
NEXT_REWRITTEN_PATH_HEADER: null,
NEXT_REWRITTEN_QUERY_HEADER: null,
NEXT_ROUTER_PREFETCH_HEADER: null,
NEXT_ROUTER_SEGMENT_PREFETCH_HEADER: null,
NEXT_ROUTER_STALE_TIME_HEADER: null,
NEXT_ROUTER_STATE_TREE_HEADER: null,
NEXT_RSC_UNION_QUERY: null,
NEXT_URL: null,
RSC_CONTENT_TYPE_HEADER: null,
RSC_HEADER: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
ACTION_HEADER: function() {
return ACTION_HEADER;
},
FLIGHT_HEADERS: function() {
return FLIGHT_HEADERS;
},
NEXT_ACTION_NOT_FOUND_HEADER: function() {
return NEXT_ACTION_NOT_FOUND_HEADER;
},
NEXT_ACTION_REVALIDATED_HEADER: function() {
return NEXT_ACTION_REVALIDATED_HEADER;
},
NEXT_DID_POSTPONE_HEADER: function() {
return NEXT_DID_POSTPONE_HEADER;
},
NEXT_HMR_REFRESH_HASH_COOKIE: function() {
return NEXT_HMR_REFRESH_HASH_COOKIE;
},
NEXT_HMR_REFRESH_HEADER: function() {
return NEXT_HMR_REFRESH_HEADER;
},
NEXT_HTML_REQUEST_ID_HEADER: function() {
return NEXT_HTML_REQUEST_ID_HEADER;
},
NEXT_INSTANT_PREFETCH_HEADER: function() {
return NEXT_INSTANT_PREFETCH_HEADER;
},
NEXT_INSTANT_TEST_COOKIE: function() {
return NEXT_INSTANT_TEST_COOKIE;
},
NEXT_IS_PRERENDER_HEADER: function() {
return NEXT_IS_PRERENDER_HEADER;
},
NEXT_REQUEST_ID_HEADER: function() {
return NEXT_REQUEST_ID_HEADER;
},
NEXT_REWRITTEN_PATH_HEADER: function() {
return NEXT_REWRITTEN_PATH_HEADER;
},
NEXT_REWRITTEN_QUERY_HEADER: function() {
return NEXT_REWRITTEN_QUERY_HEADER;
},
NEXT_ROUTER_PREFETCH_HEADER: function() {
return NEXT_ROUTER_PREFETCH_HEADER;
},
NEXT_ROUTER_SEGMENT_PREFETCH_HEADER: function() {
return NEXT_ROUTER_SEGMENT_PREFETCH_HEADER;
},
NEXT_ROUTER_STALE_TIME_HEADER: function() {
return NEXT_ROUTER_STALE_TIME_HEADER;
},
NEXT_ROUTER_STATE_TREE_HEADER: function() {
return NEXT_ROUTER_STATE_TREE_HEADER;
},
NEXT_RSC_UNION_QUERY: function() {
return NEXT_RSC_UNION_QUERY;
},
NEXT_URL: function() {
return NEXT_URL;
},
RSC_CONTENT_TYPE_HEADER: function() {
return RSC_CONTENT_TYPE_HEADER;
},
RSC_HEADER: function() {
return RSC_HEADER;
}
});
const RSC_HEADER = 'rsc';
const ACTION_HEADER = 'next-action';
const NEXT_ROUTER_STATE_TREE_HEADER = 'next-router-state-tree';
const NEXT_ROUTER_PREFETCH_HEADER = 'next-router-prefetch';
const NEXT_ROUTER_SEGMENT_PREFETCH_HEADER = 'next-router-segment-prefetch';
const NEXT_HMR_REFRESH_HEADER = 'next-hmr-refresh';
const NEXT_HMR_REFRESH_HASH_COOKIE = '__next_hmr_refresh_hash__';
const NEXT_URL = 'next-url';
const RSC_CONTENT_TYPE_HEADER = 'text/x-component';
const NEXT_INSTANT_PREFETCH_HEADER = 'next-instant-navigation-testing-prefetch';
const NEXT_INSTANT_TEST_COOKIE = 'next-instant-navigation-testing';
const FLIGHT_HEADERS = [
RSC_HEADER,
NEXT_ROUTER_STATE_TREE_HEADER,
NEXT_ROUTER_PREFETCH_HEADER,
NEXT_HMR_REFRESH_HEADER,
NEXT_ROUTER_SEGMENT_PREFETCH_HEADER
];
const NEXT_RSC_UNION_QUERY = '_rsc';
const NEXT_ROUTER_STALE_TIME_HEADER = 'x-nextjs-stale-time';
const NEXT_DID_POSTPONE_HEADER = 'x-nextjs-postponed';
const NEXT_REWRITTEN_PATH_HEADER = 'x-nextjs-rewritten-path';
const NEXT_REWRITTEN_QUERY_HEADER = 'x-nextjs-rewritten-query';
const NEXT_IS_PRERENDER_HEADER = 'x-nextjs-prerender';
const NEXT_ACTION_NOT_FOUND_HEADER = 'x-nextjs-action-not-found';
const NEXT_REQUEST_ID_HEADER = 'x-nextjs-request-id';
const NEXT_HTML_REQUEST_ID_HEADER = 'x-nextjs-html-request-id';
const NEXT_ACTION_REVALIDATED_HEADER = 'x-action-revalidated';
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=app-router-headers.js.map

View File

@@ -0,0 +1,397 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
createMutableActionQueue: null,
dispatchNavigateAction: null,
dispatchTraverseAction: null,
getCurrentAppRouterState: null,
publicAppRouterInstance: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
createMutableActionQueue: function() {
return createMutableActionQueue;
},
dispatchNavigateAction: function() {
return dispatchNavigateAction;
},
dispatchTraverseAction: function() {
return dispatchTraverseAction;
},
getCurrentAppRouterState: function() {
return getCurrentAppRouterState;
},
publicAppRouterInstance: function() {
return publicAppRouterInstance;
}
});
const _routerreducertypes = require("./router-reducer/router-reducer-types");
const _routerreducer = require("./router-reducer/router-reducer");
const _react = require("react");
const _isthenable = require("../../shared/lib/is-thenable");
const _types = require("./segment-cache/types");
const _prefetch = require("./segment-cache/prefetch");
const _navigation = require("./segment-cache/navigation");
const _useactionqueue = require("./use-action-queue");
const _optimisticroutes = require("./segment-cache/optimistic-routes");
const _pprnavigations = require("./router-reducer/ppr-navigations");
const _addbasepath = require("../add-base-path");
const _approuterutils = require("./app-router-utils");
const _links = require("./links");
const _javascripturl = require("../lib/javascript-url");
function runRemainingActions(actionQueue, setState) {
if (actionQueue.pending !== null) {
actionQueue.pending = actionQueue.pending.next;
if (actionQueue.pending !== null) {
runAction({
actionQueue,
action: actionQueue.pending,
setState
});
}
} else {
// Check for refresh when pending is already null
// This handles the case where a discarded server action completes
// after the navigation has already finished and the queue is empty
if (actionQueue.needsRefresh) {
actionQueue.needsRefresh = false;
actionQueue.dispatch({
type: _routerreducertypes.ACTION_REFRESH
}, setState);
}
}
}
async function runAction({ actionQueue, action, setState }) {
const prevState = actionQueue.state;
actionQueue.pending = action;
const payload = action.payload;
const actionResult = actionQueue.action(prevState, payload);
function handleResult(nextState) {
// if we discarded this action, the state should also be discarded
if (action.discarded) {
// Check if the discarded server action revalidated data
if (action.payload.type === _routerreducertypes.ACTION_SERVER_ACTION && action.payload.didRevalidate) {
// The server action was discarded but it revalidated data,
// mark that we need to refresh after all actions complete
actionQueue.needsRefresh = true;
}
// Still need to run remaining actions even for discarded actions
// to potentially trigger the refresh
runRemainingActions(actionQueue, setState);
return;
}
actionQueue.state = nextState;
runRemainingActions(actionQueue, setState);
action.resolve(nextState);
}
// if the action is a promise, set up a callback to resolve it
if ((0, _isthenable.isThenable)(actionResult)) {
actionResult.then(handleResult, (err)=>{
runRemainingActions(actionQueue, setState);
action.reject(err);
});
} else {
handleResult(actionResult);
}
}
function dispatchAction(actionQueue, payload, setState) {
let resolvers = {
resolve: setState,
reject: ()=>{}
};
// most of the action types are async with the exception of restore
// it's important that restore is handled quickly since it's fired on the popstate event
// and we don't want to add any delay on a back/forward nav
// this only creates a promise for the async actions
if (payload.type !== _routerreducertypes.ACTION_RESTORE) {
// Create the promise and assign the resolvers to the object.
const deferredPromise = new Promise((resolve, reject)=>{
resolvers = {
resolve,
reject
};
});
(0, _react.startTransition)(()=>{
// we immediately notify React of the pending promise -- the resolver is attached to the action node
// and will be called when the associated action promise resolves
setState(deferredPromise);
});
}
const newAction = {
payload,
next: null,
resolve: resolvers.resolve,
reject: resolvers.reject
};
// Check if the queue is empty
if (actionQueue.pending === null) {
// The queue is empty, so add the action and start it immediately
// Mark this action as the last in the queue
actionQueue.last = newAction;
runAction({
actionQueue,
action: newAction,
setState
});
} else if (payload.type === _routerreducertypes.ACTION_NAVIGATE || payload.type === _routerreducertypes.ACTION_RESTORE) {
// Navigations (including back/forward) take priority over any pending actions.
// Mark the pending action as discarded (so the state is never applied) and start the navigation action immediately.
actionQueue.pending.discarded = true;
// The rest of the current queue should still execute after this navigation.
// (Note that it can't contain any earlier navigations, because we always put those into `actionQueue.pending` by calling `runAction`)
newAction.next = actionQueue.pending.next;
runAction({
actionQueue,
action: newAction,
setState
});
} else {
// The queue is not empty, so add the action to the end of the queue
// It will be started by runRemainingActions after the previous action finishes
if (actionQueue.last !== null) {
actionQueue.last.next = newAction;
}
actionQueue.last = newAction;
}
}
let globalActionQueue = null;
function createMutableActionQueue(initialState, instrumentationHooks) {
const actionQueue = {
state: initialState,
dispatch: (payload, setState)=>dispatchAction(actionQueue, payload, setState),
action: async (state, action)=>{
const result = (0, _routerreducer.reducer)(state, action);
return result;
},
pending: null,
last: null,
onRouterTransitionStart: instrumentationHooks !== null && typeof instrumentationHooks.onRouterTransitionStart === 'function' ? instrumentationHooks.onRouterTransitionStart : null
};
if (typeof window !== 'undefined') {
// The action queue is lazily created on hydration, but after that point
// it doesn't change. So we can store it in a global rather than pass
// it around everywhere via props/context.
if (globalActionQueue !== null) {
throw Object.defineProperty(new Error('Internal Next.js Error: createMutableActionQueue was called more ' + 'than once'), "__NEXT_ERROR_CODE", {
value: "E624",
enumerable: false,
configurable: true
});
}
globalActionQueue = actionQueue;
}
return actionQueue;
}
function getCurrentAppRouterState() {
return globalActionQueue !== null ? globalActionQueue.state : null;
}
function getAppRouterActionQueue() {
if (globalActionQueue === null) {
throw Object.defineProperty(new Error('Internal Next.js error: Router action dispatched before initialization.'), "__NEXT_ERROR_CODE", {
value: "E668",
enumerable: false,
configurable: true
});
}
return globalActionQueue;
}
function getProfilingHookForOnNavigationStart() {
if (globalActionQueue !== null) {
return globalActionQueue.onRouterTransitionStart;
}
return null;
}
function dispatchNavigateAction(href, navigateType, scrollBehavior, linkInstanceRef, transitionTypes) {
// TODO: This stuff could just go into the reducer. Leaving as-is for now
// since we're about to rewrite all the router reducer stuff anyway.
if (transitionTypes) {
for (const type of transitionTypes){
(0, _react.addTransitionType)(type);
}
}
const url = new URL((0, _addbasepath.addBasePath)(href), location.href);
if (process.env.__NEXT_APP_NAV_FAIL_HANDLING) {
window.next.__pendingUrl = url;
}
(0, _links.setLinkForCurrentNavigation)(linkInstanceRef);
const onRouterTransitionStart = getProfilingHookForOnNavigationStart();
if (onRouterTransitionStart !== null) {
onRouterTransitionStart(href, navigateType);
}
(0, _useactionqueue.dispatchAppRouterAction)({
type: _routerreducertypes.ACTION_NAVIGATE,
url,
isExternalUrl: (0, _approuterutils.isExternalURL)(url),
locationSearch: location.search,
scrollBehavior,
navigateType
});
}
function dispatchTraverseAction(href, historyState) {
const onRouterTransitionStart = getProfilingHookForOnNavigationStart();
if (onRouterTransitionStart !== null) {
onRouterTransitionStart(href, 'traverse');
}
(0, _useactionqueue.dispatchAppRouterAction)({
type: _routerreducertypes.ACTION_RESTORE,
url: new URL(href),
historyState
});
}
/**
* (Experimental) Perform a gesture navigation. This dispatches through React's
* useOptimistic instead of the main action queue, allowing the state to be
* shown during a gesture transition and discarded when the canonical navigation
* completes.
*
* Only available when experimental.gestureTransition is enabled.
*/ function gesturePush(href, options) {
if (process.env.__NEXT_GESTURE_TRANSITION) {
// TODO: Trigger a prefetch so the cache starts populating if there isn't
// already a prefetch for this route.
if ((0, _javascripturl.isJavaScriptURLString)(href)) {
throw Object.defineProperty(new Error('Next.js has blocked a javascript: URL as a security precaution.'), "__NEXT_ERROR_CODE", {
value: "E978",
enumerable: false,
configurable: true
});
}
const state = getCurrentAppRouterState();
if (state === null) {
return;
}
const url = new URL((0, _addbasepath.addBasePath)(href), location.href);
if ((0, _approuterutils.isExternalURL)(url)) {
return;
}
// Fork the router state for the duration of the gesture transition.
const currentUrl = new URL(state.canonicalUrl, location.href);
const scrollBehavior = options?.scroll === false ? _routerreducertypes.ScrollBehavior.NoScroll : _routerreducertypes.ScrollBehavior.Default;
// This is a special freshness policy that prevents dynamic requests from
// being spawned. During the gesture, we should only show the cached
// prefetched UI, not dynamic data.
// TODO: In the case of navigations to an unknown route, this will still
// end up performing a dynamic request. The plan is to do prefetch instead.
// There's a separate TODO for this.
const freshnessPolicy = _pprnavigations.FreshnessPolicy.Gesture;
const forkedGestureState = (0, _navigation.navigate)(state, url, currentUrl, state.renderedSearch, state.cache, state.tree, state.nextUrl, freshnessPolicy, scrollBehavior, 'push');
(0, _useactionqueue.dispatchGestureState)(forkedGestureState);
}
}
const publicAppRouterInstance = {
back: ()=>window.history.back(),
forward: ()=>window.history.forward(),
prefetch: // Unlike the old implementation, the Segment Cache doesn't store its
// data in the router reducer state; it writes into a global mutable
// cache. So we don't need to dispatch an action.
(href, options)=>{
if ((0, _javascripturl.isJavaScriptURLString)(href)) {
throw Object.defineProperty(new Error('Next.js has blocked a javascript: URL as a security precaution.'), "__NEXT_ERROR_CODE", {
value: "E978",
enumerable: false,
configurable: true
});
}
const actionQueue = getAppRouterActionQueue();
const prefetchKind = options?.kind ?? _routerreducertypes.PrefetchKind.AUTO;
// We don't currently offer a way to issue a runtime prefetch via `router.prefetch()`.
// This will be possible when we update its API to not take a PrefetchKind.
let fetchStrategy;
switch(prefetchKind){
case _routerreducertypes.PrefetchKind.AUTO:
{
// We default to PPR. We'll discover whether or not the route supports it with the initial prefetch.
fetchStrategy = _types.FetchStrategy.PPR;
break;
}
case _routerreducertypes.PrefetchKind.FULL:
{
fetchStrategy = _types.FetchStrategy.Full;
break;
}
default:
{
prefetchKind;
// Despite typescript thinking that this can't happen,
// we might get an unexpected value from user code.
// We don't know what they want, but we know they want a prefetch,
// so use the default.
fetchStrategy = _types.FetchStrategy.PPR;
}
}
(0, _prefetch.prefetch)(href, actionQueue.state.nextUrl, actionQueue.state.tree, fetchStrategy, options?.onInvalidate ?? null);
},
replace: (href, options)=>{
if ((0, _javascripturl.isJavaScriptURLString)(href)) {
throw Object.defineProperty(new Error('Next.js has blocked a javascript: URL as a security precaution.'), "__NEXT_ERROR_CODE", {
value: "E978",
enumerable: false,
configurable: true
});
}
(0, _react.startTransition)(()=>{
dispatchNavigateAction(href, 'replace', options?.scroll === false ? _routerreducertypes.ScrollBehavior.NoScroll : _routerreducertypes.ScrollBehavior.Default, null, options?.transitionTypes);
});
},
push: (href, options)=>{
if ((0, _javascripturl.isJavaScriptURLString)(href)) {
throw Object.defineProperty(new Error('Next.js has blocked a javascript: URL as a security precaution.'), "__NEXT_ERROR_CODE", {
value: "E978",
enumerable: false,
configurable: true
});
}
(0, _react.startTransition)(()=>{
dispatchNavigateAction(href, 'push', options?.scroll === false ? _routerreducertypes.ScrollBehavior.NoScroll : _routerreducertypes.ScrollBehavior.Default, null, options?.transitionTypes);
});
},
refresh: ()=>{
(0, _react.startTransition)(()=>{
(0, _useactionqueue.dispatchAppRouterAction)({
type: _routerreducertypes.ACTION_REFRESH
});
});
},
hmrRefresh: ()=>{
if (process.env.NODE_ENV !== 'development') {
throw Object.defineProperty(new Error('hmrRefresh can only be used in development mode. Please use refresh instead.'), "__NEXT_ERROR_CODE", {
value: "E485",
enumerable: false,
configurable: true
});
} else {
// Reset the known routes table so that route predictions are cleared
// when routes change during development.
(0, _optimisticroutes.resetKnownRoutes)();
(0, _react.startTransition)(()=>{
(0, _useactionqueue.dispatchAppRouterAction)({
type: _routerreducertypes.ACTION_HMR_REFRESH
});
});
}
}
};
// Conditionally add experimental_gesturePush when gestureTransition is enabled
if (process.env.__NEXT_GESTURE_TRANSITION) {
;
publicAppRouterInstance.experimental_gesturePush = gesturePush;
}
// Exists for debugging purposes. Don't use in application code.
if (typeof window !== 'undefined' && window.next) {
window.next.router = publicAppRouterInstance;
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=app-router-instance.js.map

View File

@@ -0,0 +1,62 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
createPrefetchURL: null,
isExternalURL: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
createPrefetchURL: function() {
return createPrefetchURL;
},
isExternalURL: function() {
return isExternalURL;
}
});
const _isbot = require("../../shared/lib/router/utils/is-bot");
const _addbasepath = require("../add-base-path");
function isExternalURL(url) {
return url.origin !== window.location.origin;
}
function createPrefetchURL(href) {
// Don't prefetch for bots as they don't navigate.
if ((0, _isbot.isBot)(window.navigator.userAgent)) {
return null;
}
let url;
try {
url = new URL((0, _addbasepath.addBasePath)(href), window.location.href);
} catch (_) {
// TODO: Does this need to throw or can we just console.error instead? Does
// anyone rely on this throwing? (Seems unlikely.)
throw Object.defineProperty(new Error(`Cannot prefetch '${href}' because it cannot be converted to a URL.`), "__NEXT_ERROR_CODE", {
value: "E234",
enumerable: false,
configurable: true
});
}
// Don't prefetch during development (improves compilation performance)
if (process.env.NODE_ENV === 'development') {
return null;
}
// External urls can't be prefetched in the same way.
if (isExternalURL(url)) {
return null;
}
return url;
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=app-router-utils.js.map

View File

@@ -0,0 +1,514 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "default", {
enumerable: true,
get: function() {
return AppRouter;
}
});
const _interop_require_default = require("@swc/helpers/_/_interop_require_default");
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
const _jsxruntime = require("react/jsx-runtime");
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
const _approutercontextsharedruntime = require("../../shared/lib/app-router-context.shared-runtime");
const _routerreducertypes = require("./router-reducer/router-reducer-types");
const _createhreffromurl = require("./router-reducer/create-href-from-url");
const _hooksclientcontextsharedruntime = require("../../shared/lib/hooks-client-context.shared-runtime");
const _useactionqueue = require("./use-action-queue");
const _committedstate = require("./router-reducer/reducers/committed-state");
const _approuterannouncer = require("./app-router-announcer");
const _redirectboundary = require("./redirect-boundary");
const _findheadincache = require("./router-reducer/reducers/find-head-in-cache");
const _unresolvedthenable = require("./unresolved-thenable");
const _removebasepath = require("../remove-base-path");
const _hasbasepath = require("../has-base-path");
const _computechangedpath = require("./router-reducer/compute-changed-path");
const _navfailurehandler = require("./nav-failure-handler");
const _approuterinstance = require("./app-router-instance");
const _redirect = require("./redirect");
const _redirecterror = require("./redirect-error");
const _links = require("./links");
const _rooterrorboundary = /*#__PURE__*/ _interop_require_default._(require("./errors/root-error-boundary"));
const _globalerror = /*#__PURE__*/ _interop_require_default._(require("./builtin/global-error"));
const _boundarycomponents = require("../../lib/framework/boundary-components");
const _deploymentid = require("../../shared/lib/deployment-id");
const globalMutable = {};
function HistoryUpdater({ appRouterState }) {
(0, _react.useInsertionEffect)(()=>{
if (process.env.__NEXT_APP_NAV_FAIL_HANDLING) {
// clear pending URL as navigation is no longer
// in flight
window.next.__pendingUrl = undefined;
}
const { tree, pushRef, canonicalUrl, renderedSearch } = appRouterState;
const appHistoryState = {
tree,
renderedSearch
};
// TODO: Use Navigation API if available
const historyState = {
...pushRef.preserveCustomHistoryState ? window.history.state : {},
// Identifier is shortened intentionally.
// __NA is used to identify if the history entry can be handled by the app-router.
// __N is used to identify if the history entry can be handled by the old router.
__NA: true,
__PRIVATE_NEXTJS_INTERNALS_TREE: appHistoryState
};
if (pushRef.pendingPush && // Skip pushing an additional history entry if the canonicalUrl is the same as the current url.
// This mirrors the browser behavior for normal navigation.
(0, _createhreffromurl.createHrefFromUrl)(new URL(window.location.href)) !== canonicalUrl) {
// This intentionally mutates React state, pushRef is overwritten to ensure additional push/replace calls do not trigger an additional history entry.
pushRef.pendingPush = false;
window.history.pushState(historyState, '', canonicalUrl);
} else {
window.history.replaceState(historyState, '', canonicalUrl);
}
(0, _committedstate.setLastCommittedTree)(tree);
}, [
appRouterState
]);
(0, _react.useEffect)(()=>{
// The Next-Url and the base tree may affect the result of a prefetch
// task. Re-prefetch all visible links with the updated values. In most
// cases, this will not result in any new network requests, only if
// the prefetch result actually varies on one of these inputs.
(0, _links.pingVisibleLinks)(appRouterState.nextUrl, appRouterState.tree);
}, [
appRouterState.nextUrl,
appRouterState.tree
]);
return null;
}
function copyNextJsInternalHistoryState(data) {
if (data == null) data = {};
const currentState = window.history.state;
const __NA = currentState?.__NA;
if (__NA) {
data.__NA = __NA;
}
const __PRIVATE_NEXTJS_INTERNALS_TREE = currentState?.__PRIVATE_NEXTJS_INTERNALS_TREE;
if (__PRIVATE_NEXTJS_INTERNALS_TREE) {
data.__PRIVATE_NEXTJS_INTERNALS_TREE = __PRIVATE_NEXTJS_INTERNALS_TREE;
}
return data;
}
function Head({ headCacheNode }) {
// If this segment has a `prefetchHead`, it's the statically prefetched data.
// We should use that on initial render instead of `head`. Then we'll switch
// to `head` when the dynamic response streams in.
const head = headCacheNode !== null ? headCacheNode.head : null;
const prefetchHead = headCacheNode !== null ? headCacheNode.prefetchHead : null;
// If no prefetch data is available, then we go straight to rendering `head`.
const resolvedPrefetchRsc = prefetchHead !== null ? prefetchHead : head;
// We use `useDeferredValue` to handle switching between the prefetched and
// final values. The second argument is returned on initial render, then it
// re-renders with the first argument.
return (0, _react.useDeferredValue)(head, resolvedPrefetchRsc);
}
/**
* The global router that wraps the application components.
*/ function Router({ actionQueue, globalError, webSocket, staticIndicatorState }) {
const state = (0, _useactionqueue.useActionQueue)(actionQueue);
const { canonicalUrl } = state;
// Add memoized pathname/query for useSearchParams and usePathname.
const { searchParams, pathname } = (0, _react.useMemo)(()=>{
const url = new URL(canonicalUrl, typeof window === 'undefined' ? 'http://n' : window.location.href);
return {
// This is turned into a readonly class in `useSearchParams`
searchParams: url.searchParams,
pathname: (0, _hasbasepath.hasBasePath)(url.pathname) ? (0, _removebasepath.removeBasePath)(url.pathname) : url.pathname
};
}, [
canonicalUrl
]);
if (process.env.NODE_ENV !== 'production') {
const { cache, tree } = state;
// This hook is in a conditional but that is ok because `process.env.NODE_ENV` never changes
// eslint-disable-next-line react-hooks/rules-of-hooks
(0, _react.useEffect)(()=>{
// Add `window.nd` for debugging purposes.
// This is not meant for use in applications as concurrent rendering will affect the cache/tree/router.
// @ts-ignore this is for debugging
window.nd = {
router: _approuterinstance.publicAppRouterInstance,
cache,
tree
};
}, [
cache,
tree
]);
}
(0, _react.useEffect)(()=>{
const sourcePage = (0, _computechangedpath.extractSourcePageFromFlightRouterState)(state.tree);
if (sourcePage !== undefined) {
window.next.__internal_src_page = sourcePage;
} else {
delete window.next.__internal_src_page;
}
}, [
state.tree
]);
(0, _react.useEffect)(()=>{
// If the app is restored from bfcache, it's possible that
// pushRef.mpaNavigation is true, which would mean that any re-render of this component
// would trigger the mpa navigation logic again from the lines below.
// This will restore the router to the initial state in the event that the app is restored from bfcache.
function handlePageShow(event) {
if (!event.persisted || !window.history.state?.__PRIVATE_NEXTJS_INTERNALS_TREE) {
return;
}
// Clear the pendingMpaPath value so that a subsequent MPA navigation to the same URL can be triggered.
// This is necessary because if the browser restored from bfcache, the pendingMpaPath would still be set to the value
// of the last MPA navigation.
globalMutable.pendingMpaPath = undefined;
(0, _useactionqueue.dispatchAppRouterAction)({
type: _routerreducertypes.ACTION_RESTORE,
url: new URL(window.location.href),
historyState: window.history.state.__PRIVATE_NEXTJS_INTERNALS_TREE
});
}
window.addEventListener('pageshow', handlePageShow);
return ()=>{
window.removeEventListener('pageshow', handlePageShow);
};
}, []);
(0, _react.useEffect)(()=>{
// Ensure that any redirect errors that bubble up outside of the RedirectBoundary
// are caught and handled by the router.
function handleUnhandledRedirect(event) {
const error = 'reason' in event ? event.reason : event.error;
if ((0, _redirecterror.isRedirectError)(error)) {
event.preventDefault();
const url = (0, _redirect.getURLFromRedirectError)(error);
const redirectType = (0, _redirect.getRedirectTypeFromError)(error);
// TODO: This should access the router methods directly, rather than
// go through the public interface.
if (redirectType === 'push') {
_approuterinstance.publicAppRouterInstance.push(url, {});
} else {
_approuterinstance.publicAppRouterInstance.replace(url, {});
}
}
}
window.addEventListener('error', handleUnhandledRedirect);
window.addEventListener('unhandledrejection', handleUnhandledRedirect);
return ()=>{
window.removeEventListener('error', handleUnhandledRedirect);
window.removeEventListener('unhandledrejection', handleUnhandledRedirect);
};
}, []);
// When mpaNavigation flag is set do a hard navigation to the new url.
// Infinitely suspend because we don't actually want to rerender any child
// components with the new URL and any entangled state updates shouldn't
// commit either (eg: useTransition isPending should stay true until the page
// unloads).
//
// This is a side effect in render. Don't try this at home, kids. It's
// probably safe because we know this is a singleton component and it's never
// in <Offscreen>. At least I hope so. (It will run twice in dev strict mode,
// but that's... fine?)
const { pushRef } = state;
if (pushRef.mpaNavigation) {
// if there's a re-render, we don't want to trigger another redirect if one is already in flight to the same URL
if (globalMutable.pendingMpaPath !== canonicalUrl) {
const location = window.location;
if (pushRef.pendingPush) {
location.assign(canonicalUrl);
} else {
location.replace(canonicalUrl);
}
globalMutable.pendingMpaPath = canonicalUrl;
}
// TODO-APP: Should we listen to navigateerror here to catch failed
// navigations somehow? And should we call window.stop() if a SPA navigation
// should interrupt an MPA one?
// NOTE: This is intentionally using `throw` instead of `use` because we're
// inside an externally mutable condition (pushRef.mpaNavigation), which
// violates the rules of hooks.
throw _unresolvedthenable.unresolvedThenable;
}
(0, _react.useEffect)(()=>{
const originalPushState = window.history.pushState.bind(window.history);
const originalReplaceState = window.history.replaceState.bind(window.history);
// Ensure the canonical URL in the Next.js Router is updated when the URL is changed so that `usePathname` and `useSearchParams` hold the pushed values.
const applyUrlFromHistoryPushReplace = (url)=>{
const href = window.location.href;
const appHistoryState = window.history.state?.__PRIVATE_NEXTJS_INTERNALS_TREE;
(0, _react.startTransition)(()=>{
(0, _useactionqueue.dispatchAppRouterAction)({
type: _routerreducertypes.ACTION_RESTORE,
url: new URL(url ?? href, href),
historyState: appHistoryState
});
});
};
/**
* Patch pushState to ensure external changes to the history are reflected in the Next.js Router.
* Ensures Next.js internal history state is copied to the new history entry.
* Ensures usePathname and useSearchParams hold the newly provided url.
*/ window.history.pushState = function pushState(data, _unused, url) {
// TODO: Warn when Navigation API is available (navigation.navigate() should be used)
// Avoid a loop when Next.js internals trigger pushState/replaceState
if (data?.__NA || data?._N) {
return originalPushState(data, _unused, url);
}
data = copyNextJsInternalHistoryState(data);
if (url) {
applyUrlFromHistoryPushReplace(url);
}
return originalPushState(data, _unused, url);
};
/**
* Patch replaceState to ensure external changes to the history are reflected in the Next.js Router.
* Ensures Next.js internal history state is copied to the new history entry.
* Ensures usePathname and useSearchParams hold the newly provided url.
*/ window.history.replaceState = function replaceState(data, _unused, url) {
// TODO: Warn when Navigation API is available (navigation.navigate() should be used)
// Avoid a loop when Next.js internals trigger pushState/replaceState
if (data?.__NA || data?._N) {
return originalReplaceState(data, _unused, url);
}
data = copyNextJsInternalHistoryState(data);
if (url) {
applyUrlFromHistoryPushReplace(url);
}
return originalReplaceState(data, _unused, url);
};
/**
* Handle popstate event, this is used to handle back/forward in the browser.
* By default dispatches ACTION_RESTORE, however if the history entry was not pushed/replaced by app-router it will reload the page.
* That case can happen when the old router injected the history entry.
*/ const onPopState = (event)=>{
if (!event.state) {
// TODO-APP: this case only happens when pushState/replaceState was called outside of Next.js. It should probably reload the page in this case.
return;
}
// This case happens when the history entry was pushed by the `pages` router.
if (!event.state.__NA) {
window.location.reload();
return;
}
// TODO-APP: Ideally the back button should not use startTransition as it should apply the updates synchronously
// Without startTransition works if the cache is there for this path
(0, _react.startTransition)(()=>{
(0, _approuterinstance.dispatchTraverseAction)(window.location.href, event.state.__PRIVATE_NEXTJS_INTERNALS_TREE);
});
};
// Register popstate event to call onPopstate.
window.addEventListener('popstate', onPopState);
return ()=>{
window.history.pushState = originalPushState;
window.history.replaceState = originalReplaceState;
window.removeEventListener('popstate', onPopState);
};
}, []);
const { cache, tree, nextUrl, focusAndScrollRef, previousNextUrl } = state;
const matchingHead = (0, _react.useMemo)(()=>{
return (0, _findheadincache.findHeadInCache)(cache, tree[1]);
}, [
cache,
tree
]);
// Add memoized pathParams for useParams.
const pathParams = (0, _react.useMemo)(()=>{
return (0, _computechangedpath.getSelectedParams)(tree);
}, [
tree
]);
// Create instrumented promises for navigation hooks (dev-only)
// These are specially instrumented promises to show in the Suspense DevTools
// Promises are cached outside of render to survive suspense retries.
let instrumentedNavigationPromises = null;
if (process.env.NODE_ENV !== 'production') {
const { createRootNavigationPromises } = require('./navigation-devtools');
instrumentedNavigationPromises = createRootNavigationPromises(tree, pathname, searchParams, pathParams);
}
const layoutRouterContext = (0, _react.useMemo)(()=>{
return {
parentTree: tree,
parentCacheNode: cache,
parentSegmentPath: null,
parentParams: {},
parentLoadingData: null,
// This is the <Activity> "name" that shows up in the Suspense DevTools.
// It represents the root of the app.
debugNameContext: '/',
// Root node always has `url`
// Provided in AppTreeContext to ensure it can be overwritten in layout-router
url: canonicalUrl,
// Root segment is always active
isActive: true
};
}, [
tree,
cache,
canonicalUrl
]);
const globalLayoutRouterContext = (0, _react.useMemo)(()=>{
return {
tree,
focusAndScrollRef,
nextUrl,
previousNextUrl
};
}, [
tree,
focusAndScrollRef,
nextUrl,
previousNextUrl
]);
let head;
if (matchingHead !== null) {
// The head is wrapped in an extra component so we can use
// `useDeferredValue` to swap between the prefetched and final versions of
// the head. (This is what LayoutRouter does for segment data, too.)
//
// The `key` is used to remount the component whenever the head moves to
// a different segment.
const [headCacheNode, headKey, headKeyWithoutSearchParams] = matchingHead;
head = /*#__PURE__*/ (0, _jsxruntime.jsx)(Head, {
headCacheNode: headCacheNode
}, // Necessary for PPR: omit search params from the key to match prerendered keys
typeof window === 'undefined' ? headKeyWithoutSearchParams : headKey);
} else {
head = null;
}
let content = /*#__PURE__*/ (0, _jsxruntime.jsxs)(_redirectboundary.RedirectBoundary, {
children: [
head,
/*#__PURE__*/ (0, _jsxruntime.jsx)(_boundarycomponents.RootLayoutBoundary, {
children: cache.rsc
}),
/*#__PURE__*/ (0, _jsxruntime.jsx)(_approuterannouncer.AppRouterAnnouncer, {
tree: tree
})
]
});
if (process.env.__NEXT_DEV_SERVER) {
// In development, we apply few error boundaries and hot-reloader:
// - DevRootHTTPAccessFallbackBoundary: avoid using navigation API like notFound() in root layout
// - HotReloader:
// - hot-reload the app when the code changes
// - render dev overlay
// - catch runtime errors and display global-error when necessary
if (typeof window !== 'undefined') {
const { DevRootHTTPAccessFallbackBoundary } = require('./dev-root-http-access-fallback-boundary');
content = /*#__PURE__*/ (0, _jsxruntime.jsx)(DevRootHTTPAccessFallbackBoundary, {
children: content
});
}
const HotReloader = require('../dev/hot-reloader/app/hot-reloader-app').default;
content = /*#__PURE__*/ (0, _jsxruntime.jsx)(HotReloader, {
globalError: globalError,
webSocket: webSocket,
staticIndicatorState: staticIndicatorState,
children: content
});
} else {
content = /*#__PURE__*/ (0, _jsxruntime.jsx)(_rooterrorboundary.default, {
errorComponent: globalError[0],
errorStyles: globalError[1],
children: content
});
}
return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_jsxruntime.Fragment, {
children: [
/*#__PURE__*/ (0, _jsxruntime.jsx)(HistoryUpdater, {
appRouterState: state
}),
process.env.TURBOPACK ? null : /*#__PURE__*/ (0, _jsxruntime.jsx)(RuntimeStylesForWebpack, {}),
/*#__PURE__*/ (0, _jsxruntime.jsx)(_hooksclientcontextsharedruntime.NavigationPromisesContext.Provider, {
value: instrumentedNavigationPromises,
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_hooksclientcontextsharedruntime.PathParamsContext.Provider, {
value: pathParams,
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_hooksclientcontextsharedruntime.PathnameContext.Provider, {
value: pathname,
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_hooksclientcontextsharedruntime.SearchParamsContext.Provider, {
value: searchParams,
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_approutercontextsharedruntime.GlobalLayoutRouterContext.Provider, {
value: globalLayoutRouterContext,
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_approutercontextsharedruntime.AppRouterContext.Provider, {
value: _approuterinstance.publicAppRouterInstance,
children: /*#__PURE__*/ (0, _jsxruntime.jsx)(_approutercontextsharedruntime.LayoutRouterContext.Provider, {
value: layoutRouterContext,
children: content
})
})
})
})
})
})
})
]
});
}
function AppRouter({ actionQueue, globalErrorState, webSocket, staticIndicatorState }) {
(0, _navfailurehandler.useNavFailureHandler)();
const router = /*#__PURE__*/ (0, _jsxruntime.jsx)(Router, {
actionQueue: actionQueue,
globalError: globalErrorState,
webSocket: webSocket,
staticIndicatorState: staticIndicatorState
});
// At the very top level, use the default GlobalError component as the final fallback.
// When the app router itself fails, which means the framework itself fails, we show the default error.
return /*#__PURE__*/ (0, _jsxruntime.jsx)(_rooterrorboundary.default, {
errorComponent: _globalerror.default,
children: router
});
}
let runtimeStyles;
let runtimeStyleChanged;
if (!process.env.TURBOPACK && typeof window !== 'undefined') {
runtimeStyles = new Set();
runtimeStyleChanged = new Set();
globalThis._N_E_STYLE_LOAD = function(href) {
if (!runtimeStyles || !runtimeStyleChanged) return Promise.resolve();
let len = runtimeStyles.size;
runtimeStyles.add(href);
if (runtimeStyles.size !== len) {
runtimeStyleChanged.forEach((cb)=>cb());
}
// TODO figure out how to get a promise here
// But maybe it's not necessary as react would block rendering until it's loaded
return Promise.resolve();
};
}
function RuntimeStylesForWebpack() {
const [, forceUpdate] = _react.default.useState(0);
const renderedStylesSize = runtimeStyles?.size ?? 0;
(0, _react.useEffect)(()=>{
if (!runtimeStyles || !runtimeStyleChanged) return;
const changed = ()=>forceUpdate((c)=>c + 1);
runtimeStyleChanged.add(changed);
if (renderedStylesSize !== runtimeStyles.size) {
changed();
}
return ()=>{
runtimeStyleChanged.delete(changed);
};
}, [
renderedStylesSize,
forceUpdate
]);
const query = (0, _deploymentid.getAssetTokenQuery)();
return [
...runtimeStyles || []
].map((href, i)=>/*#__PURE__*/ (0, _jsxruntime.jsx)("link", {
rel: "stylesheet",
href: `${href}${query}`,
// @ts-ignore
precedence: "next"
}, i));
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=app-router.js.map

View File

@@ -0,0 +1,35 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
PARALLEL_ROUTE_DEFAULT_PATH: null,
default: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
PARALLEL_ROUTE_DEFAULT_PATH: function() {
return PARALLEL_ROUTE_DEFAULT_PATH;
},
default: function() {
return ParallelRouteDefault;
}
});
const _notfound = require("../not-found");
const PARALLEL_ROUTE_DEFAULT_PATH = 'next/dist/client/components/builtin/default.js';
function ParallelRouteDefault() {
(0, _notfound.notFound)();
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=default.js.map

View File

@@ -0,0 +1,165 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
WarningIcon: null,
errorStyles: null,
errorThemeCss: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
WarningIcon: function() {
return WarningIcon;
},
errorStyles: function() {
return errorStyles;
},
errorThemeCss: function() {
return errorThemeCss;
}
});
const _interop_require_default = require("@swc/helpers/_/_interop_require_default");
const _jsxruntime = require("react/jsx-runtime");
const _react = /*#__PURE__*/ _interop_require_default._(require("react"));
const errorStyles = {
container: {
fontFamily: 'system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji"',
height: '100vh',
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
},
card: {
marginTop: '-32px',
maxWidth: '325px',
padding: '32px 28px',
textAlign: 'left'
},
icon: {
marginBottom: '24px'
},
title: {
fontSize: '24px',
fontWeight: 500,
letterSpacing: '-0.02em',
lineHeight: '32px',
margin: '0 0 12px 0',
color: 'var(--next-error-title)'
},
message: {
fontSize: '14px',
fontWeight: 400,
lineHeight: '21px',
margin: '0 0 20px 0',
color: 'var(--next-error-message)'
},
form: {
margin: 0
},
buttonGroup: {
display: 'flex',
gap: '8px',
alignItems: 'center'
},
button: {
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
height: '32px',
padding: '0 12px',
fontSize: '14px',
fontWeight: 500,
lineHeight: '20px',
borderRadius: '6px',
cursor: 'pointer',
color: 'var(--next-error-btn-text)',
background: 'var(--next-error-btn-bg)',
border: 'var(--next-error-btn-border)'
},
buttonSecondary: {
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
height: '32px',
padding: '0 12px',
fontSize: '14px',
fontWeight: 500,
lineHeight: '20px',
borderRadius: '6px',
cursor: 'pointer',
color: 'var(--next-error-btn-secondary-text)',
background: 'var(--next-error-btn-secondary-bg)',
border: 'var(--next-error-btn-secondary-border)'
},
digestFooter: {
position: 'fixed',
bottom: '32px',
left: '0',
right: '0',
textAlign: 'center',
fontFamily: 'ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,monospace',
fontSize: '12px',
lineHeight: '18px',
fontWeight: 400,
margin: '0',
color: 'var(--next-error-digest)'
}
};
const errorThemeCss = `
:root {
--next-error-bg: #fff;
--next-error-text: #171717;
--next-error-title: #171717;
--next-error-message: #171717;
--next-error-digest: #666666;
--next-error-btn-text: #fff;
--next-error-btn-bg: #171717;
--next-error-btn-border: none;
--next-error-btn-secondary-text: #171717;
--next-error-btn-secondary-bg: transparent;
--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);
}
@media (prefers-color-scheme: dark) {
:root {
--next-error-bg: #0a0a0a;
--next-error-text: #ededed;
--next-error-title: #ededed;
--next-error-message: #ededed;
--next-error-digest: #a0a0a0;
--next-error-btn-text: #0a0a0a;
--next-error-btn-bg: #ededed;
--next-error-btn-border: none;
--next-error-btn-secondary-text: #ededed;
--next-error-btn-secondary-bg: transparent;
--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);
}
}
body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }
`.replace(/\n\s*/g, '');
function WarningIcon() {
return /*#__PURE__*/ (0, _jsxruntime.jsx)("svg", {
width: "32",
height: "32",
viewBox: "-0.2 -1.5 32 32",
fill: "none",
style: errorStyles.icon,
children: /*#__PURE__*/ (0, _jsxruntime.jsx)("path", {
d: "M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z",
fill: "var(--next-error-title)"
})
});
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=error-styles.js.map

View File

@@ -0,0 +1,100 @@
'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, // Exported so that the import signature in the loaders can be identical to user
// supplied custom global error signatures.
"default", {
enumerable: true,
get: function() {
return _default;
}
});
const _interop_require_default = require("@swc/helpers/_/_interop_require_default");
const _jsxruntime = require("react/jsx-runtime");
const _react = /*#__PURE__*/ _interop_require_default._(require("react"));
const _handleisrerror = require("../handle-isr-error");
const _errorstyles = require("./error-styles");
function DefaultGlobalError({ error }) {
const digest = error?.digest;
const isServerError = !!digest;
const message = isServerError ? 'A server error occurred. Reload to try again.' : 'Reload to try again, or go back.';
(0, _handleisrerror.handleISRError)({
error
});
return /*#__PURE__*/ (0, _jsxruntime.jsxs)("html", {
id: "__next_error__",
children: [
/*#__PURE__*/ (0, _jsxruntime.jsx)("head", {
children: /*#__PURE__*/ (0, _jsxruntime.jsx)("style", {
dangerouslySetInnerHTML: {
__html: _errorstyles.errorThemeCss
}
})
}),
/*#__PURE__*/ (0, _jsxruntime.jsxs)("body", {
children: [
/*#__PURE__*/ (0, _jsxruntime.jsx)("div", {
style: _errorstyles.errorStyles.container,
children: /*#__PURE__*/ (0, _jsxruntime.jsxs)("div", {
style: _errorstyles.errorStyles.card,
children: [
/*#__PURE__*/ (0, _jsxruntime.jsx)(_errorstyles.WarningIcon, {}),
/*#__PURE__*/ (0, _jsxruntime.jsx)("h1", {
style: _errorstyles.errorStyles.title,
children: "This page couldnt load"
}),
/*#__PURE__*/ (0, _jsxruntime.jsx)("p", {
style: _errorstyles.errorStyles.message,
children: message
}),
/*#__PURE__*/ (0, _jsxruntime.jsxs)("div", {
style: _errorstyles.errorStyles.buttonGroup,
children: [
/*#__PURE__*/ (0, _jsxruntime.jsx)("form", {
style: _errorstyles.errorStyles.form,
children: /*#__PURE__*/ (0, _jsxruntime.jsx)("button", {
type: "submit",
style: _errorstyles.errorStyles.button,
children: "Reload"
})
}),
!isServerError && /*#__PURE__*/ (0, _jsxruntime.jsx)("button", {
type: "button",
style: _errorstyles.errorStyles.buttonSecondary,
onClick: ()=>{
if (window.history.length > 1) {
window.history.back();
} else {
window.location.href = '/';
}
},
children: "Back"
})
]
})
]
})
}),
digest && /*#__PURE__*/ (0, _jsxruntime.jsxs)("p", {
style: _errorstyles.errorStyles.digestFooter,
children: [
"ERROR ",
digest
]
})
]
})
]
});
}
const _default = DefaultGlobalError;
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=global-error.js.map

View File

@@ -0,0 +1,52 @@
'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
DevRootHTTPAccessFallbackBoundary: null,
bailOnRootNotFound: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
DevRootHTTPAccessFallbackBoundary: function() {
return DevRootHTTPAccessFallbackBoundary;
},
bailOnRootNotFound: function() {
return bailOnRootNotFound;
}
});
const _interop_require_default = require("@swc/helpers/_/_interop_require_default");
const _jsxruntime = require("react/jsx-runtime");
const _react = /*#__PURE__*/ _interop_require_default._(require("react"));
const _errorboundary = require("./http-access-fallback/error-boundary");
function bailOnRootNotFound() {
throw Object.defineProperty(new Error('notFound() is not allowed to use in root layout'), "__NEXT_ERROR_CODE", {
value: "E192",
enumerable: false,
configurable: true
});
}
function NotAllowedRootHTTPFallbackError() {
bailOnRootNotFound();
return null;
}
function DevRootHTTPAccessFallbackBoundary({ children }) {
return /*#__PURE__*/ (0, _jsxruntime.jsx)(_errorboundary.HTTPAccessFallbackBoundary, {
notFound: /*#__PURE__*/ (0, _jsxruntime.jsx)(NotAllowedRootHTTPFallbackError, {}),
children: children
});
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=dev-root-http-access-fallback-boundary.js.map

View File

@@ -0,0 +1,144 @@
'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
ErrorBoundary: null,
ErrorBoundaryHandler: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
ErrorBoundary: function() {
return ErrorBoundary;
},
ErrorBoundaryHandler: function() {
return ErrorBoundaryHandler;
}
});
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
const _jsxruntime = require("react/jsx-runtime");
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
const _navigationuntracked = require("./navigation-untracked");
const _isnextroutererror = require("./is-next-router-error");
const _navfailurehandler = require("./nav-failure-handler");
const _handleisrerror = require("./handle-isr-error");
const _isbot = require("../../shared/lib/router/utils/is-bot");
const _approutercontextsharedruntime = require("../../shared/lib/app-router-context.shared-runtime");
const isBotUserAgent = typeof window !== 'undefined' && (0, _isbot.isBot)(window.navigator.userAgent);
class ErrorBoundaryHandler extends _react.default.Component {
static{
this.contextType = _approutercontextsharedruntime.AppRouterContext;
}
constructor(props){
super(props), this.reset = ()=>{
this.setState({
error: null
});
}, this.unstable_retry = ()=>{
(0, _react.startTransition)(()=>{
this.context?.refresh();
this.reset();
});
};
this.state = {
error: null,
previousPathname: this.props.pathname
};
}
static getDerivedStateFromError(error) {
if ((0, _isnextroutererror.isNextRouterError)(error)) {
// Re-throw if an expected internal Next.js router error occurs
// this means it should be handled by a different boundary (such as a NotFound boundary in a parent segment)
throw error;
}
return {
error
};
}
static getDerivedStateFromProps(props, state) {
const { error } = state;
// if we encounter an error while
// a navigation is pending we shouldn't render
// the error boundary and instead should fallback
// to a hard navigation to attempt recovering
if (process.env.__NEXT_APP_NAV_FAIL_HANDLING) {
if (error && (0, _navfailurehandler.handleHardNavError)(error)) {
// clear error so we don't render anything
return {
error: null,
previousPathname: props.pathname
};
}
}
/**
* Handles reset of the error boundary when a navigation happens.
* Ensures the error boundary does not stay enabled when navigating to a new page.
* Approach of setState in render is safe as it checks the previous pathname and then overrides
* it as outlined in https://react.dev/reference/react/useState#storing-information-from-previous-renders
*/ if (props.pathname !== state.previousPathname && state.error) {
return {
error: null,
previousPathname: props.pathname
};
}
return {
error: state.error,
previousPathname: props.pathname
};
}
// Explicit type is needed to avoid the generated `.d.ts` having a wide return type that could be specific to the `@types/react` version.
render() {
//When it's bot request, segment level error boundary will keep rendering the children,
// the final error will be caught by the root error boundary and determine wether need to apply graceful degrade.
if (this.state.error && !isBotUserAgent) {
(0, _handleisrerror.handleISRError)({
error: this.state.error
});
return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_jsxruntime.Fragment, {
children: [
this.props.errorStyles,
this.props.errorScripts,
/*#__PURE__*/ (0, _jsxruntime.jsx)(this.props.errorComponent, {
error: this.state.error,
reset: this.reset,
unstable_retry: this.unstable_retry
})
]
});
}
return this.props.children;
}
}
function ErrorBoundary({ errorComponent, errorStyles, errorScripts, children }) {
// When we're rendering the missing params shell, this will return null. This
// is because we won't be rendering any not found boundaries or error
// boundaries for the missing params shell. When this runs on the client
// (where these errors can occur), we will get the correct pathname.
const pathname = (0, _navigationuntracked.useUntrackedPathname)();
if (errorComponent) {
return /*#__PURE__*/ (0, _jsxruntime.jsx)(ErrorBoundaryHandler, {
pathname: pathname,
errorComponent: errorComponent,
errorStyles: errorStyles,
errorScripts: errorScripts,
children: children
});
}
return /*#__PURE__*/ (0, _jsxruntime.jsx)(_jsxruntime.Fragment, {
children: children
});
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=error-boundary.js.map

View File

@@ -0,0 +1,86 @@
'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
GracefulDegradeBoundary: null,
default: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
GracefulDegradeBoundary: function() {
return GracefulDegradeBoundary;
},
default: function() {
return _default;
}
});
const _jsxruntime = require("react/jsx-runtime");
const _react = require("react");
function getDomNodeAttributes(node) {
const result = {};
for(let i = 0; i < node.attributes.length; i++){
const attr = node.attributes[i];
result[attr.name] = attr.value;
}
return result;
}
class GracefulDegradeBoundary extends _react.Component {
constructor(props){
super(props);
this.state = {
hasError: false
};
this.rootHtml = '';
this.htmlAttributes = {};
this.htmlRef = /*#__PURE__*/ (0, _react.createRef)();
}
static getDerivedStateFromError(_) {
return {
hasError: true
};
}
componentDidMount() {
const htmlNode = this.htmlRef.current;
if (this.state.hasError && htmlNode) {
// Reapply the cached HTML attributes to the root element
Object.entries(this.htmlAttributes).forEach(([key, value])=>{
htmlNode.setAttribute(key, value);
});
}
}
render() {
const { hasError } = this.state;
// Cache the root HTML content on the first render
if (typeof window !== 'undefined' && !this.rootHtml) {
this.rootHtml = document.documentElement.innerHTML;
this.htmlAttributes = getDomNodeAttributes(document.documentElement);
}
if (hasError) {
// Render the current HTML content without hydration
return /*#__PURE__*/ (0, _jsxruntime.jsx)("html", {
ref: this.htmlRef,
suppressHydrationWarning: true,
dangerouslySetInnerHTML: {
__html: this.rootHtml
}
});
}
return this.props.children;
}
}
const _default = GracefulDegradeBoundary;
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=graceful-degrade-boundary.js.map

View File

@@ -0,0 +1,41 @@
'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "default", {
enumerable: true,
get: function() {
return RootErrorBoundary;
}
});
const _interop_require_default = require("@swc/helpers/_/_interop_require_default");
const _jsxruntime = require("react/jsx-runtime");
const _react = /*#__PURE__*/ _interop_require_default._(require("react"));
const _gracefuldegradeboundary = /*#__PURE__*/ _interop_require_default._(require("./graceful-degrade-boundary"));
const _errorboundary = require("../error-boundary");
const _isbot = require("../../../shared/lib/router/utils/is-bot");
const isBotUserAgent = typeof window !== 'undefined' && (0, _isbot.isBot)(window.navigator.userAgent);
function RootErrorBoundary({ children, errorComponent, errorStyles, errorScripts }) {
if (isBotUserAgent) {
// Preserve existing DOM/HTML for bots to avoid replacing content with an error UI
// and to keep the original SSR output intact.
return /*#__PURE__*/ (0, _jsxruntime.jsx)(_gracefuldegradeboundary.default, {
children: children
});
}
return /*#__PURE__*/ (0, _jsxruntime.jsx)(_errorboundary.ErrorBoundary, {
errorComponent: errorComponent,
errorStyles: errorStyles,
errorScripts: errorScripts,
children: children
});
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=root-error-boundary.js.map

View File

@@ -0,0 +1,48 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "forbidden", {
enumerable: true,
get: function() {
return forbidden;
}
});
const _httpaccessfallback = require("./http-access-fallback/http-access-fallback");
// TODO: Add `forbidden` docs
/**
* @experimental
* This function allows you to render the [forbidden.js file](https://nextjs.org/docs/app/api-reference/file-conventions/forbidden)
* within a route segment as well as inject a tag.
*
* `forbidden()` can be used in
* [Server Components](https://nextjs.org/docs/app/building-your-application/rendering/server-components),
* [Route Handlers](https://nextjs.org/docs/app/building-your-application/routing/route-handlers), and
* [Server Actions](https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations).
*
* Read more: [Next.js Docs: `forbidden`](https://nextjs.org/docs/app/api-reference/functions/forbidden)
*/ const DIGEST = `${_httpaccessfallback.HTTP_ERROR_FALLBACK_ERROR_CODE};403`;
function forbidden() {
if (!process.env.__NEXT_EXPERIMENTAL_AUTH_INTERRUPTS) {
throw Object.defineProperty(new Error(`\`forbidden()\` is experimental and only allowed to be enabled when \`experimental.authInterrupts\` is enabled.`), "__NEXT_ERROR_CODE", {
value: "E488",
enumerable: false,
configurable: true
});
}
const error = Object.defineProperty(new Error(DIGEST), "__NEXT_ERROR_CODE", {
value: "E1019",
enumerable: false,
configurable: true
});
error.digest = DIGEST;
throw error;
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=forbidden.js.map

View File

@@ -0,0 +1,30 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "handleISRError", {
enumerable: true,
get: function() {
return handleISRError;
}
});
const workAsyncStorage = typeof window === 'undefined' ? require('../../server/app-render/work-async-storage.external').workAsyncStorage : undefined;
function handleISRError({ error }) {
if (workAsyncStorage) {
const store = workAsyncStorage.getStore();
if (store?.isStaticGeneration) {
if (error) {
console.error(error);
}
throw error;
}
}
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=handle-isr-error.js.map

View File

@@ -0,0 +1,42 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
DynamicServerError: null,
isDynamicServerError: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
DynamicServerError: function() {
return DynamicServerError;
},
isDynamicServerError: function() {
return isDynamicServerError;
}
});
const DYNAMIC_ERROR_CODE = 'DYNAMIC_SERVER_USAGE';
class DynamicServerError extends Error {
constructor(description){
super(`Dynamic server usage: ${description}`), this.description = description, this.digest = DYNAMIC_ERROR_CODE;
}
}
function isDynamicServerError(err) {
if (typeof err !== 'object' || err === null || !('digest' in err) || typeof err.digest !== 'string') {
return false;
}
return err.digest === DYNAMIC_ERROR_CODE;
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=hooks-server-context.js.map

View File

@@ -0,0 +1,125 @@
'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "HTTPAccessFallbackBoundary", {
enumerable: true,
get: function() {
return HTTPAccessFallbackBoundary;
}
});
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
const _jsxruntime = require("react/jsx-runtime");
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
const _navigationuntracked = require("../navigation-untracked");
const _httpaccessfallback = require("./http-access-fallback");
const _warnonce = require("../../../shared/lib/utils/warn-once");
const _approutercontextsharedruntime = require("../../../shared/lib/app-router-context.shared-runtime");
class HTTPAccessFallbackErrorBoundary extends _react.default.Component {
constructor(props){
super(props);
this.state = {
triggeredStatus: undefined,
previousPathname: props.pathname
};
}
componentDidCatch() {
if (process.env.NODE_ENV === 'development' && this.props.missingSlots && this.props.missingSlots.size > 0 && // A missing children slot is the typical not-found case, so no need to warn
!this.props.missingSlots.has('children')) {
let warningMessage = 'No default component was found for a parallel route rendered on this page. Falling back to nearest NotFound boundary.\n' + 'Learn more: https://nextjs.org/docs/app/building-your-application/routing/parallel-routes#defaultjs\n\n';
const formattedSlots = Array.from(this.props.missingSlots).sort((a, b)=>a.localeCompare(b)).map((slot)=>`@${slot}`).join(', ');
warningMessage += 'Missing slots: ' + formattedSlots;
(0, _warnonce.warnOnce)(warningMessage);
}
}
static getDerivedStateFromError(error) {
if ((0, _httpaccessfallback.isHTTPAccessFallbackError)(error)) {
const httpStatus = (0, _httpaccessfallback.getAccessFallbackHTTPStatus)(error);
return {
triggeredStatus: httpStatus
};
}
// Re-throw if error is not for 404
throw error;
}
static getDerivedStateFromProps(props, state) {
/**
* Handles reset of the error boundary when a navigation happens.
* Ensures the error boundary does not stay enabled when navigating to a new page.
* Approach of setState in render is safe as it checks the previous pathname and then overrides
* it as outlined in https://react.dev/reference/react/useState#storing-information-from-previous-renders
*/ if (props.pathname !== state.previousPathname && state.triggeredStatus) {
return {
triggeredStatus: undefined,
previousPathname: props.pathname
};
}
return {
triggeredStatus: state.triggeredStatus,
previousPathname: props.pathname
};
}
render() {
const { notFound, forbidden, unauthorized, children } = this.props;
const { triggeredStatus } = this.state;
const errorComponents = {
[_httpaccessfallback.HTTPAccessErrorStatus.NOT_FOUND]: notFound,
[_httpaccessfallback.HTTPAccessErrorStatus.FORBIDDEN]: forbidden,
[_httpaccessfallback.HTTPAccessErrorStatus.UNAUTHORIZED]: unauthorized
};
if (triggeredStatus) {
const isNotFound = triggeredStatus === _httpaccessfallback.HTTPAccessErrorStatus.NOT_FOUND && notFound;
const isForbidden = triggeredStatus === _httpaccessfallback.HTTPAccessErrorStatus.FORBIDDEN && forbidden;
const isUnauthorized = triggeredStatus === _httpaccessfallback.HTTPAccessErrorStatus.UNAUTHORIZED && unauthorized;
// If there's no matched boundary in this layer, keep throwing the error by rendering the children
if (!(isNotFound || isForbidden || isUnauthorized)) {
return children;
}
return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_jsxruntime.Fragment, {
children: [
/*#__PURE__*/ (0, _jsxruntime.jsx)("meta", {
name: "robots",
content: "noindex"
}),
process.env.NODE_ENV === 'development' && /*#__PURE__*/ (0, _jsxruntime.jsx)("meta", {
name: "boundary-next-error",
content: (0, _httpaccessfallback.getAccessFallbackErrorTypeByStatus)(triggeredStatus)
}),
errorComponents[triggeredStatus]
]
});
}
return children;
}
}
function HTTPAccessFallbackBoundary({ notFound, forbidden, unauthorized, children }) {
// When we're rendering the missing params shell, this will return null. This
// is because we won't be rendering any not found boundaries or error
// boundaries for the missing params shell. When this runs on the client
// (where these error can occur), we will get the correct pathname.
const pathname = (0, _navigationuntracked.useUntrackedPathname)();
const missingSlots = (0, _react.useContext)(_approutercontextsharedruntime.MissingSlotContext);
const hasErrorFallback = !!(notFound || forbidden || unauthorized);
if (hasErrorFallback) {
return /*#__PURE__*/ (0, _jsxruntime.jsx)(HTTPAccessFallbackErrorBoundary, {
pathname: pathname,
notFound: notFound,
forbidden: forbidden,
unauthorized: unauthorized,
missingSlots: missingSlots,
children: children
});
}
return /*#__PURE__*/ (0, _jsxruntime.jsx)(_jsxruntime.Fragment, {
children: children
});
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=error-boundary.js.map

View File

@@ -0,0 +1,72 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
HTTPAccessErrorStatus: null,
HTTP_ERROR_FALLBACK_ERROR_CODE: null,
getAccessFallbackErrorTypeByStatus: null,
getAccessFallbackHTTPStatus: null,
isHTTPAccessFallbackError: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
HTTPAccessErrorStatus: function() {
return HTTPAccessErrorStatus;
},
HTTP_ERROR_FALLBACK_ERROR_CODE: function() {
return HTTP_ERROR_FALLBACK_ERROR_CODE;
},
getAccessFallbackErrorTypeByStatus: function() {
return getAccessFallbackErrorTypeByStatus;
},
getAccessFallbackHTTPStatus: function() {
return getAccessFallbackHTTPStatus;
},
isHTTPAccessFallbackError: function() {
return isHTTPAccessFallbackError;
}
});
const HTTPAccessErrorStatus = {
NOT_FOUND: 404,
FORBIDDEN: 403,
UNAUTHORIZED: 401
};
const ALLOWED_CODES = new Set(Object.values(HTTPAccessErrorStatus));
const HTTP_ERROR_FALLBACK_ERROR_CODE = 'NEXT_HTTP_ERROR_FALLBACK';
function isHTTPAccessFallbackError(error) {
if (typeof error !== 'object' || error === null || !('digest' in error) || typeof error.digest !== 'string') {
return false;
}
const [prefix, httpStatus] = error.digest.split(';');
return prefix === HTTP_ERROR_FALLBACK_ERROR_CODE && ALLOWED_CODES.has(Number(httpStatus));
}
function getAccessFallbackHTTPStatus(error) {
const httpStatus = error.digest.split(';')[1];
return Number(httpStatus);
}
function getAccessFallbackErrorTypeByStatus(status) {
switch(status){
case 401:
return 'unauthorized';
case 403:
return 'forbidden';
case 404:
return 'not-found';
default:
return;
}
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=http-access-fallback.js.map

View File

@@ -0,0 +1,23 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "isNextRouterError", {
enumerable: true,
get: function() {
return isNextRouterError;
}
});
const _httpaccessfallback = require("./http-access-fallback/http-access-fallback");
const _redirecterror = require("./redirect-error");
function isNextRouterError(error) {
return (0, _redirecterror.isRedirectError)(error) || (0, _httpaccessfallback.isHTTPAccessFallbackError)(error);
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=is-next-router-error.js.map

299
build/node_modules/next/dist/client/components/links.js generated vendored Normal file
View File

@@ -0,0 +1,299 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
IDLE_LINK_STATUS: null,
PENDING_LINK_STATUS: null,
getLinkForCurrentNavigation: null,
mountFormInstance: null,
mountLinkInstance: null,
onLinkVisibilityChanged: null,
onNavigationIntent: null,
pingVisibleLinks: null,
setLinkForCurrentNavigation: null,
unmountLinkForCurrentNavigation: null,
unmountPrefetchableInstance: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
IDLE_LINK_STATUS: function() {
return IDLE_LINK_STATUS;
},
PENDING_LINK_STATUS: function() {
return PENDING_LINK_STATUS;
},
getLinkForCurrentNavigation: function() {
return getLinkForCurrentNavigation;
},
mountFormInstance: function() {
return mountFormInstance;
},
mountLinkInstance: function() {
return mountLinkInstance;
},
onLinkVisibilityChanged: function() {
return onLinkVisibilityChanged;
},
onNavigationIntent: function() {
return onNavigationIntent;
},
pingVisibleLinks: function() {
return pingVisibleLinks;
},
setLinkForCurrentNavigation: function() {
return setLinkForCurrentNavigation;
},
unmountLinkForCurrentNavigation: function() {
return unmountLinkForCurrentNavigation;
},
unmountPrefetchableInstance: function() {
return unmountPrefetchableInstance;
}
});
const _types = require("./segment-cache/types");
const _cachekey = require("./segment-cache/cache-key");
const _scheduler = require("./segment-cache/scheduler");
const _react = require("react");
// Tracks the most recently navigated link instance. When null, indicates
// the current navigation was not initiated by a link click.
let linkForMostRecentNavigation = null;
const PENDING_LINK_STATUS = {
pending: true
};
const IDLE_LINK_STATUS = {
pending: false
};
function setLinkForCurrentNavigation(link) {
(0, _react.startTransition)(()=>{
linkForMostRecentNavigation?.setOptimisticLinkStatus(IDLE_LINK_STATUS);
link?.setOptimisticLinkStatus(PENDING_LINK_STATUS);
linkForMostRecentNavigation = link;
});
}
function unmountLinkForCurrentNavigation(link) {
if (linkForMostRecentNavigation === link) {
linkForMostRecentNavigation = null;
}
}
function getLinkForCurrentNavigation() {
return linkForMostRecentNavigation;
}
// Use a WeakMap to associate a Link instance with its DOM element. This is
// used by the IntersectionObserver to track the link's visibility.
const prefetchable = typeof WeakMap === 'function' ? new WeakMap() : new Map();
// A Set of the currently visible links. We re-prefetch visible links after a
// cache invalidation, or when the current URL changes. It's a separate data
// structure from the WeakMap above because only the visible links need to
// be enumerated.
const prefetchableAndVisible = new Set();
// A single IntersectionObserver instance shared by all <Link> components.
const observer = typeof IntersectionObserver === 'function' ? new IntersectionObserver(handleIntersect, {
rootMargin: '200px'
}) : null;
function observeVisibility(element, instance) {
const existingInstance = prefetchable.get(element);
if (existingInstance !== undefined) {
// This shouldn't happen because each <Link> component should have its own
// anchor tag instance, but it's defensive coding to avoid a memory leak in
// case there's a logical error somewhere else.
unmountPrefetchableInstance(element);
}
// Only track prefetchable links that have a valid prefetch URL
prefetchable.set(element, instance);
if (observer !== null) {
observer.observe(element);
}
}
function coercePrefetchableUrl(href) {
if (typeof window !== 'undefined') {
const { createPrefetchURL } = require('./app-router-utils');
try {
return createPrefetchURL(href);
} catch {
// createPrefetchURL sometimes throws an error if an invalid URL is
// provided, though I'm not sure if it's actually necessary.
// TODO: Consider removing the throw from the inner function, or change it
// to reportError. Or maybe the error isn't even necessary for automatic
// prefetches, just navigations.
const reportErrorFn = typeof reportError === 'function' ? reportError : console.error;
reportErrorFn(`Cannot prefetch '${href}' because it cannot be converted to a URL.`);
return null;
}
} else {
return null;
}
}
function mountLinkInstance(element, href, router, fetchStrategy, prefetchEnabled, setOptimisticLinkStatus) {
if (prefetchEnabled) {
const prefetchURL = coercePrefetchableUrl(href);
if (prefetchURL !== null) {
const instance = {
router,
fetchStrategy,
isVisible: false,
prefetchTask: null,
prefetchHref: prefetchURL.href,
setOptimisticLinkStatus
};
// We only observe the link's visibility if it's prefetchable. For
// example, this excludes links to external URLs.
observeVisibility(element, instance);
return instance;
}
}
// If the link is not prefetchable, we still create an instance so we can
// track its optimistic state (i.e. useLinkStatus).
const instance = {
router,
fetchStrategy,
isVisible: false,
prefetchTask: null,
prefetchHref: null,
setOptimisticLinkStatus
};
return instance;
}
function mountFormInstance(element, href, router, fetchStrategy) {
const prefetchURL = coercePrefetchableUrl(href);
if (prefetchURL === null) {
// This href is not prefetchable, so we don't track it.
// TODO: We currently observe/unobserve a form every time its href changes.
// For Links, this isn't a big deal because the href doesn't usually change,
// but for forms it's extremely common. We should optimize this.
return;
}
const instance = {
router,
fetchStrategy,
isVisible: false,
prefetchTask: null,
prefetchHref: prefetchURL.href,
setOptimisticLinkStatus: null
};
observeVisibility(element, instance);
}
function unmountPrefetchableInstance(element) {
const instance = prefetchable.get(element);
if (instance !== undefined) {
prefetchable.delete(element);
prefetchableAndVisible.delete(instance);
const prefetchTask = instance.prefetchTask;
if (prefetchTask !== null) {
(0, _scheduler.cancelPrefetchTask)(prefetchTask);
}
}
if (observer !== null) {
observer.unobserve(element);
}
}
function handleIntersect(entries) {
for (const entry of entries){
// Some extremely old browsers or polyfills don't reliably support
// isIntersecting so we check intersectionRatio instead. (Do we care? Not
// really. But whatever this is fine.)
const isVisible = entry.intersectionRatio > 0;
onLinkVisibilityChanged(entry.target, isVisible);
}
}
function onLinkVisibilityChanged(element, isVisible) {
if (process.env.NODE_ENV !== 'production') {
// Prefetching on viewport is disabled in development for performance
// reasons, because it requires compiling the target page.
// TODO: Investigate re-enabling this.
return;
}
const instance = prefetchable.get(element);
if (instance === undefined) {
return;
}
instance.isVisible = isVisible;
if (isVisible) {
prefetchableAndVisible.add(instance);
} else {
prefetchableAndVisible.delete(instance);
}
rescheduleLinkPrefetch(instance, _types.PrefetchPriority.Default);
}
function onNavigationIntent(element, unstable_upgradeToDynamicPrefetch) {
const instance = prefetchable.get(element);
if (instance === undefined) {
return;
}
// Prefetch the link on hover/touchstart.
if (instance !== undefined) {
if (process.env.__NEXT_DYNAMIC_ON_HOVER && unstable_upgradeToDynamicPrefetch) {
// Switch to a full prefetch
instance.fetchStrategy = _types.FetchStrategy.Full;
}
rescheduleLinkPrefetch(instance, _types.PrefetchPriority.Intent);
}
}
function rescheduleLinkPrefetch(instance, priority) {
// Ensures that app-router-instance is not compiled in the server bundle
if (typeof window !== 'undefined') {
const existingPrefetchTask = instance.prefetchTask;
if (!instance.isVisible) {
// Cancel any in-progress prefetch task. (If it already finished then this
// is a no-op.)
if (existingPrefetchTask !== null) {
(0, _scheduler.cancelPrefetchTask)(existingPrefetchTask);
}
// We don't need to reset the prefetchTask to null upon cancellation; an
// old task object can be rescheduled with reschedulePrefetchTask. This is a
// micro-optimization but also makes the code simpler (don't need to
// worry about whether an old task object is stale).
return;
}
const { getCurrentAppRouterState } = require('./app-router-instance');
const appRouterState = getCurrentAppRouterState();
if (appRouterState !== null) {
const treeAtTimeOfPrefetch = appRouterState.tree;
if (existingPrefetchTask === null) {
// Initiate a prefetch task.
const nextUrl = appRouterState.nextUrl;
const cacheKey = (0, _cachekey.createCacheKey)(instance.prefetchHref, nextUrl);
instance.prefetchTask = (0, _scheduler.schedulePrefetchTask)(cacheKey, treeAtTimeOfPrefetch, instance.fetchStrategy, priority, null);
} else {
// We already have an old task object that we can reschedule. This is
// effectively the same as canceling the old task and creating a new one.
(0, _scheduler.reschedulePrefetchTask)(existingPrefetchTask, treeAtTimeOfPrefetch, instance.fetchStrategy, priority);
}
}
}
}
function pingVisibleLinks(nextUrl, tree) {
// For each currently visible link, cancel the existing prefetch task (if it
// exists) and schedule a new one. This is effectively the same as if all the
// visible links left and then re-entered the viewport.
//
// This is called when the Next-Url or the base tree changes, since those
// may affect the result of a prefetch task. It's also called after a
// cache invalidation.
for (const instance of prefetchableAndVisible){
const task = instance.prefetchTask;
if (task !== null && !(0, _scheduler.isPrefetchTaskDirty)(task, nextUrl, tree)) {
continue;
}
// Something changed. Cancel the existing prefetch task and schedule a
// new one.
if (task !== null) {
(0, _scheduler.cancelPrefetchTask)(task);
}
const cacheKey = (0, _cachekey.createCacheKey)(instance.prefetchHref, nextUrl);
instance.prefetchTask = (0, _scheduler.schedulePrefetchTask)(cacheKey, tree, instance.fetchStrategy, _types.PrefetchPriority.Default, null);
}
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=links.js.map

View File

@@ -0,0 +1,32 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "matchSegment", {
enumerable: true,
get: function() {
return matchSegment;
}
});
const matchSegment = (existingSegment, segment)=>{
// segment is either Array or string
if (typeof existingSegment === 'string') {
if (typeof segment === 'string') {
// Common case: segment is just a string
return existingSegment === segment;
}
return false;
}
if (typeof segment === 'string') {
return false;
}
return existingSegment[0] === segment[0] && existingSegment[1] === segment[1];
};
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=match-segments.js.map

View File

@@ -0,0 +1,61 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
handleHardNavError: null,
useNavFailureHandler: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
handleHardNavError: function() {
return handleHardNavError;
},
useNavFailureHandler: function() {
return useNavFailureHandler;
}
});
const _react = require("react");
const _createhreffromurl = require("./router-reducer/create-href-from-url");
function handleHardNavError(error) {
if (error && typeof window !== 'undefined' && window.next.__pendingUrl && (0, _createhreffromurl.createHrefFromUrl)(new URL(window.location.href)) !== (0, _createhreffromurl.createHrefFromUrl)(window.next.__pendingUrl)) {
console.error(`Error occurred during navigation, falling back to hard navigation`, error);
window.location.href = window.next.__pendingUrl.toString();
return true;
}
return false;
}
function useNavFailureHandler() {
if (process.env.__NEXT_APP_NAV_FAIL_HANDLING) {
// this if is only for DCE of the feature flag not conditional
// eslint-disable-next-line react-hooks/rules-of-hooks
(0, _react.useEffect)(()=>{
const uncaughtExceptionHandler = (evt)=>{
const error = 'reason' in evt ? evt.reason : evt.error;
// if we have an unhandled exception/rejection during
// a navigation we fall back to a hard navigation to
// attempt recovering to a good state
handleHardNavError(error);
};
window.addEventListener('unhandledrejection', uncaughtExceptionHandler);
window.addEventListener('error', uncaughtExceptionHandler);
return ()=>{
window.removeEventListener('error', uncaughtExceptionHandler);
window.removeEventListener('unhandledrejection', uncaughtExceptionHandler);
};
}, []);
}
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=nav-failure-handler.js.map

View File

@@ -0,0 +1,126 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
createNestedLayoutNavigationPromises: null,
createRootNavigationPromises: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
createNestedLayoutNavigationPromises: function() {
return createNestedLayoutNavigationPromises;
},
createRootNavigationPromises: function() {
return createRootNavigationPromises;
}
});
const _hooksclientcontextsharedruntime = require("../../shared/lib/hooks-client-context.shared-runtime");
const _segment = require("../../shared/lib/segment");
const layoutSegmentPromisesCache = new WeakMap();
/**
* Creates instrumented promises for layout segment hooks at a given tree level.
* This is dev-only code for React Suspense DevTools instrumentation.
*/ function createLayoutSegmentPromises(tree) {
if (process.env.NODE_ENV === 'production') {
return null;
}
// Check if we already have cached promises for this tree
const cached = layoutSegmentPromisesCache.get(tree);
if (cached) {
return cached;
}
// Create new promises and cache them
const segmentPromises = new Map();
const segmentsPromises = new Map();
const parallelRoutes = tree[1];
for (const parallelRouteKey of Object.keys(parallelRoutes)){
const segments = (0, _segment.getSelectedLayoutSegmentPath)(tree, parallelRouteKey);
// Use the shared logic to compute the segment value
const segment = (0, _segment.computeSelectedLayoutSegment)(segments, parallelRouteKey);
segmentPromises.set(parallelRouteKey, (0, _hooksclientcontextsharedruntime.createDevToolsInstrumentedPromise)('useSelectedLayoutSegment', segment));
segmentsPromises.set(parallelRouteKey, (0, _hooksclientcontextsharedruntime.createDevToolsInstrumentedPromise)('useSelectedLayoutSegments', segments));
}
const result = {
selectedLayoutSegmentPromises: segmentPromises,
selectedLayoutSegmentsPromises: segmentsPromises
};
// Cache the result for future renders
layoutSegmentPromisesCache.set(tree, result);
return result;
}
const rootNavigationPromisesCache = new WeakMap();
function createRootNavigationPromises(tree, pathname, searchParams, pathParams) {
if (process.env.NODE_ENV === 'production') {
return null;
}
// Create stable cache keys from the values
const searchParamsString = searchParams.toString();
const pathParamsString = JSON.stringify(pathParams);
const cacheKey = `${pathname}:${searchParamsString}:${pathParamsString}`;
// Get or create the cache for this tree
let treeCache = rootNavigationPromisesCache.get(tree);
if (!treeCache) {
treeCache = new Map();
rootNavigationPromisesCache.set(tree, treeCache);
}
// Check if we have cached promises for this combination
const cached = treeCache.get(cacheKey);
if (cached) {
return cached;
}
const readonlySearchParams = new _hooksclientcontextsharedruntime.ReadonlyURLSearchParams(searchParams);
const layoutSegmentPromises = createLayoutSegmentPromises(tree);
const promises = {
pathname: (0, _hooksclientcontextsharedruntime.createDevToolsInstrumentedPromise)('usePathname', pathname),
searchParams: (0, _hooksclientcontextsharedruntime.createDevToolsInstrumentedPromise)('useSearchParams', readonlySearchParams),
params: (0, _hooksclientcontextsharedruntime.createDevToolsInstrumentedPromise)('useParams', pathParams),
...layoutSegmentPromises
};
treeCache.set(cacheKey, promises);
return promises;
}
const nestedLayoutPromisesCache = new WeakMap();
function createNestedLayoutNavigationPromises(tree, parentNavPromises) {
if (process.env.NODE_ENV === 'production') {
return null;
}
const parallelRoutes = tree[1];
const parallelRouteKeys = Object.keys(parallelRoutes);
// Only create promises if there are parallel routes at this level
if (parallelRouteKeys.length === 0) {
return null;
}
// Get or create the cache for this tree
let treeCache = nestedLayoutPromisesCache.get(tree);
if (!treeCache) {
treeCache = new Map();
nestedLayoutPromisesCache.set(tree, treeCache);
}
// Check if we have cached promises for this parent combination
const cached = treeCache.get(parentNavPromises);
if (cached) {
return cached;
}
// Create merged promises
const layoutSegmentPromises = createLayoutSegmentPromises(tree);
const promises = {
...parentNavPromises,
...layoutSegmentPromises
};
treeCache.set(parentNavPromises, promises);
return promises;
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=navigation-devtools.js.map

View File

@@ -0,0 +1,67 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "useUntrackedPathname", {
enumerable: true,
get: function() {
return useUntrackedPathname;
}
});
const _react = require("react");
const _hooksclientcontextsharedruntime = require("../../shared/lib/hooks-client-context.shared-runtime");
/**
* This checks to see if the current render has any unknown route parameters that
* would cause the pathname to be dynamic. It's used to trigger a different
* render path in the error boundary.
*
* @returns true if there are any unknown route parameters, false otherwise
*/ function hasFallbackRouteParams() {
if (typeof window === 'undefined') {
// AsyncLocalStorage should not be included in the client bundle.
const { workUnitAsyncStorage } = require('../../server/app-render/work-unit-async-storage.external');
const workUnitStore = workUnitAsyncStorage.getStore();
if (!workUnitStore) return false;
switch(workUnitStore.type){
case 'prerender':
case 'prerender-client':
case 'prerender-ppr':
case 'validation-client':
const fallbackParams = workUnitStore.fallbackRouteParams;
return fallbackParams ? fallbackParams.size > 0 : false;
case 'prerender-legacy':
case 'request':
case 'prerender-runtime':
case 'cache':
case 'private-cache':
case 'unstable-cache':
case 'generate-static-params':
break;
default:
workUnitStore;
}
return false;
}
return false;
}
function useUntrackedPathname() {
// If there are any unknown route parameters we would typically throw
// an error, but this internal method allows us to return a null value instead
// for components that do not propagate the pathname to the static shell (like
// the error boundary).
if (hasFallbackRouteParams()) {
return null;
}
// This shouldn't cause any issues related to conditional rendering because
// the environment will be consistent for the render.
// eslint-disable-next-line react-hooks/rules-of-hooks
return (0, _react.useContext)(_hooksclientcontextsharedruntime.PathnameContext);
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=navigation-untracked.js.map

View File

@@ -0,0 +1,225 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
ReadonlyURLSearchParams: null,
RedirectType: null,
ServerInsertedHTMLContext: null,
forbidden: null,
notFound: null,
permanentRedirect: null,
redirect: null,
unauthorized: null,
unstable_isUnrecognizedActionError: null,
unstable_rethrow: null,
useParams: null,
usePathname: null,
useRouter: null,
useSearchParams: null,
useSelectedLayoutSegment: null,
useSelectedLayoutSegments: null,
useServerInsertedHTML: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
// We need the same class that was used to instantiate the context value
// Otherwise instanceof checks will fail in usercode
ReadonlyURLSearchParams: function() {
return _hooksclientcontextsharedruntime.ReadonlyURLSearchParams;
},
RedirectType: function() {
return _navigationreactserver.RedirectType;
},
ServerInsertedHTMLContext: function() {
return _serverinsertedhtmlsharedruntime.ServerInsertedHTMLContext;
},
forbidden: function() {
return _navigationreactserver.forbidden;
},
notFound: function() {
return _navigationreactserver.notFound;
},
permanentRedirect: function() {
return _navigationreactserver.permanentRedirect;
},
redirect: function() {
return _navigationreactserver.redirect;
},
unauthorized: function() {
return _navigationreactserver.unauthorized;
},
unstable_isUnrecognizedActionError: function() {
return _unrecognizedactionerror.unstable_isUnrecognizedActionError;
},
unstable_rethrow: function() {
return _navigationreactserver.unstable_rethrow;
},
useParams: function() {
return useParams;
},
usePathname: function() {
return usePathname;
},
useRouter: function() {
return useRouter;
},
useSearchParams: function() {
return useSearchParams;
},
useSelectedLayoutSegment: function() {
return useSelectedLayoutSegment;
},
useSelectedLayoutSegments: function() {
return useSelectedLayoutSegments;
},
useServerInsertedHTML: function() {
return _serverinsertedhtmlsharedruntime.useServerInsertedHTML;
}
});
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
const _approutercontextsharedruntime = require("../../shared/lib/app-router-context.shared-runtime");
const _hooksclientcontextsharedruntime = require("../../shared/lib/hooks-client-context.shared-runtime");
const _segment = require("../../shared/lib/segment");
const _serverinsertedhtmlsharedruntime = require("../../shared/lib/server-inserted-html.shared-runtime");
const _unrecognizedactionerror = require("./unrecognized-action-error");
const _navigationreactserver = require("./navigation.react-server");
const useDynamicRouteParams = typeof window === 'undefined' ? require('../../server/app-render/dynamic-rendering').useDynamicRouteParams : undefined;
const useDynamicSearchParams = typeof window === 'undefined' ? require('../../server/app-render/dynamic-rendering').useDynamicSearchParams : undefined;
const { instrumentParamsForClientValidation, instrumentSearchParamsForClientValidation, expectCompleteParamsInClientValidation } = typeof window === 'undefined' && process.env.__NEXT_CACHE_COMPONENTS ? require('../../server/app-render/instant-validation/instant-samples-client') : {};
function useSearchParams() {
useDynamicSearchParams?.('useSearchParams()');
const searchParams = (0, _react.useContext)(_hooksclientcontextsharedruntime.SearchParamsContext);
// In the case where this is `null`, the compat types added in
// `next-env.d.ts` will add a new overload that changes the return type to
// include `null`.
const readonlySearchParams = (0, _react.useMemo)(()=>{
if (!searchParams) {
// When the router is not ready in pages, we won't have the search params
// available.
return null;
}
return new _hooksclientcontextsharedruntime.ReadonlyURLSearchParams(searchParams);
}, [
searchParams
]);
// During build-time instant validation, wrap with an proxy
// so that accessing undeclared search params throws an error.
if (typeof window === 'undefined' && process.env.__NEXT_CACHE_COMPONENTS && readonlySearchParams) {
return instrumentSearchParamsForClientValidation(readonlySearchParams);
}
// Instrument with Suspense DevTools (dev-only)
if (process.env.NODE_ENV !== 'production' && 'use' in _react.default) {
const navigationPromises = (0, _react.use)(_hooksclientcontextsharedruntime.NavigationPromisesContext);
if (navigationPromises) {
return (0, _react.use)(navigationPromises.searchParams);
}
}
return readonlySearchParams;
}
function usePathname() {
useDynamicRouteParams?.('usePathname()');
// In the case where this is `null`, the compat types added in `next-env.d.ts`
// will add a new overload that changes the return type to include `null`.
const pathname = (0, _react.useContext)(_hooksclientcontextsharedruntime.PathnameContext);
// During build-time instant validation, error if fallback params exist
// because usePathname() can't return a sensible value without all params.
if (typeof window === 'undefined' && process.env.__NEXT_CACHE_COMPONENTS && pathname) {
expectCompleteParamsInClientValidation('usePathname()');
return pathname;
}
// Instrument with Suspense DevTools (dev-only)
if (process.env.NODE_ENV !== 'production' && 'use' in _react.default) {
const navigationPromises = (0, _react.use)(_hooksclientcontextsharedruntime.NavigationPromisesContext);
if (navigationPromises) {
return (0, _react.use)(navigationPromises.pathname);
}
}
return pathname;
}
function useRouter() {
const router = (0, _react.useContext)(_approutercontextsharedruntime.AppRouterContext);
if (router === null) {
throw Object.defineProperty(new Error('invariant expected app router to be mounted'), "__NEXT_ERROR_CODE", {
value: "E238",
enumerable: false,
configurable: true
});
}
return router;
}
function useParams() {
useDynamicRouteParams?.('useParams()');
const params = (0, _react.useContext)(_hooksclientcontextsharedruntime.PathParamsContext);
// During build-time instant validation, wrap with a proxy
// so that accessing undeclared params throws an error.
if (typeof window === 'undefined' && process.env.__NEXT_CACHE_COMPONENTS && params) {
return instrumentParamsForClientValidation(params);
}
// Instrument with Suspense DevTools (dev-only)
if (process.env.NODE_ENV !== 'production' && 'use' in _react.default) {
const navigationPromises = (0, _react.use)(_hooksclientcontextsharedruntime.NavigationPromisesContext);
if (navigationPromises) {
return (0, _react.use)(navigationPromises.params);
}
}
return params;
}
function useSelectedLayoutSegments(parallelRouteKey = 'children') {
useDynamicRouteParams?.('useSelectedLayoutSegments()');
const context = (0, _react.useContext)(_approutercontextsharedruntime.LayoutRouterContext);
// @ts-expect-error This only happens in `pages`. Type is overwritten in navigation.d.ts
if (!context) return null;
// During build-time instant validation, error if fallback params exist
// because useSelectedLayoutSegments() can't return a sensible value without all params.
if (typeof window === 'undefined' && process.env.__NEXT_CACHE_COMPONENTS && context) {
expectCompleteParamsInClientValidation('useSelectedLayoutSegments()');
}
// Instrument with Suspense DevTools (dev-only)
if (process.env.NODE_ENV !== 'production' && 'use' in _react.default) {
const navigationPromises = (0, _react.use)(_hooksclientcontextsharedruntime.NavigationPromisesContext);
if (navigationPromises) {
const promise = navigationPromises.selectedLayoutSegmentsPromises?.get(parallelRouteKey);
if (promise) {
// We should always have a promise here, but if we don't, it's not worth erroring over.
// We just won't be able to instrument it, but can still provide the value.
return (0, _react.use)(promise);
}
}
}
return (0, _segment.getSelectedLayoutSegmentPath)(context.parentTree, parallelRouteKey);
}
function useSelectedLayoutSegment(parallelRouteKey = 'children') {
useDynamicRouteParams?.('useSelectedLayoutSegment()');
const navigationPromises = (0, _react.useContext)(_hooksclientcontextsharedruntime.NavigationPromisesContext);
const selectedLayoutSegments = useSelectedLayoutSegments(parallelRouteKey);
// During build-time instant validation, error if fallback params exist
// because useSelectedLayoutSegment() can't return a sensible value without all params.
if (typeof window === 'undefined' && process.env.__NEXT_CACHE_COMPONENTS) {
expectCompleteParamsInClientValidation('useSelectedLayoutSegment()');
}
// Instrument with Suspense DevTools (dev-only)
if (process.env.NODE_ENV !== 'production' && navigationPromises && 'use' in _react.default) {
const promise = navigationPromises.selectedLayoutSegmentPromises?.get(parallelRouteKey);
if (promise) {
// We should always have a promise here, but if we don't, it's not worth erroring over.
// We just won't be able to instrument it, but can still provide the value.
return (0, _react.use)(promise);
}
}
return (0, _segment.computeSelectedLayoutSegment)(selectedLayoutSegments, parallelRouteKey);
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=navigation.js.map

View File

@@ -0,0 +1,75 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
ReadonlyURLSearchParams: null,
RedirectType: null,
forbidden: null,
notFound: null,
permanentRedirect: null,
redirect: null,
unauthorized: null,
unstable_isUnrecognizedActionError: null,
unstable_rethrow: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
ReadonlyURLSearchParams: function() {
return _readonlyurlsearchparams.ReadonlyURLSearchParams;
},
RedirectType: function() {
return RedirectType;
},
forbidden: function() {
return _forbidden.forbidden;
},
notFound: function() {
return _notfound.notFound;
},
permanentRedirect: function() {
return _redirect.permanentRedirect;
},
redirect: function() {
return _redirect.redirect;
},
unauthorized: function() {
return _unauthorized.unauthorized;
},
unstable_isUnrecognizedActionError: function() {
return unstable_isUnrecognizedActionError;
},
unstable_rethrow: function() {
return _unstablerethrow.unstable_rethrow;
}
});
const _readonlyurlsearchparams = require("./readonly-url-search-params");
const _redirect = require("./redirect");
const _notfound = require("./not-found");
const _forbidden = require("./forbidden");
const _unauthorized = require("./unauthorized");
const _unstablerethrow = require("./unstable-rethrow");
function unstable_isUnrecognizedActionError() {
throw Object.defineProperty(new Error('`unstable_isUnrecognizedActionError` can only be used on the client.'), "__NEXT_ERROR_CODE", {
value: "E776",
enumerable: false,
configurable: true
});
}
const RedirectType = {
push: 'push',
replace: 'replace'
};
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=navigation.react-server.js.map

View File

@@ -0,0 +1,42 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "notFound", {
enumerable: true,
get: function() {
return notFound;
}
});
const _httpaccessfallback = require("./http-access-fallback/http-access-fallback");
/**
* This function allows you to render the [not-found.js file](https://nextjs.org/docs/app/api-reference/file-conventions/not-found)
* within a route segment as well as inject a tag.
*
* `notFound()` can be used in
* [Server Components](https://nextjs.org/docs/app/building-your-application/rendering/server-components),
* [Route Handlers](https://nextjs.org/docs/app/building-your-application/routing/route-handlers), and
* [Server Actions](https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations).
*
* - In a Server Component, this will insert a `<meta name="robots" content="noindex" />` meta tag and set the status code to 404.
* - In a Route Handler or Server Action, it will serve a 404 to the caller.
*
* Read more: [Next.js Docs: `notFound`](https://nextjs.org/docs/app/api-reference/functions/not-found)
*/ const DIGEST = `${_httpaccessfallback.HTTP_ERROR_FALLBACK_ERROR_CODE};404`;
function notFound() {
const error = Object.defineProperty(new Error(DIGEST), "__NEXT_ERROR_CODE", {
value: "E1041",
enumerable: false,
configurable: true
});
error.digest = DIGEST;
throw error;
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=not-found.js.map

View File

@@ -0,0 +1,41 @@
/**
* ReadonlyURLSearchParams implementation shared between client and server.
* This file is intentionally not marked as 'use client' or 'use server'
* so it can be imported by both environments.
*/ /** @internal */ "use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "ReadonlyURLSearchParams", {
enumerable: true,
get: function() {
return ReadonlyURLSearchParams;
}
});
class ReadonlyURLSearchParamsError extends Error {
constructor(){
super('Method unavailable on `ReadonlyURLSearchParams`. Read more: https://nextjs.org/docs/app/api-reference/functions/use-search-params#updating-searchparams');
}
}
class ReadonlyURLSearchParams extends URLSearchParams {
/** @deprecated Method unavailable on `ReadonlyURLSearchParams`. Read more: https://nextjs.org/docs/app/api-reference/functions/use-search-params#updating-searchparams */ append() {
throw new ReadonlyURLSearchParamsError();
}
/** @deprecated Method unavailable on `ReadonlyURLSearchParams`. Read more: https://nextjs.org/docs/app/api-reference/functions/use-search-params#updating-searchparams */ delete() {
throw new ReadonlyURLSearchParamsError();
}
/** @deprecated Method unavailable on `ReadonlyURLSearchParams`. Read more: https://nextjs.org/docs/app/api-reference/functions/use-search-params#updating-searchparams */ set() {
throw new ReadonlyURLSearchParamsError();
}
/** @deprecated Method unavailable on `ReadonlyURLSearchParams`. Read more: https://nextjs.org/docs/app/api-reference/functions/use-search-params#updating-searchparams */ sort() {
throw new ReadonlyURLSearchParamsError();
}
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=readonly-url-search-params.js.map

View File

@@ -0,0 +1,107 @@
'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
RedirectBoundary: null,
RedirectErrorBoundary: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
RedirectBoundary: function() {
return RedirectBoundary;
},
RedirectErrorBoundary: function() {
return RedirectErrorBoundary;
}
});
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
const _jsxruntime = require("react/jsx-runtime");
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
const _navigation = require("./navigation");
const _redirect = require("./redirect");
const _redirecterror = require("./redirect-error");
function HandleRedirect({ redirect, reset, redirectType }) {
const router = (0, _navigation.useRouter)();
(0, _react.useEffect)(()=>{
_react.default.startTransition(()=>{
if (redirectType === 'push') {
router.push(redirect, {});
} else {
router.replace(redirect, {});
}
reset();
});
}, [
redirect,
redirectType,
reset,
router
]);
return null;
}
class RedirectErrorBoundary extends _react.default.Component {
constructor(props){
super(props);
this.state = {
redirect: null,
redirectType: null
};
}
static getDerivedStateFromError(error) {
if ((0, _redirecterror.isRedirectError)(error)) {
const url = (0, _redirect.getURLFromRedirectError)(error);
const redirectType = (0, _redirect.getRedirectTypeFromError)(error);
if ('handled' in error) {
// The redirect was already handled. We'll still catch the redirect error
// so that we can remount the subtree, but we don't actually need to trigger the
// router.push.
return {
redirect: null,
redirectType: null
};
}
return {
redirect: url,
redirectType
};
}
// Re-throw if error is not for redirect
throw error;
}
// Explicit type is needed to avoid the generated `.d.ts` having a wide return type that could be specific to the `@types/react` version.
render() {
const { redirect, redirectType } = this.state;
if (redirect !== null && redirectType !== null) {
return /*#__PURE__*/ (0, _jsxruntime.jsx)(HandleRedirect, {
redirect: redirect,
redirectType: redirectType,
reset: ()=>this.setState({
redirect: null
})
});
}
return this.props.children;
}
}
function RedirectBoundary({ children }) {
const router = (0, _navigation.useRouter)();
return /*#__PURE__*/ (0, _jsxruntime.jsx)(RedirectErrorBoundary, {
router: router,
children: children
});
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=redirect-boundary.js.map

View File

@@ -0,0 +1,43 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
REDIRECT_ERROR_CODE: null,
isRedirectError: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
REDIRECT_ERROR_CODE: function() {
return REDIRECT_ERROR_CODE;
},
isRedirectError: function() {
return isRedirectError;
}
});
const _redirectstatuscode = require("./redirect-status-code");
const REDIRECT_ERROR_CODE = 'NEXT_REDIRECT';
function isRedirectError(error) {
if (typeof error !== 'object' || error === null || !('digest' in error) || typeof error.digest !== 'string') {
return false;
}
const digest = error.digest.split(';');
const [errorCode, type] = digest;
const destination = digest.slice(2, -2).join(';');
const status = digest.at(-2);
const statusCode = Number(status);
return errorCode === REDIRECT_ERROR_CODE && (type === 'replace' || type === 'push') && typeof destination === 'string' && !isNaN(statusCode) && statusCode in _redirectstatuscode.RedirectStatusCode;
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=redirect-error.js.map

View File

@@ -0,0 +1,24 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "RedirectStatusCode", {
enumerable: true,
get: function() {
return RedirectStatusCode;
}
});
var RedirectStatusCode = /*#__PURE__*/ function(RedirectStatusCode) {
RedirectStatusCode[RedirectStatusCode["SeeOther"] = 303] = "SeeOther";
RedirectStatusCode[RedirectStatusCode["TemporaryRedirect"] = 307] = "TemporaryRedirect";
RedirectStatusCode[RedirectStatusCode["PermanentRedirect"] = 308] = "PermanentRedirect";
return RedirectStatusCode;
}({});
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=redirect-status-code.js.map

View File

@@ -0,0 +1,91 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
getRedirectError: null,
getRedirectStatusCodeFromError: null,
getRedirectTypeFromError: null,
getURLFromRedirectError: null,
permanentRedirect: null,
redirect: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
getRedirectError: function() {
return getRedirectError;
},
getRedirectStatusCodeFromError: function() {
return getRedirectStatusCodeFromError;
},
getRedirectTypeFromError: function() {
return getRedirectTypeFromError;
},
getURLFromRedirectError: function() {
return getURLFromRedirectError;
},
permanentRedirect: function() {
return permanentRedirect;
},
redirect: function() {
return redirect;
}
});
const _redirectstatuscode = require("./redirect-status-code");
const _redirecterror = require("./redirect-error");
const actionAsyncStorage = typeof window === 'undefined' ? require('../../server/app-render/action-async-storage.external').actionAsyncStorage : undefined;
function getRedirectError(url, type, statusCode = _redirectstatuscode.RedirectStatusCode.TemporaryRedirect) {
const error = Object.defineProperty(new Error(_redirecterror.REDIRECT_ERROR_CODE), "__NEXT_ERROR_CODE", {
value: "E394",
enumerable: false,
configurable: true
});
error.digest = `${_redirecterror.REDIRECT_ERROR_CODE};${type};${url};${statusCode};`;
return error;
}
function redirect(/** The URL to redirect to */ url, type) {
type ??= actionAsyncStorage?.getStore()?.isAction ? 'push' : 'replace';
throw getRedirectError(url, type, _redirectstatuscode.RedirectStatusCode.TemporaryRedirect);
}
function permanentRedirect(/** The URL to redirect to */ url, type = 'replace') {
throw getRedirectError(url, type, _redirectstatuscode.RedirectStatusCode.PermanentRedirect);
}
function getURLFromRedirectError(error) {
if (!(0, _redirecterror.isRedirectError)(error)) return null;
// Slices off the beginning of the digest that contains the code and the
// separating ';'.
return error.digest.split(';').slice(2, -2).join(';');
}
function getRedirectTypeFromError(error) {
if (!(0, _redirecterror.isRedirectError)(error)) {
throw Object.defineProperty(new Error('Not a redirect error'), "__NEXT_ERROR_CODE", {
value: "E260",
enumerable: false,
configurable: true
});
}
return error.digest.split(';', 2)[1];
}
function getRedirectStatusCodeFromError(error) {
if (!(0, _redirecterror.isRedirectError)(error)) {
throw Object.defineProperty(new Error('Not a redirect error'), "__NEXT_ERROR_CODE", {
value: "E260",
enumerable: false,
configurable: true
});
}
return Number(error.digest.split(';').at(-2));
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=redirect.js.map

View File

@@ -0,0 +1,201 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
computeChangedPath: null,
extractPathFromFlightRouterState: null,
extractSourcePageFromFlightRouterState: null,
getSelectedParams: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
computeChangedPath: function() {
return computeChangedPath;
},
extractPathFromFlightRouterState: function() {
return extractPathFromFlightRouterState;
},
extractSourcePageFromFlightRouterState: function() {
return extractSourcePageFromFlightRouterState;
},
getSelectedParams: function() {
return getSelectedParams;
}
});
const _interceptionroutes = require("../../../shared/lib/router/utils/interception-routes");
const _segment = require("../../../shared/lib/segment");
const _matchsegments = require("../match-segments");
const removeLeadingSlash = (segment)=>{
return segment[0] === '/' ? segment.slice(1) : segment;
};
const segmentToPathname = (segment)=>{
if (typeof segment === 'string') {
// 'children' is not a valid path -- it's technically a parallel route that corresponds with the current segment's page
// if we don't skip it, then the computed pathname might be something like `/children` which doesn't make sense.
if (segment === 'children') return '';
return segment;
}
return segment[1];
};
const segmentToSourcePagePathname = (segment)=>{
if (typeof segment === 'string') {
if (segment === 'children') return '';
if (segment.startsWith(_segment.PAGE_SEGMENT_KEY)) return 'page';
return segment;
}
const [paramName, , dynamicParamType] = segment;
switch(dynamicParamType){
case 'c':
return `[...${paramName}]`;
case 'ci(..)(..)':
return `(..)(..)[...${paramName}]`;
case 'ci(.)':
return `(.)[...${paramName}]`;
case 'ci(..)':
return `(..)[...${paramName}]`;
case 'ci(...)':
return `(...)[...${paramName}]`;
case 'oc':
return `[[...${paramName}]]`;
case 'd':
return `[${paramName}]`;
case 'di(..)(..)':
return `(..)(..)[${paramName}]`;
case 'di(.)':
return `(.)[${paramName}]`;
case 'di(..)':
return `(..)[${paramName}]`;
case 'di(...)':
return `(...)[${paramName}]`;
default:
dynamicParamType;
return `[${paramName}]`;
}
};
function normalizeSegments(segments) {
return segments.reduce((acc, segment)=>{
segment = removeLeadingSlash(segment);
if (segment === '' || (0, _segment.isGroupSegment)(segment)) {
return acc;
}
return `${acc}/${segment}`;
}, '') || '/';
}
function extractPathFromFlightRouterState(flightRouterState) {
const segment = Array.isArray(flightRouterState[0]) ? flightRouterState[0][1] : flightRouterState[0];
if (segment === _segment.DEFAULT_SEGMENT_KEY || _interceptionroutes.INTERCEPTION_ROUTE_MARKERS.some((m)=>segment.startsWith(m))) return undefined;
if (segment.startsWith(_segment.PAGE_SEGMENT_KEY)) return '';
const segments = [
segmentToPathname(segment)
];
const parallelRoutes = flightRouterState[1] ?? {};
const childrenPath = parallelRoutes.children ? extractPathFromFlightRouterState(parallelRoutes.children) : undefined;
if (childrenPath !== undefined) {
segments.push(childrenPath);
} else {
for (const [key, value] of Object.entries(parallelRoutes)){
if (key === 'children') continue;
const childPath = extractPathFromFlightRouterState(value);
if (childPath !== undefined) {
segments.push(childPath);
}
}
}
return normalizeSegments(segments);
}
function extractSourcePageSegmentsFromFlightRouterState(flightRouterState) {
const segment = segmentToSourcePagePathname(flightRouterState[0]);
if (segment === _segment.DEFAULT_SEGMENT_KEY) {
return undefined;
}
if (segment === 'page') {
return [
segment
];
}
const parallelRoutes = flightRouterState[1] ?? {};
const childrenPath = parallelRoutes.children ? extractSourcePageSegmentsFromFlightRouterState(parallelRoutes.children) : undefined;
if (childrenPath !== undefined) {
return segment === '' ? childrenPath : [
removeLeadingSlash(segment),
...childrenPath
];
}
for (const [key, value] of Object.entries(parallelRoutes)){
if (key === 'children') continue;
const childPath = extractSourcePageSegmentsFromFlightRouterState(value);
if (childPath !== undefined) {
return segment === '' ? childPath : [
removeLeadingSlash(segment),
...childPath
];
}
}
return undefined;
}
function extractSourcePageFromFlightRouterState(flightRouterState) {
const sourcePageSegments = extractSourcePageSegmentsFromFlightRouterState(flightRouterState);
return sourcePageSegments ? `/${sourcePageSegments.join('/')}` : undefined;
}
function computeChangedPathImpl(treeA, treeB) {
const [segmentA, parallelRoutesA] = treeA;
const [segmentB, parallelRoutesB] = treeB;
const normalizedSegmentA = segmentToPathname(segmentA);
const normalizedSegmentB = segmentToPathname(segmentB);
if (_interceptionroutes.INTERCEPTION_ROUTE_MARKERS.some((m)=>normalizedSegmentA.startsWith(m) || normalizedSegmentB.startsWith(m))) {
return '';
}
if (!(0, _matchsegments.matchSegment)(segmentA, segmentB)) {
// once we find where the tree changed, we compute the rest of the path by traversing the tree
return extractPathFromFlightRouterState(treeB) ?? '';
}
for(const parallelRouterKey in parallelRoutesA){
if (parallelRoutesB[parallelRouterKey]) {
const changedPath = computeChangedPathImpl(parallelRoutesA[parallelRouterKey], parallelRoutesB[parallelRouterKey]);
if (changedPath !== null) {
return `${segmentToPathname(segmentB)}/${changedPath}`;
}
}
}
return null;
}
function computeChangedPath(treeA, treeB) {
const changedPath = computeChangedPathImpl(treeA, treeB);
if (changedPath == null || changedPath === '/') {
return changedPath;
}
// lightweight normalization to remove route groups
return normalizeSegments(changedPath.split('/'));
}
function getSelectedParams(currentTree, params = {}) {
const parallelRoutes = currentTree[1];
for (const parallelRoute of Object.values(parallelRoutes)){
const segment = parallelRoute[0];
const isDynamicParameter = Array.isArray(segment);
const segmentValue = isDynamicParameter ? segment[1] : segment;
if (!segmentValue || segmentValue.startsWith(_segment.PAGE_SEGMENT_KEY)) continue;
// Ensure catchAll and optional catchall are turned into an array
const isCatchAll = isDynamicParameter && (segment[2] === 'c' || segment[2] === 'oc');
if (isCatchAll) {
params[segment[0]] = segment[1].split('/');
} else if (isDynamicParameter) {
params[segment[0]] = segment[1];
}
params = getSelectedParams(parallelRoute, params);
}
return params;
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=compute-changed-path.js.map

View File

@@ -0,0 +1,21 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "createHrefFromUrl", {
enumerable: true,
get: function() {
return createHrefFromUrl;
}
});
function createHrefFromUrl(url, includeHash = true) {
return url.pathname + url.search + (includeHash ? url.hash : '');
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=create-href-from-url.js.map

View File

@@ -0,0 +1,153 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "createInitialRouterState", {
enumerable: true,
get: function() {
return createInitialRouterState;
}
});
const _createhreffromurl = require("./create-href-from-url");
const _computechangedpath = require("./compute-changed-path");
const _flightdatahelpers = require("../../flight-data-helpers");
const _pprnavigations = require("./ppr-navigations");
const _cache = require("../segment-cache/cache");
const _types = require("../segment-cache/types");
const _bfcache = require("../segment-cache/bfcache");
const _fetchserverresponse = require("./fetch-server-response");
const _optimisticroutes = require("../segment-cache/optimistic-routes");
function createInitialRouterState({ navigatedAt, initialRSCPayload, initialFlightStreamForCache, location }) {
const { c: initialCanonicalUrlParts, f: initialFlightData, q: initialRenderedSearch, i: initialCouldBeIntercepted, S: initialSupportsPerSegmentPrefetching, s: initialStaleTime, l: initialStaticStageByteLength, h: initialHeadVaryParams, p: initialRuntimePrefetchStream, d: initialDynamicStaleTimeSeconds } = initialRSCPayload;
// When initialized on the server, the canonical URL is provided as an array of parts.
// This is to ensure that when the RSC payload streamed to the client, crawlers don't interpret it
// as a URL that should be crawled.
const initialCanonicalUrl = initialCanonicalUrlParts.join('/');
const normalizedFlightData = (0, _flightdatahelpers.getFlightDataPartsFromPath)(initialFlightData[0]);
const { tree: initialTree, seedData: initialSeedData, head: initialHead } = normalizedFlightData;
// For the SSR render, seed data should always be available (we only send back a `null` response
// in the case of a `loading` segment, pre-PPR.)
const canonicalUrl = // location.href is read as the initial value for canonicalUrl in the browser
// This is safe to do as canonicalUrl can't be rendered, it's only used to control the history updates in the useEffect further down in this file.
location ? (0, _createhreffromurl.createHrefFromUrl)(location) : initialCanonicalUrl;
// Convert the initial FlightRouterState into the RouteTree type.
// NOTE: The metadataVaryPath isn't used for anything currently because the
// head is embedded into the CacheNode tree, but eventually we'll lift it out
// and store it on the top-level state object.
//
// TODO: For statically-generated-at-build-time HTML pages, the
// FlightRouterState baked into the initial RSC payload won't have the
// correct segment inlining hints (ParentInlinedIntoSelf, InlinedIntoChild)
// because those are computed after the pre-render. The client will need to
// fetch the correct hints from the route tree prefetch (/_tree) response
// before acting on inlining decisions.
const acc = {
metadataVaryPath: null
};
const initialRouteTree = (0, _cache.convertRootFlightRouterStateToRouteTree)(initialTree, initialRenderedSearch, acc);
const metadataVaryPath = acc.metadataVaryPath;
const initialTask = (0, _pprnavigations.createInitialCacheNodeForHydration)(navigatedAt, initialRouteTree, initialSeedData, initialHead, (0, _bfcache.computeDynamicStaleAt)(navigatedAt, initialDynamicStaleTimeSeconds ?? _bfcache.UnknownDynamicStaleTime));
// The following only applies in the browser (location !== null) since neither
// route learning nor segment cache state persists from SSR to client.
if (location !== null && metadataVaryPath !== null) {
// Learn the route pattern so we can predict it for future navigations.
(0, _optimisticroutes.discoverKnownRoute)(Date.now(), location.pathname, null, null, initialRouteTree, metadataVaryPath, initialCouldBeIntercepted, canonicalUrl, initialSupportsPerSegmentPrefetching, false // hasDynamicRewrite
);
// Write the initial seed data into the segment cache so subsequent
// navigations to the initial page can serve cached segments instantly.
if (initialSeedData !== null && initialStaleTime !== undefined) {
if (initialStaticStageByteLength !== undefined && initialFlightStreamForCache != null) {
// Partially static page — truncate the cloned Flight stream at the
// static stage byte boundary, decode, and cache the static subset.
(0, _fetchserverresponse.decodeStaticStage)(initialFlightStreamForCache, initialStaticStageByteLength, undefined).then(async (staticStageResponse)=>{
const now = Date.now();
const staleAt = await (0, _cache.getStaleAt)(now, staticStageResponse.s);
(0, _cache.writeStaticStageResponseIntoCache)(now, staticStageResponse.f, undefined, staticStageResponse.h, staleAt, initialTree, initialRenderedSearch, true // isResponsePartial
);
}).catch(()=>{
// The static stage processing failed. Not fatal — the page
// rendered normally, we just won't write into the cache.
});
} else {
// Fully static page — cache the entire decoded seed data as-is. We're
// not using the initial response here (which would allow us to combine
// the two branches) to avoid unnecessary decoding of the Flight data,
// since we can just take the seed data that we already decoded during
// hydration and write it into the cache directly.
const now = Date.now();
(0, _cache.getStaleAt)(now, initialStaleTime).then((staleAt)=>{
(0, _cache.writeStaticStageResponseIntoCache)(now, initialFlightData, undefined, initialHeadVaryParams, staleAt, initialTree, initialRenderedSearch, false // isResponsePartial
);
}).catch(()=>{
// The static stage processing failed. Not fatal — the page
// rendered normally, we just won't write into the cache.
});
// Cancel the stream clone — fully static path doesn't need it.
initialFlightStreamForCache?.cancel();
}
} else {
// No caching — cancel the unused stream clone.
initialFlightStreamForCache?.cancel();
}
// If the initial RSC payload includes an embedded runtime prefetch stream,
// decode it and write the runtime data into the segment cache. This allows
// subsequent navigations to serve runtime-prefetchable content from cache
// without a separate prefetch request.
if (initialRuntimePrefetchStream != null) {
(0, _cache.processRuntimePrefetchStream)(Date.now(), initialRuntimePrefetchStream, initialTree, initialRenderedSearch).then((processed)=>{
if (processed !== null) {
(0, _cache.writeDynamicRenderResponseIntoCache)(Date.now(), _types.FetchStrategy.PPRRuntime, processed.flightDatas, processed.buildId, processed.isResponsePartial, processed.headVaryParams, processed.staleAt, processed.navigationSeed, null);
}
}).catch(()=>{
// Runtime prefetch cache write failed. Not fatal — the page rendered
// normally, we just won't cache runtime data.
});
}
}
// NOTE: We intentionally don't check if any data needs to be fetched from the
// server. We assume the initial hydration payload is sufficient to render
// the page.
//
// The completeness of the initial data is an important property that we rely
// on as a last-ditch mechanism for recovering the app; we must always be able
// to reload a fresh HTML document to get to a consistent state.
//
// In the future, there may be cases where the server intentionally sends
// partial data and expects the client to fill in the rest, in which case this
// logic may change. (There already is a similar case where the server sends
// _no_ hydration data in the HTML document at all, and the client fetches it
// separately, but that's different because we still end up hydrating with a
// complete tree.)
const initialState = {
tree: initialTask.route,
cache: initialTask.node,
pushRef: {
pendingPush: false,
mpaNavigation: false,
// First render needs to preserve the previous window.history.state
// to avoid it being overwritten on navigation back/forward with MPA Navigation.
preserveCustomHistoryState: true
},
focusAndScrollRef: {
scrollRef: null,
forceScroll: false,
onlyHashChange: false,
hashFragment: null
},
canonicalUrl,
renderedSearch: initialRenderedSearch,
// the || operator is intentional, the pathname can be an empty string
nextUrl: ((0, _computechangedpath.extractPathFromFlightRouterState)(initialTree) || location?.pathname) ?? null,
previousNextUrl: null,
debugInfo: null
};
return initialState;
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=create-initial-router-state.js.map

View File

@@ -0,0 +1,32 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "createRouterCacheKey", {
enumerable: true,
get: function() {
return createRouterCacheKey;
}
});
const _segment = require("../../../shared/lib/segment");
function createRouterCacheKey(segment, withoutSearchParameters = false) {
// if the segment is an array, it means it's a dynamic segment
// for example, ['lang', 'en', 'd']. We need to convert it to a string to store it as a cache node key.
if (Array.isArray(segment)) {
return `${segment[0]}|${segment[1]}|${segment[2]}`;
}
// Page segments might have search parameters, ie __PAGE__?foo=bar
// When `withoutSearchParameters` is true, we only want to return the page segment
if (withoutSearchParameters && segment.startsWith(_segment.PAGE_SEGMENT_KEY)) {
return _segment.PAGE_SEGMENT_KEY;
}
return segment;
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=create-router-cache-key.js.map

View File

@@ -0,0 +1,457 @@
'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
createFetch: null,
createFromNextReadableStream: null,
decodeStaticStage: null,
fetchServerResponse: null,
processFetch: null,
resolveStaticStageData: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
createFetch: function() {
return createFetch;
},
createFromNextReadableStream: function() {
return createFromNextReadableStream;
},
decodeStaticStage: function() {
return decodeStaticStage;
},
fetchServerResponse: function() {
return fetchServerResponse;
},
processFetch: function() {
return processFetch;
},
resolveStaticStageData: function() {
return resolveStaticStageData;
}
});
const _client = require("react-server-dom-webpack/client");
const _invarianterror = require("../../../shared/lib/invariant-error");
const _approuterheaders = require("../app-router-headers");
const _appcallserver = require("../../app-call-server");
const _appfindsourcemapurl = require("../../app-find-source-map-url");
const _flightdatahelpers = require("../../flight-data-helpers");
const _setcachebustingsearchparam = require("./set-cache-busting-search-param");
const _routeparams = require("../../route-params");
const _deploymentid = require("../../../shared/lib/deployment-id");
const _navigationbuildid = require("../../navigation-build-id");
const _constants = require("../../../lib/constants");
const _cache = require("../segment-cache/cache");
const _bfcache = require("../segment-cache/bfcache");
const createFromReadableStream = _client.createFromReadableStream;
const createFromFetch = _client.createFromFetch;
let createDebugChannel;
if (process.env.__NEXT_DEV_SERVER && process.env.__NEXT_REACT_DEBUG_CHANNEL) {
createDebugChannel = require('../../dev/debug-channel').createDebugChannel;
}
function doMpaNavigation(url) {
return (0, _routeparams.urlToUrlWithoutFlightMarker)(new URL(url, location.origin)).toString();
}
let isPageUnloading = false;
if (typeof window !== 'undefined') {
// Track when the page is unloading, e.g. due to reloading the page or
// performing hard navigations. This allows us to suppress error logging when
// the browser cancels in-flight requests during page unload.
window.addEventListener('pagehide', ()=>{
isPageUnloading = true;
});
// Reset the flag on pageshow, e.g. when navigating back and the JavaScript
// execution context is restored by the browser.
window.addEventListener('pageshow', ()=>{
isPageUnloading = false;
});
}
async function fetchServerResponse(url, options) {
const { flightRouterState, nextUrl } = options;
const headers = {
// Enable flight response
[_approuterheaders.RSC_HEADER]: '1',
// Provide the current router state
[_approuterheaders.NEXT_ROUTER_STATE_TREE_HEADER]: (0, _flightdatahelpers.prepareFlightRouterStateForRequest)(flightRouterState, options.isHmrRefresh)
};
if (process.env.NODE_ENV === 'development' && options.isHmrRefresh) {
headers[_approuterheaders.NEXT_HMR_REFRESH_HEADER] = '1';
}
if (nextUrl) {
headers[_approuterheaders.NEXT_URL] = nextUrl;
}
// In static export mode, we need to modify the URL to request the .txt file,
// but we should preserve the original URL for the canonical URL and error handling.
const originalUrl = url;
try {
if (process.env.NODE_ENV === 'production') {
if (process.env.__NEXT_CONFIG_OUTPUT === 'export') {
// In "output: export" mode, we can't rely on headers to distinguish
// between HTML and RSC requests. Instead, we append an extra prefix
// to the request.
url = new URL(url);
if (url.pathname.endsWith('/')) {
url.pathname += 'index.txt';
} else {
url.pathname += '.txt';
}
}
}
// Typically, during a navigation, we decode the response using Flight's
// `createFromFetch` API, which accepts a `fetch` promise.
// TODO: Remove this check once the old PPR flag is removed
const isLegacyPPR = process.env.__NEXT_PPR && !process.env.__NEXT_CACHE_COMPONENTS;
const shouldImmediatelyDecode = !isLegacyPPR;
const res = await createFetch(url, headers, 'auto', shouldImmediatelyDecode);
const responseUrl = (0, _routeparams.urlToUrlWithoutFlightMarker)(new URL(res.url));
const canonicalUrl = res.redirected ? responseUrl : originalUrl;
const contentType = res.headers.get('content-type') || '';
const interception = !!res.headers.get('vary')?.includes(_approuterheaders.NEXT_URL);
const postponed = !!res.headers.get(_approuterheaders.NEXT_DID_POSTPONE_HEADER);
let isFlightResponse = contentType.startsWith(_approuterheaders.RSC_CONTENT_TYPE_HEADER);
if (process.env.NODE_ENV === 'production') {
if (process.env.__NEXT_CONFIG_OUTPUT === 'export') {
if (!isFlightResponse) {
isFlightResponse = contentType.startsWith('text/plain');
}
}
}
// If fetch returns something different than flight response handle it like a mpa navigation
// If the fetch was not 200, we also handle it like a mpa navigation
if (!isFlightResponse || !res.ok || !res.body) {
// in case the original URL came with a hash, preserve it before redirecting to the new URL
if (url.hash) {
responseUrl.hash = url.hash;
}
return doMpaNavigation(responseUrl.toString());
}
// We may navigate to a page that requires a different Webpack runtime.
// In prod, every page will have the same Webpack runtime.
// In dev, the Webpack runtime is minimal for each page.
// We need to ensure the Webpack runtime is updated before executing client-side JS of the new page.
// TODO: This needs to happen in the Flight Client.
// Or Webpack needs to include the runtime update in the Flight response as
// a blocking script.
if (process.env.NODE_ENV !== 'production' && !process.env.TURBOPACK) {
await require('../../dev/hot-reloader/app/hot-reloader-app').waitForWebpackRuntimeHotUpdate();
}
let flightResponsePromise = res.flightResponsePromise;
if (flightResponsePromise === null) {
// Typically, `createFetch` would have already started decoding the
// Flight response. If it hasn't, though, we need to decode it now.
// TODO: This should only be reachable if legacy PPR is enabled (i.e. PPR
// without Cache Components). Remove this branch once legacy PPR
// is deleted.
flightResponsePromise = createFromNextReadableStream(res.body, headers, {
allowPartialStream: postponed
});
}
const [flightResponse, cacheData] = await Promise.all([
flightResponsePromise,
res.cacheData
]);
if ((res.headers.get(_constants.NEXT_NAV_DEPLOYMENT_ID_HEADER) ?? flightResponse.b) !== (0, _navigationbuildid.getNavigationBuildId)()) {
// The server build does not match the client build.
return doMpaNavigation(res.url);
}
const normalizedFlightData = (0, _flightdatahelpers.normalizeFlightData)(flightResponse.f);
if (typeof normalizedFlightData === 'string') {
return doMpaNavigation(normalizedFlightData);
}
const staticStageData = cacheData !== null ? await resolveStaticStageData(cacheData, flightResponse, headers) : null;
return {
flightData: normalizedFlightData,
canonicalUrl: canonicalUrl,
// TODO: We should be able to read this from the rewrite header, not the
// Flight response. Theoretically they should always agree, but there are
// currently some cases where it's incorrect for interception routes. We
// can always trust the value in the response body. However, per-segment
// prefetch responses don't embed the value in the body; they rely on the
// header alone. So we need to investigate why the header is sometimes
// wrong for interception routes.
renderedSearch: flightResponse.q,
couldBeIntercepted: interception,
supportsPerSegmentPrefetching: flightResponse.S,
postponed,
// The dynamicStaleTime is only present in the response body when
// a page exports unstable_dynamicStaleTime and this is a dynamic render.
// When absent (UnknownDynamicStaleTime), the client falls back to the
// global DYNAMIC_STALETIME_MS. The value is in seconds.
dynamicStaleTime: flightResponse.d ?? _bfcache.UnknownDynamicStaleTime,
staticStageData,
runtimePrefetchStream: flightResponse.p ?? null,
responseHeaders: res.headers,
debugInfo: flightResponsePromise._debugInfo ?? null
};
} catch (err) {
if (!isPageUnloading) {
console.error(`Failed to fetch RSC payload for ${originalUrl}. Falling back to browser navigation.`, err);
}
// If fetch fails handle it like a mpa navigation
// TODO-APP: Add a test for the case where a CORS request fails, e.g. external url redirect coming from the response.
// See https://github.com/vercel/next.js/issues/43605#issuecomment-1451617521 for a reproduction.
return originalUrl.toString();
}
}
async function processFetch(response) {
if (process.env.__NEXT_CACHE_COMPONENTS) {
if (!response.body) {
throw Object.defineProperty(new _invarianterror.InvariantError('Expected RSC navigation response to have a body'), "__NEXT_ERROR_CODE", {
value: "E1088",
enumerable: false,
configurable: true
});
}
const { stream, isPartial } = await (0, _cache.stripIsPartialByte)(response.body);
let responseStream;
let cacheData;
if (process.env.__NEXT_EXPERIMENTAL_CACHED_NAVIGATIONS) {
const [stream1, stream2] = stream.tee();
responseStream = stream1;
cacheData = {
isResponsePartial: isPartial,
responseBodyClone: stream2
};
} else {
responseStream = stream;
cacheData = {
isResponsePartial: isPartial
};
}
const strippedResponse = new Response(responseStream, {
headers: response.headers,
status: response.status,
statusText: response.statusText
});
// The Response constructor doesn't preserve `url` or `redirected` from
// the original. We need both: `url` for React DevTools and `redirected`
// for the redirect replay logic below.
Object.defineProperty(strippedResponse, 'url', {
value: response.url
});
Object.defineProperty(strippedResponse, 'redirected', {
value: response.redirected
});
return {
response: strippedResponse,
cacheData
};
}
return {
response,
cacheData: null
};
}
async function resolveStaticStageData(cacheData, flightResponse, headers) {
const { isResponsePartial, responseBodyClone } = cacheData;
if (responseBodyClone) {
if (!isResponsePartial) {
// Fully static — cache the entire decoded response as-is.
responseBodyClone.cancel();
return {
response: flightResponse,
isResponsePartial: false
};
}
if (flightResponse.l !== undefined) {
// Partially static — truncate the body clone at the byte boundary and
// decode it.
const response = await decodeStaticStage(responseBodyClone, flightResponse.l, headers);
return {
response,
isResponsePartial: true
};
}
// No caching — cancel the unused clone.
responseBodyClone.cancel();
}
return null;
}
async function decodeStaticStage(responseBodyClone, staticStageByteLengthPromise, headers) {
const staticStageByteLength = await staticStageByteLengthPromise;
const truncatedStream = truncateStream(responseBodyClone, staticStageByteLength);
return createFromNextReadableStream(truncatedStream, headers, {
allowPartialStream: true
});
}
async function createFetch(url, headers, fetchPriority, shouldImmediatelyDecode, signal) {
// TODO: In output: "export" mode, the headers do nothing. Omit them (and the
// cache busting search param) from the request so they're
// maximally cacheable.
if (process.env.__NEXT_TEST_MODE && fetchPriority !== null) {
headers['Next-Test-Fetch-Priority'] = fetchPriority;
}
const deploymentId = (0, _deploymentid.getDeploymentId)();
if (deploymentId) {
headers['x-deployment-id'] = deploymentId;
}
if (process.env.__NEXT_DEV_SERVER) {
if (self.__next_r) {
headers[_approuterheaders.NEXT_HTML_REQUEST_ID_HEADER] = self.__next_r;
}
// Create a new request ID for the server action request. The server uses
// this to tag debug information sent via WebSocket to the client, which
// then routes those chunks to the debug channel associated with this ID.
headers[_approuterheaders.NEXT_REQUEST_ID_HEADER] = crypto.getRandomValues(new Uint32Array(1))[0].toString(16);
}
const fetchOptions = {
// Backwards compat for older browsers. `same-origin` is the default in modern browsers.
credentials: 'same-origin',
headers,
priority: fetchPriority || undefined,
signal
};
// `fetchUrl` is slightly different from `url` because we add a cache-busting
// search param to it. This should not leak outside of this function, so we
// track them separately.
let fetchUrl = new URL(url);
await (0, _setcachebustingsearchparam.setCacheBustingSearchParam)(fetchUrl, headers);
let processed = fetch(fetchUrl, fetchOptions).then(processFetch);
let fetchPromise = processed.then(({ response })=>response);
// Immediately pass the fetch promise to the Flight client so that the debug
// info includes the latency from the client to the server. The internal timer
// in React starts as soon as `createFromFetch` is called.
//
// The only case where we don't do this is during a prefetch, because a
// top-level prefetch response never blocks a navigation; if it hasn't already
// been written into the cache by the time the navigation happens, the router
// will go straight to a dynamic request.
let flightResponsePromise = shouldImmediatelyDecode ? createFromNextFetch(fetchPromise, headers) : null;
let browserResponse = await fetchPromise;
// If the server responds with a redirect (e.g. 307), and the redirected
// location does not contain the cache busting search param set in the
// original request, the response is likely invalid — when following the
// redirect, the browser forwards the request headers, but since the cache
// busting search param is missing, the server will reject the request due to
// a mismatch.
//
// Ideally, we would be able to intercept the redirect response and perform it
// manually, instead of letting the browser automatically follow it, but this
// is not allowed by the fetch API.
//
// So instead, we must "replay" the redirect by fetching the new location
// again, but this time we'll append the cache busting search param to prevent
// a mismatch.
//
// TODO: We can optimize Next.js's built-in middleware APIs by returning a
// custom status code, to prevent the browser from automatically following it.
//
// This does not affect Server Action-based redirects; those are encoded
// differently, as part of the Flight body. It only affects redirects that
// occur in a middleware or a third-party proxy.
let redirected = browserResponse.redirected;
if (process.env.__NEXT_CLIENT_VALIDATE_RSC_REQUEST_HEADERS) {
// This is to prevent a redirect loop. Same limit used by Chrome.
const MAX_REDIRECTS = 20;
for(let n = 0; n < MAX_REDIRECTS; n++){
if (!browserResponse.redirected) {
break;
}
const responseUrl = new URL(browserResponse.url, fetchUrl);
if (responseUrl.origin !== fetchUrl.origin) {
break;
}
if (responseUrl.searchParams.get(_approuterheaders.NEXT_RSC_UNION_QUERY) === fetchUrl.searchParams.get(_approuterheaders.NEXT_RSC_UNION_QUERY)) {
break;
}
// The RSC request was redirected. Assume the response is invalid.
//
// Append the cache busting search param to the redirected URL and
// fetch again.
// TODO: We should abort the previous request.
fetchUrl = new URL(responseUrl);
await (0, _setcachebustingsearchparam.setCacheBustingSearchParam)(fetchUrl, headers);
processed = fetch(fetchUrl, fetchOptions).then(processFetch);
fetchPromise = processed.then(({ response })=>response);
flightResponsePromise = shouldImmediatelyDecode ? createFromNextFetch(fetchPromise, headers) : null;
browserResponse = await fetchPromise;
// We just performed a manual redirect, so this is now true.
redirected = true;
}
}
// Remove the cache busting search param from the response URL, to prevent it
// from leaking outside of this function.
const responseUrl = new URL(browserResponse.url, fetchUrl);
responseUrl.searchParams.delete(_approuterheaders.NEXT_RSC_UNION_QUERY);
const rscResponse = {
url: responseUrl.href,
// This is true if any redirects occurred, either automatically by the
// browser, or manually by us. So it's different from
// `browserResponse.redirected`, which only tells us whether the browser
// followed a redirect, and only for the last response in the chain.
redirected,
// These can be copied from the last browser response we received. We
// intentionally only expose the subset of fields that are actually used
// elsewhere in the codebase.
ok: browserResponse.ok,
headers: browserResponse.headers,
body: browserResponse.body,
status: browserResponse.status,
// This is the exact promise returned by `createFromFetch`. It contains
// debug information that we need to transfer to any derived promises that
// are later rendered by React.
flightResponsePromise: flightResponsePromise,
cacheData: processed.then(({ cacheData })=>cacheData)
};
return rscResponse;
}
function createFromNextReadableStream(flightStream, requestHeaders, options) {
return createFromReadableStream(flightStream, {
callServer: _appcallserver.callServer,
findSourceMapURL: _appfindsourcemapurl.findSourceMapURL,
debugChannel: createDebugChannel && createDebugChannel(requestHeaders),
unstable_allowPartialStream: options?.allowPartialStream
});
}
function createFromNextFetch(promiseForResponse, requestHeaders) {
return createFromFetch(promiseForResponse, {
callServer: _appcallserver.callServer,
findSourceMapURL: _appfindsourcemapurl.findSourceMapURL,
debugChannel: createDebugChannel && createDebugChannel(requestHeaders)
});
}
function truncateStream(stream, byteLength) {
const reader = stream.getReader();
let remaining = byteLength;
return new ReadableStream({
async pull (controller) {
if (remaining <= 0) {
reader.cancel();
controller.close();
return;
}
const { done, value } = await reader.read();
if (done) {
controller.close();
return;
}
if (value.byteLength <= remaining) {
controller.enqueue(value);
remaining -= value.byteLength;
} else {
controller.enqueue(value.subarray(0, remaining));
remaining = 0;
reader.cancel();
controller.close();
}
},
cancel () {
reader.cancel();
}
});
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=fetch-server-response.js.map

View File

@@ -0,0 +1,59 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "isNavigatingToNewRootLayout", {
enumerable: true,
get: function() {
return isNavigatingToNewRootLayout;
}
});
const _approutertypes = require("../../../shared/lib/app-router-types");
function isNavigatingToNewRootLayout(currentTree, nextTree) {
// Compare segments
const currentTreeSegment = currentTree[0];
const nextTreeSegment = nextTree.segment;
// If any segment is different before we find the root layout, the root layout has changed.
// E.g. /same/(group1)/layout.js -> /same/(group2)/layout.js
// First segment is 'same' for both, keep looking. (group1) changed to (group2) before the root layout was found, it must have changed.
if (Array.isArray(currentTreeSegment) && Array.isArray(nextTreeSegment)) {
// Compare dynamic param name and type but ignore the value, different values would not affect the current root layout
// /[name] - /slug1 and /slug2, both values (slug1 & slug2) still has the same layout /[name]/layout.js
if (currentTreeSegment[0] !== nextTreeSegment[0] || currentTreeSegment[2] !== nextTreeSegment[2]) {
return true;
}
} else if (currentTreeSegment !== nextTreeSegment) {
return true;
}
// Current tree root layout found
const currentIsRootLayout = ((currentTree[4] ?? 0) & _approutertypes.PrefetchHint.IsRootLayout) !== 0;
const nextIsRootLayout = (nextTree.prefetchHints & _approutertypes.PrefetchHint.IsRootLayout) !== 0;
if (currentIsRootLayout) {
// If the next tree doesn't have the root layout flag, it must have changed.
return !nextIsRootLayout;
}
// Current tree didn't have its root layout here, must have changed.
if (nextIsRootLayout) {
return true;
}
const slots = nextTree.slots;
const currentTreeChildren = currentTree[1];
if (slots !== null) {
for(const slot in slots){
const nextTreeChild = slots[slot];
const currentTreeChild = currentTreeChildren[slot];
if (currentTreeChild === undefined || isNavigatingToNewRootLayout(currentTreeChild, nextTreeChild)) {
return true;
}
}
}
return false;
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=is-navigating-to-new-root-layout.js.map

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,49 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
getLastCommittedTree: null,
setLastCommittedTree: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
getLastCommittedTree: function() {
return getLastCommittedTree;
},
setLastCommittedTree: function() {
return setLastCommittedTree;
}
});
// The tree from the last state that was committed to the browser history
// (i.e., the last state for which HistoryUpdater's useInsertionEffect ran).
// This lets the server-patch reducer distinguish between retrying a
// navigation that already pushed a history entry vs one whose transition
// suspended and never committed.
//
// Currently only used by the server-patch retry logic, but this module is a
// stepping stone toward a broader refactor of the navigation queue. The
// existing AppRouter action queue will eventually be replaced by a more
// reactive model that explicitly tracks pending vs committed navigation
// state. This file will likely evolve into (or be subsumed by) that new
// implementation.
let lastCommittedTree = null;
function getLastCommittedTree() {
return lastCommittedTree;
}
function setLastCommittedTree(tree) {
lastCommittedTree = tree;
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=committed-state.js.map

View File

@@ -0,0 +1,63 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "findHeadInCache", {
enumerable: true,
get: function() {
return findHeadInCache;
}
});
const _segment = require("../../../../shared/lib/segment");
const _createroutercachekey = require("../create-router-cache-key");
function findHeadInCache(cache, parallelRoutes) {
return findHeadInCacheImpl(cache, parallelRoutes, '', '');
}
function findHeadInCacheImpl(cache, parallelRoutes, keyPrefix, keyPrefixWithoutSearchParams) {
const isLastItem = Object.keys(parallelRoutes).length === 0;
if (isLastItem) {
// Returns the entire Cache Node of the segment whose head we will render.
return [
cache,
keyPrefix,
keyPrefixWithoutSearchParams
];
}
// First try the 'children' parallel route if it exists
// when starting from the "root", this corresponds with the main page component
const parallelRoutesKeys = Object.keys(parallelRoutes).filter((key)=>key !== 'children');
// if we are at the root, we need to check the children slot first
if ('children' in parallelRoutes) {
parallelRoutesKeys.unshift('children');
}
const slots = cache.slots;
if (slots !== null) {
for (const key of parallelRoutesKeys){
const [segment, childParallelRoutes] = parallelRoutes[key];
// If the parallel is not matched and using the default segment,
// skip searching the head from it.
if (segment === _segment.DEFAULT_SEGMENT_KEY) {
continue;
}
const childCacheNode = slots[key];
if (!childCacheNode) {
continue;
}
const cacheKey = (0, _createroutercachekey.createRouterCacheKey)(segment);
const cacheKeyWithoutSearchParams = (0, _createroutercachekey.createRouterCacheKey)(segment, true);
const item = findHeadInCacheImpl(childCacheNode, childParallelRoutes, keyPrefix + '/' + cacheKey, keyPrefix + '/' + cacheKeyWithoutSearchParams);
if (item) {
return item;
}
}
}
return null;
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=find-head-in-cache.js.map

View File

@@ -0,0 +1,38 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "hasInterceptionRouteInCurrentTree", {
enumerable: true,
get: function() {
return hasInterceptionRouteInCurrentTree;
}
});
const _interceptionroutes = require("../../../../shared/lib/router/utils/interception-routes");
function hasInterceptionRouteInCurrentTree([segment, parallelRoutes]) {
// If we have a dynamic segment, it's marked as an interception route by the presence of the `i` suffix.
if (Array.isArray(segment) && (segment[2] === 'di(..)(..)' || segment[2] === 'ci(..)(..)' || segment[2] === 'di(.)' || segment[2] === 'ci(.)' || segment[2] === 'di(..)' || segment[2] === 'ci(..)' || segment[2] === 'di(...)' || segment[2] === 'ci(...)')) {
return true;
}
// If segment is not an array, apply the existing string-based check
if (typeof segment === 'string' && (0, _interceptionroutes.isInterceptionRouteAppPath)(segment)) {
return true;
}
// Iterate through parallelRoutes if they exist
if (parallelRoutes) {
for(const key in parallelRoutes){
if (hasInterceptionRouteInCurrentTree(parallelRoutes[key])) {
return true;
}
}
}
return false;
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=has-interception-route-in-current-tree.js.map

View File

@@ -0,0 +1,23 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "hmrRefreshReducer", {
enumerable: true,
get: function() {
return hmrRefreshReducer;
}
});
const _refreshreducer = require("./refresh-reducer");
const _pprnavigations = require("../ppr-navigations");
function hmrRefreshReducer(state) {
return (0, _refreshreducer.refreshDynamicData)(state, _pprnavigations.FreshnessPolicy.HMRRefresh);
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=hmr-refresh-reducer.js.map

View File

@@ -0,0 +1,56 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
DYNAMIC_STALETIME_MS: null,
STATIC_STALETIME_MS: null,
navigateReducer: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
DYNAMIC_STALETIME_MS: function() {
return DYNAMIC_STALETIME_MS;
},
STATIC_STALETIME_MS: function() {
return STATIC_STALETIME_MS;
},
navigateReducer: function() {
return navigateReducer;
}
});
const _navigation = require("../../segment-cache/navigation");
const _cache = require("../../segment-cache/cache");
const _pprnavigations = require("../ppr-navigations");
const DYNAMIC_STALETIME_MS = Number(process.env.__NEXT_CLIENT_ROUTER_DYNAMIC_STALETIME) * 1000;
const STATIC_STALETIME_MS = (0, _cache.getStaleTimeMs)(Number(process.env.__NEXT_CLIENT_ROUTER_STATIC_STALETIME));
function navigateReducer(state, action) {
const { url, isExternalUrl, navigateType, scrollBehavior } = action;
if (isExternalUrl) {
return (0, _navigation.completeHardNavigation)(state, url, navigateType);
}
// Handles case where `<meta http-equiv="refresh">` tag is present,
// which will trigger an MPA navigation.
if (document.getElementById('__next-page-redirect')) {
return (0, _navigation.completeHardNavigation)(state, url, navigateType);
}
// Temporary glue code between the router reducer and the new navigation
// implementation. Eventually we'll rewrite the router reducer to a
// state machine.
const currentUrl = new URL(state.canonicalUrl, location.origin);
const currentRenderedSearch = state.renderedSearch;
return (0, _navigation.navigate)(state, url, currentUrl, currentRenderedSearch, state.cache, state.tree, state.nextUrl, _pprnavigations.FreshnessPolicy.Default, scrollBehavior, navigateType);
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=navigate-reducer.js.map

View File

@@ -0,0 +1,83 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
refreshDynamicData: null,
refreshReducer: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
refreshDynamicData: function() {
return refreshDynamicData;
},
refreshReducer: function() {
return refreshReducer;
}
});
const _routerreducertypes = require("../router-reducer-types");
const _navigation = require("../../segment-cache/navigation");
const _cache = require("../../segment-cache/cache");
const _hasinterceptionrouteincurrenttree = require("./has-interception-route-in-current-tree");
const _pprnavigations = require("../ppr-navigations");
const _bfcache = require("../../segment-cache/bfcache");
function refreshReducer(state, action) {
// During a refresh, we invalidate the segment cache but not the route cache.
// The route cache contains the tree structure (which segments exist at a
// given URL) which doesn't change during a refresh. The segment cache
// contains the actual RSC data which needs to be re-fetched.
//
// The Instant Navigation Testing API can bypass cache invalidation to
// preserve prefetched data when refreshing after an MPA navigation. This is
// only used for testing and is not exposed in production builds by default.
const bypassCacheInvalidation = process.env.__NEXT_EXPOSE_TESTING_API && action.bypassCacheInvalidation;
if (!bypassCacheInvalidation) {
const currentNextUrl = state.nextUrl;
const currentRouterState = state.tree;
(0, _cache.invalidateSegmentCacheEntries)(currentNextUrl, currentRouterState);
}
return refreshDynamicData(state, _pprnavigations.FreshnessPolicy.RefreshAll);
}
function refreshDynamicData(state, freshnessPolicy) {
// During a refresh, invalidate the BFCache, which may contain dynamic data.
(0, _bfcache.invalidateBfCache)();
const currentNextUrl = state.nextUrl;
// We always send the last next-url, not the current when performing a dynamic
// request. This is because we update the next-url after a navigation, but we
// want the same interception route to be matched that used the last next-url.
const nextUrlForRefresh = (0, _hasinterceptionrouteincurrenttree.hasInterceptionRouteInCurrentTree)(state.tree) ? state.previousNextUrl || currentNextUrl : null;
// A refresh is modeled as a navigation to the current URL, but where any
// existing dynamic data (including in shared layouts) is re-fetched.
const currentCanonicalUrl = state.canonicalUrl;
const currentUrl = new URL(currentCanonicalUrl, location.origin);
const currentRenderedSearch = state.renderedSearch;
const currentFlightRouterState = state.tree;
const scrollBehavior = _routerreducertypes.ScrollBehavior.NoScroll;
// Create a NavigationSeed from the current FlightRouterState.
// TODO: Eventually we will store this type directly on the state object
// instead of reconstructing it on demand. Part of a larger series of
// refactors to unify the various tree types that the client deals with.
const now = Date.now();
// TODO: Store the dynamic stale time on the top-level state so it's known
// during restores and refreshes.
const refreshSeed = (0, _navigation.convertServerPatchToFullTree)(now, currentFlightRouterState, null, currentRenderedSearch, _bfcache.UnknownDynamicStaleTime);
const navigateType = 'replace';
return (0, _navigation.navigateToKnownRoute)(now, state, currentUrl, currentCanonicalUrl, refreshSeed, currentUrl, currentRenderedSearch, state.cache, currentFlightRouterState, freshnessPolicy, nextUrlForRefresh, scrollBehavior, navigateType, null, // Refresh navigations don't use route prediction, so there's no route
// cache entry to mark as having a dynamic rewrite on mismatch. If a
// mismatch occurs, the retry handler will traverse the known route tree
// to find and mark the entry.
null);
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=refresh-reducer.js.map

View File

@@ -0,0 +1,62 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "restoreReducer", {
enumerable: true,
get: function() {
return restoreReducer;
}
});
const _computechangedpath = require("../compute-changed-path");
const _pprnavigations = require("../ppr-navigations");
const _navigation = require("../../segment-cache/navigation");
const _bfcache = require("../../segment-cache/bfcache");
function restoreReducer(state, action) {
// This action is used to restore the router state from the history state.
// However, it's possible that the history state no longer contains the `FlightRouterState`.
// We will copy over the internal state on pushState/replaceState events, but if a history entry
// occurred before hydration, or if the user navigated to a hash using a regular anchor link,
// the history state will not contain the `FlightRouterState`.
// In this case, we'll continue to use the existing tree so the router doesn't get into an invalid state.
let treeToRestore;
let renderedSearch;
const historyState = action.historyState;
if (historyState) {
treeToRestore = historyState.tree;
renderedSearch = historyState.renderedSearch;
} else {
treeToRestore = state.tree;
renderedSearch = state.renderedSearch;
}
const currentUrl = new URL(state.canonicalUrl, location.origin);
const restoredUrl = action.url;
const restoredNextUrl = (0, _computechangedpath.extractPathFromFlightRouterState)(treeToRestore) ?? restoredUrl.pathname;
const now = Date.now();
// TODO: Store the dynamic stale time on the top-level state so it's known
// during restores and refreshes.
const accumulation = {
separateRefreshUrls: null,
scrollRef: null
};
const restoreSeed = (0, _navigation.convertServerPatchToFullTree)(now, treeToRestore, null, renderedSearch, _bfcache.UnknownDynamicStaleTime);
const task = (0, _pprnavigations.startPPRNavigation)(now, currentUrl, state.renderedSearch, state.cache, state.tree, restoreSeed.routeTree, restoreSeed.metadataVaryPath, _pprnavigations.FreshnessPolicy.HistoryTraversal, null, null, restoreSeed.dynamicStaleAt, false, accumulation);
if (task === null) {
return (0, _navigation.completeHardNavigation)(state, restoredUrl, 'replace');
}
(0, _pprnavigations.spawnDynamicRequests)(task, restoredUrl, restoredNextUrl, _pprnavigations.FreshnessPolicy.HistoryTraversal, accumulation, // History traversal doesn't use route prediction, so there's no route
// cache entry to mark as having a dynamic rewrite on mismatch. If a
// mismatch occurs, the retry handler will traverse the known route tree
// to find and mark the entry.
null, // History traversal always uses 'replace'.
'replace');
return (0, _navigation.completeTraverseNavigation)(state, restoredUrl, renderedSearch, task.node, task.route, restoredNextUrl);
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=restore-reducer.js.map

View File

@@ -0,0 +1,320 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "serverActionReducer", {
enumerable: true,
get: function() {
return serverActionReducer;
}
});
const _appcallserver = require("../../../app-call-server");
const _appfindsourcemapurl = require("../../../app-find-source-map-url");
const _approuterheaders = require("../../app-router-headers");
const _unrecognizedactionerror = require("../../unrecognized-action-error");
const _client = require("react-server-dom-webpack/client");
const _routerreducertypes = require("../router-reducer-types");
const _assignlocation = require("../../../assign-location");
const _createhreffromurl = require("../create-href-from-url");
const _hasinterceptionrouteincurrenttree = require("./has-interception-route-in-current-tree");
const _flightdatahelpers = require("../../../flight-data-helpers");
const _redirect = require("../../redirect");
const _removebasepath = require("../../../remove-base-path");
const _hasbasepath = require("../../../has-base-path");
const _serverreferenceinfo = require("../../../../shared/lib/server-reference-info");
const _cache = require("../../segment-cache/cache");
const _scheduler = require("../../segment-cache/scheduler");
const _deploymentid = require("../../../../shared/lib/deployment-id");
const _navigationbuildid = require("../../../navigation-build-id");
const _constants = require("../../../../lib/constants");
const _navigation = require("../../segment-cache/navigation");
const _optimisticroutes = require("../../segment-cache/optimistic-routes");
const _actionrevalidationkind = require("../../../../shared/lib/action-revalidation-kind");
const _approuterutils = require("../../app-router-utils");
const _pprnavigations = require("../ppr-navigations");
const _fetchserverresponse = require("../fetch-server-response");
const _bfcache = require("../../segment-cache/bfcache");
const createFromFetch = _client.createFromFetch;
let createDebugChannel;
if (process.env.__NEXT_DEV_SERVER && process.env.__NEXT_REACT_DEBUG_CHANNEL) {
createDebugChannel = require('../../../dev/debug-channel').createDebugChannel;
}
async function fetchServerAction(state, nextUrl, { actionId, actionArgs }) {
const temporaryReferences = (0, _client.createTemporaryReferenceSet)();
const info = (0, _serverreferenceinfo.extractInfoFromServerReferenceId)(actionId);
const usedArgs = (0, _serverreferenceinfo.omitUnusedArgs)(actionArgs, info);
const body = await (0, _client.encodeReply)(usedArgs, {
temporaryReferences
});
const headers = {
Accept: _approuterheaders.RSC_CONTENT_TYPE_HEADER,
[_approuterheaders.ACTION_HEADER]: actionId,
[_approuterheaders.NEXT_ROUTER_STATE_TREE_HEADER]: (0, _flightdatahelpers.prepareFlightRouterStateForRequest)(state.tree)
};
const deploymentId = (0, _deploymentid.getDeploymentId)();
if (deploymentId) {
headers['x-deployment-id'] = deploymentId;
}
if (nextUrl) {
headers[_approuterheaders.NEXT_URL] = nextUrl;
}
if (process.env.__NEXT_DEV_SERVER) {
if (self.__next_r) {
headers[_approuterheaders.NEXT_HTML_REQUEST_ID_HEADER] = self.__next_r;
}
// Create a new request ID for the server action request. The server uses
// this to tag debug information sent via WebSocket to the client, which
// then routes those chunks to the debug channel associated with this ID.
headers[_approuterheaders.NEXT_REQUEST_ID_HEADER] = crypto.getRandomValues(new Uint32Array(1))[0].toString(16);
}
const res = await fetch(state.canonicalUrl, {
method: 'POST',
headers,
body
});
// Handle server actions that the server didn't recognize.
const unrecognizedActionHeader = res.headers.get(_approuterheaders.NEXT_ACTION_NOT_FOUND_HEADER);
if (unrecognizedActionHeader === '1') {
throw Object.defineProperty(new _unrecognizedactionerror.UnrecognizedActionError(`Server Action "${actionId}" was not found on the server. \nRead more: https://nextjs.org/docs/messages/failed-to-find-server-action`), "__NEXT_ERROR_CODE", {
value: "E715",
enumerable: false,
configurable: true
});
}
const redirectHeader = res.headers.get('x-action-redirect');
const [location1, _redirectType] = redirectHeader?.split(';') || [];
let redirectType;
switch(_redirectType){
case 'push':
redirectType = 'push';
break;
case 'replace':
redirectType = 'replace';
break;
default:
redirectType = undefined;
}
const isPrerender = !!res.headers.get(_approuterheaders.NEXT_IS_PRERENDER_HEADER);
let revalidationKind = _actionrevalidationkind.ActionDidNotRevalidate;
try {
const revalidationHeader = res.headers.get('x-action-revalidated');
if (revalidationHeader) {
const parsedKind = JSON.parse(revalidationHeader);
if (parsedKind === _actionrevalidationkind.ActionDidRevalidateStaticAndDynamic || parsedKind === _actionrevalidationkind.ActionDidRevalidateDynamicOnly) {
revalidationKind = parsedKind;
}
}
} catch {}
const redirectLocation = location1 ? (0, _assignlocation.assignLocation)(location1, new URL(state.canonicalUrl, window.location.href)) : undefined;
const contentType = res.headers.get('content-type');
const isRscResponse = !!(contentType && contentType.startsWith(_approuterheaders.RSC_CONTENT_TYPE_HEADER));
// Handle invalid server action responses.
// A valid response must have `content-type: text/x-component`, unless it's an external redirect.
// (external redirects have an 'x-action-redirect' header, but the body is an empty 'text/plain')
if (!isRscResponse && !redirectLocation) {
// The server can respond with a text/plain error message, but we'll fallback to something generic
// if there isn't one.
const message = res.status >= 400 && contentType === 'text/plain' ? await res.text() : 'An unexpected response was received from the server.';
throw Object.defineProperty(new Error(message), "__NEXT_ERROR_CODE", {
value: "E394",
enumerable: false,
configurable: true
});
}
let actionResult;
let actionFlightData;
let actionFlightDataRenderedSearch;
let couldBeIntercepted = false;
if (isRscResponse) {
// Server action redirect responses carry the Flight data of the redirect
// target, which may be prerendered with a completeness marker byte
// prepended. Strip it before passing to Flight.
const responsePromise = redirectLocation ? (0, _fetchserverresponse.processFetch)(res).then(({ response: r })=>r) : Promise.resolve(res);
const response = await createFromFetch(responsePromise, {
callServer: _appcallserver.callServer,
findSourceMapURL: _appfindsourcemapurl.findSourceMapURL,
temporaryReferences,
debugChannel: createDebugChannel && createDebugChannel(headers)
});
// An internal redirect can send an RSC response, but does not have a useful `actionResult`.
actionResult = redirectLocation ? undefined : response.a;
couldBeIntercepted = response.i;
// Check if the response build ID matches the client build ID.
// In a multi-zone setup, when a server action triggers a redirect,
// the server pre-fetches the redirect target as RSC. If the redirect
// target is served by a different Next.js zone (different build), the
// pre-fetched RSC data will have a foreign build ID. We must discard
// the flight data in that case so the redirect triggers an MPA
// navigation (full page load) instead of trying to apply the foreign
// RSC payload — which would result in a blank page.
const responseBuildId = res.headers.get(_constants.NEXT_NAV_DEPLOYMENT_ID_HEADER) ?? response.b;
if (responseBuildId !== undefined && responseBuildId !== (0, _navigationbuildid.getNavigationBuildId)()) {
// Build ID mismatch — discard the flight data. The redirect will
// still be processed, and the absence of flight data will cause an
// MPA navigation via completeHardNavigation().
} else {
const maybeFlightData = (0, _flightdatahelpers.normalizeFlightData)(response.f);
if (maybeFlightData !== '') {
actionFlightData = maybeFlightData;
actionFlightDataRenderedSearch = response.q;
}
}
} else {
// An external redirect doesn't contain RSC data.
actionResult = undefined;
actionFlightData = undefined;
actionFlightDataRenderedSearch = undefined;
}
return {
actionResult,
actionFlightData,
actionFlightDataRenderedSearch,
redirectLocation,
redirectType,
revalidationKind,
isPrerender,
couldBeIntercepted
};
}
function serverActionReducer(state, action) {
const { resolve, reject } = action;
// only pass along the `nextUrl` param (used for interception routes) if the current route was intercepted.
// If the route has been intercepted, the action should be as well.
// Otherwise the server action might be intercepted with the wrong action id
// (ie, one that corresponds with the intercepted route)
const nextUrl = // We always send the last next-url, not the current when
// performing a dynamic request. This is because we update
// the next-url after a navigation, but we want the same
// interception route to be matched that used the last
// next-url.
(state.previousNextUrl || state.nextUrl) && (0, _hasinterceptionrouteincurrenttree.hasInterceptionRouteInCurrentTree)(state.tree) ? state.previousNextUrl || state.nextUrl : null;
return fetchServerAction(state, nextUrl, action).then(async ({ revalidationKind, actionResult, actionFlightData: flightData, actionFlightDataRenderedSearch: flightDataRenderedSearch, redirectLocation, redirectType, isPrerender, couldBeIntercepted })=>{
if (revalidationKind !== _actionrevalidationkind.ActionDidNotRevalidate) {
// There was either a revalidation or a refresh, or maybe both.
// Evict the BFCache, which may contain dynamic data.
(0, _bfcache.invalidateBfCache)();
// Store whether this action triggered any revalidation
// The action queue will use this information to potentially
// trigger a refresh action if the action was discarded
// (ie, due to a navigation, before the action completed)
action.didRevalidate = true;
// If there was a revalidation, evict the prefetch cache.
// TODO: Evict only segments with matching tags and/or paths.
// TODO: We should only invalidate the route cache if cookies were
// mutated, since route trees may vary based on cookies. For now we
// invalidate both caches until we have a way to detect cookie
// mutations on the client.
if (revalidationKind === _actionrevalidationkind.ActionDidRevalidateStaticAndDynamic) {
(0, _cache.invalidateEntirePrefetchCache)(nextUrl, state.tree);
}
// Start a cooldown before re-prefetching to allow CDN cache
// propagation.
(0, _scheduler.startRevalidationCooldown)();
}
const navigateType = redirectType || 'push';
if (redirectLocation !== undefined) {
// If the action triggered a redirect, the action promise will be rejected with
// a redirect so that it's handled by RedirectBoundary as we won't have a valid
// action result to resolve the promise with. This will effectively reset the state of
// the component that called the action as the error boundary will remount the tree.
// The status code doesn't matter here as the action handler will have already sent
// a response with the correct status code.
if ((0, _approuterutils.isExternalURL)(redirectLocation)) {
// External redirect. Triggers an MPA navigation.
const redirectHref = redirectLocation.href;
const redirectError = createRedirectErrorForAction(redirectHref, navigateType);
reject(redirectError);
return (0, _navigation.completeHardNavigation)(state, redirectLocation, navigateType);
} else {
// Internal redirect. Triggers an SPA navigation.
const redirectWithBasepath = (0, _createhreffromurl.createHrefFromUrl)(redirectLocation, false);
const redirectHref = (0, _hasbasepath.hasBasePath)(redirectWithBasepath) ? (0, _removebasepath.removeBasePath)(redirectWithBasepath) : redirectWithBasepath;
const redirectError = createRedirectErrorForAction(redirectHref, navigateType);
reject(redirectError);
}
} else {
// If there's no redirect, resolve the action with the result.
resolve(actionResult);
}
// Check if we can bail out without updating any state.
if (// Did the action trigger a redirect?
redirectLocation === undefined && // Did the action revalidate any data?
revalidationKind === _actionrevalidationkind.ActionDidNotRevalidate && // Did the server render new data?
flightData === undefined) {
// The action did not trigger any revalidations or redirects. No
// navigation is required.
return state;
}
if (flightData === undefined && redirectLocation !== undefined) {
// The server redirected, but did not send any Flight data. This implies
// an external redirect.
// TODO: We should refactor the action response type to be more explicit
// about the various response types.
return (0, _navigation.completeHardNavigation)(state, redirectLocation, navigateType);
}
if (typeof flightData === 'string') {
// If the flight data is just a string, something earlier in the
// response handling triggered an external redirect.
return (0, _navigation.completeHardNavigation)(state, new URL(flightData, location.origin), navigateType);
}
// The action triggered a navigation — either a redirect, a revalidation,
// or both.
// If there was no redirect, then the target URL is the same as the
// current URL.
const currentUrl = new URL(state.canonicalUrl, location.origin);
const currentRenderedSearch = state.renderedSearch;
const redirectUrl = redirectLocation !== undefined ? redirectLocation : currentUrl;
const currentFlightRouterState = state.tree;
const scrollBehavior = _routerreducertypes.ScrollBehavior.Default;
// If the action triggered a revalidation of the cache, we should also
// refresh all the dynamic data.
const freshnessPolicy = revalidationKind === _actionrevalidationkind.ActionDidNotRevalidate ? _pprnavigations.FreshnessPolicy.Default : _pprnavigations.FreshnessPolicy.RefreshAll;
// The server may have sent back new data. If so, we will perform a
// "seeded" navigation that uses the data from the response.
// TODO: Currently the server always renders from the root in
// response to a Server Action. In the case of a normal redirect
// with no revalidation, it should skip over the shared layouts.
if (flightData !== undefined && flightDataRenderedSearch !== undefined) {
// The server sent back new route data as part of the response. We
// will use this to render the new page. If this happens to be only a
// subset of the data needed to render the new page, we'll initiate a
// new fetch, like we would for a normal navigation.
const redirectCanonicalUrl = (0, _createhreffromurl.createHrefFromUrl)(redirectUrl);
const now = Date.now();
// TODO: Store the dynamic stale time on the top-level state so it's
// known during restores and refreshes.
const redirectSeed = (0, _navigation.convertServerPatchToFullTree)(now, currentFlightRouterState, flightData, flightDataRenderedSearch, _bfcache.UnknownDynamicStaleTime);
// Learn the route pattern so we can predict it for future navigations.
const metadataVaryPath = redirectSeed.metadataVaryPath;
if (metadataVaryPath !== null) {
(0, _optimisticroutes.discoverKnownRoute)(now, redirectUrl.pathname, nextUrl, null, redirectSeed.routeTree, metadataVaryPath, couldBeIntercepted, redirectCanonicalUrl, isPrerender, false // hasDynamicRewrite
);
}
return (0, _navigation.navigateToKnownRoute)(now, state, redirectUrl, redirectCanonicalUrl, redirectSeed, currentUrl, currentRenderedSearch, state.cache, currentFlightRouterState, freshnessPolicy, nextUrl, scrollBehavior, navigateType, null, // Server action redirects don't use route prediction - we already
// have the route tree from the server response. If a mismatch occurs
// during dynamic data fetch, the retry handler will traverse the
// known route tree to mark the entry as having a dynamic rewrite.
null);
}
// The server did not send back new data. We'll perform a regular, non-
// seeded navigation — effectively the same as <Link> or router.push().
return (0, _navigation.navigate)(state, redirectUrl, currentUrl, currentRenderedSearch, state.cache, currentFlightRouterState, nextUrl, freshnessPolicy, scrollBehavior, navigateType);
}, (e)=>{
// When the server action is rejected we don't update the state and instead call the reject handler of the promise.
reject(e);
return state;
});
}
function createRedirectErrorForAction(redirectHref, resolvedRedirectType) {
const redirectError = (0, _redirect.getRedirectError)(redirectHref, resolvedRedirectType);
redirectError.handled = true;
return redirectError;
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=server-action-reducer.js.map

View File

@@ -0,0 +1,58 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "serverPatchReducer", {
enumerable: true,
get: function() {
return serverPatchReducer;
}
});
const _createhreffromurl = require("../create-href-from-url");
const _routerreducertypes = require("../router-reducer-types");
const _navigation = require("../../segment-cache/navigation");
const _refreshreducer = require("./refresh-reducer");
const _pprnavigations = require("../ppr-navigations");
function serverPatchReducer(state, action) {
// A "retry" is a navigation that happens due to a route mismatch. It's
// similar to a refresh, because we will omit any existing dynamic data on
// the page. But we seed the retry navigation with the exact tree that the
// server just responded with.
const retryMpa = action.mpa;
const retryUrl = new URL(action.url, location.origin);
const retrySeed = action.seed;
const navigateType = action.navigateType;
if (retryMpa || retrySeed === null) {
// If the server did not send back data during the mismatch, fall back to
// an MPA navigation.
return (0, _navigation.completeHardNavigation)(state, retryUrl, navigateType);
}
const currentUrl = new URL(state.canonicalUrl, location.origin);
const currentRenderedSearch = state.renderedSearch;
if (action.previousTree !== state.tree) {
// There was another, more recent navigation since the once that
// mismatched. We can abort the retry, but we still need to refresh the
// page to evict any stale dynamic data.
return (0, _refreshreducer.refreshReducer)(state, {
type: _routerreducertypes.ACTION_REFRESH
});
}
// There have been no new navigations since the mismatched one. Refresh,
// using the tree we just received from the server.
const retryCanonicalUrl = (0, _createhreffromurl.createHrefFromUrl)(retryUrl);
const retryNextUrl = action.nextUrl;
const scrollBehavior = _routerreducertypes.ScrollBehavior.Default;
const now = Date.now();
return (0, _navigation.navigateToKnownRoute)(now, state, retryUrl, retryCanonicalUrl, retrySeed, currentUrl, currentRenderedSearch, state.cache, state.tree, _pprnavigations.FreshnessPolicy.RefreshAll, retryNextUrl, scrollBehavior, navigateType, null, // Server patch (retry) navigations don't use route prediction. This is
// typically a retry after a previous mismatch, so the route was already
// marked as having a dynamic rewrite when the mismatch was detected.
null);
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=server-patch-reducer.js.map

View File

@@ -0,0 +1,70 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
ACTION_HMR_REFRESH: null,
ACTION_NAVIGATE: null,
ACTION_REFRESH: null,
ACTION_RESTORE: null,
ACTION_SERVER_ACTION: null,
ACTION_SERVER_PATCH: null,
PrefetchKind: null,
ScrollBehavior: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
ACTION_HMR_REFRESH: function() {
return ACTION_HMR_REFRESH;
},
ACTION_NAVIGATE: function() {
return ACTION_NAVIGATE;
},
ACTION_REFRESH: function() {
return ACTION_REFRESH;
},
ACTION_RESTORE: function() {
return ACTION_RESTORE;
},
ACTION_SERVER_ACTION: function() {
return ACTION_SERVER_ACTION;
},
ACTION_SERVER_PATCH: function() {
return ACTION_SERVER_PATCH;
},
PrefetchKind: function() {
return PrefetchKind;
},
ScrollBehavior: function() {
return ScrollBehavior;
}
});
const ACTION_REFRESH = 'refresh';
const ACTION_NAVIGATE = 'navigate';
const ACTION_RESTORE = 'restore';
const ACTION_SERVER_PATCH = 'server-patch';
const ACTION_HMR_REFRESH = 'hmr-refresh';
const ACTION_SERVER_ACTION = 'server-action';
var PrefetchKind = /*#__PURE__*/ function(PrefetchKind) {
PrefetchKind["AUTO"] = "auto";
PrefetchKind["FULL"] = "full";
return PrefetchKind;
}({});
var ScrollBehavior = /*#__PURE__*/ function(ScrollBehavior) {
/** Use per-node ScrollRef to decide whether to scroll. */ ScrollBehavior[ScrollBehavior["Default"] = 0] = "Default";
/** Suppress scroll entirely (e.g. scroll={false} on Link or router.push). */ ScrollBehavior[ScrollBehavior["NoScroll"] = 1] = "NoScroll";
return ScrollBehavior;
}({});
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=router-reducer-types.js.map

View File

@@ -0,0 +1,66 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "reducer", {
enumerable: true,
get: function() {
return reducer;
}
});
const _routerreducertypes = require("./router-reducer-types");
const _navigatereducer = require("./reducers/navigate-reducer");
const _serverpatchreducer = require("./reducers/server-patch-reducer");
const _restorereducer = require("./reducers/restore-reducer");
const _refreshreducer = require("./reducers/refresh-reducer");
const _hmrrefreshreducer = require("./reducers/hmr-refresh-reducer");
const _serveractionreducer = require("./reducers/server-action-reducer");
/**
* Reducer that handles the app-router state updates.
*/ function clientReducer(state, action) {
switch(action.type){
case _routerreducertypes.ACTION_NAVIGATE:
{
return (0, _navigatereducer.navigateReducer)(state, action);
}
case _routerreducertypes.ACTION_SERVER_PATCH:
{
return (0, _serverpatchreducer.serverPatchReducer)(state, action);
}
case _routerreducertypes.ACTION_RESTORE:
{
return (0, _restorereducer.restoreReducer)(state, action);
}
case _routerreducertypes.ACTION_REFRESH:
{
return (0, _refreshreducer.refreshReducer)(state, action);
}
case _routerreducertypes.ACTION_HMR_REFRESH:
{
return (0, _hmrrefreshreducer.hmrRefreshReducer)(state);
}
case _routerreducertypes.ACTION_SERVER_ACTION:
{
return (0, _serveractionreducer.serverActionReducer)(state, action);
}
// This case should never be hit as dispatch is strongly typed.
default:
throw Object.defineProperty(new Error('Unknown action'), "__NEXT_ERROR_CODE", {
value: "E295",
enumerable: false,
configurable: true
});
}
}
function serverReducer(state, _action) {
return state;
}
const reducer = typeof window === 'undefined' ? serverReducer : clientReducer;
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=router-reducer.js.map

View File

@@ -0,0 +1,66 @@
'use client';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
setCacheBustingSearchParam: null,
setCacheBustingSearchParamWithHash: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
setCacheBustingSearchParam: function() {
return setCacheBustingSearchParam;
},
setCacheBustingSearchParamWithHash: function() {
return setCacheBustingSearchParamWithHash;
}
});
const _cachebustingsearchparam = require("../../../shared/lib/router/utils/cache-busting-search-param");
const _approuterheaders = require("../app-router-headers");
async function computeClientCacheBustingSearchParam(headers) {
if (typeof globalThis.crypto?.subtle?.digest === 'function') {
return (0, _cachebustingsearchparam.computeCacheBustingSearchParam)(headers[_approuterheaders.NEXT_ROUTER_PREFETCH_HEADER], headers[_approuterheaders.NEXT_ROUTER_SEGMENT_PREFETCH_HEADER], headers[_approuterheaders.NEXT_ROUTER_STATE_TREE_HEADER], headers[_approuterheaders.NEXT_URL]);
}
return (0, _cachebustingsearchparam.computeLegacyCacheBustingSearchParam)(headers[_approuterheaders.NEXT_ROUTER_PREFETCH_HEADER], headers[_approuterheaders.NEXT_ROUTER_SEGMENT_PREFETCH_HEADER], headers[_approuterheaders.NEXT_ROUTER_STATE_TREE_HEADER], headers[_approuterheaders.NEXT_URL]);
}
const setCacheBustingSearchParam = async (url, headers)=>{
const uniqueCacheKey = await computeClientCacheBustingSearchParam(headers);
setCacheBustingSearchParamWithHash(url, uniqueCacheKey);
};
const setCacheBustingSearchParamWithHash = (url, hash)=>{
/**
* Note that we intentionally do not use `url.searchParams.set` here:
*
* const url = new URL('https://example.com/search?q=custom%20spacing');
* url.searchParams.set('_rsc', 'abc123');
* console.log(url.toString()); // Outputs: https://example.com/search?q=custom+spacing&_rsc=abc123
* ^ <--- this is causing confusion
* This is in fact intended based on https://url.spec.whatwg.org/#interface-urlsearchparams, but
* we want to preserve the %20 as %20 if that's what the user passed in, hence the custom
* logic below.
*/ const existingSearch = url.search;
const rawQuery = existingSearch.startsWith('?') ? existingSearch.slice(1) : existingSearch;
// Always remove any existing cache busting param and add a fresh one to ensure
// we have the correct value based on current request headers
const pairs = rawQuery.split('&').filter((pair)=>pair && !pair.startsWith(`${_approuterheaders.NEXT_RSC_UNION_QUERY}=`));
if (hash.length > 0) {
pairs.push(`${_approuterheaders.NEXT_RSC_UNION_QUERY}=${hash}`);
} else {
pairs.push(`${_approuterheaders.NEXT_RSC_UNION_QUERY}`);
}
url.search = pairs.length ? `?${pairs.join('&')}` : '';
};
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=set-cache-busting-search-param.js.map

View File

@@ -0,0 +1,128 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
UnknownDynamicStaleTime: null,
computeDynamicStaleAt: null,
invalidateBfCache: null,
readFromBFCache: null,
readFromBFCacheDuringRegularNavigation: null,
updateBFCacheEntryStaleAt: null,
writeHeadToBFCache: null,
writeToBFCache: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
UnknownDynamicStaleTime: function() {
return UnknownDynamicStaleTime;
},
computeDynamicStaleAt: function() {
return computeDynamicStaleAt;
},
invalidateBfCache: function() {
return invalidateBfCache;
},
readFromBFCache: function() {
return readFromBFCache;
},
readFromBFCacheDuringRegularNavigation: function() {
return readFromBFCacheDuringRegularNavigation;
},
updateBFCacheEntryStaleAt: function() {
return updateBFCacheEntryStaleAt;
},
writeHeadToBFCache: function() {
return writeHeadToBFCache;
},
writeToBFCache: function() {
return writeToBFCache;
}
});
const _navigatereducer = require("../router-reducer/reducers/navigate-reducer");
const _cachemap = require("./cache-map");
const UnknownDynamicStaleTime = -1;
function computeDynamicStaleAt(now, dynamicStaleTimeSeconds) {
return dynamicStaleTimeSeconds !== UnknownDynamicStaleTime ? now + dynamicStaleTimeSeconds * 1000 : now + _navigatereducer.DYNAMIC_STALETIME_MS;
}
const bfcacheMap = (0, _cachemap.createCacheMap)();
let currentBfCacheVersion = 0;
function invalidateBfCache() {
if (typeof window === 'undefined') {
return;
}
currentBfCacheVersion++;
}
function writeToBFCache(now, varyPath, rsc, prefetchRsc, head, prefetchHead, dynamicStaleAt) {
if (typeof window === 'undefined') {
return;
}
const entry = {
rsc,
prefetchRsc,
// TODO: These fields will be removed from both BFCacheEntry and
// SegmentCacheEntry. The head has its own separate cache entry.
head,
prefetchHead,
ref: null,
// TODO: This is just a heuristic. Getting the actual size of the segment
// isn't feasible because it's part of a larger streaming response. The
// LRU will still evict it, we just won't have a fully accurate total
// LRU size. However, we'll probably remove the size tracking from the LRU
// entirely and use memory pressure events instead.
size: 100,
navigatedAt: now,
// A back/forward navigation will disregard the stale time. This field is
// only relevant when staleTimes.dynamic is enabled or unstable_dynamicStaleTime
// is exported by a page.
staleAt: dynamicStaleAt,
version: currentBfCacheVersion
};
const isRevalidation = false;
(0, _cachemap.setInCacheMap)(bfcacheMap, varyPath, entry, isRevalidation);
}
function writeHeadToBFCache(now, varyPath, head, prefetchHead, dynamicStaleAt) {
// Read the special "segment" that represents the head data.
writeToBFCache(now, varyPath, head, prefetchHead, null, null, dynamicStaleAt);
}
function updateBFCacheEntryStaleAt(varyPath, newStaleAt) {
if (typeof window === 'undefined') {
return;
}
const isRevalidation = false;
// Read with staleness bypass (-1) so we can update even stale entries
const entry = (0, _cachemap.getFromCacheMap)(-1, currentBfCacheVersion, bfcacheMap, varyPath, isRevalidation);
if (entry !== null) {
entry.staleAt = newStaleAt;
}
}
function readFromBFCache(varyPath) {
if (typeof window === 'undefined') {
return null;
}
const isRevalidation = false;
return (0, _cachemap.getFromCacheMap)(// During a back/forward navigation, it doesn't matter how stale the data
// might be. Pass -1 instead of the actual current time to bypass
// staleness checks.
-1, currentBfCacheVersion, bfcacheMap, varyPath, isRevalidation);
}
function readFromBFCacheDuringRegularNavigation(now, varyPath) {
if (typeof window === 'undefined') {
return null;
}
const isRevalidation = false;
return (0, _cachemap.getFromCacheMap)(now, currentBfCacheVersion, bfcacheMap, varyPath, isRevalidation);
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=bfcache.js.map

View File

@@ -0,0 +1,28 @@
// TypeScript trick to simulate opaque types, like in Flow.
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "createCacheKey", {
enumerable: true,
get: function() {
return createCacheKey;
}
});
function createCacheKey(originalHref, nextUrl) {
const originalUrl = new URL(originalHref);
const cacheKey = {
pathname: originalUrl.pathname,
search: originalUrl.search,
nextUrl: nextUrl
};
return cacheKey;
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=cache-key.js.map

View File

@@ -0,0 +1,305 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
Fallback: null,
createCacheMap: null,
deleteFromCacheMap: null,
deleteMapEntry: null,
getFromCacheMap: null,
isValueExpired: null,
setInCacheMap: null,
setSizeInCacheMap: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
Fallback: function() {
return Fallback;
},
createCacheMap: function() {
return createCacheMap;
},
deleteFromCacheMap: function() {
return deleteFromCacheMap;
},
deleteMapEntry: function() {
return deleteMapEntry;
},
getFromCacheMap: function() {
return getFromCacheMap;
},
isValueExpired: function() {
return isValueExpired;
},
setInCacheMap: function() {
return setInCacheMap;
},
setSizeInCacheMap: function() {
return setSizeInCacheMap;
}
});
const _lru = require("./lru");
const Fallback = {};
// This is a special internal key that is used for "revalidation" entries. It's
// an implementation detail that shouldn't leak outside of this module.
const Revalidation = {};
function createCacheMap() {
const cacheMap = {
parent: null,
key: null,
value: null,
map: null,
// LRU-related fields
prev: null,
next: null,
size: 0
};
return cacheMap;
}
function getOrInitialize(cacheMap, keys, isRevalidation) {
// Go through each level of keys until we find the entry that matches, or
// create a new entry if one doesn't exist.
//
// This function will only return entries that match the keypath _exactly_.
// Unlike getWithFallback, it will not access fallback entries unless it's
// explicitly part of the keypath.
let entry = cacheMap;
let remainingKeys = keys;
let key = null;
while(true){
const previousKey = key;
if (remainingKeys !== null) {
key = remainingKeys.value;
remainingKeys = remainingKeys.parent;
} else if (isRevalidation && previousKey !== Revalidation) {
// During a revalidation, we append an internal "Revalidation" key to
// the end of the keypath. The "normal" entry is its parent.
// However, if the parent entry is currently empty, we don't need to store
// this as a revalidation entry. Just insert the revalidation into the
// normal slot.
if (entry.value === null) {
return entry;
}
// Otheriwse, create a child entry.
key = Revalidation;
} else {
break;
}
let map = entry.map;
if (map !== null) {
const existingEntry = map.get(key);
if (existingEntry !== undefined) {
// Found a match. Keep going.
entry = existingEntry;
continue;
}
} else {
map = new Map();
entry.map = map;
}
// No entry exists yet at this level. Create a new one.
const newEntry = {
parent: entry,
key,
value: null,
map: null,
// LRU-related fields
prev: null,
next: null,
size: 0
};
map.set(key, newEntry);
entry = newEntry;
}
return entry;
}
function getFromCacheMap(now, currentCacheVersion, rootEntry, keys, isRevalidation) {
const entry = getEntryWithFallbackImpl(now, currentCacheVersion, rootEntry, keys, isRevalidation, 0);
if (entry === null || entry.value === null) {
return null;
}
// This is an LRU access. Move the entry to the front of the list.
(0, _lru.lruPut)(entry);
return entry.value;
}
function isValueExpired(now, currentCacheVersion, value) {
return value.staleAt <= now || value.version < currentCacheVersion;
}
function lazilyEvictIfNeeded(now, currentCacheVersion, entry) {
// We have a matching entry, but before we can return it, we need to check if
// it's still fresh. Otherwise it should be treated the same as a cache miss.
if (entry.value === null) {
// This entry has no value, so there's nothing to evict.
return entry;
}
const value = entry.value;
if (isValueExpired(now, currentCacheVersion, value)) {
// The value expired. Lazily evict it from the cache, and return null. This
// is conceptually the same as a cache miss.
deleteMapEntry(entry);
return null;
}
// The matched entry has not expired. Return it.
return entry;
}
function getEntryWithFallbackImpl(now, currentCacheVersion, entry, keys, isRevalidation, previousKey) {
// This is similar to getExactEntry, but if an exact match is not found for
// a key, it will return the fallback entry instead. This is recursive at
// every level, e.g. an entry with keypath [a, Fallback, c, Fallback] is
// valid match for [a, b, c, d].
//
// It will return the most specific match available.
let key;
let remainingKeys;
if (keys !== null) {
key = keys.value;
remainingKeys = keys.parent;
} else if (isRevalidation && previousKey !== Revalidation) {
// During a revalidation, we append an internal "Revalidation" key to
// the end of the keypath.
key = Revalidation;
remainingKeys = null;
} else {
// There are no more keys. This is the terminal entry.
// TODO: When performing a lookup during a navigation, as opposed to a
// prefetch, we may want to skip entries that are Pending if there's also
// a Fulfilled fallback entry. Tricky to say, though, since if it's
// already pending, it's likely to stream in soon. Maybe we could do this
// just on slow connections and offline mode.
return lazilyEvictIfNeeded(now, currentCacheVersion, entry);
}
const map = entry.map;
if (map !== null) {
const existingEntry = map.get(key);
if (existingEntry !== undefined) {
// Found an exact match for this key. Keep searching.
const result = getEntryWithFallbackImpl(now, currentCacheVersion, existingEntry, remainingKeys, isRevalidation, key);
if (result !== null) {
return result;
}
}
// No match found for this key. Check if there's a fallback.
const fallbackEntry = map.get(Fallback);
if (fallbackEntry !== undefined) {
// Found a fallback for this key. Keep searching.
return getEntryWithFallbackImpl(now, currentCacheVersion, fallbackEntry, remainingKeys, isRevalidation, key);
}
}
return null;
}
function setInCacheMap(cacheMap, keys, value, isRevalidation) {
// Add a value to the map at the given keypath. If the value is already
// part of the map, it's removed from its previous keypath. (NOTE: This is
// unlike a regular JS map, but the behavior is intentional.)
const entry = getOrInitialize(cacheMap, keys, isRevalidation);
setMapEntryValue(entry, value);
// This is an LRU access. Move the entry to the front of the list.
(0, _lru.lruPut)(entry);
(0, _lru.updateLruSize)(entry, value.size);
}
function setMapEntryValue(entry, value) {
if (entry.value !== null) {
// There's already a value at the given keypath. Disconnect the old value
// from the map. We're not calling `deleteMapEntry` here because the
// entry itself is still in the map. We just want to overwrite its value.
dropRef(entry.value);
entry.value = null;
}
// This value may already be in the map at a different keypath.
// Grab a reference before we overwrite it.
const oldEntry = value.ref;
entry.value = value;
value.ref = entry;
(0, _lru.updateLruSize)(entry, value.size);
if (oldEntry !== null && oldEntry !== entry && oldEntry.value === value) {
// This value is already in the map at a different keypath in the map.
// Values only exist at a single keypath at a time. Remove it from the
// previous keypath.
//
// Note that only the internal map entry is garbage collected; we don't
// call `dropRef` here because it's still in the map, just
// at a new keypath (the one we just set, above).
deleteMapEntry(oldEntry);
}
}
function deleteFromCacheMap(value) {
const entry = value.ref;
if (entry === null) {
// This value is not a member of any map.
return;
}
dropRef(value);
deleteMapEntry(entry);
}
function dropRef(value) {
// Drop the value from the map by setting its `ref` backpointer to
// null. This is a separate operation from `deleteMapEntry` because when
// re-keying a value we need to be able to delete the old, internal map
// entry without garbage collecting the value itself.
value.ref = null;
}
function deleteMapEntry(entry) {
// Delete the entry from the cache.
entry.value = null;
(0, _lru.deleteFromLru)(entry);
// Check if we can garbage collect the entry.
const map = entry.map;
if (map === null) {
// Since this entry has no value, and also no child entries, we can
// garbage collect it. Remove it from its parent, and keep garbage
// collecting the parents until we reach a non-empty entry.
let parent = entry.parent;
let key = entry.key;
while(parent !== null){
const parentMap = parent.map;
if (parentMap !== null) {
parentMap.delete(key);
if (parentMap.size === 0) {
// We just removed the last entry in the parent map.
parent.map = null;
if (parent.value === null) {
// The parent node has no child entries, nor does it have a value
// on itself. It can be garbage collected. Keep going.
key = parent.key;
parent = parent.parent;
continue;
}
}
}
break;
}
} else {
// Check if there's a revalidating entry. If so, promote it to a
// "normal" entry, since the normal one was just deleted.
const revalidatingEntry = map.get(Revalidation);
if (revalidatingEntry !== undefined && revalidatingEntry.value !== null) {
setMapEntryValue(entry, revalidatingEntry.value);
}
}
}
function setSizeInCacheMap(value, size) {
const entry = value.ref;
if (entry === null) {
// This value is not a member of any map.
return;
}
// Except during initialization (when the size is set to 0), this is the only
// place the `size` field should be updated, to ensure it's in sync with the
// the LRU.
value.size = size;
(0, _lru.updateLruSize)(entry, size);
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=cache-map.js.map

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,152 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
cleanup: null,
deleteFromLru: null,
lruPut: null,
updateLruSize: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
cleanup: function() {
return cleanup;
},
deleteFromLru: function() {
return deleteFromLru;
},
lruPut: function() {
return lruPut;
},
updateLruSize: function() {
return updateLruSize;
}
});
const _cachemap = require("./cache-map");
const _scheduler = require("./scheduler");
// We use an LRU for memory management. We must update this whenever we add or
// remove a new cache entry, or when an entry changes size.
let head = null;
let lruSize = 0;
// TODO: I chose the max size somewhat arbitrarily. Consider setting this based
// on navigator.deviceMemory, or some other heuristic. We should make this
// customizable via the Next.js config, too.
const maxLruSize = 50 * 1024 * 1024 // 50 MB
;
function lruPut(node) {
if (head === node) {
// Already at the head
return;
}
const prev = node.prev;
const next = node.next;
if (next === null || prev === null) {
// This is an insertion
lruSize += node.size;
// Whenever we add an entry, we need to check if we've exceeded the
// max size. We don't evict entries immediately; they're evicted later in
// an asynchronous task.
ensureCleanupIsScheduled();
} else {
// This is a move. Remove from its current position.
prev.next = next;
next.prev = prev;
}
// Move to the front of the list
if (head === null) {
// This is the first entry
node.prev = node;
node.next = node;
} else {
// Add to the front of the list
const tail = head.prev;
node.prev = tail;
// In practice, this is never null, but that isn't encoded in the type
if (tail !== null) {
tail.next = node;
}
node.next = head;
head.prev = node;
}
head = node;
}
function updateLruSize(node, newNodeSize) {
// This is a separate function from `put` so that we can resize the entry
// regardless of whether it's currently being tracked by the LRU.
const prevNodeSize = node.size;
node.size = newNodeSize;
if (node.next === null) {
// This entry is not currently being tracked by the LRU.
return;
}
// Update the total LRU size
lruSize = lruSize - prevNodeSize + newNodeSize;
ensureCleanupIsScheduled();
}
function deleteFromLru(deleted) {
const next = deleted.next;
const prev = deleted.prev;
if (next !== null && prev !== null) {
lruSize -= deleted.size;
deleted.next = null;
deleted.prev = null;
// Remove from the list
if (head === deleted) {
// Update the head
if (next === head) {
// This was the last entry
head = null;
} else {
head = next;
prev.next = next;
next.prev = prev;
}
} else {
prev.next = next;
next.prev = prev;
}
} else {
// Already deleted
}
}
function ensureCleanupIsScheduled() {
if (lruSize <= maxLruSize) {
return;
}
// To schedule cleanup, ping the prefetch scheduler. At the end of its work
// loop, once there are no queued tasks and no in-progress requests, it will
// call cleanup().
(0, _scheduler.pingPrefetchScheduler)();
}
function cleanup() {
if (lruSize <= maxLruSize) {
return;
}
// Evict entries until we're at 90% capacity. We can assume this won't
// infinite loop because even if `maxLruSize` were 0, eventually
// `deleteFromLru` sets `head` to `null` when we run out entries.
const ninetyPercentMax = maxLruSize * 0.9;
while(lruSize > ninetyPercentMax && head !== null){
const tail = head.prev;
// In practice, this is never null, but that isn't encoded in the type
if (tail !== null) {
// Delete the entry from the map. In turn, this will remove it from
// the LRU.
(0, _cachemap.deleteMapEntry)(tail);
}
}
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=lru.js.map

View File

@@ -0,0 +1,194 @@
/**
* Navigation lock for the Instant Navigation Testing API.
*
* Manages the in-memory lock (a promise) that gates dynamic data writes
* during instant navigation captures, and owns all cookie state
* transitions (pending → captured-MPA, pending → captured-SPA).
*
* External actors (Playwright, devtools) set [0] to start a lock scope
* and delete the cookie to end one. Next.js writes captured values.
* The CookieStore handler distinguishes them by value: pending = external,
* captured = self-write (ignored).
*/ "use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
isNavigationLocked: null,
startListeningForInstantNavigationCookie: null,
transitionToCapturedSPA: null,
updateCapturedSPAToTree: null,
waitForNavigationLockIfActive: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
isNavigationLocked: function() {
return isNavigationLocked;
},
startListeningForInstantNavigationCookie: function() {
return startListeningForInstantNavigationCookie;
},
transitionToCapturedSPA: function() {
return transitionToCapturedSPA;
},
updateCapturedSPAToTree: function() {
return updateCapturedSPAToTree;
},
waitForNavigationLockIfActive: function() {
return waitForNavigationLockIfActive;
}
});
const _approuterheaders = require("../app-router-headers");
const _useactionqueue = require("../use-action-queue");
function parseCookieValue(raw) {
try {
const parsed = JSON.parse(raw);
if (Array.isArray(parsed) && parsed.length >= 3) {
const rawState = parsed[2];
return rawState === null ? 'mpa' : 'spa';
}
} catch {}
return 'pending';
}
function writeCookieValue(value) {
if (typeof cookieStore === 'undefined') {
return;
}
// Read the existing cookie to preserve its attributes (domain, path),
// then write back with the new value. This updates the same cookie
// entry that the external actor created, regardless of how it was
// scoped.
cookieStore.get(_approuterheaders.NEXT_INSTANT_TEST_COOKIE).then((existing)=>{
if (existing) {
const options = {
name: _approuterheaders.NEXT_INSTANT_TEST_COOKIE,
value: JSON.stringify(value),
path: existing.path ?? '/'
};
if (existing.domain) {
options.domain = existing.domain;
}
cookieStore.set(options);
}
});
}
let lockState = null;
function acquireLock() {
if (lockState !== null) {
return;
}
let resolve;
const promise = new Promise((r)=>{
resolve = r;
});
lockState = {
promise,
resolve: resolve
};
}
function releaseLock() {
if (lockState !== null) {
lockState.resolve();
lockState = null;
}
}
function startListeningForInstantNavigationCookie() {
if (process.env.__NEXT_EXPOSE_TESTING_API) {
// If the server served a static shell, this is an MPA page load
// while the lock is held. Transition to captured-MPA and acquire.
if (self.__next_instant_test) {
if (typeof cookieStore !== 'undefined') {
// If the cookie was already cleared during the MPA page
// transition, reload to get the full dynamic page.
cookieStore.get(_approuterheaders.NEXT_INSTANT_TEST_COOKIE).then((cookie)=>{
if (!cookie) {
window.location.reload();
}
});
}
writeCookieValue([
1,
`c${Math.random()}`,
null
]);
acquireLock();
}
if (typeof cookieStore === 'undefined') {
return;
}
cookieStore.addEventListener('change', (event)=>{
for (const cookie of event.changed){
if (cookie.name === _approuterheaders.NEXT_INSTANT_TEST_COOKIE) {
const state = parseCookieValue(cookie.value ?? '');
if (state !== 'pending') {
// Captured value — our own transition. Ignore.
return;
}
// Pending value — external actor starting a new lock scope.
if (lockState !== null) {
releaseLock();
}
acquireLock();
return;
}
}
for (const cookie of event.deleted){
if (cookie.name === _approuterheaders.NEXT_INSTANT_TEST_COOKIE) {
releaseLock();
(0, _useactionqueue.refreshOnInstantNavigationUnlock)();
return;
}
}
});
}
}
function transitionToCapturedSPA(fromTree, toTree) {
if (process.env.__NEXT_EXPOSE_TESTING_API) {
writeCookieValue([
1,
`c${Math.random()}`,
{
from: fromTree,
to: toTree
}
]);
}
}
function updateCapturedSPAToTree(fromTree, toTree) {
if (process.env.__NEXT_EXPOSE_TESTING_API) {
writeCookieValue([
1,
`c${Math.random()}`,
{
from: fromTree,
to: toTree
}
]);
}
}
function isNavigationLocked() {
if (process.env.__NEXT_EXPOSE_TESTING_API) {
return lockState !== null;
}
return false;
}
async function waitForNavigationLockIfActive() {
if (process.env.__NEXT_EXPOSE_TESTING_API) {
if (lockState !== null) {
await lockState.promise;
}
}
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=navigation-testing-lock.js.map

View File

@@ -0,0 +1,597 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
completeHardNavigation: null,
completeSoftNavigation: null,
completeTraverseNavigation: null,
convertServerPatchToFullTree: null,
navigate: null,
navigateToKnownRoute: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
completeHardNavigation: function() {
return completeHardNavigation;
},
completeSoftNavigation: function() {
return completeSoftNavigation;
},
completeTraverseNavigation: function() {
return completeTraverseNavigation;
},
convertServerPatchToFullTree: function() {
return convertServerPatchToFullTree;
},
navigate: function() {
return navigate;
},
navigateToKnownRoute: function() {
return navigateToKnownRoute;
}
});
const _fetchserverresponse = require("../router-reducer/fetch-server-response");
const _pprnavigations = require("../router-reducer/ppr-navigations");
const _createhreffromurl = require("../router-reducer/create-href-from-url");
const _constants = require("../../../lib/constants");
const _cache = require("./cache");
const _optimisticroutes = require("./optimistic-routes");
const _cachekey = require("./cache-key");
const _scheduler = require("./scheduler");
const _types = require("./types");
const _links = require("../links");
const _routerreducertypes = require("../router-reducer/router-reducer-types");
const _computechangedpath = require("../router-reducer/compute-changed-path");
const _javascripturl = require("../../lib/javascript-url");
const _bfcache = require("./bfcache");
function navigate(state, url, currentUrl, currentRenderedSearch, currentCacheNode, currentFlightRouterState, nextUrl, freshnessPolicy, scrollBehavior, navigateType) {
// Instant Navigation Testing API: when the lock is active, ensure a
// prefetch task has been initiated before proceeding with the navigation.
// This guarantees that segment data requests are at least pending, even
// for routes that already have a cached route tree. Without this, the
// static shell might be incomplete because some segments were never
// requested.
if (process.env.__NEXT_EXPOSE_TESTING_API) {
const { isNavigationLocked } = require('./navigation-testing-lock');
if (isNavigationLocked()) {
return ensurePrefetchThenNavigate(state, url, currentUrl, currentRenderedSearch, currentCacheNode, currentFlightRouterState, nextUrl, freshnessPolicy, scrollBehavior, navigateType);
}
}
return navigateImpl(state, url, currentUrl, currentRenderedSearch, currentCacheNode, currentFlightRouterState, nextUrl, freshnessPolicy, scrollBehavior, navigateType);
}
function navigateImpl(state, url, currentUrl, currentRenderedSearch, currentCacheNode, currentFlightRouterState, nextUrl, freshnessPolicy, scrollBehavior, navigateType) {
const now = Date.now();
const href = url.href;
const cacheKey = (0, _cachekey.createCacheKey)(href, nextUrl);
const route = (0, _cache.readRouteCacheEntry)(now, cacheKey);
if (route !== null && route.status === _cache.EntryStatus.Fulfilled) {
// We have a matching prefetch.
return navigateUsingPrefetchedRouteTree(now, state, url, currentUrl, currentRenderedSearch, nextUrl, currentCacheNode, currentFlightRouterState, freshnessPolicy, scrollBehavior, navigateType, route);
}
// There was no matching route tree in the cache. Let's see if we can
// construct an "optimistic" route tree using the deprecated search-params
// based matching. This is only used when the new optimisticRouting flag is
// disabled.
//
// Do not construct an optimistic route tree if there was a cache hit, but
// the entry has a rejected status, since it may have been rejected due to a
// rewrite or redirect based on the search params.
//
// TODO: There are multiple reasons a prefetch might be rejected; we should
// track them explicitly and choose what to do here based on that.
if (!process.env.__NEXT_OPTIMISTIC_ROUTING) {
if (route === null || route.status !== _cache.EntryStatus.Rejected) {
const optimisticRoute = (0, _cache.deprecated_requestOptimisticRouteCacheEntry)(now, url, nextUrl);
if (optimisticRoute !== null) {
// We have an optimistic route tree. Proceed with the normal flow.
return navigateUsingPrefetchedRouteTree(now, state, url, currentUrl, currentRenderedSearch, nextUrl, currentCacheNode, currentFlightRouterState, freshnessPolicy, scrollBehavior, navigateType, optimisticRoute);
}
}
}
// There's no matching prefetch for this route in the cache. We must lazily
// fetch it from the server before we can perform the navigation.
//
// TODO: If this is a gesture navigation, instead of performing a
// dynamic request, we should do a runtime prefetch.
return navigateToUnknownRoute(now, state, url, currentUrl, currentRenderedSearch, nextUrl, currentCacheNode, currentFlightRouterState, freshnessPolicy, scrollBehavior, navigateType).catch(()=>{
// If the navigation fails, return the current state
return state;
});
}
function navigateToKnownRoute(now, state, url, canonicalUrl, navigationSeed, currentUrl, currentRenderedSearch, currentCacheNode, currentFlightRouterState, freshnessPolicy, nextUrl, scrollBehavior, navigateType, debugInfo, // The route cache entry used for this navigation, if it came from route
// prediction. Passed through so it can be marked as having a dynamic rewrite
// if the server returns a different pathname (indicating dynamic rewrite
// behavior).
//
// When null, the navigation did not use route prediction - either because
// the route was already fully cached, or it's a navigation that doesn't
// involve prediction (refresh, history traversal, server action, etc.).
// In these cases, if a mismatch occurs, we still mark the route as having a
// dynamic rewrite by traversing the known route tree (see
// dispatchRetryDueToTreeMismatch).
routeCacheEntry) {
// A version of navigate() that accepts the target route tree as an argument
// rather than reading it from the prefetch cache.
const accumulation = {
separateRefreshUrls: null,
scrollRef: null
};
// We special case navigations to the exact same URL as the current location.
// It's a common UI pattern for apps to refresh when you click a link to the
// current page. So when this happens, we refresh the dynamic data in the page
// segments.
//
// Note that this does not apply if the any part of the hash or search query
// has changed. This might feel a bit weird but it makes more sense when you
// consider that the way to trigger this behavior is to click the same link
// multiple times.
//
// TODO: We should probably refresh the *entire* route when this case occurs,
// not just the page segments. Essentially treating it the same as a refresh()
// triggered by an action, which is the more explicit way of modeling the UI
// pattern described above.
//
// Also note that this only refreshes the dynamic data, not static/ cached
// data. If the page segment is fully static and prefetched, the request is
// skipped. (This is also how refresh() works.)
const isSamePageNavigation = url.href === currentUrl.href;
const task = (0, _pprnavigations.startPPRNavigation)(now, currentUrl, currentRenderedSearch, currentCacheNode, currentFlightRouterState, navigationSeed.routeTree, navigationSeed.metadataVaryPath, freshnessPolicy, navigationSeed.data, navigationSeed.head, navigationSeed.dynamicStaleAt, isSamePageNavigation, accumulation);
if (task !== null) {
if (freshnessPolicy !== _pprnavigations.FreshnessPolicy.Gesture) {
(0, _pprnavigations.spawnDynamicRequests)(task, url, nextUrl, freshnessPolicy, accumulation, routeCacheEntry, navigateType);
}
return completeSoftNavigation(state, url, nextUrl, task.route, task.node, navigationSeed.renderedSearch, canonicalUrl, navigateType, scrollBehavior, accumulation.scrollRef, debugInfo);
}
// Could not perform a SPA navigation. Revert to a full-page (MPA) navigation.
return completeHardNavigation(state, url, navigateType);
}
function navigateUsingPrefetchedRouteTree(now, state, url, currentUrl, currentRenderedSearch, nextUrl, currentCacheNode, currentFlightRouterState, freshnessPolicy, scrollBehavior, navigateType, route) {
const routeTree = route.tree;
const canonicalUrl = route.canonicalUrl + url.hash;
const renderedSearch = route.renderedSearch;
const prefetchSeed = {
renderedSearch,
routeTree,
metadataVaryPath: route.metadata.varyPath,
data: null,
head: null,
dynamicStaleAt: (0, _bfcache.computeDynamicStaleAt)(now, _bfcache.UnknownDynamicStaleTime)
};
return navigateToKnownRoute(now, state, url, canonicalUrl, prefetchSeed, currentUrl, currentRenderedSearch, currentCacheNode, currentFlightRouterState, freshnessPolicy, nextUrl, scrollBehavior, navigateType, null, route);
}
// Used to request all the dynamic data for a route, rather than just a subset,
// e.g. during a refresh or a revalidation. Typically this gets constructed
// during the normal flow when diffing the route tree, but for an unprefetched
// navigation, where we don't know the structure of the target route, we use
// this instead.
const DynamicRequestTreeForEntireRoute = [
'',
{},
null,
'refetch'
];
async function navigateToUnknownRoute(now, state, url, currentUrl, currentRenderedSearch, nextUrl, currentCacheNode, currentFlightRouterState, freshnessPolicy, scrollBehavior, navigateType) {
// Runs when a navigation happens but there's no cached prefetch we can use.
// Don't bother to wait for a prefetch response; go straight to a full
// navigation that contains both static and dynamic data in a single stream.
// (This is unlike the old navigation implementation, which instead blocks
// the dynamic request until a prefetch request is received.)
//
// To avoid duplication of logic, we're going to pretend that the tree
// returned by the dynamic request is, in fact, a prefetch tree. Then we can
// use the same server response to write the actual data into the CacheNode
// tree. So it's the same flow as the "happy path" (prefetch, then
// navigation), except we use a single server response for both stages.
let dynamicRequestTree;
switch(freshnessPolicy){
case _pprnavigations.FreshnessPolicy.Default:
case _pprnavigations.FreshnessPolicy.HistoryTraversal:
case _pprnavigations.FreshnessPolicy.Gesture:
dynamicRequestTree = currentFlightRouterState;
break;
case _pprnavigations.FreshnessPolicy.Hydration:
case _pprnavigations.FreshnessPolicy.RefreshAll:
case _pprnavigations.FreshnessPolicy.HMRRefresh:
dynamicRequestTree = DynamicRequestTreeForEntireRoute;
break;
default:
freshnessPolicy;
dynamicRequestTree = currentFlightRouterState;
break;
}
const promiseForDynamicServerResponse = (0, _fetchserverresponse.fetchServerResponse)(url, {
flightRouterState: dynamicRequestTree,
nextUrl
});
const result = await promiseForDynamicServerResponse;
if (typeof result === 'string') {
// This is an MPA navigation.
const redirectUrl = new URL(result, location.origin);
return completeHardNavigation(state, redirectUrl, navigateType);
}
const { flightData, canonicalUrl, renderedSearch, couldBeIntercepted, supportsPerSegmentPrefetching, dynamicStaleTime, staticStageData, runtimePrefetchStream, responseHeaders, debugInfo } = result;
// Since the response format of dynamic requests and prefetches is slightly
// different, we'll need to massage the data a bit. Create FlightRouterState
// tree that simulates what we'd receive as the result of a prefetch.
const navigationSeed = convertServerPatchToFullTree(now, currentFlightRouterState, flightData, renderedSearch, dynamicStaleTime);
// Learn the route pattern so we can predict it for future navigations.
// hasDynamicRewrite is false because this is a fresh navigation to an
// unknown route - any rewrite detection happens during the traversal inside
// discoverKnownRoute. The hasDynamicRewrite param is only set to true when
// retrying after a tree mismatch (see dispatchRetryDueToTreeMismatch).
const metadataVaryPath = navigationSeed.metadataVaryPath;
if (metadataVaryPath !== null) {
(0, _optimisticroutes.discoverKnownRoute)(now, url.pathname, nextUrl, null, navigationSeed.routeTree, metadataVaryPath, couldBeIntercepted, (0, _createhreffromurl.createHrefFromUrl)(canonicalUrl), supportsPerSegmentPrefetching, false // hasDynamicRewrite - not a retry, rewrite detection happens during traversal
);
if (staticStageData !== null) {
const { response: staticStageResponse, isResponsePartial } = staticStageData;
// Write the static stage of the response into the segment cache so that
// subsequent navigations can serve cached static segments instantly.
(0, _cache.getStaleAt)(now, staticStageResponse.s).then((staleAt)=>{
const buildId = responseHeaders.get(_constants.NEXT_NAV_DEPLOYMENT_ID_HEADER) ?? staticStageResponse.b;
(0, _cache.writeStaticStageResponseIntoCache)(now, staticStageResponse.f, buildId, staticStageResponse.h, staleAt, currentFlightRouterState, renderedSearch, isResponsePartial);
}).catch(()=>{
// The static stage processing failed. Not fatal — the navigation
// completed normally, we just won't write into the cache.
});
}
if (runtimePrefetchStream !== null) {
(0, _cache.processRuntimePrefetchStream)(now, runtimePrefetchStream, currentFlightRouterState, renderedSearch).then((processed)=>{
if (processed !== null) {
(0, _cache.writeDynamicRenderResponseIntoCache)(now, _types.FetchStrategy.PPRRuntime, processed.flightDatas, processed.buildId, processed.isResponsePartial, processed.headVaryParams, processed.staleAt, processed.navigationSeed, null);
}
}).catch(()=>{
// The runtime prefetch cache write failed. Not fatal — the
// navigation completed normally, we just won't cache runtime data.
});
}
}
return navigateToKnownRoute(now, state, url, (0, _createhreffromurl.createHrefFromUrl)(canonicalUrl), navigationSeed, currentUrl, currentRenderedSearch, currentCacheNode, currentFlightRouterState, freshnessPolicy, nextUrl, scrollBehavior, navigateType, debugInfo, // Unknown route navigations don't use route prediction - the route tree
// came directly from the server. If a mismatch occurs during dynamic data
// fetch, the retry handler will traverse the known route tree to mark the
// entry as having a dynamic rewrite.
null);
}
function completeHardNavigation(state, url, navigateType) {
if ((0, _javascripturl.isJavaScriptURLString)(url.href)) {
console.error('Next.js has blocked a javascript: URL as a security precaution.');
return state;
}
const newState = {
canonicalUrl: url.origin === location.origin ? (0, _createhreffromurl.createHrefFromUrl)(url) : url.href,
pushRef: {
pendingPush: navigateType === 'push',
mpaNavigation: true,
preserveCustomHistoryState: false
},
// TODO: None of the rest of these values are consistent with the incoming
// navigation. We rely on the fact that AppRouter will suspend and trigger
// a hard navigation before it accesses any of these values. But instead
// we should trigger the hard navigation and blocking any subsequent
// router updates without updating React.
renderedSearch: state.renderedSearch,
focusAndScrollRef: state.focusAndScrollRef,
cache: state.cache,
tree: state.tree,
nextUrl: state.nextUrl,
previousNextUrl: state.previousNextUrl,
debugInfo: null
};
return newState;
}
function completeSoftNavigation(oldState, url, referringNextUrl, tree, cache, renderedSearch, canonicalUrl, navigateType, scrollBehavior, scrollRef, collectedDebugInfo) {
// The "Next-Url" is a special representation of the URL that Next.js
// uses to implement interception routes.
// TODO: Get rid of this extra traversal by computing this during the
// same traversal that computes the tree itself. We should also figure out
// what is the minimum information needed for the server to correctly
// intercept the route.
const changedPath = (0, _computechangedpath.computeChangedPath)(oldState.tree, tree);
const nextUrlForNewRoute = changedPath ? changedPath : oldState.nextUrl;
// This value is stored on the state as `previousNextUrl`; the naming is
// confusing. What it represents is the "Next-Url" header that was used to
// fetch the incoming route. It's essentially the refererer URL, but in a
// Next.js specific format. During refreshes, this is sent back to the server
// instead of the current route's "Next-Url" so that the same interception
// logic is applied as during the original navigation.
const previousNextUrl = referringNextUrl;
// Check if the only thing that changed was the hash fragment.
const oldUrl = new URL(oldState.canonicalUrl, url);
const onlyHashChange = // We don't need to compare the origins, because client-driven
// navigations are always same-origin.
url.pathname === oldUrl.pathname && url.search === oldUrl.search && url.hash !== oldUrl.hash;
// Determine whether and how the page should scroll after this
// navigation.
//
// By default, we scroll to the segments that were navigated to — i.e.
// segments in the new part of the route, as opposed to shared segments
// that were already part of the previous route. All newly navigated
// segments share a single ScrollRef. When they mount, the first one
// to mount initiates the scroll. They share a ref so that only one
// scroll happens per navigation.
//
// If a subsequent navigation produces new segments, those supersede
// any pending scroll from the previous navigation by invalidating its
// ScrollRef. If a navigation doesn't produce any new segments (e.g.
// a refresh where the route structure didn't change), any pending
// scrolls from previous navigations are unaffected.
//
// The branches below handle special cases layered on top of this
// default model.
let activeScrollRef;
let forceScroll;
if (scrollBehavior === _routerreducertypes.ScrollBehavior.NoScroll) {
// The user explicitly opted out of scrolling (e.g. scroll={false}
// on a Link or router.push).
//
// If this navigation created new scroll targets (scrollRef !== null),
// neutralize them. If it didn't, any prior scroll targets carried
// forward on the cache nodes via reuseSharedCacheNode remain active.
if (scrollRef !== null) {
scrollRef.current = false;
}
activeScrollRef = oldState.focusAndScrollRef.scrollRef;
forceScroll = false;
} else if (onlyHashChange) {
// Hash-only navigations should scroll regardless of per-node state.
// Create a fresh ref so the first segment to scroll consumes it.
//
// Invalidate any scroll ref from a prior navigation that hasn't
// been consumed yet.
const oldScrollRef = oldState.focusAndScrollRef.scrollRef;
if (oldScrollRef !== null) {
oldScrollRef.current = false;
}
// Also invalidate any per-node refs that were accumulated during
// this navigation's tree construction — the hash-only ref
// supersedes them.
if (scrollRef !== null) {
scrollRef.current = false;
}
activeScrollRef = {
current: true
};
forceScroll = true;
} else {
// Default case. Use the accumulated scrollRef (may be null if no
// new segments were created). The handler checks per-node refs, so
// unchanged parallel route slots won't scroll.
activeScrollRef = scrollRef;
// If this navigation created new scroll targets, invalidate any
// pending scroll from a previous navigation.
if (scrollRef !== null) {
const oldScrollRef = oldState.focusAndScrollRef.scrollRef;
if (oldScrollRef !== null) {
oldScrollRef.current = false;
}
}
forceScroll = false;
}
const newState = {
canonicalUrl,
renderedSearch,
pushRef: {
pendingPush: navigateType === 'push',
mpaNavigation: false,
preserveCustomHistoryState: false
},
focusAndScrollRef: {
scrollRef: activeScrollRef,
forceScroll,
onlyHashChange,
hashFragment: // Remove leading # and decode hash to make non-latin hashes work.
//
// Empty hash should trigger default behavior of scrolling layout into
// view. #top is handled in layout-router.
//
// Refer to `ScrollAndFocusHandler` for details on how this is used.
scrollBehavior !== _routerreducertypes.ScrollBehavior.NoScroll && url.hash !== '' ? decodeURIComponent(url.hash.slice(1)) : oldState.focusAndScrollRef.hashFragment
},
cache,
tree,
nextUrl: nextUrlForNewRoute,
previousNextUrl,
debugInfo: collectedDebugInfo
};
return newState;
}
function completeTraverseNavigation(state, url, renderedSearch, cache, tree, nextUrl) {
return {
// Set canonical url
canonicalUrl: (0, _createhreffromurl.createHrefFromUrl)(url),
renderedSearch,
pushRef: {
pendingPush: false,
mpaNavigation: false,
// Ensures that the custom history state that was set is preserved when applying this update.
preserveCustomHistoryState: true
},
focusAndScrollRef: state.focusAndScrollRef,
cache,
// Restore provided tree
tree,
nextUrl,
// TODO: We need to restore previousNextUrl, too, which represents the
// Next-Url that was used to fetch the data. Anywhere we fetch using the
// canonical URL, there should be a corresponding Next-Url.
previousNextUrl: null,
debugInfo: null
};
}
function convertServerPatchToFullTree(now, currentTree, flightData, renderedSearch, dynamicStaleTimeSeconds) {
// During a client navigation or prefetch, the server sends back only a patch
// for the parts of the tree that have changed.
//
// This applies the patch to the base tree to create a full representation of
// the resulting tree.
//
// The return type includes a full FlightRouterState tree and a full
// CacheNodeSeedData tree. (Conceptually these are the same tree, and should
// eventually be unified, but there's still lots of existing code that
// operates on FlightRouterState trees alone without the CacheNodeSeedData.)
//
// TODO: This similar to what apply-router-state-patch-to-tree does. It
// will eventually fully replace it. We should get rid of all the remaining
// places where we iterate over the server patch format. This should also
// eventually replace normalizeFlightData.
let baseTree = currentTree;
let baseData = null;
let head = null;
if (flightData !== null) {
for (const { segmentPath, tree: treePatch, seedData: dataPatch, head: headPatch } of flightData){
const result = convertServerPatchToFullTreeImpl(baseTree, baseData, treePatch, dataPatch, segmentPath, renderedSearch, 0);
baseTree = result.tree;
baseData = result.data;
// This is the same for all patches per response, so just pick an
// arbitrary one
head = headPatch;
}
}
const finalFlightRouterState = baseTree;
// Convert the final FlightRouterState into a RouteTree type.
//
// TODO: Eventually, FlightRouterState will evolve to being a transport format
// only. The RouteTree type will become the main type used for dealing with
// routes on the client, and we'll store it in the state directly.
const acc = {
metadataVaryPath: null
};
const routeTree = (0, _cache.convertRootFlightRouterStateToRouteTree)(finalFlightRouterState, renderedSearch, acc);
return {
routeTree,
metadataVaryPath: acc.metadataVaryPath,
data: baseData,
renderedSearch,
head,
dynamicStaleAt: (0, _bfcache.computeDynamicStaleAt)(now, dynamicStaleTimeSeconds)
};
}
function convertServerPatchToFullTreeImpl(baseRouterState, baseData, treePatch, dataPatch, segmentPath, renderedSearch, index) {
if (index === segmentPath.length) {
// We reached the part of the tree that we need to patch.
return {
tree: treePatch,
data: dataPatch
};
}
// segmentPath represents the parent path of subtree. It's a repeating
// pattern of parallel route key and segment:
//
// [string, Segment, string, Segment, string, Segment, ...]
//
// This path tells us which part of the base tree to apply the tree patch.
//
// NOTE: We receive the FlightRouterState patch in the same request as the
// seed data patch. Therefore we don't need to worry about diffing the segment
// values; we can assume the server sent us a correct result.
const updatedParallelRouteKey = segmentPath[index];
// const segment: Segment = segmentPath[index + 1] <-- Not used, see note above
const baseTreeChildren = baseRouterState[1];
const baseSeedDataChildren = baseData !== null ? baseData[1] : null;
const newTreeChildren = {};
const newSeedDataChildren = {};
for(const parallelRouteKey in baseTreeChildren){
const childBaseRouterState = baseTreeChildren[parallelRouteKey];
const childBaseSeedData = baseSeedDataChildren !== null ? baseSeedDataChildren[parallelRouteKey] ?? null : null;
if (parallelRouteKey === updatedParallelRouteKey) {
const result = convertServerPatchToFullTreeImpl(childBaseRouterState, childBaseSeedData, treePatch, dataPatch, segmentPath, renderedSearch, // Advance the index by two and keep cloning until we reach
// the end of the segment path.
index + 2);
newTreeChildren[parallelRouteKey] = result.tree;
newSeedDataChildren[parallelRouteKey] = result.data;
} else {
// This child is not being patched. Copy it over as-is.
newTreeChildren[parallelRouteKey] = childBaseRouterState;
newSeedDataChildren[parallelRouteKey] = childBaseSeedData;
}
}
let clonedTree;
let clonedSeedData;
// Clone all the fields except the children.
// Clone the FlightRouterState tree. Based on equivalent logic in
// apply-router-state-patch-to-tree, but should confirm whether we need to
// copy all of these fields. Not sure the server ever sends, e.g. the
// refetch marker.
clonedTree = [
baseRouterState[0],
newTreeChildren
];
if (2 in baseRouterState) {
const compressedRefreshState = baseRouterState[2];
if (compressedRefreshState !== undefined && compressedRefreshState !== null) {
// Since this part of the tree was patched with new data, any parent
// refresh states should be updated to reflect the new rendered search
// value. (The refresh state acts like a "context provider".) All pages
// within the same server response share the same renderedSearch value,
// but the same RouteTree could be composed from multiple different
// routes, and multiple responses.
clonedTree[2] = [
compressedRefreshState[0],
renderedSearch
];
}
}
if (3 in baseRouterState) {
clonedTree[3] = baseRouterState[3];
}
if (4 in baseRouterState) {
clonedTree[4] = baseRouterState[4];
}
// Clone the CacheNodeSeedData tree.
const isEmptySeedDataPartial = true;
clonedSeedData = [
null,
newSeedDataChildren,
null,
isEmptySeedDataPartial,
null
];
return {
tree: clonedTree,
data: clonedSeedData
};
}
/**
* Instant Navigation Testing API: ensures a prefetch task has been initiated
* and completed before proceeding with the navigation. This guarantees that
* segment data requests are at least pending, even for routes whose route
* tree is already cached.
*
* After the prefetch completes, delegates to the normal navigation flow.
*/ async function ensurePrefetchThenNavigate(state, url, currentUrl, currentRenderedSearch, currentCacheNode, currentFlightRouterState, nextUrl, freshnessPolicy, scrollBehavior, navigateType) {
const link = (0, _links.getLinkForCurrentNavigation)();
const fetchStrategy = link !== null ? link.fetchStrategy : _types.FetchStrategy.PPR;
// Transition the cookie to captured-SPA immediately, before waiting
// for the prefetch. This ensures the devtools panel can update its UI
// right away, even if the prefetch takes time (e.g. dev compilation).
// The "to" tree starts as null and is filled in after the prefetch
// resolves and the navigation produces a new router state.
const { transitionToCapturedSPA, updateCapturedSPAToTree } = require('./navigation-testing-lock');
transitionToCapturedSPA(currentFlightRouterState, null);
const cacheKey = (0, _cachekey.createCacheKey)(url.href, nextUrl);
await new Promise((resolve)=>{
(0, _scheduler.schedulePrefetchTask)(cacheKey, currentFlightRouterState, fetchStrategy, _types.PrefetchPriority.Default, null, resolve // _onComplete callback
);
});
// Prefetch is complete. Proceed with the normal navigation flow, which
// will now find the route in the cache.
const result = await navigateImpl(state, url, currentUrl, currentRenderedSearch, currentCacheNode, currentFlightRouterState, nextUrl, freshnessPolicy, scrollBehavior, navigateType);
// Update the cookie with the resolved "to" tree so the devtools
// panel can display both routes immediately.
updateCapturedSPAToTree(currentFlightRouterState, result.tree);
return result;
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=navigation.js.map

View File

@@ -0,0 +1,543 @@
/**
* Optimistic Routing (Known Routes)
*
* This module enables the client to predict route structure for URLs that
* haven't been prefetched yet, based on previously learned route patterns.
* When successful, this allows skipping the route tree prefetch request
* entirely.
*
* The core idea is that many URLs map to the same route structure. For example,
* /blog/post-1 and /blog/post-2 both resolve to /blog/[slug]. Once we've
* prefetched one, we can predict the structure of the other.
*
* However, we can't always make this prediction. Static siblings (like
* /blog/featured alongside /blog/[slug]) have different route structures.
* When we learn a dynamic route, we also learn its static siblings so we
* know when NOT to apply the prediction.
*
* Main entry points:
*
* 1. discoverKnownRoute: Called after receiving a route tree from the server.
* Traverses the route tree, compares URL parts to segments, and populates
* the known route tree if they match. Routes are always inserted into the
* cache.
*
* 2. matchKnownRoute: Called when looking up a route with no cache entry.
* Matches the candidate URL against learned patterns. Returns a synthetic
* cache entry if successful, or null to fall back to server resolution.
*
* Rewrite detection happens during traversal: if a URL path part doesn't match
* the corresponding route segment, we stop populating the known route tree
* (since the mapping is incorrect) but still insert the route into the cache.
*
* The known route tree is append-only with no eviction. Route patterns are
* derived from the filesystem, so they don't become stale within a session.
* Cache invalidation on deploy clears everything anyway.
*
* Current limitations (deopt to server resolution):
* - Rewrites: Detected during traversal (tree not populated, but route cached)
* - Intercepted routes: The route tree varies by referrer (Next-Url header),
* so we can't predict the correct structure from the URL alone. Patterns are
* still stored during discovery (so the trie stays populated for non-
* intercepted siblings), but matching bails out when the pattern is marked
* as interceptable.
*/ "use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
discoverKnownRoute: null,
matchKnownRoute: null,
resetKnownRoutes: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
discoverKnownRoute: function() {
return discoverKnownRoute;
},
matchKnownRoute: function() {
return matchKnownRoute;
},
resetKnownRoutes: function() {
return resetKnownRoutes;
}
});
const _cache = require("./cache");
const _routeparams = require("../../route-params");
const _varypath = require("./vary-path");
function createEmptyPart() {
return {
staticChildren: null,
dynamicChild: null,
dynamicChildParamName: null,
dynamicChildParamType: null,
pattern: null
};
}
// The root of the known route tree.
let knownRouteTreeRoot = createEmptyPart();
function discoverKnownRoute(now, pathname, nextUrl, pendingEntry, routeTree, metadataVaryPath, couldBeIntercepted, canonicalUrl, supportsPerSegmentPrefetching, hasDynamicRewrite) {
const tree = routeTree;
const pathnameParts = pathname.split('/').filter((p)=>p !== '');
const firstPart = pathnameParts.length > 0 ? pathnameParts[0] : null;
const remainingParts = pathnameParts.length > 0 ? pathnameParts.slice(1) : [];
if (pendingEntry !== null) {
// Fulfill the pending entry first
const fulfilledEntry = (0, _cache.fulfillRouteCacheEntry)(now, pendingEntry, tree, metadataVaryPath, couldBeIntercepted, canonicalUrl, supportsPerSegmentPrefetching);
if (hasDynamicRewrite) {
fulfilledEntry.hasDynamicRewrite = true;
}
// Populate the known route tree (handles rewrite detection internally).
// The entry is already in the cache; this just stores it as a pattern
// if the URL matches the route structure.
discoverKnownRoutePart(knownRouteTreeRoot, tree, firstPart, remainingParts, fulfilledEntry, now, pathname, nextUrl, tree, metadataVaryPath, couldBeIntercepted, canonicalUrl, supportsPerSegmentPrefetching, hasDynamicRewrite);
return fulfilledEntry;
}
// No pending entry - discoverKnownRoutePart will create one and insert it
// into the cache, or return an existing pattern if one exists.
return discoverKnownRoutePart(knownRouteTreeRoot, tree, firstPart, remainingParts, null, now, pathname, nextUrl, tree, metadataVaryPath, couldBeIntercepted, canonicalUrl, supportsPerSegmentPrefetching, hasDynamicRewrite);
}
/**
* Gets or creates the dynamic child node for a KnownRoutePart.
* A node can have at most one dynamic child (you can't have both [slug] and
* [id] at the same route level), so we either return existing or create new.
*/ function discoverDynamicChild(part, paramName, paramType) {
if (part.dynamicChild !== null) {
return part.dynamicChild;
}
const newChild = createEmptyPart();
// Type assertion needed because we're converting from "without" to "with"
// dynamic child variant.
const mutablePart = part;
mutablePart.dynamicChild = newChild;
mutablePart.dynamicChildParamName = paramName;
mutablePart.dynamicChildParamType = paramType;
return newChild;
}
/**
* Recursive workhorse for discoverKnownRoute.
*
* Walks the route tree and URL parts in parallel, building out the known
* route tree as it goes. At each step:
* 1. Determines if the current segment appears in the URL (dynamic/static)
* 2. Validates URL matches route structure (detects rewrites)
* 3. Creates/updates the corresponding KnownRoutePart node
* 4. Records static siblings for future matching
* 5. Recurses into child slots (parallel routes)
*
* If a URL/route mismatch is detected (rewrite), we stop building the known
* route tree but still cache the route entry for direct lookup.
*/ function discoverKnownRoutePart(parentKnownRoutePart, routeTree, urlPart, remainingParts, existingEntry, // These are passed through unchanged for entry creation at the leaf
now, pathname, nextUrl, fullTree, metadataVaryPath, couldBeIntercepted, canonicalUrl, supportsPerSegmentPrefetching, hasDynamicRewrite) {
const segment = routeTree.segment;
let segmentAppearsInURL;
let paramName = null;
let paramType = null;
let staticSiblings = null;
if (typeof segment === 'string') {
segmentAppearsInURL = (0, _routeparams.doesStaticSegmentAppearInURL)(segment);
} else {
// Dynamic segment tuple: [paramName, paramCacheKey, paramType, staticSiblings]
paramName = segment[0];
paramType = segment[2];
staticSiblings = segment[3];
segmentAppearsInURL = true;
}
let knownRoutePart = parentKnownRoutePart;
let nextUrlPart = urlPart;
let nextRemainingParts = remainingParts;
if (segmentAppearsInURL) {
// Check for mismatch: if this is a static segment, the URL part must match
if (paramName === null && urlPart !== segment) {
// URL doesn't match route structure (likely a rewrite).
// Don't populate the known route tree, just write the route into the
// cache and return immediately.
if (existingEntry !== null) {
return existingEntry;
}
return (0, _cache.writeRouteIntoCache)(now, pathname, nextUrl, fullTree, metadataVaryPath, couldBeIntercepted, canonicalUrl, supportsPerSegmentPrefetching);
}
// URL matches route structure. Build the known route tree.
if (paramName !== null && paramType !== null) {
// Dynamic segment
knownRoutePart = discoverDynamicChild(parentKnownRoutePart, paramName, paramType);
// Record static siblings as placeholder parts.
// IMPORTANT: We use the null vs Map distinction to track whether
// siblings are known at this level:
// - staticChildren: null = siblings unknown (can't safely match dynamic)
// - staticChildren: Map = siblings known (even if empty)
// This matters in dev mode where webpack may not know all siblings yet.
if (staticSiblings !== null) {
// Siblings are known - ensure we have a Map (even if empty)
if (parentKnownRoutePart.staticChildren === null) {
parentKnownRoutePart.staticChildren = new Map();
}
for (const sibling of staticSiblings){
if (!parentKnownRoutePart.staticChildren.has(sibling)) {
parentKnownRoutePart.staticChildren.set(sibling, createEmptyPart());
}
}
}
} else {
// Static segment
if (parentKnownRoutePart.staticChildren === null) {
parentKnownRoutePart.staticChildren = new Map();
}
let existingChild = parentKnownRoutePart.staticChildren.get(urlPart);
if (existingChild === undefined) {
existingChild = createEmptyPart();
parentKnownRoutePart.staticChildren.set(urlPart, existingChild);
}
knownRoutePart = existingChild;
}
// Advance to next URL part
nextUrlPart = remainingParts.length > 0 ? remainingParts[0] : null;
nextRemainingParts = remainingParts.length > 0 ? remainingParts.slice(1) : [];
}
// else: Transparent segment (route group, __PAGE__, etc.)
// Stay at the same known route part, don't advance URL parts
// Recurse into child routes. A route tree can have multiple parallel routes
// (e.g., @modal alongside children). Each parallel route is a separate
// branch, but they all share the same URL - we just need to traverse all
// branches to build out the known route tree.
const slots = routeTree.slots;
let resultFromChildren = null;
if (slots !== null) {
for(const parallelRouteKey in slots){
const childRouteTree = slots[parallelRouteKey];
// Skip branches with refreshState set - these were reused from a
// different route (e.g., a "default" parallel slot) and don't represent
// the actual route structure for this URL.
if (childRouteTree.refreshState !== null) {
continue;
}
const result = discoverKnownRoutePart(knownRoutePart, childRouteTree, nextUrlPart, nextRemainingParts, existingEntry, now, pathname, nextUrl, fullTree, metadataVaryPath, couldBeIntercepted, canonicalUrl, supportsPerSegmentPrefetching, hasDynamicRewrite);
// All parallel route branches share the same URL, so they should all
// reach compatible leaf nodes. We capture any result.
resultFromChildren = result;
}
if (resultFromChildren !== null) {
return resultFromChildren;
}
// Defensive fallback: no children returned a result. This shouldn't happen
// for valid route trees, but handle it gracefully.
if (existingEntry !== null) {
return existingEntry;
}
return (0, _cache.writeRouteIntoCache)(now, pathname, nextUrl, fullTree, metadataVaryPath, couldBeIntercepted, canonicalUrl, supportsPerSegmentPrefetching);
}
// Reached a page node. Create/get the route cache entry and store as a
// pattern. First, check if there's already a pattern for this route.
if (knownRoutePart.pattern !== null) {
// If this route has a dynamic rewrite, mark the existing pattern.
if (hasDynamicRewrite) {
knownRoutePart.pattern.hasDynamicRewrite = true;
}
return knownRoutePart.pattern;
}
// Get or create the entry
let entry;
if (existingEntry !== null) {
// Already have a fulfilled entry, use it directly. It's already in the
// route cache map.
entry = existingEntry;
} else {
// Create the entry and insert it into the route cache map.
entry = (0, _cache.writeRouteIntoCache)(now, pathname, nextUrl, fullTree, metadataVaryPath, couldBeIntercepted, canonicalUrl, supportsPerSegmentPrefetching);
}
if (hasDynamicRewrite) {
entry.hasDynamicRewrite = true;
}
// Store as pattern
knownRoutePart.pattern = entry;
return entry;
}
function matchKnownRoute(pathname, search) {
const pathnameParts = pathname.split('/').filter((p)=>p !== '');
const resolvedParams = new Map();
const match = matchKnownRoutePart(knownRouteTreeRoot, pathnameParts, 0, resolvedParams);
if (match === null) {
return null;
}
const matchedPart = match.part;
const pattern = match.pattern;
// If the pattern could be intercepted, we can't safely use it for prediction.
// Interception routes resolve to different route trees depending on the
// referrer (the Next-Url header), which means the same URL can map to
// different page components depending on where the navigation originated.
// Since the known route tree only stores a single pattern per URL shape, we
// can't distinguish between the intercepted and non-intercepted cases, so we
// bail out to server resolution.
//
// TODO: We could store interception behavior in the known route tree itself
// (e.g., which segments use interception markers and what they resolve to).
// With enough information embedded in the trie, we could match interception
// routes entirely on the client without a server round-trip.
if (pattern.couldBeIntercepted) {
return null;
}
// "Reify" the pattern: clone the template tree with concrete param values.
// This substitutes resolved params (e.g., slug: "hello") into dynamic
// segments and recomputes vary paths for correct segment cache keying.
const acc = {
metadataVaryPath: null
};
const reifiedTree = reifyRouteTree(pattern.tree, resolvedParams, search, null, acc);
// The metadata tree is a flat page node without the intermediate layout
// structure. Clone it with the updated metadata vary path collected during
// the main tree traversal.
const metadataVaryPath = acc.metadataVaryPath;
if (metadataVaryPath === null) {
// This shouldn't be reachable for a valid route tree.
return null;
}
const reifiedMetadata = (0, _cache.createMetadataRouteTree)(metadataVaryPath);
// Create a synthetic (predicted) entry and store it as the new pattern.
//
// Why replace the pattern? We intentionally update the pattern with this
// synthetic entry so that if our prediction was wrong (server returns a
// different pathname due to dynamic rewrite), the entry gets marked with
// hasDynamicRewrite. Future predictions for this route will see the flag
// and bail out to server resolution instead of making the same mistake.
const syntheticEntry = {
canonicalUrl: pathname + search,
status: _cache.EntryStatus.Fulfilled,
blockedTasks: null,
tree: reifiedTree,
metadata: reifiedMetadata,
couldBeIntercepted: pattern.couldBeIntercepted,
supportsPerSegmentPrefetching: pattern.supportsPerSegmentPrefetching,
hasDynamicRewrite: false,
renderedSearch: search,
ref: null,
size: pattern.size,
staleAt: pattern.staleAt,
version: pattern.version
};
matchedPart.pattern = syntheticEntry;
return syntheticEntry;
}
/**
* Recursively matches a URL against the known route tree.
*
* Matching priority (most specific first):
* 1. Static children - exact path segment match
* 2. Dynamic child - [param], [...param], [[...param]]
* 3. Direct pattern - when no more URL parts remain
*
* Collects resolved param values in resolvedParams as it traverses.
* Returns null if no match found (caller should fall back to server).
*/ function matchKnownRoutePart(part, pathnameParts, partIndex, resolvedParams) {
const urlPart = partIndex < pathnameParts.length ? pathnameParts[partIndex] : null;
// If staticChildren is null, we don't know what static routes exist at this
// level. This happens in webpack dev mode where routes are compiled
// on-demand. We can't safely match a dynamicChild because the URL part might
// be a static sibling we haven't discovered yet. Example: We know
// /blog/[slug] exists, but haven't compiled /blog/featured. A request for
// /blog/featured would incorrectly match /blog/[slug].
if (part.staticChildren === null) {
// The only safe match is a direct pattern when no URL parts remain.
if (urlPart === null) {
const pattern = part.pattern;
if (pattern !== null && !pattern.hasDynamicRewrite) {
return {
part,
pattern
};
}
}
return null;
}
// Static children take priority over dynamic. This ensures /blog/featured
// matches its own route rather than /blog/[slug].
if (urlPart !== null) {
const staticChild = part.staticChildren.get(urlPart);
if (staticChild !== undefined) {
// Check if this is an "unknown" placeholder part. These are created when
// we learn about static siblings (from the route tree's staticSiblings
// field) but haven't prefetched them yet. We know the path exists but
// don't know its structure, so we can't predict it.
if (staticChild.pattern === null && staticChild.dynamicChild === null && staticChild.staticChildren === null) {
// Bail out - server must resolve this route.
return null;
}
const match = matchKnownRoutePart(staticChild, pathnameParts, partIndex + 1, resolvedParams);
if (match !== null) {
return match;
}
// Static child is a real node (not a placeholder) but its subtree
// didn't match the remaining URL parts. This means the route exists
// in the static subtree but hasn't been fully discovered yet. Do not
// fall through to try the dynamic child — the static match is
// authoritative. Bail out to server resolution.
return null;
}
}
// Try dynamic child
if (part.dynamicChild !== null) {
const dynamicPart = part.dynamicChild;
const paramName = part.dynamicChildParamName;
const paramType = part.dynamicChildParamType;
const dynamicPattern = dynamicPart.pattern;
switch(paramType){
case 'c':
// Required catch-all [...param]: consumes 1+ URL parts
if (dynamicPattern !== null && !dynamicPattern.hasDynamicRewrite && urlPart !== null) {
resolvedParams.set(paramName, pathnameParts.slice(partIndex));
return {
part: dynamicPart,
pattern: dynamicPattern
};
}
break;
case 'oc':
// Optional catch-all [[...param]]: consumes 0+ URL parts
if (dynamicPattern !== null && !dynamicPattern.hasDynamicRewrite) {
if (urlPart !== null) {
resolvedParams.set(paramName, pathnameParts.slice(partIndex));
return {
part: dynamicPart,
pattern: dynamicPattern
};
}
// urlPart is null - can match with zero parts, but a direct pattern
// (e.g., page.tsx alongside [[...param]]) takes precedence.
if (part.pattern === null || part.pattern.hasDynamicRewrite) {
resolvedParams.set(paramName, []);
return {
part: dynamicPart,
pattern: dynamicPattern
};
}
}
break;
case 'd':
// Regular dynamic [param]: consumes exactly 1 URL part.
// Unlike catch-all which terminates here, regular dynamic must
// continue recursing to find the leaf pattern.
if (urlPart !== null) {
resolvedParams.set(paramName, urlPart);
return matchKnownRoutePart(dynamicPart, pathnameParts, partIndex + 1, resolvedParams);
}
break;
// Intercepted routes use relative path markers like (.), (..), (...)
// Their behavior depends on navigation context (soft vs hard nav),
// so we can't predict them client-side. Defer to server.
case 'ci(..)(..)':
case 'ci(.)':
case 'ci(..)':
case 'ci(...)':
case 'di(..)(..)':
case 'di(.)':
case 'di(..)':
case 'di(...)':
return null;
default:
paramType;
}
}
// No children matched. If we've consumed all URL parts, check for a direct
// pattern at this node (the route terminates here).
if (urlPart === null) {
const pattern = part.pattern;
if (pattern !== null && !pattern.hasDynamicRewrite) {
return {
part,
pattern
};
}
}
return null;
}
/**
* "Reify" means to make concrete - we take an abstract pattern (the template
* route tree) and produce a concrete instance with actual param values.
*
* This function clones a RouteTree, substituting dynamic segment values from
* resolvedParams and computing new vary paths. The vary path encodes param
* values so segment cache entries can be correctly keyed.
*
* Example: Pattern for /blog/[slug] with resolvedParams { slug: "hello" }
* produces a tree where segment [slug] has cacheKey "hello".
*/ function reifyRouteTree(pattern, resolvedParams, search, parentPartialVaryPath, acc) {
const originalSegment = pattern.segment;
let newSegment = originalSegment;
let partialVaryPath;
if (typeof originalSegment !== 'string') {
// Dynamic segment: compute new cache key and append to partial vary path
const paramName = originalSegment[0];
const paramType = originalSegment[2];
const staticSiblings = originalSegment[3];
const newValue = resolvedParams.get(paramName);
if (newValue !== undefined) {
const newCacheKey = Array.isArray(newValue) ? newValue.join('/') : newValue;
newSegment = [
paramName,
newCacheKey,
paramType,
staticSiblings
];
partialVaryPath = (0, _varypath.appendLayoutVaryPath)(parentPartialVaryPath, newCacheKey, paramName);
} else {
// Param not found in resolvedParams - keep original and inherit partial
// TODO: This should never happen. Bail out with null.
partialVaryPath = parentPartialVaryPath;
}
} else {
// Static segment: inherit partial vary path from parent
partialVaryPath = parentPartialVaryPath;
}
// Recurse into children with the (possibly updated) partial vary path
let newSlots = null;
if (pattern.slots !== null) {
newSlots = {};
for(const key in pattern.slots){
newSlots[key] = reifyRouteTree(pattern.slots[key], resolvedParams, search, partialVaryPath, acc);
}
}
if (pattern.isPage) {
// Page segment: finalize with search params
const newVaryPath = (0, _varypath.finalizePageVaryPath)(pattern.requestKey, search, partialVaryPath);
// Collect metadata vary path (first page wins, same as original algorithm)
if (acc.metadataVaryPath === null) {
acc.metadataVaryPath = (0, _varypath.finalizeMetadataVaryPath)(pattern.requestKey, search, partialVaryPath);
}
return {
requestKey: pattern.requestKey,
segment: newSegment,
refreshState: pattern.refreshState,
slots: newSlots,
prefetchHints: pattern.prefetchHints,
isPage: true,
varyPath: newVaryPath
};
} else {
// Layout segment: finalize without search params
const newVaryPath = (0, _varypath.finalizeLayoutVaryPath)(pattern.requestKey, partialVaryPath);
return {
requestKey: pattern.requestKey,
segment: newSegment,
refreshState: pattern.refreshState,
slots: newSlots,
prefetchHints: pattern.prefetchHints,
isPage: false,
varyPath: newVaryPath
};
}
}
function resetKnownRoutes() {
knownRouteTreeRoot = createEmptyPart();
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=optimistic-routes.js.map

View File

@@ -0,0 +1,31 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "prefetch", {
enumerable: true,
get: function() {
return prefetch;
}
});
const _approuterutils = require("../app-router-utils");
const _cachekey = require("./cache-key");
const _scheduler = require("./scheduler");
const _types = require("./types");
function prefetch(href, nextUrl, treeAtTimeOfPrefetch, fetchStrategy, onInvalidate) {
const url = (0, _approuterutils.createPrefetchURL)(href);
if (url === null) {
// This href should not be prefetched.
return;
}
const cacheKey = (0, _cachekey.createCacheKey)(url.href, nextUrl);
(0, _scheduler.schedulePrefetchTask)(cacheKey, treeAtTimeOfPrefetch, fetchStrategy, _types.PrefetchPriority.Default, onInvalidate);
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=prefetch.js.map

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,69 @@
/**
* Shared types and constants for the Segment Cache.
*/ "use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
FetchStrategy: null,
NavigationResultTag: null,
PrefetchPriority: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
FetchStrategy: function() {
return FetchStrategy;
},
NavigationResultTag: function() {
return NavigationResultTag;
},
PrefetchPriority: function() {
return PrefetchPriority;
}
});
var NavigationResultTag = /*#__PURE__*/ function(NavigationResultTag) {
NavigationResultTag[NavigationResultTag["MPA"] = 0] = "MPA";
NavigationResultTag[NavigationResultTag["Success"] = 1] = "Success";
NavigationResultTag[NavigationResultTag["NoOp"] = 2] = "NoOp";
NavigationResultTag[NavigationResultTag["Async"] = 3] = "Async";
return NavigationResultTag;
}({});
var PrefetchPriority = /*#__PURE__*/ function(PrefetchPriority) {
/**
* Assigned to the most recently hovered/touched link. Special network
* bandwidth is reserved for this task only. There's only ever one Intent-
* priority task at a time; when a new Intent task is scheduled, the previous
* one is bumped down to Default.
*/ PrefetchPriority[PrefetchPriority["Intent"] = 2] = "Intent";
/**
* The default priority for prefetch tasks.
*/ PrefetchPriority[PrefetchPriority["Default"] = 1] = "Default";
/**
* Assigned to tasks when they spawn non-blocking background work, like
* revalidating a partially cached entry to see if more data is available.
*/ PrefetchPriority[PrefetchPriority["Background"] = 0] = "Background";
return PrefetchPriority;
}({});
var FetchStrategy = /*#__PURE__*/ function(FetchStrategy) {
// Deliberately ordered so we can easily compare two segments
// and determine if one segment is "more specific" than another
// (i.e. if it's likely that it contains more data)
FetchStrategy[FetchStrategy["LoadingBoundary"] = 0] = "LoadingBoundary";
FetchStrategy[FetchStrategy["PPR"] = 1] = "PPR";
FetchStrategy[FetchStrategy["PPRRuntime"] = 2] = "PPRRuntime";
FetchStrategy[FetchStrategy["Full"] = 3] = "Full";
return FetchStrategy;
}({});
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=types.js.map

View File

@@ -0,0 +1,278 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
appendLayoutVaryPath: null,
clonePageVaryPathWithNewSearchParams: null,
finalizeLayoutVaryPath: null,
finalizeMetadataVaryPath: null,
finalizePageVaryPath: null,
getFulfilledRouteVaryPath: null,
getFulfilledSegmentVaryPath: null,
getPartialLayoutVaryPath: null,
getPartialPageVaryPath: null,
getRenderedSearchFromVaryPath: null,
getRouteVaryPath: null,
getSegmentVaryPathForRequest: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
appendLayoutVaryPath: function() {
return appendLayoutVaryPath;
},
clonePageVaryPathWithNewSearchParams: function() {
return clonePageVaryPathWithNewSearchParams;
},
finalizeLayoutVaryPath: function() {
return finalizeLayoutVaryPath;
},
finalizeMetadataVaryPath: function() {
return finalizeMetadataVaryPath;
},
finalizePageVaryPath: function() {
return finalizePageVaryPath;
},
getFulfilledRouteVaryPath: function() {
return getFulfilledRouteVaryPath;
},
getFulfilledSegmentVaryPath: function() {
return getFulfilledSegmentVaryPath;
},
getPartialLayoutVaryPath: function() {
return getPartialLayoutVaryPath;
},
getPartialPageVaryPath: function() {
return getPartialPageVaryPath;
},
getRenderedSearchFromVaryPath: function() {
return getRenderedSearchFromVaryPath;
},
getRouteVaryPath: function() {
return getRouteVaryPath;
},
getSegmentVaryPathForRequest: function() {
return getSegmentVaryPathForRequest;
}
});
const _types = require("./types");
const _cachemap = require("./cache-map");
const _segmentvalueencoding = require("../../../shared/lib/segment-cache/segment-value-encoding");
function getRouteVaryPath(pathname, search, nextUrl) {
// requestKey -> searchParams -> nextUrl
const varyPath = {
id: null,
value: pathname,
parent: {
id: '?',
value: search,
parent: {
id: null,
value: nextUrl,
parent: null
}
}
};
return varyPath;
}
function getFulfilledRouteVaryPath(pathname, search, nextUrl, couldBeIntercepted) {
// This is called when a route's data is fulfilled. The cache entry will be
// re-keyed based on which inputs the response varies by.
// requestKey -> searchParams -> nextUrl
const varyPath = {
id: null,
value: pathname,
parent: {
id: '?',
value: search,
parent: {
id: null,
value: couldBeIntercepted ? nextUrl : _cachemap.Fallback,
parent: null
}
}
};
return varyPath;
}
function appendLayoutVaryPath(parentPath, cacheKey, paramName) {
const varyPathPart = {
id: paramName,
value: cacheKey,
parent: parentPath
};
return varyPathPart;
}
function finalizeLayoutVaryPath(requestKey, varyPath) {
const layoutVaryPath = {
id: null,
value: requestKey,
parent: varyPath
};
return layoutVaryPath;
}
function getPartialLayoutVaryPath(finalizedVaryPath) {
// This is the inverse of finalizeLayoutVaryPath.
return finalizedVaryPath.parent;
}
function finalizePageVaryPath(requestKey, renderedSearch, varyPath) {
// Unlike layouts, a page segment's vary path also includes the search string.
// requestKey -> searchParams -> pathParams
const pageVaryPath = {
id: null,
value: requestKey,
parent: {
id: '?',
value: renderedSearch,
parent: varyPath
}
};
return pageVaryPath;
}
function getPartialPageVaryPath(finalizedVaryPath) {
// This is the inverse of finalizePageVaryPath.
return finalizedVaryPath.parent.parent;
}
function finalizeMetadataVaryPath(pageRequestKey, renderedSearch, varyPath) {
// The metadata "segment" is not a real segment because it doesn't exist in
// the normal structure of the route tree, but in terms of caching, it
// behaves like a page segment because it varies by all the same params as
// a page.
//
// To keep the protocol for querying the server simple, the request key for
// the metadata does not include any path information. It's unnecessary from
// the server's perspective, because unlike page segments, there's only one
// metadata response per URL, i.e. there's no need to distinguish multiple
// parallel pages.
//
// However, this means the metadata request key is insufficient for
// caching the the metadata in the client cache, because on the client we
// use the request key to distinguish the metadata entry from all other
// page's metadata entries.
//
// So instead we create a simulated request key based on the page segment.
// Conceptually this is equivalent to the request key the server would have
// assigned the metadata segment if it treated it as part of the actual
// route structure.
// If there are multiple parallel pages, we use whichever is the first one.
// This is fine because the only difference between request keys for
// different parallel pages are things like route groups and parallel
// route slots. As long as it's always the same one, it doesn't matter.
const pageVaryPath = {
id: null,
// Append the actual metadata request key to the page request key. Note
// that we're not using a separate vary path part; it's unnecessary because
// these are not conceptually separate inputs.
value: pageRequestKey + _segmentvalueencoding.HEAD_REQUEST_KEY,
parent: {
id: '?',
value: renderedSearch,
parent: varyPath
}
};
return pageVaryPath;
}
function getSegmentVaryPathForRequest(fetchStrategy, tree) {
// This is used for storing pending requests in the cache. We want to choose
// the most generic vary path based on the strategy used to fetch it, i.e.
// static/PPR versus runtime prefetching, so that it can be reused as much
// as possible.
//
// We may be able to re-key the response to something even more generic once
// we receive it — for example, if the server tells us that the response
// doesn't vary on a particular param — but even before we send the request,
// we know some params are reusable based on the fetch strategy alone. For
// example, a static prefetch will never vary on search params.
//
// The original vary path with all the params filled in is stored on the
// route tree object. We will clone this one to create a new vary path
// where certain params are replaced with Fallback.
//
// This result of this function is not stored anywhere. It's only used to
// access the cache a single time.
//
// TODO: Rather than create a new list object just to access the cache, the
// plan is to add the concept of a "vary mask". This will represent all the
// params that can be treated as Fallback. (Or perhaps the inverse.)
const originalVaryPath = tree.varyPath;
// Only page segments (and the special "metadata" segment, which is treated
// like a page segment for the purposes of caching) may contain search
// params. There's no reason to include them in the vary path otherwise.
if (tree.isPage) {
// Only a runtime prefetch will include search params in the vary path.
// Static prefetches never include search params, so they can be reused
// across all possible search param values.
const doesVaryOnSearchParams = fetchStrategy === _types.FetchStrategy.Full || fetchStrategy === _types.FetchStrategy.PPRRuntime;
if (!doesVaryOnSearchParams) {
// The response from the the server will not vary on search params. Clone
// the end of the original vary path to replace the search params
// with Fallback.
//
// requestKey -> searchParams -> pathParams
// ^ This part gets replaced with Fallback
const searchParamsVaryPath = originalVaryPath.parent;
const pathParamsVaryPath = searchParamsVaryPath.parent;
const patchedVaryPath = {
id: null,
value: originalVaryPath.value,
parent: {
id: '?',
value: _cachemap.Fallback,
parent: pathParamsVaryPath
}
};
return patchedVaryPath;
}
}
// The request does vary on search params. We don't need to modify anything.
return originalVaryPath;
}
function clonePageVaryPathWithNewSearchParams(originalVaryPath, newSearch) {
// requestKey -> searchParams -> pathParams
// ^ This part gets replaced with newSearch
const searchParamsVaryPath = originalVaryPath.parent;
const clonedVaryPath = {
id: null,
value: originalVaryPath.value,
parent: {
id: '?',
value: newSearch,
parent: searchParamsVaryPath.parent
}
};
return clonedVaryPath;
}
function getRenderedSearchFromVaryPath(varyPath) {
const searchParams = varyPath.parent.value;
return typeof searchParams === 'string' ? searchParams : null;
}
function getFulfilledSegmentVaryPath(original, varyParams) {
// Re-keys a segment's vary path based on which params the segment actually
// depends on. Params that are NOT in the varyParams set are replaced with
// Fallback, allowing the cache entry to be reused across different values of
// those params.
// This is called when a segment is fulfilled with data from the server. The
// varyParams set comes from the server and indicates which params were
// accessed during rendering.
const clone = {
id: original.id,
// If the id is null, this node is not a param (e.g., it's a request key).
// If the id is in the varyParams set, keep the original value.
// Otherwise, replace with Fallback to make it reusable.
value: original.id === null || varyParams.has(original.id) ? original.value : _cachemap.Fallback,
parent: original.parent === null ? null : getFulfilledSegmentVaryPath(original.parent, varyParams)
};
return clone;
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=vary-path.js.map

View File

@@ -0,0 +1,42 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
StaticGenBailoutError: null,
isStaticGenBailoutError: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
StaticGenBailoutError: function() {
return StaticGenBailoutError;
},
isStaticGenBailoutError: function() {
return isStaticGenBailoutError;
}
});
const NEXT_STATIC_GEN_BAILOUT = 'NEXT_STATIC_GEN_BAILOUT';
class StaticGenBailoutError extends Error {
constructor(...args){
super(...args), this.code = NEXT_STATIC_GEN_BAILOUT;
}
}
function isStaticGenBailoutError(error) {
if (typeof error !== 'object' || error === null || !('code' in error)) {
return false;
}
return error.code === NEXT_STATIC_GEN_BAILOUT;
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=static-generation-bailout.js.map

View File

@@ -0,0 +1,49 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "unauthorized", {
enumerable: true,
get: function() {
return unauthorized;
}
});
const _httpaccessfallback = require("./http-access-fallback/http-access-fallback");
// TODO: Add `unauthorized` docs
/**
* @experimental
* This function allows you to render the [unauthorized.js file](https://nextjs.org/docs/app/api-reference/file-conventions/unauthorized)
* within a route segment as well as inject a tag.
*
* `unauthorized()` can be used in
* [Server Components](https://nextjs.org/docs/app/building-your-application/rendering/server-components),
* [Route Handlers](https://nextjs.org/docs/app/building-your-application/routing/route-handlers), and
* [Server Actions](https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations).
*
*
* Read more: [Next.js Docs: `unauthorized`](https://nextjs.org/docs/app/api-reference/functions/unauthorized)
*/ const DIGEST = `${_httpaccessfallback.HTTP_ERROR_FALLBACK_ERROR_CODE};401`;
function unauthorized() {
if (!process.env.__NEXT_EXPERIMENTAL_AUTH_INTERRUPTS) {
throw Object.defineProperty(new Error(`\`unauthorized()\` is experimental and only allowed to be used when \`experimental.authInterrupts\` is enabled.`), "__NEXT_ERROR_CODE", {
value: "E411",
enumerable: false,
configurable: true
});
}
const error = Object.defineProperty(new Error(DIGEST), "__NEXT_ERROR_CODE", {
value: "E1002",
enumerable: false,
configurable: true
});
error.digest = DIGEST;
throw error;
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=unauthorized.js.map

View File

@@ -0,0 +1,39 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
UnrecognizedActionError: null,
unstable_isUnrecognizedActionError: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
UnrecognizedActionError: function() {
return UnrecognizedActionError;
},
unstable_isUnrecognizedActionError: function() {
return unstable_isUnrecognizedActionError;
}
});
class UnrecognizedActionError extends Error {
constructor(...args){
super(...args);
this.name = 'UnrecognizedActionError';
}
}
function unstable_isUnrecognizedActionError(error) {
return !!(error && typeof error === 'object' && error instanceof UnrecognizedActionError);
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=unrecognized-action-error.js.map

View File

@@ -0,0 +1,23 @@
/**
* Create a "Thenable" that does not resolve. This is used to suspend indefinitely when data is not available yet.
*/ "use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "unresolvedThenable", {
enumerable: true,
get: function() {
return unresolvedThenable;
}
});
const unresolvedThenable = {
then: ()=>{}
};
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=unresolved-thenable.js.map

View File

@@ -0,0 +1,28 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "unstable_rethrow", {
enumerable: true,
get: function() {
return unstable_rethrow;
}
});
const _bailouttocsr = require("../../shared/lib/lazy-dynamic/bailout-to-csr");
const _isnextroutererror = require("./is-next-router-error");
function unstable_rethrow(error) {
if ((0, _isnextroutererror.isNextRouterError)(error) || (0, _bailouttocsr.isBailoutToCSRError)(error)) {
throw error;
}
if (error instanceof Error && 'cause' in error) {
unstable_rethrow(error.cause);
}
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=unstable-rethrow.browser.js.map

View File

@@ -0,0 +1,25 @@
/**
* This function should be used to rethrow internal Next.js errors so that they can be handled by the framework.
* When wrapping an API that uses errors to interrupt control flow, you should use this function before you do any error handling.
* This function will rethrow the error if it is a Next.js error so it can be handled, otherwise it will do nothing.
*
* Read more: [Next.js Docs: `unstable_rethrow`](https://nextjs.org/docs/app/api-reference/functions/unstable_rethrow)
*/ "use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "unstable_rethrow", {
enumerable: true,
get: function() {
return unstable_rethrow;
}
});
const unstable_rethrow = typeof window === 'undefined' ? require('./unstable-rethrow.server').unstable_rethrow : require('./unstable-rethrow.browser').unstable_rethrow;
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=unstable-rethrow.js.map

View File

@@ -0,0 +1,32 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "unstable_rethrow", {
enumerable: true,
get: function() {
return unstable_rethrow;
}
});
const _dynamicrenderingutils = require("../../server/dynamic-rendering-utils");
const _ispostpone = require("../../server/lib/router-utils/is-postpone");
const _bailouttocsr = require("../../shared/lib/lazy-dynamic/bailout-to-csr");
const _isnextroutererror = require("./is-next-router-error");
const _dynamicrendering = require("../../server/app-render/dynamic-rendering");
const _hooksservercontext = require("./hooks-server-context");
function unstable_rethrow(error) {
if ((0, _isnextroutererror.isNextRouterError)(error) || (0, _bailouttocsr.isBailoutToCSRError)(error) || (0, _hooksservercontext.isDynamicServerError)(error) || (0, _dynamicrendering.isDynamicPostpone)(error) || (0, _ispostpone.isPostpone)(error) || (0, _dynamicrenderingutils.isHangingPromiseRejectionError)(error) || (0, _dynamicrendering.isPrerenderInterruptedError)(error)) {
throw error;
}
if (error instanceof Error && 'cause' in error) {
unstable_rethrow(error.cause);
}
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=unstable-rethrow.server.js.map

View File

@@ -0,0 +1,148 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
dispatchAppRouterAction: null,
dispatchGestureState: null,
refreshOnInstantNavigationUnlock: null,
useActionQueue: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
dispatchAppRouterAction: function() {
return dispatchAppRouterAction;
},
dispatchGestureState: function() {
return dispatchGestureState;
},
refreshOnInstantNavigationUnlock: function() {
return refreshOnInstantNavigationUnlock;
},
useActionQueue: function() {
return useActionQueue;
}
});
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
const _isthenable = require("../../shared/lib/is-thenable");
const _routerreducertypes = require("./router-reducer/router-reducer-types");
// The app router state lives outside of React, so we can import the dispatch
// method directly wherever we need it, rather than passing it around via props
// or context.
let dispatch = null;
function refreshOnInstantNavigationUnlock() {
if (process.env.__NEXT_EXPOSE_TESTING_API) {
if (dispatch !== null) {
dispatch({
type: _routerreducertypes.ACTION_REFRESH,
bypassCacheInvalidation: true
});
} else {
window.location.reload();
}
}
}
function dispatchAppRouterAction(action) {
if (dispatch === null) {
throw Object.defineProperty(new Error('Internal Next.js error: Router action dispatched before initialization.'), "__NEXT_ERROR_CODE", {
value: "E668",
enumerable: false,
configurable: true
});
}
dispatch(action);
}
// Optimistic state setter for experimental_gesturePush. Only should be used
// during a gesture transition.
let setGestureRouterState = null;
function dispatchGestureState(state) {
if (setGestureRouterState === null) {
throw Object.defineProperty(new Error('Internal Next.js error: Router action dispatched before initialization.'), "__NEXT_ERROR_CODE", {
value: "E668",
enumerable: false,
configurable: true
});
}
setGestureRouterState(state);
}
const __DEV__ = process.env.NODE_ENV !== 'production';
const promisesWithDebugInfo = __DEV__ ? new WeakMap() : null;
function useActionQueue(actionQueue) {
const [canonicalState, setState] = _react.default.useState(actionQueue.state);
// Wrap the canonical state in useOptimistic to support
// experimental_gesturePush. During a gesture transition, this returns a fork
// of the router state that represents the eventual target if/when the gesture
// completes. Otherwise it returns the canonical state.
const [state, setGesture] = (0, _react.useOptimistic)(canonicalState);
if (typeof window !== 'undefined') {
setGestureRouterState = setGesture;
}
// Because of a known issue that requires to decode Flight streams inside the
// render phase, we have to be a bit clever and assign the dispatch method to
// a module-level variable upon initialization. The useState hook in this
// module only exists to synchronize state that lives outside of React.
// Ideally, what we'd do instead is pass the state as a prop to root.render;
// this is conceptually how we're modeling the app router state, despite the
// weird implementation details.
let nextDispatch;
if (process.env.NODE_ENV !== 'production') {
const { useAppDevRenderingIndicator } = require('../../next-devtools/userspace/use-app-dev-rendering-indicator');
// eslint-disable-next-line react-hooks/rules-of-hooks
const appDevRenderingIndicator = useAppDevRenderingIndicator();
nextDispatch = (action)=>{
appDevRenderingIndicator(()=>{
actionQueue.dispatch(action, setState);
});
};
} else {
nextDispatch = (action)=>actionQueue.dispatch(action, setState);
}
if (typeof window !== 'undefined') {
dispatch = nextDispatch;
}
// When navigating to a non-prefetched route, then App Router state will be
// blocked until the server responds. We need to transfer the `_debugInfo`
// from the underlying Flight response onto the top-level promise that is
// passed to React (via `use`) so that the latency is accurately represented
// in the React DevTools.
const stateWithDebugInfo = (0, _react.useMemo)(()=>{
if (!__DEV__) {
return state;
}
if ((0, _isthenable.isThenable)(state)) {
// useMemo can't be used to cache a Promise since the memoized value is thrown
// away when we suspend. So we use a WeakMap to cache the Promise with debug info.
let promiseWithDebugInfo = promisesWithDebugInfo.get(state);
if (promiseWithDebugInfo === undefined) {
const debugInfo = [];
promiseWithDebugInfo = Promise.resolve(state).then((asyncState)=>{
if (asyncState.debugInfo !== null) {
debugInfo.push(...asyncState.debugInfo);
}
return asyncState;
});
promiseWithDebugInfo._debugInfo = debugInfo;
promisesWithDebugInfo.set(state, promiseWithDebugInfo);
}
return promiseWithDebugInfo;
}
return state;
}, [
state
]);
return (0, _isthenable.isThenable)(stateWithDebugInfo) ? (0, _react.use)(stateWithDebugInfo) : stateWithDebugInfo;
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=use-action-queue.js.map

View File

@@ -0,0 +1,72 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
createDebugChannel: null,
getOrCreateDebugChannelReadableWriterPair: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
createDebugChannel: function() {
return createDebugChannel;
},
getOrCreateDebugChannelReadableWriterPair: function() {
return getOrCreateDebugChannelReadableWriterPair;
}
});
const _approuterheaders = require("../components/app-router-headers");
const _invarianterror = require("../../shared/lib/invariant-error");
const pairs = new Map();
function getOrCreateDebugChannelReadableWriterPair(requestId) {
let pair = pairs.get(requestId);
if (!pair) {
const { readable, writable } = new TransformStream();
pair = {
readable,
writer: writable.getWriter()
};
pairs.set(requestId, pair);
pair.writer.closed.finally(()=>pairs.delete(requestId));
}
return pair;
}
function createDebugChannel(requestHeaders) {
let requestId;
if (requestHeaders) {
requestId = requestHeaders[_approuterheaders.NEXT_REQUEST_ID_HEADER] ?? undefined;
if (!requestId) {
throw Object.defineProperty(new _invarianterror.InvariantError(`Expected a ${JSON.stringify(_approuterheaders.NEXT_REQUEST_ID_HEADER)} request header.`), "__NEXT_ERROR_CODE", {
value: "E854",
enumerable: false,
configurable: true
});
}
} else {
requestId = self.__next_r;
if (!requestId) {
throw Object.defineProperty(new _invarianterror.InvariantError(`Expected a request ID to be defined for the document via self.__next_r.`), "__NEXT_ERROR_CODE", {
value: "E806",
enumerable: false,
configurable: true
});
}
}
const { readable } = getOrCreateDebugChannelReadableWriterPair(requestId);
return {
readable
};
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=debug-channel.js.map

View File

@@ -0,0 +1,232 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
createInitialRSCPayloadFromFallbackPrerender: null,
getFlightDataPartsFromPath: null,
getNextFlightSegmentPath: null,
normalizeFlightData: null,
prepareFlightRouterStateForRequest: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
createInitialRSCPayloadFromFallbackPrerender: function() {
return createInitialRSCPayloadFromFallbackPrerender;
},
getFlightDataPartsFromPath: function() {
return getFlightDataPartsFromPath;
},
getNextFlightSegmentPath: function() {
return getNextFlightSegmentPath;
},
normalizeFlightData: function() {
return normalizeFlightData;
},
prepareFlightRouterStateForRequest: function() {
return prepareFlightRouterStateForRequest;
}
});
const _segment = require("../shared/lib/segment");
const _routeparams = require("./route-params");
const _createhreffromurl = require("./components/router-reducer/create-href-from-url");
function getFlightDataPartsFromPath(flightDataPath) {
// Pick the last 4 items from the `FlightDataPath` to get the [tree, seedData, viewport, isHeadPartial].
const flightDataPathLength = 4;
// tree, seedData, and head are *always* the last three items in the `FlightDataPath`.
const [tree, seedData, head, isHeadPartial] = flightDataPath.slice(-flightDataPathLength);
// The `FlightSegmentPath` is everything except the last three items. For a root render, it won't be present.
const segmentPath = flightDataPath.slice(0, -flightDataPathLength);
return {
// TODO: Unify these two segment path helpers. We are inconsistently pushing an empty segment ("")
// to the start of the segment path in some places which makes it hard to use solely the segment path.
// Look for "// TODO-APP: remove ''" in the codebase.
pathToSegment: segmentPath.slice(0, -1),
segmentPath,
// if the `FlightDataPath` corresponds with the root, there'll be no segment path,
// in which case we default to ''.
segment: segmentPath[segmentPath.length - 1] ?? '',
tree,
seedData,
head,
isHeadPartial,
isRootRender: flightDataPath.length === flightDataPathLength
};
}
function createInitialRSCPayloadFromFallbackPrerender(response, fallbackInitialRSCPayload) {
// This is a static fallback page. In order to hydrate the page, we need to
// parse the client params from the URL, but to account for the possibility
// that the page was rewritten, we need to check the response headers
// for x-nextjs-rewritten-path or x-nextjs-rewritten-query headers. Since
// we can't access the headers of the initial document response, the client
// performs a fetch request to the current location. Since it's possible that
// the fetch request will be dynamically rewritten to a different path than
// the initial document, this fetch request delivers _all_ the hydration data
// for the page; it was not inlined into the document, like it normally
// would be.
//
// TODO: Consider treating the case where fetch is rewritten to a different
// path from the document as a special deopt case. We should optimistically
// assume this won't happen, inline the data into the document, and perform
// a minimal request (like a HEAD or range request) to verify that the
// response matches. Tricky to get right because we need to account for
// all the different deployment environments we support, like output:
// "export" mode, where we currently don't assume that custom response
// headers are present.
// Patch the Flight data sent by the server with the correct params parsed
// from the URL + response object.
const renderedPathname = (0, _routeparams.getRenderedPathname)(response);
const renderedSearch = (0, _routeparams.getRenderedSearch)(response);
const canonicalUrl = (0, _createhreffromurl.createHrefFromUrl)(new URL(location.href));
const originalFlightDataPath = fallbackInitialRSCPayload.f[0];
const originalFlightRouterState = originalFlightDataPath[0];
const payload = {
c: canonicalUrl.split('/'),
q: renderedSearch,
i: fallbackInitialRSCPayload.i,
f: [
[
fillInFallbackFlightRouterState(originalFlightRouterState, renderedPathname, renderedSearch),
originalFlightDataPath[1],
originalFlightDataPath[2],
originalFlightDataPath[2]
]
],
m: fallbackInitialRSCPayload.m,
G: fallbackInitialRSCPayload.G,
S: fallbackInitialRSCPayload.S,
h: fallbackInitialRSCPayload.h
};
if (fallbackInitialRSCPayload.b) {
payload.b = fallbackInitialRSCPayload.b;
}
return payload;
}
function fillInFallbackFlightRouterState(flightRouterState, renderedPathname, renderedSearch) {
const pathnameParts = renderedPathname.split('/').filter((p)=>p !== '');
const index = 0;
return fillInFallbackFlightRouterStateImpl(flightRouterState, renderedSearch, pathnameParts, index);
}
function fillInFallbackFlightRouterStateImpl(flightRouterState, renderedSearch, pathnameParts, pathnamePartsIndex) {
const originalSegment = flightRouterState[0];
let newSegment;
let doesAppearInURL;
if (typeof originalSegment === 'string') {
newSegment = originalSegment;
doesAppearInURL = (0, _routeparams.doesStaticSegmentAppearInURL)(originalSegment);
} else {
const paramName = originalSegment[0];
const paramType = originalSegment[2];
const staticSiblings = originalSegment[3];
const paramValue = (0, _routeparams.parseDynamicParamFromURLPart)(paramType, pathnameParts, pathnamePartsIndex);
const cacheKey = (0, _routeparams.getCacheKeyForDynamicParam)(paramValue, renderedSearch);
newSegment = [
paramName,
cacheKey,
paramType,
staticSiblings
];
doesAppearInURL = true;
}
// Only increment the index if the segment appears in the URL. If it's a
// "virtual" segment, like a route group, it remains the same.
const childPathnamePartsIndex = doesAppearInURL ? pathnamePartsIndex + 1 : pathnamePartsIndex;
const children = flightRouterState[1];
const newChildren = {};
for(let key in children){
const childFlightRouterState = children[key];
newChildren[key] = fillInFallbackFlightRouterStateImpl(childFlightRouterState, renderedSearch, pathnameParts, childPathnamePartsIndex);
}
const newState = [
newSegment,
newChildren,
null,
flightRouterState[3],
flightRouterState[4]
];
return newState;
}
function getNextFlightSegmentPath(flightSegmentPath) {
// Since `FlightSegmentPath` is a repeated tuple of `Segment` and `ParallelRouteKey`, we slice off two items
// to get the next segment path.
return flightSegmentPath.slice(2);
}
function normalizeFlightData(flightData) {
// FlightData can be a string when the server didn't respond with a proper flight response,
// or when a redirect happens, to signal to the client that it needs to perform an MPA navigation.
if (typeof flightData === 'string') {
return flightData;
}
return flightData.map((flightDataPath)=>getFlightDataPartsFromPath(flightDataPath));
}
function prepareFlightRouterStateForRequest(flightRouterState, isHmrRefresh) {
// HMR requests need the complete, unmodified state for proper functionality
if (isHmrRefresh) {
return encodeURIComponent(JSON.stringify(flightRouterState));
}
return encodeURIComponent(JSON.stringify(stripClientOnlyDataFromFlightRouterState(flightRouterState)));
}
/**
* Recursively strips client-only data from FlightRouterState while preserving
* server-needed information for proper rendering decisions.
*/ function stripClientOnlyDataFromFlightRouterState(flightRouterState) {
const [segment, parallelRoutes, _refreshState, refreshMarker, prefetchHints] = flightRouterState;
// Strip client-only data from the segment
const cleanedSegment = stripClientOnlyDataFromSegment(segment);
// Recursively process parallel routes
const cleanedParallelRoutes = {};
for (const [key, childState] of Object.entries(parallelRoutes)){
cleanedParallelRoutes[key] = stripClientOnlyDataFromFlightRouterState(childState);
}
const result = [
cleanedSegment,
cleanedParallelRoutes
];
if (refreshMarker) {
result[2] = null // null slightly more compact than undefined
;
result[3] = refreshMarker;
}
// Append optional fields if present
if (prefetchHints !== undefined) {
result[4] = prefetchHints;
}
// Everything else is used only by the client and is not needed for requests.
return result;
}
/**
* Strips client-only data from segments:
* - Search parameters from __PAGE__ segments
* - staticSiblings from dynamic segment tuples (only needed for client-side
* prefetch reuse decisions)
*/ function stripClientOnlyDataFromSegment(segment) {
if (typeof segment === 'string') {
// Strip search params from __PAGE__ segments
if (segment.startsWith(_segment.PAGE_SEGMENT_KEY + '?')) {
return _segment.PAGE_SEGMENT_KEY;
}
return segment;
}
// Dynamic segment tuple: [paramName, paramCacheKey, paramType, staticSiblings]
// Strip staticSiblings (4th element) since server doesn't need it
const [paramName, paramCacheKey, paramType] = segment;
return [
paramName,
paramCacheKey,
paramType,
null
];
}
if ((typeof exports.default === 'function' || (typeof exports.default === 'object' && exports.default !== null)) && typeof exports.default.__esModule === 'undefined') {
Object.defineProperty(exports.default, '__esModule', { value: true });
Object.assign(exports.default, exports);
module.exports = exports.default;
}
//# sourceMappingURL=flight-data-helpers.js.map

Some files were not shown because too many files have changed in this diff Show More