diff --git a/__tests__/matcher/pathRanking.spec.ts b/__tests__/matcher/pathRanking.spec.ts index ce6e68848..a5d4d46a1 100644 --- a/__tests__/matcher/pathRanking.spec.ts +++ b/__tests__/matcher/pathRanking.spec.ts @@ -143,6 +143,15 @@ describe('Path ranking', () => { }) }) + it('puts catchall param after same prefix', () => { + possibleOptions.forEach(options => { + checkPathOrder([ + ['/a', options], + ['/a/:a(.*)*', options], + ]) + }) + }) + it('sensitive should go before non sensitive', () => { checkPathOrder([ ['/Home', { sensitive: true }], diff --git a/src/matcher/pathParserRanker.ts b/src/matcher/pathParserRanker.ts index 483a29c47..f225fa7a1 100644 --- a/src/matcher/pathParserRanker.ts +++ b/src/matcher/pathParserRanker.ts @@ -329,6 +329,10 @@ export function comparePathParserScore(a: PathParser, b: PathParser): number { i++ } + if (Math.abs(bScore.length - aScore.length) === 1) { + if (isLastScoreNegative(aScore)) return 1 + if (isLastScoreNegative(bScore)) return -1 + } // if a and b share the same score entries but b has more, sort b first return bScore.length - aScore.length @@ -339,3 +343,14 @@ export function comparePathParserScore(a: PathParser, b: PathParser): number { // ? -1 // : 0 } + +/** + * This allows detecting splats at the end of a path: /home/:id(.*)* + * + * @param score - score to check + * @returns true if the last entry is negative + */ +function isLastScoreNegative(score: PathParser['score']): boolean { + const last = score[score.length - 1] + return score.length > 0 && last[last.length - 1] < 0 +}