From eb4d99ef08e811b617ae88849f1d80827a9c74b0 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Sun, 30 Jan 2022 21:33:34 -0400 Subject: flash data --- src/thing/validators.js | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'src/thing/validators.js') diff --git a/src/thing/validators.js b/src/thing/validators.js index e745771a..a465e9d1 100644 --- a/src/thing/validators.js +++ b/src/thing/validators.js @@ -222,6 +222,18 @@ export function isDuration(duration) { return true; } +export function isFileExtension(string) { + isStringNonEmpty(string); + + if (string[0] === '.') + throw new TypeError(`Expected no dot (.) at the start of file extension`); + + if (string.match(/[^a-zA-Z0-9_]/)) + throw new TypeError(`Expected only alphanumeric and underscore`); + + return true; +} + export function isName(name) { return isString(name); } @@ -260,3 +272,36 @@ export function validateReference(type = 'track') { export function validateReferenceList(type = '') { return validateArrayItems(validateReference(type)); } + +// Compositional utilities + +export function oneOf(...checks) { + return value => { + const errorMeta = []; + + for (let i = 0, check; check = checks[i]; i++) { + try { + const result = check(value); + + if (result !== true) { + throw new Error(`Check returned false`); + } + + return true; + } catch (error) { + errorMeta.push([check, i, error]); + } + } + + // Don't process error messages until every check has failed. + const errors = []; + for (const [ check, i, error ] of errorMeta) { + error.message = (check.name + ? `(#${i} "${check.name}") ${error.message}` + : `(#${i}) ${error.message}`); + error.check = check; + errors.push(error); + } + throw new AggregateError(errors, `Expected one of ${checks.length} possible checks, but none were true`); + }; +} -- cgit 1.3.0-6-gf8a5