@@ -3,14 +3,13 @@ import { Dsn, DsnComponents, DsnLike, DsnProtocol } from '@sentry/types';
3
3
import { isDebugBuild } from './env' ;
4
4
import { SentryError } from './error' ;
5
5
6
+ /** Regular expression used to parse a Dsn. */
7
+ const DSN_REGEX = / ^ (?: ( \w + ) : ) \/ \/ (?: ( \w + ) (?: : ( \w + ) ) ? @ ) ( [ \w . - ] + ) (?: : ( \d + ) ) ? \/ ( .+ ) / ;
8
+
6
9
function isValidProtocol ( protocol ?: string ) : protocol is DsnProtocol {
7
10
return protocol === 'http' || protocol === 'https' ;
8
11
}
9
12
10
- function normalizeProtocol ( input : string ) : string {
11
- return input . replace ( / : $ / , '' ) ;
12
- }
13
-
14
13
/**
15
14
* Renders the string representation of this Dsn.
16
15
*
@@ -21,28 +20,38 @@ function normalizeProtocol(input: string): string {
21
20
* @param withPassword When set to true, the password will be included.
22
21
*/
23
22
function dsntoString ( dsn : Dsn , withPassword : boolean = false ) : string {
24
- const { host, port , path, pass, projectId, protocol, publicKey } = dsn ;
23
+ const { host, path, pass, port , projectId, protocol, publicKey } = dsn ;
25
24
return (
26
25
`${ protocol } ://${ publicKey } ${ withPassword && pass ? `:${ pass } ` : '' } ` +
27
- `@${ host } ${ port ? `:${ port } ` : '' } ${ path } / ${ projectId } `
26
+ `@${ host } ${ port ? `:${ port } ` : '' } / ${ path ? ` ${ path } /` : path } ${ projectId } `
28
27
) ;
29
28
}
30
29
31
30
function dsnFromString ( str : string ) : Dsn {
32
- const url = new URL ( str ) ;
33
-
34
- const pathComponents = url . pathname . split ( '/' ) ;
35
- const projectId = pathComponents . pop ( ) ;
36
-
37
- return dsnFromComponents ( {
38
- host : url . hostname ,
39
- pass : url . password ,
40
- path : pathComponents . join ( '/' ) ,
41
- projectId : projectId || '' ,
42
- port : url . port ,
43
- protocol : normalizeProtocol ( url . protocol ) as DsnProtocol ,
44
- publicKey : url . username ,
45
- } ) ;
31
+ const match = DSN_REGEX . exec ( str ) ;
32
+
33
+ if ( ! match ) {
34
+ throw new SentryError ( 'Invalid Dsn' ) ;
35
+ }
36
+
37
+ const [ protocol , publicKey , pass = '' , host , port = '' , lastPath ] = match . slice ( 1 ) ;
38
+ let path = '' ;
39
+ let projectId = lastPath ;
40
+
41
+ const split = projectId . split ( '/' ) ;
42
+ if ( split . length > 1 ) {
43
+ path = split . slice ( 0 , - 1 ) . join ( '/' ) ;
44
+ projectId = split . pop ( ) as string ;
45
+ }
46
+
47
+ if ( projectId ) {
48
+ const projectMatch = projectId . match ( / ^ \d + / ) ;
49
+ if ( projectMatch ) {
50
+ projectId = projectMatch [ 0 ] ;
51
+ }
52
+ }
53
+
54
+ return dsnFromComponents ( { host, pass, path, projectId, port, protocol : protocol as DsnProtocol , publicKey } ) ;
46
55
}
47
56
48
57
function dsnFromComponents ( components : DsnComponents ) : Dsn {
0 commit comments