From 06e594211dd5848c5027ad15b9cebe90fb4d1238 Mon Sep 17 00:00:00 2001 From: Sven Slootweg Date: Mon, 15 Jul 2019 00:16:35 +0200 Subject: [PATCH] Add validateOptions, oneOf, forbidden, isBuffer --- index.js | 92 +++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 65 insertions(+), 27 deletions(-) diff --git a/index.js b/index.js index ef2f781..7654919 100644 --- a/index.js +++ b/index.js @@ -3,9 +3,16 @@ const createError = require("create-error"); const assureArray = require("assure-array"); const defaultValue = require("default-value"); +const util = require("util"); let ValidationError = createError("ValidationError", { path: [] }); +function allowExtraProperties (rules) { + return function (value) { + return validateObject(value, rules, true); + }; +} + function validateValue(value, argRules) { let argRules_ = assureArray(argRules); let isRequired = argRules_.some((rule) => rule.___validationMarker === "required"); @@ -21,6 +28,7 @@ function validateValue(value, argRules) { for (let rule of actualRules) { if (typeof rule === "object") { + /* FIXME: Check that this isn't an array, Date, Buffer, ... */ errors = validateObject(value, rule); } else { try { @@ -125,17 +133,24 @@ function aggregrateErrors(errors) { } } -module.exports = { - validateArguments: function (args, rules) { - let errors = validateArgumentList(args, rules); +function validateArguments(args, rules) { + let errors = validateArgumentList(args, rules); aggregrateErrors(errors); - }, +} + +module.exports = { + validateArguments: validateArguments, validateValue: function (value, rules) { let errors = validateValue(value, assureArray(rules)); aggregrateErrors(errors); }, + validateOptions: function (args, optionsRules) { + return validateArguments(args, [ + ["options", optionsRules] + ]); + }, ValidationError: ValidationError, required: {___validationMarker: "required"}, isFunction: function (value) { @@ -163,6 +178,11 @@ module.exports = { throw new ValidationError("Must be a Date object"); } }, + isBuffer: function (value) { + if (!(value instanceof Buffer)) { + throw new ValidationError("Must be a Buffer object"); + } + }, either: function (...alternatives) { if (alternatives.length === 0) { throw new Error("Must specify at least one alternative"); @@ -189,24 +209,28 @@ module.exports = { } }, when: function (predicate, rules) { - let rules_ = assureArray(rules).map((rule) => { - if (typeof rule === "object") { - /* We automatically allow extraneous properties in a `when` clause, because it'll generally be used as a partial addition to an otherwise-fully-specified object structure. */ - return allowExtraProperties(rule); - } else { - return rule; - } - }); - - return function (value) { - let matches = predicate(value); - - if (matches) { - return validateValue(value, rules_); - } else { - return []; - } - }; + if (rules == null) { + throw new Error("No rules specified for a `when` validation clause; did you misplace a parenthese?"); + } else { + let rules_ = assureArray(rules).map((rule) => { + if (typeof rule === "object") { + /* We automatically allow extraneous properties in a `when` clause, because it'll generally be used as a partial addition to an otherwise-fully-specified object structure. */ + return allowExtraProperties(rule); + } else { + return rule; + } + }); + + return function (value) { + let matches = predicate(value); + + if (matches) { + return validateValue(value, rules_); + } else { + return []; + } + }; + } }, matchesFormat: function (regex) { return function (value) { @@ -215,6 +239,19 @@ module.exports = { } }; }, + oneOf: function (validValues) { + if (Array.isArray(validValues)) { + let validValueSet = new Set(validValues); + + return function (value) { + if (!validValueSet.has(value)) { + throw new ValidationError(`Must be one of: ${validValues.map((item) => util.inspect(item)).join(", ")}`); + } + } + } else { + throw new Error("Argument to `oneOf` must be an array of values"); + } + }, arrayOf: function (rules) { let rules_ = assureArray(rules); @@ -256,9 +293,10 @@ module.exports = { } }; }, - allowExtraProperties: function (rules) { - return function (value) { - return validateObject(value, rules, true); - }; + allowExtraProperties: allowExtraProperties, + forbidden: function (value) { + if (value != null) { + throw new ValidationError("Value exists in a place that should be empty"); + } } -}; \ No newline at end of file +};