UNPKG

shelving

Version:

Toolkit for using data in JavaScript.

50 lines (49 loc) 1.9 kB
import { formatURL } from "../util/format.js"; import { sanitizeWord } from "../util/string.js"; import { HTTP_SCHEMES } from "../util/uri.js"; import { getURL } from "../util/url.js"; import { NULLABLE } from "./NullableSchema.js"; import { StringSchema } from "./StringSchema.js"; /** * Type of `StringSchema` that defines a valid URL string. * - Checks URL scheme against a whitelist (always), and checks URL domain against a whitelist (optional). * - URLs are limited to 512 characters, but generally these won't be data: URIs so this is a reasonable limit. */ export class URLSchema extends StringSchema { base; schemes; constructor({ one = "URL", title = "URL", base, schemes = HTTP_SCHEMES, ...options }) { super({ one, title, ...options, input: "url", min: 1, max: 512, rows: 1, }); this.base = getURL(base)?.href; this.schemes = schemes; } // Override to validate the URL and check the schemes and hosts against the whitelists. validate(unsafeValue) { const str = super.validate(unsafeValue); const url = getURL(str, this.base); if (!url) throw str ? `Invalid ${this.one} format` : "Required"; if (this.schemes && !this.schemes.includes(url.protocol)) throw `Invalid ${this.one} scheme`; return url.href; } sanitize(str) { // URLs never contain whitespace (a real space must be `%20`-encoded), so strip it entirely. return sanitizeWord(str); } format(value) { return formatURL(value, this.base, this.format); } } /** Valid URL string, e.g. `https://www.google.com` */ export const URL_SCHEMA = new URLSchema({}); /** Valid URL string, e.g. `https://www.google.com`, or `null` */ export const NULLABLE_URL_SCHEMA = NULLABLE(URL_SCHEMA);