-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(react): Fix React Router v6 paramaterization (#5515)
Make sure paramaterization occurs in scenarios where the full path is not available after all the branches are walked. In those scenarios, we have to construct the paramaterized name based on the previous branches that were analyzed. This patch also creates a new file in `@sentry/utils` - `url.ts`, where we store some url / string related utils. This was made so that the react package would get access to the `getNumberOfUrlSegments` util.
- Loading branch information
1 parent
31fd072
commit f0ab0e0
Showing
9 changed files
with
164 additions
and
82 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/** | ||
* Parses string form of URL into an object | ||
* // borrowed from https://tools.ietf.org/html/rfc3986#appendix-B | ||
* // intentionally using regex and not <a/> href parsing trick because React Native and other | ||
* // environments where DOM might not be available | ||
* @returns parsed URL object | ||
*/ | ||
export function parseUrl(url: string): { | ||
host?: string; | ||
path?: string; | ||
protocol?: string; | ||
relative?: string; | ||
} { | ||
if (!url) { | ||
return {}; | ||
} | ||
|
||
const match = url.match(/^(([^:/?#]+):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/); | ||
|
||
if (!match) { | ||
return {}; | ||
} | ||
|
||
// coerce to undefined values to empty string so we don't get 'undefined' | ||
const query = match[6] || ''; | ||
const fragment = match[8] || ''; | ||
return { | ||
host: match[4], | ||
path: match[5], | ||
protocol: match[2], | ||
relative: match[5] + query + fragment, // everything minus origin | ||
}; | ||
} | ||
|
||
/** | ||
* Strip the query string and fragment off of a given URL or path (if present) | ||
* | ||
* @param urlPath Full URL or path, including possible query string and/or fragment | ||
* @returns URL or path without query string or fragment | ||
*/ | ||
export function stripUrlQueryAndFragment(urlPath: string): string { | ||
// eslint-disable-next-line no-useless-escape | ||
return urlPath.split(/[\?#]/, 1)[0]; | ||
} | ||
|
||
/** | ||
* Returns number of URL segments of a passed string URL. | ||
*/ | ||
export function getNumberOfUrlSegments(url: string): number { | ||
// split at '/' or at '\/' to split regex urls correctly | ||
return url.split(/\\?\//).filter(s => s.length > 0 && s !== ',').length; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { getNumberOfUrlSegments, stripUrlQueryAndFragment } from '../src/url'; | ||
|
||
describe('stripQueryStringAndFragment', () => { | ||
const urlString = 'http://dogs.are.great:1231/yay/'; | ||
const queryString = '?furry=yes&funny=very'; | ||
const fragment = '#adoptnotbuy'; | ||
|
||
it('strips query string from url', () => { | ||
const urlWithQueryString = `${urlString}${queryString}`; | ||
expect(stripUrlQueryAndFragment(urlWithQueryString)).toBe(urlString); | ||
}); | ||
|
||
it('strips fragment from url', () => { | ||
const urlWithFragment = `${urlString}${fragment}`; | ||
expect(stripUrlQueryAndFragment(urlWithFragment)).toBe(urlString); | ||
}); | ||
|
||
it('strips query string and fragment from url', () => { | ||
const urlWithQueryStringAndFragment = `${urlString}${queryString}${fragment}`; | ||
expect(stripUrlQueryAndFragment(urlWithQueryStringAndFragment)).toBe(urlString); | ||
}); | ||
}); | ||
|
||
describe('getNumberOfUrlSegments', () => { | ||
test.each([ | ||
['regular path', '/projects/123/views/234', 4], | ||
['single param paramaterized path', '/users/:id/details', 3], | ||
['multi param paramaterized path', '/stores/:storeId/products/:productId', 4], | ||
['regex path', String(/\/api\/post[0-9]/), 2], | ||
])('%s', (_: string, input, output) => { | ||
expect(getNumberOfUrlSegments(input)).toEqual(output); | ||
}); | ||
}); |