diff --git a/CHANGELOG.md b/CHANGELOG.md index 404e8c0..2c17312 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +- added `validateUrl` utility function + ## [1.1.0] - 2024-10-17 - export `boolean` utilities diff --git a/src/lib/url.spec.ts b/src/lib/url.spec.ts new file mode 100644 index 0000000..e5fa221 --- /dev/null +++ b/src/lib/url.spec.ts @@ -0,0 +1,19 @@ +import { validateUrl } from "./url"; + +describe("url tests", () => { + test.each([ + ["google.com", true], + ["https://www.example.com", true], + ["http://localhost:3000", true], + ["invalid_url", false], + ["javascript:alert('XSS')", false], + ["ftp://example.com", false], + ["mailto:someone@example.com", false], + ["", false], + [123, false], + [null, false], + [undefined, false], + ])('validateUrl("%s")', (value, expected) => { + expect(validateUrl(value)).toBe(expected); + }); +}); diff --git a/src/lib/url.ts b/src/lib/url.ts new file mode 100644 index 0000000..3262aec --- /dev/null +++ b/src/lib/url.ts @@ -0,0 +1,21 @@ +/** + * Validate the url + * @param value The Url String + * @returns The parsed boolean + */ +export function validateUrl(value?: string | number | null): boolean { + try { + if (!value || typeof value !== "string") { + return false; + } + + if (!value.startsWith("http://") && !value.startsWith("https://")) { + value = "http://".concat(value); + } + + const urlPattern = /^(http|https):\/\/[a-z0-9]+([-.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/i; + return urlPattern.test(value); + } catch (err) { + return false; + } +}