diff --git a/lib/util/schema-utils.spec.ts b/lib/util/schema-utils.spec.ts index f62fcc4bbff..9be7ac651c4 100644 --- a/lib/util/schema-utils.spec.ts +++ b/lib/util/schema-utils.spec.ts @@ -1,5 +1,12 @@ import { z } from 'zod'; -import { Json, Json5, LooseArray, LooseRecord, UtcDate } from './schema-utils'; +import { + Json, + Json5, + LooseArray, + LooseRecord, + Url, + UtcDate, +} from './schema-utils'; describe('util/schema-utils', () => { describe('LooseArray', () => { @@ -270,4 +277,22 @@ describe('util/schema-utils', () => { expect(() => UtcDate.parse('foobar')).toThrow(); }); }); + + describe('Url', () => { + it('parses valid URLs', () => { + const urlStr = 'https://www.example.com/foo/bar?baz=qux'; + const parsedUrl = Url.parse(urlStr); + expect(parsedUrl).toMatchObject({ + protocol: 'https:', + hostname: 'www.example.com', + pathname: '/foo/bar', + search: '?baz=qux', + }); + }); + + it('throws an error for invalid URLs', () => { + const urlStr = 'invalid-url-string'; + expect(() => Url.parse(urlStr)).toThrow('Invalid URL'); + }); + }); }); diff --git a/lib/util/schema-utils.ts b/lib/util/schema-utils.ts index f3dfe108ce7..0caa342e391 100644 --- a/lib/util/schema-utils.ts +++ b/lib/util/schema-utils.ts @@ -223,3 +223,12 @@ export const UtcDate = z } return date; }); + +export const Url = z.string().transform((str, ctx): URL => { + try { + return new URL(str); + } catch (e) { + ctx.addIssue({ code: 'custom', message: 'Invalid URL' }); + return z.NEVER; + } +});