From fd3d577a8adb0f2c289d26f4e77ac025ce182dba Mon Sep 17 00:00:00 2001 From: Sergei Zharinov <zharinov@users.noreply.github.com> Date: Thu, 29 Jun 2023 19:22:26 +0300 Subject: [PATCH] feat: Schema utility for URL parsing (#23043) --- lib/util/schema-utils.spec.ts | 27 ++++++++++++++++++++++++++- lib/util/schema-utils.ts | 9 +++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/lib/util/schema-utils.spec.ts b/lib/util/schema-utils.spec.ts index f62fcc4bbf..9be7ac651c 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 f3dfe108ce..0caa342e39 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; + } +}); -- GitLab