UNPKG

logitar-validation

Version:

JavaScript validation library distributed by Logitar.

227 lines (226 loc) 8.48 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const logitar_js_1 = require("logitar-js"); const format_1 = require("./format"); const { isNullOrWhiteSpace } = logitar_js_1.stringUtils; /** * Applies the execution outcome of a validation rule to a result. * @param result The result to apply the execution outcome to. * @param outcome The execution outcome of the validation rule execution. * @param options The options of the validation rule execution. */ function apply(result, outcome, options) { // severity result.severity = outcome.severity; // key if (!isNullOrWhiteSpace(options.key)) { result.key = options.key; } else if (!isNullOrWhiteSpace(outcome.key)) { result.key = outcome.key; } // message if (!isNullOrWhiteSpace(options.message)) { result.message = options.message; } else if (!isNullOrWhiteSpace(outcome.message)) { result.message = outcome.message; } // name if (!isNullOrWhiteSpace(outcome.name)) { result.name = outcome.name; } // value if (typeof outcome.value !== "undefined") { result.value = outcome.value; } // custom result.custom = outcome.custom; } /** * Fills the placeholders of a validation rule execution. * @param result The result to fill the placeholders of. * @param outcome The execution outcome of the validation rule. * @param rule The options of the validation rule execution. * @param validation The options of the validation operation. */ function fillPlaceholders(result, outcome, rule, validation) { result.placeholders.key = result.key; result.placeholders.name = result.name; result.placeholders.value = result.value; result.placeholders.severity = result.severity; if (outcome && outcome.placeholders) { result.placeholders = Object.assign(Object.assign({}, result.placeholders), outcome.placeholders); } if (rule && rule.placeholders) { result.placeholders = Object.assign(Object.assign({}, result.placeholders), rule.placeholders); } if (validation && validation.placeholders) { result.placeholders = Object.assign(Object.assign({}, result.placeholders), validation.placeholders); } } /** * A validator is a collection of validation rules that can be executed on a value. */ class Validator { /** * Initializes a new instance of the Validator class. * @param options The options of the validator. */ constructor(options) { var _a, _b, _c; options !== null && options !== void 0 ? options : (options = {}); this.messageFormatter = (_a = options.messageFormatter) !== null && _a !== void 0 ? _a : new format_1.DefaultMessageFormatter(); this.rules = new Map(); this.throwOnFailure = (_b = options.throwOnFailure) !== null && _b !== void 0 ? _b : false; this.treatWarningsAsErrors = (_c = options.treatWarningsAsErrors) !== null && _c !== void 0 ? _c : false; } /** * Clears all the rules registered to this validator. */ clearRules() { this.rules.clear(); } /** * Gets a rule from the validator. * @param key The key of the rule to get. * @returns The rule configuration. */ getRule(key) { return this.rules.get(key); } /** * Checks if a rule is registered to this validator. * @param key The key of the rule to check. * @returns A value indicating whether the rule is registered to this validator. */ hasRule(key) { return this.rules.has(key); } /** * Lists all the rules registered to this validator. * @returns The rules registered to this validator. */ listRules() { return [...this.rules.entries()]; } /** * Removes a rule from the validator. * @param key The key of the rule to remove. * @returns A value indicating whether the rule was removed from the validator. */ removeRule(key) { return this.rules.delete(key); } /** * Registers a rule to the validator. * @param key The key of the rule to register. * @param rule The rule to register. * @param options The options of the rule. */ setRule(key, rule, options) { options !== null && options !== void 0 ? options : (options = {}); const configuration = { rule, options }; this.rules.set(key, configuration); } /** * Validates a field/property against a set of rules. * @param name The name of the field/property to validate. * @param value The value of the field/property to validate. * @param rules The rule set to validate the value against. * @param options The options of the validation operation. * @returns The result of the validation operation. */ validate(name, value, rules, options) { var _a, _b; options !== null && options !== void 0 ? options : (options = {}); const context = (_a = options.context) !== null && _a !== void 0 ? _a : {}; let errors = 0; const results = {}; const missingRules = []; for (const key in rules) { const configuration = this.rules.get(key); if (!configuration) { missingRules.push(key); continue; } const args = rules[key]; if (typeof args === "undefined" || args === null || args === false || args === "" || (typeof args === "number" && isNaN(args))) { // NOTE(fpion): 0, -0 and 0n (BigInt) are considered valid arguments. continue; } const result = { key, severity: "error", placeholders: { [key]: args }, name, value, }; const outcome = configuration.rule(value, args, context); switch (typeof outcome) { case "boolean": result.severity = Boolean(outcome) ? "information" : "error"; break; case "string": result.severity = outcome; break; default: apply(result, outcome, configuration.options); break; } fillPlaceholders(result, typeof outcome === "object" ? outcome : undefined, configuration.options, options); this.formatMessage(result, options); if (this.isError(result.severity, options)) { errors++; } results[key] = result; } if (missingRules.length > 0) { throw new Error(`The following rules are not registered: ${missingRules.join(", ")}`); } const result = { isValid: errors === 0, rules: results, context, }; if (!result.isValid && ((_b = options.throwOnFailure) !== null && _b !== void 0 ? _b : this.throwOnFailure)) { throw result; } return result; } /** * Formats a validation rule execution message. * @param result The result to format the message of. * @param options The options of the validation operation. */ formatMessage(result, options) { var _a; options !== null && options !== void 0 ? options : (options = {}); const messageFormatter = (_a = options.messageFormatter) !== null && _a !== void 0 ? _a : this.messageFormatter; if (typeof result.message === "string") { result.message = messageFormatter.format(result.message, result.placeholders); } } /** * Checks if a severity is an error. * @param severity The severity to check. * @param options The options of the validation operation. * @returns A value indicating whether the severity is an error. */ isError(severity, options) { var _a; options !== null && options !== void 0 ? options : (options = {}); switch (severity) { case "error": case "critical": return true; case "warning": if ((_a = options.treatWarningsAsErrors) !== null && _a !== void 0 ? _a : this.treatWarningsAsErrors) { return true; } break; } return false; } } exports.default = Validator;