including-modules
This commit is contained in:
Generated
Vendored
+134
@@ -0,0 +1,134 @@
|
||||
import { parseAppRouteSegment } from '../../../shared/lib/router/routes/app';
|
||||
import { parseLoaderTree } from '../../../shared/lib/router/utils/parse-loader-tree';
|
||||
import { resolveParamValue } from '../../../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;
|
||||
}
|
||||
/**
|
||||
* Extracts pathname route param segments from a loader tree and resolves
|
||||
* parameter values from static segments in the route.
|
||||
*
|
||||
* @param loaderTree - The loader tree structure containing route hierarchy
|
||||
* @param route - The target route to match against
|
||||
* @returns Object containing pathname route param segments and resolved params
|
||||
*/ export 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 } = parseLoaderTree(tree);
|
||||
// Build the path for the current node
|
||||
let updatedPath = currentPath;
|
||||
let nextDepth = depth;
|
||||
const appSegment = 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 = 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
|
||||
Generated
Vendored
+1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user