UNPKG

@cowwoc/requirements

Version:

A fluent API for enforcing design contracts with automatic message generation.

480 lines 20.1 kB
import { BooleanValidatorImpl, StringValidatorImpl, NumberValidatorImpl, SetValidatorImpl, MapValidatorImpl, UnknownValidatorImpl, Configuration, AbstractValidators, ArrayValidatorImpl, MainApplicationScope, verifyName, JavascriptValidators, Type, requireThatType, ValidationTarget, AssertionError, Pluralizer, messagesIsInstanceOf, AbstractValidator } from "../internal.mjs"; const typedocWorkaround = null; /* eslint-disable @typescript-eslint/no-unnecessary-condition */ // noinspection PointlessBooleanExpressionJS if (typedocWorkaround !== null) console.log("WORKAROUND: https://github.com/microsoft/tsdoc/issues/348"); /* eslint-enable @typescript-eslint/no-unnecessary-condition */ /** * The default implementation of JavascriptValidators. */ class JavascriptValidatorsImpl extends AbstractValidators { static DEFAULT_NAME = "value"; /** * A validator factory that creates validators to check the arguments of validation methods. */ static INTERNAL = new JavascriptValidatorsImpl(MainApplicationScope.INSTANCE, Configuration.DEFAULT); constructor(scope, configurationOrOther) { super(scope, JavascriptValidatorsImpl.getRequireThatConfiguration(configurationOrOther)); if (configurationOrOther instanceof JavascriptValidatorsImpl) { for (const entry of configurationOrOther.context) this.context.set(entry[0], entry[1]); } } /** * @param configurationOrOther - the configuration to use for new validators or the factory to copy * @returns the configuration to use for new validators */ static getRequireThatConfiguration(configurationOrOther) { if (configurationOrOther instanceof Configuration) return configurationOrOther; return configurationOrOther.getRequireThatConfiguration(); } /** * Validates the state of a number. * <p> * The returned validator throws an error immediately if a validation fails. * * @typeParam T - the type the value * @param value - the value * @param name - the name of the value * @returns a validator for the value * @throws TypeError if `name` is `undefined` or `null` * @throws RangeError if `name` is empty */ requireThatNumber(value, name) { verifyName(name, "name"); return this.validateNumber(value, name, this.getRequireThatConfiguration()); } /** * Validates the state of a boolean. * <p> * The returned validator throws an error immediately if a validation fails. * * @typeParam T - the type the value * @param value - the value * @param name - the name of the value * @returns a validator for the value * @throws TypeError if `name` is `undefined` or `null` * @throws RangeError if `name` is empty */ requireThatBoolean(value, name) { verifyName(name, "name"); return this.validateBoolean(value, name, this.getRequireThatConfiguration()); } /** * Validates the state of an array. * <p> * The returned validator throws an error immediately if a validation fails. * * @typeParam T - the type the value * @typeParam E - the type elements in the array * @param value - the value * @param name - the name of the value * @returns a validator for the value * @throws TypeError if `name` is `undefined` or `null` * @throws RangeError if `name` is empty */ requireThatArray(value, name) { verifyName(name, "name"); return this.validateArray(value, name, this.getRequireThatConfiguration()); } /** * Validates the state of a set. * <p> * The returned validator throws an error immediately if a validation fails. * * @typeParam T - the type the value * @typeParam E - the type elements in the set * @param value - the value * @param name - the name of the value * @returns a validator for the value * @throws TypeError if `name` is `undefined` or `null` * @throws RangeError if `name` is empty */ requireThatSet(value, name) { verifyName(name, "name"); return this.validateSet(value, name, this.getRequireThatConfiguration()); } /** * Validates the state of a map. * <p> * The returned validator throws an error immediately if a validation fails. * * @typeParam T - the type the value * @typeParam K - the type of keys in the map * @typeParam V - the type of values in the map * @param value - the value * @param name - the name of the value * @returns a validator for the value * @throws TypeError if `name` is `undefined` or `null` * @throws RangeError if `name` is empty */ requireThatMap(value, name) { verifyName(name, "name"); return this.validateMap(value, name, this.getRequireThatConfiguration()); } /** * Validates the state of a string. * <p> * The returned validator throws an error immediately if a validation fails. * * @typeParam T - the type the value * @param value - the value * @param name - the name of the value * @returns a validator for the value * @throws TypeError if `name` is `undefined` or `null` * @throws RangeError if `name` is empty */ requireThatString(value, name) { verifyName(name, "name"); return this.validateString(value, name, this.getRequireThatConfiguration()); } /** * Validates the state of an unknown value or a value that does not have a specialized validator. * <p> * The returned validator throws an error immediately if a validation fails. * * @typeParam T - the type the value * @param value - the value * @param name - the name of the value * @returns a validator for the value * @throws TypeError if `name` is `undefined` or `null` * @throws RangeError if `name` is empty */ requireThat(value, name) { verifyName(name, "name"); return this.validateUnknown(value, name, this.getRequireThatConfiguration()); } /** * Validates the state of a number. * <p> * The returned validator captures exceptions on validation failure rather than throwing them immediately. * The exceptions are converted into an {@link AssertionError} and can be retrieved or thrown once the * validation completes. Exceptions unrelated to validation failures are thrown immediately. * * @typeParam T - the type the value * @param value - the value * @param name - the name of the value * @returns validator for the value * @throws TypeError if `name` is `undefined` or `null` * @throws RangeError if `name` is empty */ assertThatNumber(value, name) { return this.validateNumber(value, name, this.getAssertThatConfiguration()); } /** * Validates the state of a boolean. * <p> * The returned validator captures exceptions on validation failure rather than throwing them immediately. * The exceptions are converted into an {@link AssertionError} and can be retrieved or thrown once the * validation completes. Exceptions unrelated to validation failures are thrown immediately. * * @typeParam T - the type the value * @param value - the value * @param name - the name of the value * @returns validator for the value * @throws TypeError if `name` is `undefined` or `null` * @throws RangeError if `name` is empty */ assertThatBoolean(value, name) { return this.validateBoolean(value, name, this.getAssertThatConfiguration()); } /** * Validates the state of an array. * <p> * The returned validator captures exceptions on validation failure rather than throwing them immediately. * The exceptions are converted into an {@link AssertionError} and can be retrieved or thrown once the * validation completes. Exceptions unrelated to validation failures are thrown immediately. * * @typeParam T - the type the value * @typeParam E - the type elements in the array * @param value - the value * @param name - the name of the value * @returns validator for the value * @throws TypeError if `name` is `undefined` or `null` * @throws RangeError if `name` is empty */ assertThatArray(value, name) { return this.validateArray(value, name, this.getAssertThatConfiguration()); } /** * Validates the state of a set. * <p> * The returned validator captures exceptions on validation failure rather than throwing them immediately. * The exceptions are converted into an {@link AssertionError} and can be retrieved or thrown once the * validation completes. Exceptions unrelated to validation failures are thrown immediately. * * @typeParam T - the type the value * @typeParam E - the type elements in the set * @param value - the value * @param name - the name of the value * @returns validator for the value * @throws TypeError if `name` is `undefined` or `null` * @throws RangeError if `name` is empty */ assertThatSet(value, name) { return this.validateSet(value, name, this.getAssertThatConfiguration()); } /** * Validates the state of a map. * <p> * The returned validator captures exceptions on validation failure rather than throwing them immediately. * The exceptions are converted into an {@link AssertionError} and can be retrieved or thrown once the * validation completes. Exceptions unrelated to validation failures are thrown immediately. * * @typeParam T - the type the value * @typeParam K - the type of keys in the map * @typeParam V - the type of values in the map * @param value - the value * @param name - the name of the value * @returns validator for the value * @throws TypeError if `name` is `undefined` or `null` * @throws RangeError if `name` is empty */ assertThatMap(value, name) { return this.validateMap(value, name, this.getAssertThatConfiguration()); } /** * Validates the state of a string. * <p> * The returned validator captures exceptions on validation failure rather than throwing them immediately. * The exceptions are converted into an {@link AssertionError} and can be retrieved or thrown once the * validation completes. Exceptions unrelated to validation failures are thrown immediately. * * @typeParam T - the type the value * @param value - the value * @param name - the name of the value * @returns validator for the value * @throws TypeError if `name` is `undefined` or `null` * @throws RangeError if `name` is empty */ assertThatString(value, name) { return this.validateString(value, name, this.getAssertThatConfiguration()); } /** * Validates the state of an unknown value or a value that does not have a specialized validator. * <p> * The returned validator captures exceptions on validation failure rather than throwing them immediately. * The exceptions are converted into an {@link AssertionError} and can be retrieved or thrown once the * validation completes. Exceptions unrelated to validation failures are thrown immediately. * * @typeParam T - the type the value * @param value - the value * @param name - the name of the value * @returns validator for the value * @throws TypeError if `name` is `undefined` or `null` * @throws RangeError if `name` is empty */ assertThat(value, name) { return this.validateUnknown(value, name, this.getAssertThatConfiguration()); } /** * Validates the state of a number. * <p> * The returned validator throws an error immediately if a validation fails. * * @typeParam T - the type the value * @param value - the value * @param name - the name of the value * @returns validator for the value * @throws TypeError if `name` is `undefined` or `null` * @throws RangeError if `name` is empty */ checkIfNumber(value, name) { return this.validateNumber(value, name, this.getCheckIfConfiguration()); } /** * Validates the state of a boolean. * <p> * The returned validator throws an error immediately if a validation fails. * * @typeParam T - the type the value * @param value - the value * @param name - the name of the value * @returns validator for the value * @throws TypeError if `name` is `undefined` or `null` * @throws RangeError if `name` is empty */ checkIfBoolean(value, name) { return this.validateBoolean(value, name, this.getCheckIfConfiguration()); } /** * Validates the state of an array. * <p> * The returned validator throws an error immediately if a validation fails. * * @typeParam T - the type the value * @typeParam E - the type elements in the array * @param value - the value * @param name - the name of the value * @returns validator for the value * @throws TypeError if `name` is `undefined` or `null` * @throws RangeError if `name` is empty */ checkIfArray(value, name) { return this.validateArray(value, name, this.getCheckIfConfiguration()); } /** * Validates the state of a set. * <p> * The returned validator throws an error immediately if a validation fails. * * @typeParam T - the type the value * @typeParam E - the type elements in the set * @param value - the value * @param name - the name of the value * @returns validator for the value * @throws TypeError if `name` is `undefined` or `null` * @throws RangeError if `name` is empty */ checkIfSet(value, name) { return this.validateSet(value, name, this.getCheckIfConfiguration()); } /** * Validates the state of a map. * <p> * The returned validator throws an error immediately if a validation fails. * * @typeParam T - the type the value * @typeParam K - the type of keys in the map * @typeParam V - the type of values in the map * @param value - the value * @param name - the name of the value * @returns validator for the value * @throws TypeError if `name` is `undefined` or `null` * @throws RangeError if `name` is empty */ checkIfMap(value, name) { return this.validateMap(value, name, this.getCheckIfConfiguration()); } /** * Validates the state of a string. * <p> * The returned validator throws an error immediately if a validation fails. * * @typeParam T - the type the value * @param value - the value * @param name - the name of the value * @returns validator for the value * @throws TypeError if `name` is `undefined` or `null` * @throws RangeError if `name` is empty */ checkIfString(value, name) { return this.validateString(value, name, this.getCheckIfConfiguration()); } /** * Validates the state of an unknown value or a value that does not have a specialized validator. * <p> * The returned validator throws an error immediately if a validation fails. * * @typeParam T - the type the value * @typeParam E - the type elements in the array or set * @typeParam K - the type of keys in the map * @typeParam V - the type of values in the map * @param value - the value * @param name - the name of the value * @returns validator for the value * @throws TypeError if `name` is `undefined` or `null` * @throws RangeError if `name` is empty */ checkIf(value, name) { return this.validateUnknown(value, name, this.getCheckIfConfiguration()); } validateNumber(value, name, configuration) { if (name === undefined) name = JavascriptValidatorsImpl.DEFAULT_NAME; else verifyName(name, "name"); const validator = new NumberValidatorImpl(this.scope, configuration, name, ValidationTarget.valid(value), new Map(), []); this.validateType(validator, value, Type.NUMBER); return validator; } /** * Ensures that the value's runtime and compile-time types match. * * @param validator - a validator * @param value - the value * @param expectedType - the value's expected type */ validateType(validator, value, expectedType) { const actualType = Type.of(value); switch (actualType) { case Type.UNDEFINED: case Type.NULL: return; } if (!expectedType.equals(expectedType)) { // Cannot compare Type inside a switch statement because it doesn't map "name == null" to any class validator.addTypeError(messagesIsInstanceOf(validator, expectedType).toString()); } } validateBoolean(value, name, configuration) { if (name === undefined) name = JavascriptValidatorsImpl.DEFAULT_NAME; else verifyName(name, "name"); const validator = new BooleanValidatorImpl(this.scope, configuration, name, ValidationTarget.valid(value), new Map(), []); this.validateType(validator, value, Type.BOOLEAN); return validator; } validateArray(value, name, configuration) { if (name === undefined) name = JavascriptValidatorsImpl.DEFAULT_NAME; else verifyName(name, "name"); const validator = new ArrayValidatorImpl(this.scope, configuration, name, ValidationTarget.valid(value), Pluralizer.ELEMENT, new Map(), []); this.validateType(validator, value, Type.ARRAY); return validator; } validateSet(value, name, configuration) { if (name === undefined) name = JavascriptValidatorsImpl.DEFAULT_NAME; else verifyName(name, "name"); const validator = new SetValidatorImpl(this.scope, configuration, name, ValidationTarget.valid(value), Pluralizer.ELEMENT, new Map(), []); this.validateType(validator, value, Type.namedClass("Set")); return validator; } validateMap(value, name, configuration) { if (name === undefined) name = JavascriptValidatorsImpl.DEFAULT_NAME; else verifyName(name, "name"); const validator = new MapValidatorImpl(this.scope, configuration, name, ValidationTarget.valid(value), new Map(), []); this.validateType(validator, value, Type.namedClass("Map")); return validator; } validateString(value, name, configuration) { if (name === undefined) name = JavascriptValidatorsImpl.DEFAULT_NAME; else verifyName(name, "name"); const validator = new StringValidatorImpl(this.scope, configuration, name, ValidationTarget.valid(value), new Map(), []); this.validateType(validator, value, Type.STRING); return validator; } validateUnknown(value, name, configuration) { if (name === undefined) name = JavascriptValidatorsImpl.DEFAULT_NAME; else verifyName(name, "name"); const validator = new UnknownValidatorImpl(this.scope, configuration, name, ValidationTarget.valid(value), new Map(), []); this.validateType(validator, value, Type.namedClass(null)); return validator; } copy() { return new JavascriptValidatorsImpl(this.scope, this); } withContext(value, name) { requireThatType(name, "name", Type.STRING); this.context.set(name, value); return this; } removeContext(name) { this.context.delete(name); return this; } } export { JavascriptValidatorsImpl }; //# sourceMappingURL=JavascriptValidatorsImpl.mjs.map