@@ -218,8 +218,7 @@ export const parsePathname = (
218218 return parsed
219219}
220220
221- const PARAM_RE = / ^ \$ [ ^ _ ] ( .* [ ^ _ ] ) ? $ / // $paramName
222- const PARAM_NON_NESTED_RE = / ^ \$ .{ 1 , } _ $ / // $paramName_
221+ const PARAM_RE = / ^ \$ .{ 1 , } $ / // $paramName
223222const PARAM_W_CURLY_BRACES_RE = / ^ ( .* ?) \{ ( \$ [ a - z A - Z _ $ ] [ a - z A - Z 0 - 9 _ $ ] * ) \} ( .* ) $ / // prefix{$paramName}suffix
224223const OPTIONAL_PARAM_W_CURLY_BRACES_RE =
225224 / ^ ( .* ?) \{ - ( \$ [ a - z A - Z _ $ ] [ a - z A - Z 0 - 9 _ $ ] * ) \} ( .* ) $ / // prefix{-$paramName}suffix
@@ -266,8 +265,11 @@ function baseParsePathname(pathname: string): ReadonlyArray<Segment> {
266265
267266 segments . push (
268267 ...split . map ( ( part ) : Segment => {
268+ // strip tailing underscore for non-nested paths
269+ const partToMatch = part . slice ( - 1 ) === '_' ? part . slice ( 0 , - 1 ) : part
270+
269271 // Check for wildcard with curly braces: prefix{$}suffix
270- const wildcardBracesMatch = part . match ( WILDCARD_W_CURLY_BRACES_RE )
272+ const wildcardBracesMatch = partToMatch . match ( WILDCARD_W_CURLY_BRACES_RE )
271273 if ( wildcardBracesMatch ) {
272274 const prefix = wildcardBracesMatch [ 1 ]
273275 const suffix = wildcardBracesMatch [ 2 ]
@@ -280,7 +282,7 @@ function baseParsePathname(pathname: string): ReadonlyArray<Segment> {
280282 }
281283
282284 // Check for optional parameter format: prefix{-$paramName}suffix
283- const optionalParamBracesMatch = part . match (
285+ const optionalParamBracesMatch = partToMatch . match (
284286 OPTIONAL_PARAM_W_CURLY_BRACES_RE ,
285287 )
286288 if ( optionalParamBracesMatch ) {
@@ -296,7 +298,7 @@ function baseParsePathname(pathname: string): ReadonlyArray<Segment> {
296298 }
297299
298300 // Check for the new parameter format: prefix{$paramName}suffix
299- const paramBracesMatch = part . match ( PARAM_W_CURLY_BRACES_RE )
301+ const paramBracesMatch = partToMatch . match ( PARAM_W_CURLY_BRACES_RE )
300302 if ( paramBracesMatch ) {
301303 const prefix = paramBracesMatch [ 1 ]
302304 const paramName = paramBracesMatch [ 2 ]
@@ -309,20 +311,10 @@ function baseParsePathname(pathname: string): ReadonlyArray<Segment> {
309311 }
310312 }
311313
312- // Check for non-nested bare parameter format: $paramName_ (without curly braces)
313- if ( PARAM_NON_NESTED_RE . test ( part ) ) {
314- const paramName = part . slice ( 1 , - 1 )
315- return {
316- type : SEGMENT_TYPE_PARAM ,
317- value : '$' + paramName ,
318- prefixSegment : undefined ,
319- suffixSegment : undefined ,
320- }
321- }
322-
323314 // Check for bare parameter format: $paramName (without curly braces)
324- if ( PARAM_RE . test ( part ) ) {
325- const paramName = part . substring ( 1 )
315+ if ( PARAM_RE . test ( partToMatch ) ) {
316+ const paramName = partToMatch . substring ( 1 )
317+
326318 return {
327319 type : SEGMENT_TYPE_PARAM ,
328320 value : '$' + paramName ,
@@ -332,7 +324,7 @@ function baseParsePathname(pathname: string): ReadonlyArray<Segment> {
332324 }
333325
334326 // Check for bare wildcard: $ (without curly braces)
335- if ( WILDCARD_RE . test ( part ) ) {
327+ if ( WILDCARD_RE . test ( partToMatch ) ) {
336328 return {
337329 type : SEGMENT_TYPE_WILDCARD ,
338330 value : '$' ,
@@ -344,8 +336,8 @@ function baseParsePathname(pathname: string): ReadonlyArray<Segment> {
344336 // Handle regular pathname segment
345337 return {
346338 type : SEGMENT_TYPE_PATHNAME ,
347- value : part . includes ( '%25' )
348- ? part
339+ value : partToMatch . includes ( '%25' )
340+ ? partToMatch
349341 . split ( '%25' )
350342 . map ( ( segment ) => decodeURI ( segment ) )
351343 . join ( '%25' )
0 commit comments