@@ -12,25 +12,43 @@ export function encodeURIPath(str: string) {
1212 return str . replace ( / [ ^ A - Z a - z 0 - 9 \- . _ ~ ! $ & ' ( ) * + , ; = : @ ] + / g, encodeURIComponent ) ;
1313}
1414
15+ const EMPTY = /* @__PURE__ */ Object . freeze ( /* @__PURE__ */ Object . create ( null ) ) ;
16+
1517export const createPathTagFunction = ( pathEncoder = encodeURIPath ) =>
1618 function path ( statics : readonly string [ ] , ...params : readonly unknown [ ] ) : string {
1719 // If there are no params, no processing is needed.
1820 if ( statics . length === 1 ) return statics [ 0 ] ! ;
1921
2022 let postPath = false ;
23+ const invalidSegments = [ ] ;
2124 const path = statics . reduce ( ( previousValue , currentValue , index ) => {
2225 if ( / [ ? # ] / . test ( currentValue ) ) {
2326 postPath = true ;
2427 }
25- return (
26- previousValue +
27- currentValue +
28- ( index === params . length ? '' : ( postPath ? encodeURIComponent : pathEncoder ) ( String ( params [ index ] ) ) )
29- ) ;
28+ const value = params [ index ] ;
29+ let encoded = ( postPath ? encodeURIComponent : pathEncoder ) ( '' + value ) ;
30+ if (
31+ index !== params . length &&
32+ ( value == null ||
33+ ( typeof value === 'object' &&
34+ // handle values from other realms
35+ value . toString ===
36+ Object . getPrototypeOf ( Object . getPrototypeOf ( ( value as any ) . hasOwnProperty ?? EMPTY ) ?? EMPTY )
37+ ?. toString ) )
38+ ) {
39+ encoded = value + '' ;
40+ invalidSegments . push ( {
41+ start : previousValue . length + currentValue . length ,
42+ length : encoded . length ,
43+ error : `Value of type ${ Object . prototype . toString
44+ . call ( value )
45+ . slice ( 8 , - 1 ) } is not a valid path parameter`,
46+ } ) ;
47+ }
48+ return previousValue + currentValue + ( index === params . length ? '' : encoded ) ;
3049 } , '' ) ;
3150
3251 const pathOnly = path . split ( / [ ? # ] / , 1 ) [ 0 ] ! ;
33- const invalidSegments = [ ] ;
3452 const invalidSegmentPattern = / (?< = ^ | \/ ) (?: \. | % 2 e ) { 1 , 2 } (? = \/ | $ ) / gi;
3553 let match ;
3654
@@ -39,9 +57,12 @@ export const createPathTagFunction = (pathEncoder = encodeURIPath) =>
3957 invalidSegments . push ( {
4058 start : match . index ,
4159 length : match [ 0 ] . length ,
60+ error : `Value "${ match [ 0 ] } " can\'t be safely passed as a path parameter` ,
4261 } ) ;
4362 }
4463
64+ invalidSegments . sort ( ( a , b ) => a . start - b . start ) ;
65+
4566 if ( invalidSegments . length > 0 ) {
4667 let lastEnd = 0 ;
4768 const underline = invalidSegments . reduce ( ( acc , segment ) => {
@@ -52,7 +73,9 @@ export const createPathTagFunction = (pathEncoder = encodeURIPath) =>
5273 } , '' ) ;
5374
5475 throw new CasParserError (
55- `Path parameters result in path with invalid segments:\n${ path } \n${ underline } ` ,
76+ `Path parameters result in path with invalid segments:\n${ invalidSegments
77+ . map ( ( e ) => e . error )
78+ . join ( '\n' ) } \n${ path } \n${ underline } `,
5679 ) ;
5780 }
5881
0 commit comments