export const normalise = ( path ? , lowerCase = true ) => { if ( ! path || path === '/' ) { return '/' ; } if ( ! path . startsWith ( '/' ) ) { path = '/' + path ; } path = removeTrailingSlash ( path ) ; if ( lowerCase ) { path = path . toLowerCase ( ) ; } return path ; } ; export const removeTrailingSlash = ( path ) => { if ( hasTrailingSlash ( path ) ) { path = path . substring ( 0 , path . length - 1 ) ; } return path ; } ; export const hasTrailingSlash = ( path ) => { if ( path . substring ( path . length - 1 ) == "/" ) { return true ; } return false ; } ; export const matchPath = ( pattern , pathname ) : Record < string , string > | undefined => { pathname = normalise ( pathname , false ) . split ( '?' ) [ 0 ] ; pattern = normalise ( pattern ) ; const params = { } ; const source = pattern . split ( '/' ) ; const test = pathname . split ( '/' ) ; if ( source . length !== test . length && ! pattern . includes ( '**' ) ) { return ; } for ( const i in source ) { if ( source [ i ] . startsWith ( ':' ) && pathname !== '/' ) { const paramName = source [ i ] . slice ( 1 ) ; params [ paramName ] = test [ i ] . toString ( ) ; continue ; } if ( source [ i ] . startsWith ( '**' ) ) { return params ; } if ( source [ i ] !== test [ i ] . toLowerCase ( ) ) { return ; } } return params ; } ; export const deserializeQuery = ( query = '' ) => { if ( ! query . startsWith ( '?' ) ) { return { } ; } var pairs = query . slice ( 1 ) . split ( '&' ) ; var result = { } ; for ( const pair of pairs ) { const newPair = pair . split ( '=' ) ; if ( ! newPair [ 0 ] ) { continue ; } result [ newPair [ 0 ] ] = decodeURIComponent ( newPair [ 1 ] || '' ) ; } return result ; } ;