From 13db5498a5d3e8ac98bf9dee482fe95e06be1c79 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Sat, 15 Feb 2025 16:51:21 -0600 Subject: [PATCH] config: break mergeURLPath into a separate module --- packages/config/DittoConfig.ts | 18 ++---------------- packages/config/utils/url.test.ts | 9 +++++++++ packages/config/utils/url.ts | 23 +++++++++++++++++++++++ 3 files changed, 34 insertions(+), 16 deletions(-) create mode 100644 packages/config/utils/url.test.ts create mode 100644 packages/config/utils/url.ts diff --git a/packages/config/DittoConfig.ts b/packages/config/DittoConfig.ts index b11ca681..c8f63a60 100644 --- a/packages/config/DittoConfig.ts +++ b/packages/config/DittoConfig.ts @@ -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(); -} diff --git a/packages/config/utils/url.test.ts b/packages/config/utils/url.test.ts new file mode 100644 index 00000000..1da9773c --- /dev/null +++ b/packages/config/utils/url.test.ts @@ -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'); +}); diff --git a/packages/config/utils/url.ts b/packages/config/utils/url.ts new file mode 100644 index 00000000..f7287bab --- /dev/null +++ b/packages/config/utils/url.ts @@ -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(); +}