config: break mergeURLPath into a separate module

This commit is contained in:
Alex Gleason 2025-02-15 16:51:21 -06:00
parent 5f6cdaf7d5
commit 13db5498a5
No known key found for this signature in database
GPG key ID: 7211D1F99744FBB7
3 changed files with 34 additions and 16 deletions

View file

@ -6,6 +6,7 @@ import { encodeBase64Url } from '@std/encoding/base64url';
import { getEcdsaPublicKey } from './utils/crypto.ts';
import { optionalBooleanSchema, optionalNumberSchema } from './utils/schema.ts';
import { mergeURLPath } from './utils/url.ts';
/** Ditto application-wide configuration. */
export class DittoConfig {
@ -288,7 +289,7 @@ export class DittoConfig {
/** Merges the path with the localDomain. */
local(path: string): string {
return mergePaths(this.localDomain, path);
return mergeURLPath(this.localDomain, path);
}
/** URL to send Sentry errors to. */
@ -461,18 +462,3 @@ export class DittoConfig {
return Number(this.env.get('STREAK_WINDOW') || 129600);
}
}
function mergePaths(base: string, path: string) {
const url = new URL(
path.startsWith('/') ? path : new URL(path).pathname,
base,
);
if (!path.startsWith('/')) {
// Copy query parameters from the original URL to the new URL
const originalUrl = new URL(path);
url.search = originalUrl.search;
}
return url.toString();
}

View file

@ -0,0 +1,9 @@
import { assertEquals } from '@std/assert';
import { mergeURLPath } from './url.ts';
Deno.test('mergeURLPath', () => {
assertEquals(mergeURLPath('https://mario.com', '/path'), 'https://mario.com/path');
assertEquals(mergeURLPath('https://mario.com', 'https://luigi.com/path'), 'https://mario.com/path');
assertEquals(mergeURLPath('https://mario.com', 'https://luigi.com/path?q=1'), 'https://mario.com/path?q=1');
});

View file

@ -0,0 +1,23 @@
/**
* Produce a URL whose origin is guaranteed to be the same as the base URL.
* The path is either an absolute path (starting with `/`), or a full URL. In either case, only its path is used.
*/
export function mergeURLPath(
/** Base URL. Result is guaranteed to use this URL's origin. */
base: string,
/** Either an absolute path (starting with `/`), or a full URL. If a full URL, its path */
path: string,
): string {
const url = new URL(
path.startsWith('/') ? path : new URL(path).pathname,
base,
);
if (!path.startsWith('/')) {
// Copy query parameters from the original URL to the new URL
const originalUrl = new URL(path);
url.search = originalUrl.search;
}
return url.toString();
}