shelving
Version:
Toolkit for using data in JavaScript.
41 lines (40 loc) • 1.54 kB
JavaScript
import { ValueFeedback } from "../feedback/Feedback.js";
import { getLinkURL } from "../util/link.js";
import { OPTIONAL } from "./OptionalSchema.js";
import { TextSchema } from "./TextSchema.js";
/**
* Type of `StringSchema` that defines a valid URL link.
* - 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.
* - Falsy values are converted to `""` empty string.
*/
export class LinkSchema extends TextSchema {
base;
schemes;
hosts;
constructor({ base, schemes, hosts, title = "Link", ...options }) {
super({
title,
...options,
type: "url",
min: 1,
max: 512,
multiline: false,
});
this.base = base;
this.schemes = schemes;
this.hosts = hosts;
}
// Override to clean the URL using builtin helper functions and check the schemes and hosts against the whitelists.
validate(unsafeValue) {
const str = super.validate(unsafeValue);
const url = getLinkURL(str, this.base, this.schemes, this.hosts);
if (!url)
throw new ValueFeedback(str ? "Invalid format" : "Required", str);
return url.href;
}
}
/** Valid link, e.g. `https://www.google.com` */
export const LINK = new LinkSchema({});
/** Valid link, e.g. `https://www.google.com`, or `null` */
export const OPTIONAL_LINK = OPTIONAL(LINK);