lingjing/node_modules/next/dist/build/static-paths/app/extract-pathname-route-param-segments-from-loader-tree.js
2026-02-23 09:51:43 +00:00

137 lines
6.0 KiB
JavaScript

"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