@@ -10,20 +10,11 @@ function pickPathsAndParams(routes: RouteObject[], pathname: string) {
10
10
let matches = matchRoutes ( routes , pathname ) ;
11
11
return (
12
12
matches &&
13
- matches . map ( ( match ) => {
14
- let { path } = match . route
15
-
16
- // filter params to only include params for the current (relative) route path
17
- let paramNames = path ?. split ( '/' )
18
- . filter ( seg => seg . startsWith ( ':' ) )
19
- . map ( paramSeg => paramSeg . replace ( / ^ : / , "" ) . replace ( / \? $ / , "" ) )
20
- let params = Object . fromEntries ( Object . entries ( match . params ) . filter ( ( [ k , v ] ) => paramNames ?. includes ( k ) ) )
21
-
22
- return {
23
- path : match . route . path ,
24
- params,
25
- }
26
- } )
13
+ matches . map ( ( match ) => ( {
14
+ ...( match . route . index ? { index : match . route . index } : { } ) ,
15
+ ...( match . route . path ? { path : match . route . path } : { } ) ,
16
+ params : match . params ,
17
+ } ) )
27
18
) ;
28
19
}
29
20
@@ -383,7 +374,6 @@ describe("path matching with optional segments", () => {
383
374
} ,
384
375
] ;
385
376
386
-
387
377
expect ( pickPathsAndParams ( nested , "/en/abc" ) ) . toEqual ( [
388
378
{ path : "/en?" , params : { } } ,
389
379
{ path : "abc" , params : { } } ,
@@ -481,17 +471,302 @@ describe("path matching with optional dynamic segments", () => {
481
471
path : "three/:four?" ,
482
472
children : [
483
473
{
484
- path : ":five?"
485
- }
486
- ]
487
- }
474
+ path : ":five?" ,
475
+ } ,
476
+ ] ,
477
+ } ,
488
478
] ,
489
479
} ,
490
480
] ;
481
+ expect ( pickPathsAndParams ( nested , "/one/dos/three/cuatro/cinco" ) ) . toEqual ( [
482
+ {
483
+ path : "/one/:two?" ,
484
+ params : { two : "dos" , four : "cuatro" , five : "cinco" } ,
485
+ } ,
486
+ {
487
+ path : "three/:four?" ,
488
+ params : { two : "dos" , four : "cuatro" , five : "cinco" } ,
489
+ } ,
490
+ { path : ":five?" , params : { two : "dos" , four : "cuatro" , five : "cinco" } } ,
491
+ ] ) ;
492
+ expect ( pickPathsAndParams ( nested , "/one/dos/three/cuatro" ) ) . toEqual ( [
493
+ {
494
+ path : "/one/:two?" ,
495
+ params : { two : "dos" , four : "cuatro" } ,
496
+ } ,
497
+ {
498
+ path : "three/:four?" ,
499
+ params : { two : "dos" , four : "cuatro" } ,
500
+ } ,
501
+ {
502
+ path : ":five?" ,
503
+ params : { two : "dos" , four : "cuatro" } ,
504
+ } ,
505
+ ] ) ;
506
+ expect ( pickPathsAndParams ( nested , "/one/dos/three" ) ) . toEqual ( [
507
+ {
508
+ path : "/one/:two?" ,
509
+ params : { two : "dos" } ,
510
+ } ,
511
+ {
512
+ path : "three/:four?" ,
513
+ params : { two : "dos" } ,
514
+ } ,
515
+ // Matches into 5 because it's just like if we did path=""
516
+ {
517
+ path : ":five?" ,
518
+ params : { two : "dos" } ,
519
+ } ,
520
+ ] ) ;
521
+ expect ( pickPathsAndParams ( nested , "/one/dos" ) ) . toEqual ( [
522
+ {
523
+ path : "/one/:two?" ,
524
+ params : { two : "dos" } ,
525
+ } ,
526
+ ] ) ;
527
+ expect ( pickPathsAndParams ( nested , "/one" ) ) . toEqual ( [
528
+ {
529
+ path : "/one/:two?" ,
530
+ params : { } ,
531
+ } ,
532
+ ] ) ;
491
533
expect ( pickPathsAndParams ( nested , "/one/three/cuatro/cinco" ) ) . toEqual ( [
492
- { path : "/one/:two?" , params : { } } ,
493
- { path : "three/:four?" , params : { four : 'cuatro' } } ,
494
- { path : ":five?" , params : { five : 'cinco' } } ,
495
- ] )
534
+ {
535
+ path : "/one/:two?" ,
536
+ params : { four : "cuatro" , five : "cinco" } ,
537
+ } ,
538
+ {
539
+ path : "three/:four?" ,
540
+ params : { four : "cuatro" , five : "cinco" } ,
541
+ } ,
542
+ { path : ":five?" , params : { four : "cuatro" , five : "cinco" } } ,
543
+ ] ) ;
544
+ expect ( pickPathsAndParams ( nested , "/one/three/cuatro" ) ) . toEqual ( [
545
+ {
546
+ path : "/one/:two?" ,
547
+ params : { four : "cuatro" } ,
548
+ } ,
549
+ {
550
+ path : "three/:four?" ,
551
+ params : { four : "cuatro" } ,
552
+ } ,
553
+ {
554
+ path : ":five?" ,
555
+ params : { four : "cuatro" } ,
556
+ } ,
557
+ ] ) ;
558
+ expect ( pickPathsAndParams ( nested , "/one/three" ) ) . toEqual ( [
559
+ {
560
+ path : "/one/:two?" ,
561
+ params : { } ,
562
+ } ,
563
+ {
564
+ path : "three/:four?" ,
565
+ params : { } ,
566
+ } ,
567
+ // Matches into 5 because it's just like if we did path=""
568
+ {
569
+ path : ":five?" ,
570
+ params : { } ,
571
+ } ,
572
+ ] ) ;
573
+ expect ( pickPathsAndParams ( nested , "/one" ) ) . toEqual ( [
574
+ {
575
+ path : "/one/:two?" ,
576
+ params : { } ,
577
+ } ,
578
+ ] ) ;
579
+ } ) ;
580
+
581
+ test ( "prefers optional static over optional dynamic segments" , ( ) => {
582
+ let nested = [
583
+ {
584
+ path : "/one" ,
585
+ children : [
586
+ {
587
+ path : ":param?" ,
588
+ children : [
589
+ {
590
+ path : "three" ,
591
+ } ,
592
+ ] ,
593
+ } ,
594
+ {
595
+ path : "two?" ,
596
+ children : [
597
+ {
598
+ path : "three" ,
599
+ } ,
600
+ ] ,
601
+ } ,
602
+ ] ,
603
+ } ,
604
+ ] ;
605
+
606
+ // static `two` segment should win
607
+ expect ( pickPathsAndParams ( nested , "/one/two/three" ) ) . toEqual ( [
608
+ {
609
+ params : { } ,
610
+ path : "/one" ,
611
+ } ,
612
+ {
613
+ params : { } ,
614
+ path : "two?" ,
615
+ } ,
616
+ {
617
+ params : { } ,
618
+ path : "three" ,
619
+ } ,
620
+ ] ) ;
621
+
622
+ // fall back to param when no static match
623
+ expect ( pickPathsAndParams ( nested , "/one/not-two/three" ) ) . toEqual ( [
624
+ {
625
+ params : {
626
+ param : "not-two" ,
627
+ } ,
628
+ path : "/one" ,
629
+ } ,
630
+ {
631
+ params : {
632
+ param : "not-two" ,
633
+ } ,
634
+ path : ":param?" ,
635
+ } ,
636
+ {
637
+ params : {
638
+ param : "not-two" ,
639
+ } ,
640
+ path : "three" ,
641
+ } ,
642
+ ] ) ;
643
+
644
+ // No optional segment provided - earlier "dup" route should win
645
+ expect ( pickPathsAndParams ( nested , "/one/three" ) ) . toEqual ( [
646
+ {
647
+ params : { } ,
648
+ path : "/one" ,
649
+ } ,
650
+ {
651
+ params : { } ,
652
+ path : ":param?" ,
653
+ } ,
654
+ {
655
+ params : { } ,
656
+ path : "three" ,
657
+ } ,
658
+ ] ) ;
659
+ } ) ;
660
+
661
+ test ( "prefers index routes over optional static segments" , ( ) => {
662
+ let nested = [
663
+ {
664
+ path : "/one" ,
665
+ children : [
666
+ {
667
+ path : ":param?" ,
668
+ children : [
669
+ {
670
+ path : "three?" ,
671
+ } ,
672
+ {
673
+ index : true ,
674
+ } ,
675
+ ] ,
676
+ } ,
677
+ ] ,
678
+ } ,
679
+ ] ;
680
+
681
+ expect ( pickPathsAndParams ( nested , "/one/two" ) ) . toEqual ( [
682
+ {
683
+ params : {
684
+ param : "two" ,
685
+ } ,
686
+ path : "/one" ,
687
+ } ,
688
+ {
689
+ params : {
690
+ param : "two" ,
691
+ } ,
692
+ path : ":param?" ,
693
+ } ,
694
+ {
695
+ index : true ,
696
+ params : {
697
+ param : "two" ,
698
+ } ,
699
+ } ,
700
+ ] ) ;
701
+ expect ( pickPathsAndParams ( nested , "/one" ) ) . toEqual ( [
702
+ {
703
+ params : { } ,
704
+ path : "/one" ,
705
+ } ,
706
+ {
707
+ params : { } ,
708
+ path : ":param?" ,
709
+ } ,
710
+ {
711
+ index : true ,
712
+ params : { } ,
713
+ } ,
714
+ ] ) ;
715
+ } ) ;
716
+
717
+ test ( "prefers index routes over optional dynamic segments" , ( ) => {
718
+ let nested = [
719
+ {
720
+ path : "/one" ,
721
+ children : [
722
+ {
723
+ path : ":param?" ,
724
+ children : [
725
+ {
726
+ path : ":three?" ,
727
+ } ,
728
+ {
729
+ index : true ,
730
+ } ,
731
+ ] ,
732
+ } ,
733
+ ] ,
734
+ } ,
735
+ ] ;
736
+
737
+ expect ( pickPathsAndParams ( nested , "/one/two" ) ) . toEqual ( [
738
+ {
739
+ params : {
740
+ param : "two" ,
741
+ } ,
742
+ path : "/one" ,
743
+ } ,
744
+ {
745
+ params : {
746
+ param : "two" ,
747
+ } ,
748
+ path : ":param?" ,
749
+ } ,
750
+ {
751
+ index : true ,
752
+ params : {
753
+ param : "two" ,
754
+ } ,
755
+ } ,
756
+ ] ) ;
757
+ expect ( pickPathsAndParams ( nested , "/one" ) ) . toEqual ( [
758
+ {
759
+ params : { } ,
760
+ path : "/one" ,
761
+ } ,
762
+ {
763
+ params : { } ,
764
+ path : ":param?" ,
765
+ } ,
766
+ {
767
+ index : true ,
768
+ params : { } ,
769
+ } ,
770
+ ] ) ;
496
771
} ) ;
497
772
} ) ;
0 commit comments