import {ValidationResult, ValidatorFunction} from './types' /** Requires the input value to be an array. */ function is(fieldName: string, inputValue: unknown): ValidationResult { if ( Array.isArray(inputValue) ) { return { valid: true } } return { valid: false, message: 'must be an array', } } /** Requires the values in the input value array to be distinct. */ function distinct(fieldName: string, inputValue: unknown): ValidationResult { const arr = is(fieldName, inputValue) if ( !arr.valid ) { return arr } if ( Array.isArray(inputValue) && (new Set(inputValue)).size === inputValue.length ) { return { valid: true } } return { valid: false, message: 'must not contain duplicate values', } } /** * Builds a validator function that requires the input array to contain the given value. * @param value */ function includes(value: unknown): ValidatorFunction { return (fieldName: string, inputValue: unknown): ValidationResult => { const arr = is(fieldName, inputValue) if ( !arr.valid ) { return arr } if ( Array.isArray(inputValue) && inputValue.includes(value) ) { return { valid: true } } return { valid: false, message: `must include ${value}`, } } } /** * Builds a validator function that requires the input array NOT to contain the given value. * @param value */ function excludes(value: unknown): ValidatorFunction { return (fieldName: string, inputValue: unknown): ValidationResult => { const arr = is(fieldName, inputValue) if ( !arr.valid ) { return arr } if ( Array.isArray(inputValue) && !inputValue.includes(value) ) { return { valid: true } } return { valid: false, message: `must not include ${value}`, } } } /** * Builds a validator function that requires the input array to have exactly `len` many entries. * @param len */ function length(len: number): ValidatorFunction { return (fieldName: string, inputValue: unknown): ValidationResult => { const arr = is(fieldName, inputValue) if ( !arr.valid ) { return arr } if ( Array.isArray(inputValue) && inputValue.length === len ) { return { valid: true } } return { valid: false, message: `must be exactly of length ${len}`, } } } /** * Builds a validator function that requires the input array to have at least `len` many entries. * @param len */ function lengthMin(len: number): ValidatorFunction { return (fieldName: string, inputValue: unknown): ValidationResult => { const arr = is(fieldName, inputValue) if ( !arr.valid ) { return arr } if ( Array.isArray(inputValue) && inputValue.length >= len ) { return { valid: true } } return { valid: false, message: `must be at least length ${len}`, } } } /** * Builds a validator function that requires the input array to have at most `len` many entries. * @param len */ function lengthMax(len: number): ValidatorFunction { return (fieldName: string, inputValue: unknown): ValidationResult => { const arr = is(fieldName, inputValue) if ( !arr.valid ) { return arr } if ( Array.isArray(inputValue) && inputValue.length <= len ) { return { valid: true } } return { valid: false, message: `must be at most length ${len}`, } } } export const Arr = { is, distinct, includes, excludes, length, lengthMin, lengthMax, }