/
opt
/
canhelp
/
node_modules
/
next
/
dist
/
esm
/
shared
/
lib
/
router
/
utils
/
/opt/canhelp/node_modules/next/dist/esm/shared/lib/router/utils
mkdir
upload
Name
Size
Mode
Actions
add-locale.js
1020
0644
edit
dl
rm
add-locale.js.map
1720
0644
edit
dl
rm
add-path-prefix.js
432
0644
edit
dl
rm
add-path-prefix.js.map
888
0644
edit
dl
rm
add-path-suffix.js
490
0644
edit
dl
rm
add-path-suffix.js.map
948
0644
edit
dl
rm
app-paths.js
1768
0644
edit
dl
rm
app-paths.js.map
2722
0644
edit
dl
rm
as-path-to-search-params.js
262
0644
edit
dl
rm
as-path-to-search-params.js.map
549
0644
edit
dl
rm
cache-busting-search-param.js
580
0644
edit
dl
rm
cache-busting-search-param.js.map
1307
0644
edit
dl
rm
compare-states.js
850
0644
edit
dl
rm
compare-states.js.map
1914
0644
edit
dl
rm
disable-smooth-scroll.js
2376
0644
edit
dl
rm
disable-smooth-scroll.js.map
3626
0644
edit
dl
rm
escape-path-delimiters.js
307
0644
edit
dl
rm
escape-path-delimiters.js.map
737
0644
edit
dl
rm
format-next-pathname-info.js
908
0644
edit
dl
rm
format-next-pathname-info.js.map
2079
0644
edit
dl
rm
format-url.js
3269
0644
edit
dl
rm
format-url.js.map
5697
0644
edit
dl
rm
get-asset-path-from-route.js
437
0644
edit
dl
rm
get-asset-path-from-route.js.map
830
0644
edit
dl
rm
get-dynamic-param.js
5308
0644
edit
dl
rm
get-dynamic-param.js.map
7436
0644
edit
dl
rm
get-next-pathname-info.js
2158
0644
edit
dl
rm
get-next-pathname-info.js.map
5177
0644
edit
dl
rm
get-route-from-asset-path.js
716
0644
edit
dl
rm
get-route-from-asset-path.js.map
1316
0644
edit
dl
rm
html-bots.js
909
0644
edit
dl
rm
html-bots.js.map
1136
0644
edit
dl
rm
index.js
155
0644
edit
dl
rm
index.js.map
389
0644
edit
dl
rm
interception-routes.js
3708
0644
edit
dl
rm
interception-routes.js.map
5016
0644
edit
dl
rm
interpolate-as.js
2000
0644
edit
dl
rm
interpolate-as.js.map
3805
0644
edit
dl
rm
is-bot.js
1100
0644
edit
dl
rm
is-bot.js.map
1947
0644
edit
dl
rm
is-dynamic.js
884
0644
edit
dl
rm
is-dynamic.js.map
1504
0644
edit
dl
rm
is-local-url.js
722
0644
edit
dl
rm
is-local-url.js.map
1282
0644
edit
dl
rm
middleware-route-matcher.js
678
0644
edit
dl
rm
middleware-route-matcher.js.map
1755
0644
edit
dl
rm
omit.js
250
0644
edit
dl
rm
omit.js.map
761
0644
edit
dl
rm
parse-path.js
841
0644
edit
dl
rm
parse-path.js.map
1495
0644
edit
dl
rm
parse-relative-url.js
1251
0644
edit
dl
rm
parse-relative-url.js.map
3015
0644
edit
dl
rm
parse-url.js
722
0644
edit
dl
rm
parse-url.js.map
1850
0644
edit
dl
rm
path-has-prefix.js
595
0644
edit
dl
rm
path-has-prefix.js.map
1002
0644
edit
dl
rm
path-match.js
1970
0644
edit
dl
rm
path-match.js.map
3791
0644
edit
dl
rm
prepare-destination.js
9828
0644
edit
dl
rm
prepare-destination.js.map
17143
0644
edit
dl
rm
querystring.js
1703
0644
edit
dl
rm
querystring.js.map
3224
0644
edit
dl
rm
relativize-url.js
851
0644
edit
dl
rm
relativize-url.js.map
1839
0644
edit
dl
rm
remove-path-prefix.js
1334
0644
edit
dl
rm
remove-path-prefix.js.map
2009
0644
edit
dl
rm
remove-trailing-slash.js
332
0644
edit
dl
rm
remove-trailing-slash.js.map
583
0644
edit
dl
rm
resolve-rewrites.js
4240
0644
edit
dl
rm
resolve-rewrites.js.map
7805
0644
edit
dl
rm
route-match-utils.js
3361
0644
edit
dl
rm
route-match-utils.js.map
5660
0644
edit
dl
rm
route-matcher.js
1271
0644
edit
dl
rm
route-matcher.js.map
2567
0644
edit
dl
rm
route-regex.js
9315
0644
edit
dl
rm
route-regex.js.map
17526
0644
edit
dl
rm
sortable-routes.js
8502
0644
edit
dl
rm
sortable-routes.js.map
12536
0644
edit
dl
rm
sorted-routes.js
11332
0644
edit
dl
rm
sorted-routes.js.map
14757
0644
edit
dl
rm
Edit:
/opt/canhelp/node_modules/next/dist/esm/shared/lib/router/utils/sortable-routes.js
(8502B)
/** * A route that can be sorted by specificity. */ /** * Determines the specificity of a route segment for sorting purposes. * * In Next.js routing, more specific routes should match before less specific ones. * This function returns a numeric value where lower numbers indicate higher specificity. * * Specificity order (most to least specific): * 1. Static segments (e.g., "about", "api") - return 0 * 2. Dynamic segments (e.g., "[id]", "[slug]") - return 1 * 3. Catch-all segments (e.g., "[...slug]") - return 2 * 4. Optional catch-all segments (e.g., "[[...slug]]") - return 3 * * @param segment - A single path segment (e.g., "api", "[id]", "[...slug]") * @returns A numeric specificity value (0-3, where 0 is most specific) */ export function getSegmentSpecificity(segment) { // Static segments are most specific - they match exactly one path if (!segment.includes('[')) { return 0; } // Optional catch-all [[...param]] is least specific - matches zero or more segments if (segment.startsWith('[[...') && segment.endsWith(']]')) { return 3; } // Catch-all [...param] is less specific - matches one or more segments if (segment.startsWith('[...') && segment.endsWith(']')) { return 2; } // Regular dynamic [param] is more specific than catch-all - matches exactly one segment if (segment.startsWith('[') && segment.endsWith(']')) { return 1; } // Default to static (fallback case) return 0; } /** * Compares two route paths using a depth-first traversal approach. * * This function implements a deterministic comparison that sorts routes by specificity: * 1. More specific routes come first (fewer dynamic segments) * 2. Shorter routes are more specific than longer ones * 3. Routes with same specificity are sorted lexicographically * * The comparison is done segment by segment, left to right, similar to how * you would traverse a route tree in depth-first order. * * @param pathA - First route path to compare (e.g., "/api/users/[id]") * @param pathB - Second route path to compare (e.g., "/api/[...slug]") * @returns Negative if pathA is more specific, positive if pathB is more specific, 0 if equal */ export function compareRouteSegments(pathA, pathB) { // Split paths into segments, removing empty strings from leading/trailing slashes const segmentsA = pathA.split('/').filter(Boolean); const segmentsB = pathB.split('/').filter(Boolean); // Compare segment by segment up to the length of the longer path const maxLength = Math.max(segmentsA.length, segmentsB.length); for(let i = 0; i < maxLength; i++){ const segA = segmentsA[i] || ''; const segB = segmentsB[i] || ''; // Handle length differences: shorter routes are MORE specific // Example: "/api" is more specific than "/api/users" if (!segA && segB) return -1 // pathA is shorter, so more specific ; if (segA && !segB) return 1 // pathB is shorter, so more specific ; if (!segA && !segB) return 0 // Both paths ended, they're equal ; // Compare segment specificity using our specificity scoring const specificityA = getSegmentSpecificity(segA); const specificityB = getSegmentSpecificity(segB); // Lower specificity number = more specific route // Example: "api" (0) vs "[slug]" (1) - "api" wins if (specificityA !== specificityB) { return specificityA - specificityB; } // If segments have same specificity, compare lexicographically for determinism // Example: "[id]" vs "[slug]" - "[id]" comes first alphabetically if (segA !== segB) { return segA.localeCompare(segB); } // Segments are identical, continue to next segment } // All segments compared equally return 0; } /** * Compares two complete routes for sorting purposes. * * Routes are compared with a two-tier priority system: * 1. Primary: Compare by source path specificity * 2. Secondary: If sources are equal, compare by page path specificity * * This ensures that routes are primarily organized by their source patterns, * with page-specific variations grouped together. * * @param a - First route to compare * @param b - Second route to compare * @returns Negative if route a should come first, positive if route b should come first, 0 if equal */ function compareSortableRoutes(a, b) { // First compare by source specificity - this is the primary sorting criterion // Source represents the original route pattern and takes precedence const sourceResult = compareRouteSegments(a.sourcePage, b.sourcePage); if (sourceResult !== 0) return sourceResult; // If sources are identical, compare by page specificity as a tiebreaker // Page represents the final rendered route and provides secondary ordering return compareRouteSegments(a.page, b.page); } /** * Sorts an array of routes by specificity using a deterministic depth-first traversal approach. * * This function implements Next.js route matching priority where more specific routes * should be matched before less specific ones. The sorting is deterministic and stable, * meaning identical inputs will always produce identical outputs. * * Sorting criteria (in order of priority): * 1. Source path specificity (primary) * 2. Page path specificity (secondary) * 3. Lexicographic ordering (tertiary, for determinism) * * Examples of specificity order: * - "/api/users" (static) comes before "/api/[slug]" (dynamic) * - "/api/[id]" (dynamic) comes before "/api/[...slug]" (catch-all) * - "/api/[...slug]" (catch-all) comes before "/api/[[...slug]]" (optional catch-all) * * @param routes - Array of routes to sort * @returns New sorted array (does not mutate input) */ export function sortSortableRoutes(routes) { // Because sort is always in-place, we need to create a shallow copy to avoid // mutating the input array. return [ ...routes ].sort(compareSortableRoutes); } /** * Sorts an array of pages by specificity using a deterministic depth-first * traversal approach. * * @param pages - Array of pages to sort * @returns New sorted array (does not mutate input) */ export function sortPages(pages) { // Because sort is always in-place, we need to create a shallow copy to avoid // mutating the input array. return [ ...pages ].sort(compareRouteSegments); } /** * Sorts an array of objects by sourcePage and page using a deterministic * depth-first traversal approach. * * @param objects - Array of objects to sort * @param getter - Function to get the sourcePage and page from an object * @returns New sorted array (does not mutate input) */ export function sortSortableRouteObjects(objects, getter) { // Create a SortableRoute for each object. const routes = []; for (const object of objects){ const route = getter(object); routes.push({ ...route, object }); } // In-place sort the SortableRoutes. routes.sort(compareSortableRoutes); // Map the sorted SortableRoutes back to the original objects. return routes.map((param)=>{ let { object } = param; return object; }); } /** * Sorts an array of objects by page using a deterministic depth-first traversal * approach. * * @param objects - Array of objects to sort * @param getter - Function to get the page from an object * @returns New sorted array (does not mutate input) */ export function sortPageObjects(objects, getter) { const indexes = {}; const pages = new Set(); for(let i = 0; i < objects.length; i++){ var _indexes_page; const object = objects[i]; const page = getter(object); ((_indexes_page = indexes[page]) == null ? void 0 : _indexes_page.push(i)) || (indexes[page] = [ i ]); pages.add(page); } // Sort the unique pages. const sortedPages = Array.from(pages).sort(compareRouteSegments); // Map the sorted pages back to the original objects. return sortedPages.reduce((sortedObjects, page)=>{ // Add all objects for this page to the sorted array. for (const i of indexes[page]){ sortedObjects.push(objects[i]); } // Return the sorted array. return sortedObjects; }, []); } //# sourceMappingURL=sortable-routes.js.map
Save
cmd:
run