Skip to content

Commit fa5eeee

Browse files
committed
ref(utils): dsn
1 parent e059f5c commit fa5eeee

File tree

6 files changed

+98
-121
lines changed

6 files changed

+98
-121
lines changed

packages/core/src/api.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { DsnLike, SdkMetadata } from '@sentry/types';
2-
import { Dsn, urlEncode } from '@sentry/utils';
2+
import { Dsn, makeDsn, urlEncode } from '@sentry/utils';
33

44
const SENTRY_API_VERSION = '7';
55

@@ -40,7 +40,7 @@ export class API {
4040
/** Create a new instance of API */
4141
public constructor(dsn: DsnLike, metadata: SdkMetadata = {}, tunnel?: string) {
4242
this.dsn = dsn;
43-
this._dsnObject = new Dsn(dsn);
43+
this._dsnObject = makeDsn(dsn);
4444
this.metadata = metadata;
4545
this._tunnel = tunnel;
4646
}
@@ -89,7 +89,7 @@ export function initAPIDetails(dsn: DsnLike, metadata?: SdkMetadata, tunnel?: st
8989
return {
9090
initDsn: dsn,
9191
metadata: metadata || {},
92-
dsn: new Dsn(dsn),
92+
dsn: makeDsn(dsn),
9393
tunnel,
9494
} as APIDetails;
9595
}
@@ -171,7 +171,7 @@ export function getReportDialogEndpoint(
171171
user?: { name?: string; email?: string };
172172
},
173173
): string {
174-
const dsn = new Dsn(dsnLike);
174+
const dsn = makeDsn(dsnLike);
175175
const endpoint = `${getBaseApiEndpoint(dsn)}embed/error-page/`;
176176

177177
let encodedOptions = `dsn=${dsn.toString()}`;

packages/core/src/baseclient.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
isPrimitive,
1919
isThenable,
2020
logger,
21+
makeDsn,
2122
normalize,
2223
SentryError,
2324
SyncPromise,
@@ -93,7 +94,7 @@ export abstract class BaseClient<B extends Backend, O extends Options> implement
9394
this._options = options;
9495

9596
if (options.dsn) {
96-
this._dsn = new Dsn(options.dsn);
97+
this._dsn = makeDsn(options.dsn);
9798
}
9899
}
99100

packages/core/test/lib/api.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* eslint-disable deprecation/deprecation */
2-
import { Dsn } from '@sentry/utils';
2+
import { makeDsn } from '@sentry/utils';
33

44
import { API, getReportDialogEndpoint, getRequestHeaders } from '../../src/api';
55

@@ -25,12 +25,12 @@ describe('API', () => {
2525
});
2626

