Skip to content

Commit

Permalink
ref(core): simplify dsn parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
JonasBa committed Dec 17, 2021
1 parent 5311fcb commit c90b6f9
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 35 deletions.
49 changes: 20 additions & 29 deletions packages/utils/src/dsn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ import { Dsn, DsnComponents, DsnLike, DsnProtocol } from '@sentry/types';
import { isDebugBuild } from './env';
import { SentryError } from './error';

/** Regular expression used to parse a Dsn. */
const DSN_REGEX = /^(?:(\w+):)\/\/(?:(\w+)(?::(\w+))?@)([\w.-]+)(?::(\d+))?\/(.+)/;

function isValidProtocol(protocol?: string): protocol is DsnProtocol {
return protocol === 'http' || protocol === 'https';
}

function normalizeProtocol(input: string): string {
return input.replace(/:$/, '');
}

/**
* Renders the string representation of this Dsn.
*
Expand All @@ -20,38 +21,28 @@ function isValidProtocol(protocol?: string): protocol is DsnProtocol {
* @param withPassword When set to true, the password will be included.
*/
function dsntoString(dsn: Dsn, withPassword: boolean = false): string {
const { host, path, pass, port, projectId, protocol, publicKey } = dsn;
const { host, port, path, pass, projectId, protocol, publicKey } = dsn;
return (
`${protocol}://${publicKey}${withPassword && pass ? `:${pass}` : ''}` +
`@${host}${port ? `:${port}` : ''}/${path ? `${path}/` : path}${projectId}`
`@${host}${port ? `:${port}` : ''}${path}/${projectId}`
);
}

function dsnFromString(str: string): Dsn {
const match = DSN_REGEX.exec(str);

if (!match) {
throw new SentryError('Invalid Dsn');
}

const [protocol, publicKey, pass = '', host, port = '', lastPath] = match.slice(1);
let path = '';
let projectId = lastPath;

const split = projectId.split('/');
if (split.length > 1) {
path = split.slice(0, -1).join('/');
projectId = split.pop() as string;
}

if (projectId) {
const projectMatch = projectId.match(/^\d+/);
if (projectMatch) {
projectId = projectMatch[0];
}
}

return dsnFromComponents({ host, pass, path, projectId, port, protocol: protocol as DsnProtocol, publicKey });
const url = new URL(str);

const pathComponents = url.pathname.split('/');
const projectId = pathComponents.pop();

return dsnFromComponents({
host: url.hostname,
pass: url.password,
path: pathComponents.join('/'),
projectId: projectId || '',
port: url.port,
protocol: normalizeProtocol(url.protocol) as DsnProtocol,
publicKey: url.username,
});
}

function dsnFromComponents(components: DsnComponents): Dsn {
Expand Down
12 changes: 6 additions & 6 deletions packages/utils/test/dsn.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,15 @@ describe('Dsn', () => {
makeDsn({
host: '',
projectId: '123',
protocol: 'https',
protocol: 'https:',
publicKey: 'abc',
}),
).toThrow(SentryError);
expect(() =>
makeDsn({
host: 'sentry.io',
projectId: '',
protocol: 'https',
protocol: 'https:',
publicKey: 'abc',
}),
).toThrow(SentryError);
Expand All @@ -72,7 +72,7 @@ describe('Dsn', () => {
makeDsn({
host: 'sentry.io',
projectId: '123',
protocol: 'https',
protocol: 'https:',
publicKey: '',
}),
).toThrow(SentryError);
Expand All @@ -92,7 +92,7 @@ describe('Dsn', () => {
host: 'sentry.io',
port: 'xxx',
projectId: '123',
protocol: 'https',
protocol: 'https:',
publicKey: 'abc',
}),
).toThrow(SentryError);
Expand All @@ -118,7 +118,7 @@ describe('Dsn', () => {
expect(dsn.pass).toBe('');
expect(dsn.host).toBe('sentry.io');
expect(dsn.port).toBe('');
expect(dsn.path).toBe('123');
expect(dsn.path).toBe('/123');
expect(dsn.projectId).toBe('321');
});

Expand All @@ -129,7 +129,7 @@ describe('Dsn', () => {
expect(dsn.pass).toBe('');
expect(dsn.host).toBe('sentry.io');
expect(dsn.port).toBe('');
expect(dsn.path).toBe('sentry/custom/installation');
expect(dsn.path).toBe('/sentry/custom/installation');
expect(dsn.projectId).toBe('321');
});

Expand Down

0 comments on commit c90b6f9

Please sign in to comment.