UNPKG

@cowwoc/requirements

Version:

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

192 lines 9.21 kB
import { NumberValidatorImpl, AbstractValidator, numberIsMultipleOf, numberIsNotMultipleOf, ValidationTarget, JavascriptValidatorsImpl, numberIsFinite, numberIsInfinite, numberIsNumber, numberIsNotNumber, collectionContainsSize, objectIsNotEmpty, objectIsEmpty, collectionSizeIsBetween, Type } from "../internal.mjs"; import { requireThatValueIsDefined } from "./Objects.mjs"; /** * Validates the state of an object's size. */ class ObjectSizeValidatorImpl extends AbstractValidator { objectValidator; pluralizer; /** * @param scope - the application configuration * @param configuration - the validator configuration * @param objectValidator - the object's validator * @param sizeName - the name of the object's size * @param size - the object's size * @param pluralizer - the type of elements in the object * @param context - the contextual information set by a parent validator or the user * @param failures - the list of validation failures * @throws TypeError if `name` is `undefined` or `null` * @throws RangeError if `name` contains whitespace, or is empty * @throws AssertionError if `scope`, `configuration`, `value`, `context` or `failures` are null */ constructor(scope, configuration, objectValidator, sizeName, size, pluralizer, context, failures) { super(scope, configuration, sizeName, size, context, failures); requireThatValueIsDefined(objectValidator, "objectValidator"); requireThatValueIsDefined(pluralizer, "pluralizer"); this.objectValidator = objectValidator; this.pluralizer = pluralizer; } isEqualTo(expected, name) { const typeOfExpected = Type.of(expected); if (typeOfExpected === Type.NUMBER) { if (name !== undefined) this.requireThatNameIsUnique(name); if (this.value.validationFailed(v => v === expected)) { this.addRangeError(collectionContainsSize(this.objectValidator, this.name, this.value.or(null), "must contain", this.name, expected, this.pluralizer).toString()); } return this; } return super.isEqualTo(expected); } isNotEqualTo(unwanted, name) { const typeOfExpected = Type.of(unwanted); if (typeOfExpected === Type.NUMBER) { if (name !== undefined) this.requireThatNameIsUnique(name); if (this.value.validationFailed(v => v !== unwanted)) { this.addRangeError(collectionContainsSize(this.objectValidator, this.name, this.value.or(null), "may not contain", this.name, unwanted, this.pluralizer).toString()); } return this; } return super.isEqualTo(unwanted); } isZero() { if (this.value.validationFailed(value => value == 0)) { this.failOnUndefinedOrNull(); this.addRangeError(objectIsEmpty(this.objectValidator).toString()); } return this; } isNotZero() { if (this.value.validationFailed(v => !(v == 0))) { this.failOnUndefinedOrNull(); this.addRangeError(objectIsNotEmpty(this.objectValidator).toString()); } return this; } isPositive() { return this.isNotZero(); } isNotPositive() { return this.isZero(); } isLessThan(maximumExclusive, name) { if (name !== undefined) this.requireThatNameIsUnique(name); if (this.value.validationFailed(v => v < maximumExclusive)) { this.failOnUndefinedOrNull(); this.addRangeError(collectionContainsSize(this.objectValidator, this.name, this.value.or(null), "must contain less than", name ?? null, maximumExclusive, this.pluralizer).toString()); } return this; } isLessThanOrEqualTo(maximumInclusive, name) { if (name !== undefined) this.requireThatNameIsUnique(name); if (this.value.validationFailed(v => v <= maximumInclusive)) { this.failOnUndefinedOrNull(); this.addRangeError(collectionContainsSize(this.objectValidator, this.name, this.value.or(null), "may not contain more than", name ?? null, maximumInclusive, this.pluralizer).toString()); } return this; } isGreaterThanOrEqualTo(minimumInclusive, name) { if (name !== undefined) this.requireThatNameIsUnique(name); if (this.value.validationFailed(v => v >= minimumInclusive)) { this.failOnUndefinedOrNull(); this.addRangeError(collectionContainsSize(this.objectValidator, this.name, this.value.or(null), "must contain at least", name ?? null, minimumInclusive, this.pluralizer).toString()); } return this; } isGreaterThan(minimumExclusive, name) { if (name !== undefined) this.requireThatNameIsUnique(name); if (this.value.validationFailed(v => v >= minimumExclusive)) { this.failOnUndefinedOrNull(); this.addRangeError(collectionContainsSize(this.objectValidator, this.name, this.value.or(null), "must contain more than", name ?? null, minimumExclusive, this.pluralizer).toString()); } return this; } isBetween(minimum, maximumExclusiveOrMinimumIsInclusive, maximum, maximumIsInclusive) { const normalized = NumberValidatorImpl.normalizeIsBetweenParameters(minimum, maximumExclusiveOrMinimumIsInclusive, maximum, maximumIsInclusive); const internalValidators = JavascriptValidatorsImpl.INTERNAL; internalValidators.requireThatNumber(normalized.minimum, "minimum"). isLessThanOrEqualTo(normalized.maximum, "maximum"); if (this.value.validationFailed(v => ObjectSizeValidatorImpl.inBounds(v, normalized.minimum, normalized.minimumIsInclusive, normalized.maximum, normalized.maximumIsInclusive))) { this.failOnUndefinedOrNull(); this.addRangeError(collectionSizeIsBetween(this, this.name, this.value.or(null), normalized.minimum, normalized.minimumIsInclusive, normalized.maximum, normalized.maximumIsInclusive, this.pluralizer). toString()); } return this; } /** * @param value - the value being validated * @param minimum - the lower bound of the range * @param minimumIsInclusive - `true` if the lower bound of the range is inclusive * @param maximum - the upper bound of the range * @param maximumIsInclusive - `true` if the upper bound of the range is inclusive * @returns `true` if the value is in bounds; false otherwise */ static inBounds(value, minimum, minimumIsInclusive, maximum, maximumIsInclusive) { if (minimumIsInclusive) { if (value < minimum) return false; } else if (value <= minimum) return false; if (maximumIsInclusive) return value <= maximum; return value < maximum; } isMultipleOf(factor, name) { if (name !== undefined) this.requireThatNameIsUnique(name); if (this.value.validationFailed(v => NumberValidatorImpl.valueIsMultipleOf(v, factor))) { this.failOnUndefinedOrNull(); const messageBuilder = numberIsMultipleOf(this, name ?? null, factor); this.objectValidator.value.ifValid(v => messageBuilder.withContext(v, this.objectValidator.getName())); this.addRangeError(messageBuilder.toString()); } return this; } isNotMultipleOf(factor, name) { if (name !== undefined) this.requireThatNameIsUnique(name); if (this.value.validationFailed(v => !NumberValidatorImpl.valueIsMultipleOf(v, factor))) { this.failOnUndefinedOrNull(); const messageBuilder = numberIsNotMultipleOf(this, name ?? null, factor); this.objectValidator.value.ifValid(v => messageBuilder.withContext(v, this.objectValidator.getName())); this.addRangeError(messageBuilder.toString()); } return this; } isFinite() { if (this.value.validationFailed(v => Number.isFinite(v))) { this.failOnUndefinedOrNull(); this.addRangeError(numberIsFinite(this).toString()); } return this; } isInfinite() { if (this.value.validationFailed(v => !Number.isFinite(v) && !Number.isNaN(v))) { this.failOnUndefinedOrNull(); this.addRangeError(numberIsInfinite(this).toString()); } return this; } isNumber() { if (this.value.validationFailed(v => !Number.isNaN(v))) { this.failOnUndefinedOrNull(); this.addRangeError(numberIsNumber(this).toString()); } return this; } isNotNumber() { if (this.value.validationFailed(v => Number.isNaN(v))) { this.failOnUndefinedOrNull(); this.addRangeError(numberIsNotNumber(this).toString()); } return this; } } export { ObjectSizeValidatorImpl }; //# sourceMappingURL=ObjectSizeValidatorImpl.mjs.map