2727
test('getRequestHeaders', () => {
28-
expect(getRequestHeaders(new Dsn(dsnPublic), 'a', '1.0')).toMatchObject({
28+
expect(getRequestHeaders(makeDsn(dsnPublic), 'a', '1.0')).toMatchObject({
2929
'Content-Type': 'application/json',
3030
'X-Sentry-Auth': expect.stringMatching(/^Sentry sentry_version=\d, sentry_client=a\/1\.0, sentry_key=abc$/),
3131
});
3232

33-
expect(getRequestHeaders(new Dsn(legacyDsn), 'a', '1.0')).toMatchObject({
33+
expect(getRequestHeaders(makeDsn(legacyDsn), 'a', '1.0')).toMatchObject({
3434
'Content-Type': 'application/json',
3535
'X-Sentry-Auth': expect.stringMatching(
3636
/^Sentry sentry_version=\d, sentry_client=a\/1\.0, sentry_key=abc, sentry_secret=123$/,
@@ -119,6 +119,6 @@ describe('API', () => {
119119
});
120120

121121
test('getDsn', () => {
122-
expect(new API(dsnPublic).getDsn()).toEqual(new Dsn(dsnPublic));
122+
expect(new API(dsnPublic).getDsn()).toEqual(makeDsn(dsnPublic));
123123
});
124124
});

packages/node/src/backend.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ import { Event, EventHint, Mechanism, SeverityLevel, Transport, TransportOptions
33
import {
44
addExceptionMechanism,
55
addExceptionTypeValue,
6-
Dsn,
76
extractExceptionKeysForMessage,
87
isError,
98
isPlainObject,
9+
makeDsn,
1010
normalizeToSize,
1111
SyncPromise,
1212
} from '@sentry/utils';
@@ -108,7 +108,7 @@ export class NodeBackend extends BaseBackend<NodeOptions> {
108108
return super._setupTransport();
109109
}
110110

111-
const dsn = new Dsn(this._options.dsn);
111+
const dsn = makeDsn(this._options.dsn);
112112

113113
const transportOptions: TransportOptions = {
114114
...this._options.transportOptions,

packages/utils/src/dsn.ts

Lines changed: 23 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ import { DsnComponents, DsnLike, DsnProtocol } from '@sentry/types';
33
import { isDebugBuild } from './env';
44
import { SentryError } from './error';
55

6+
export interface Dsn extends DsnComponents {
7+
/** Protocol used to connect to Sentry. */
8+
toString(withPassword: boolean): string;
9+
}
10+
611
/** Regular expression used to parse a Dsn. */
712
const DSN_REGEX = /^(?:(\w+):)\/\/(?:(\w+)(?::(\w+))?@)([\w.-]+)(?::(\d+))?\/(.+)/;
813

9-
/** Error message */
10-
const ERROR_MESSAGE = 'Invalid Dsn';
11-
1214
function isValidProtocol(protocol?: string): protocol is DsnProtocol {
1315
return protocol === 'http' || protocol === 'https';
1416
}
@@ -34,7 +36,7 @@ function dsnFromString(str: string): Dsn {
3436
const match = DSN_REGEX.exec(str);
3537

3638
if (!match) {
37-
throw new SentryError(ERROR_MESSAGE);
39+
throw new SentryError('Invalid Dsn');
3840
}
3941

4042
const [protocol, publicKey, pass = '', host, port = '', lastPath] = match.slice(1);
@@ -54,11 +56,7 @@ function dsnFromString(str: string): Dsn {
5456
}
5557
}
5658

57-
if (isValidProtocol(protocol)) {
58-
return dsnFromComponents({ host, pass, path, projectId, port, protocol: protocol, publicKey });
59-
}
60-
61-
throw new SentryError(ERROR_MESSAGE);
59+
return dsnFromComponents({ host, pass, path, projectId, port, protocol: protocol as DsnProtocol, publicKey });
6260
}
6361

6462
function dsnFromComponents(components: DsnComponents): Dsn {
@@ -83,55 +81,39 @@ function validateDsn(dsn: Dsn): boolean {
8381
if (isDebugBuild()) {
8482
const { port, projectId, protocol } = dsn;
8583

86-
['protocol', 'publicKey', 'host', 'projectId'].forEach(component => {
84+
const requiredComponents: ReadonlyArray<keyof DsnComponents> = ['protocol', 'publicKey', 'host', 'projectId'];
85+
requiredComponents.forEach(component => {
8786
if (!dsn[component]) {
88-
throw new SentryError(`${ERROR_MESSAGE}: ${component} missing`);
87+
throw new SentryError(`Invalid Dsn: ${component} missing`);
8988
}
9089
});
9190

9291
if (!projectId.match(/^\d+$/)) {
93-
throw new SentryError(`${ERROR_MESSAGE}: Invalid projectId ${projectId}`);
92+
throw new SentryError(`Invalid Dsn: Invalid projectId ${projectId}`);
9493
}
9594

9695
if (isValidProtocol(protocol)) {
97-
throw new SentryError(`${ERROR_MESSAGE}: Invalid protocol ${protocol}`);
96+
throw new SentryError(`Invalid Dsn: Invalid protocol ${protocol}`);
9897
}
9998

10099
if (port && isNaN(parseInt(port, 10))) {
101-
throw new SentryError(`${ERROR_MESSAGE}: Invalid port ${port}`);
100+
throw new SentryError(`Invalid Dsn: Invalid port ${port}`);
102101
}
103102
}
104103

105104
return true;
106105
}
107106

108-
function makeDsn(from: DsnLike): Dsn {
109-
let dsn = typeof from === 'string' ? dsnFromString(from) : dsnFromComponents(from);
107+
/** The Sentry Dsn, identifying a Sentry instance and project. */
108+
export function makeDsn(from: DsnLike): Dsn {
109+
const components = typeof from === 'string' ? dsnFromString(from) : dsnFromComponents(from);
110110

111-
return {
112-
...dsn,
113-
toString: () => dsntoString(dsn),
111+
validateDsn(components);
112+
113+
const dsn: Dsn = {
114+
...components,
115+
toString: (withPassword: boolean) => dsntoString(dsn),
114116
};
115-
}
116-
/** The Sentry Dsn, identifying a Sentry instance and project. */
117-
export class Dsn implements DsnComponents {
118-
/** Protocol used to connect to Sentry. */
119-
public protocol!: DsnProtocol;
120-
/** Public authorization key (deprecated, renamed to publicKey). */
121-
public user!: string;
122-
/** Public authorization key. */
123-
public publicKey!: string;
124-
/** Private authorization key (deprecated, optional). */
125-
public pass!: string;
126-
/** Hostname of the Sentry instance. */
127-
public host!: string;
128-
/** Port of the Sentry instance. */
129-
public port!: string;
130-
/** Path */
131-
public path!: string;
132-
/** Project ID */
133-
public projectId!: string;
134-
135-
/** Creates a new Dsn component */
136-
public constructor(from: DsnLike) {}
117+
118+
return dsn;
137119
}

0 commit comments

Comments
 (0)