UNPKG

@cowwoc/requirements

Version:

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

157 lines 5.01 kB
import { Type } from "../internal.mjs"; /** * Represents a value that is being validated. * * This class is not intended to replace `undefined` or `null` references but to record additional * information alongside them. * * Instead of throwing an error when an `undefined` or `null` value is accessed, the system * marks it as invalid and continues to record validation failures. * * @typeParam T - the type of the value */ class ValidationTarget { static INVALID = new ValidationTarget(false, undefined); valid; value; /** * Creates a value that may be invalid. * * @param valid - `true` if the value is valid, or `false` if invalid * @param value - the value */ constructor(valid, value) { this.valid = valid; this.value = value; } /** * Returns an invalid value. * * @typeParam T - the type of the value * @returns an invalid value */ static invalid() { return ValidationTarget.INVALID; } /** * Returns a valid value. * * @typeParam T - the type of the value * @param value - a value * @returns a valid value */ static valid(value) { return new ValidationTarget(true, value); } or(defaultValue) { if (this.valid) return this.value; return defaultValue; } /** * Returns the valid value, or a default value if invalid. A value of `null` does not hold any * special significance. It does not imply that the value is invalid. * * @param defaultValue - a supplier that returns the default value * @returns the valid value, or `defaultValue` if the value is invalid */ orGet(defaultValue) { if (this.valid) return this.value; return defaultValue(); } /** * Consumes the value if it is valid. If the value is invalid, no action is taken. * * @param consumer - consumes the value if it is valid */ ifValid(consumer) { if (this.valid) consumer(this.value); } /** * Applies a function to the value if it is valid. If the value is invalid, no action is taken. * * @typeParam U - the type of value returned by the mapper * @param mapper - the function to apply to the value if it is valid * @returns `this` if the value is invalid; otherwise, a `MaybeInvalid` instance wrapping the * result of applying the mapper to the value */ map(mapper) { if (!this.valid) return this; const newValue = mapper(this.value); if (this.value === newValue) return this; return ValidationTarget.valid(newValue); } /** * Converts an `undefined` or `null` value to an invalid value. If the value is invalid or non-`null`, no * action is taken. * * @returns an invalid value if the original value was `undefined` or `null`; otherwise, returns `this` * with `T` excluding `undefined` and `null` */ undefinedOrNullToInvalid() { if (this.valid && (this.value === undefined || this.value === null)) return ValidationTarget.invalid(); return this; } /** * Returns the value or throws an error if invalid. * * @typeParam U - the type of error to throw * @param errorSupplier - returns the error to throw if the value is invalid * @returns the value * @throws U if the value is invalid */ orThrow(errorSupplier) { if (this.valid) return this.value; // WORKAROUND: https://github.com/typescript-eslint/typescript-eslint/issues/9882 throw errorSupplier(); } /** * Checks if the value is valid. * * @returns `true` if the value is valid; `false` otherwise */ isValid() { return this.valid; } /** * Checks if the value is null. * * @returns `true` if the value is `undefined`; `false` otherwise */ isUndefined() { return this.valid && this.value === undefined; } /** * Checks if the value is null. * * @returns `true` if the value is `null`; `false` otherwise */ isNull() { return this.valid && this.value === null; } /** * Evaluates a condition on the value. * * @param condition - the condition to evaluate * @returns `true` if the value is invalid, `undefined`, `null` or if the `condition` returns `false`; * otherwise, returns `false` */ validationFailed(condition) { return !this.valid || this.value === undefined || this.value === null || !condition(this.value); } toString() { if (!this.valid) return "invalid"; if (this.value === null) return "null"; return `${JSON.stringify(Type.of(this.value), null, 2)}: ${JSON.stringify(this.value, undefined, 2)}`; } } export { ValidationTarget }; //# sourceMappingURL=ValidationTarget.mjs.map