shelving
Version:
Toolkit for using data in JavaScript.
47 lines (46 loc) • 1.73 kB
JavaScript
import { formatURI } from "../util/format.js";
import { sanitizeWord } from "../util/string.js";
import { getURI, HTTP_SCHEMES } from "../util/uri.js";
import { NULLABLE } from "./NullableSchema.js";
import { StringSchema } from "./StringSchema.js";
/**
* Type of `StringSchema` that defines a valid URI string.
* - Checks URI scheme against a whitelist (always).
* - URIs are limited to 512 characters, but generally these won't be data: URIs so this is a reasonable limit.
*/
export class URISchema extends StringSchema {
schemes;
constructor({ one = "URI", title = "URI", schemes = HTTP_SCHEMES, ...options }) {
super({
one,
title,
...options,
input: "url",
min: 1,
max: 512,
rows: 1,
});
this.schemes = schemes;
}
// Override to validate the URI and check the schemes and hosts against the whitelists.
validate(unsafeValue) {
const str = super.validate(unsafeValue);
const uri = getURI(str);
if (!uri)
throw str ? `Invalid ${this.one} format` : "Required";
if (this.schemes && !this.schemes.includes(uri.protocol))
throw `Invalid ${this.one} scheme`;
return uri.href;
}
sanitize(str) {
// URIs never contain whitespace (a real space must be `%20`-encoded), so strip it entirely.
return sanitizeWord(str);
}
format(value) {
return formatURI(value, this.format);
}
}
/** Valid URI string, e.g. `https://www.google.com` */
export const URI_SCHEMA = new URISchema({});
/** Valid URI string, e.g. `https://www.google.com`, or `null` */
export const NULLABLE_URI_SCHEMA = NULLABLE(URI_SCHEMA);