UNPKG

altheia-async-data-validator

Version:

A very simple, fast and customizable async data validator

168 lines (167 loc) 5.72 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TypeArray = exports.messages = void 0; const base_1 = require("./base"); const arraydiff_1 = __importDefault(require("../utils/arraydiff")); exports.messages = { 'array.typeof': (name) => `${name} must be a valid array`, 'array.min': (name, args) => `${name} must contains at least ${args.min} items`, 'array.max': (name, args) => `${name} must contains at most ${args.max} items`, 'array.in': (name, args) => `${name} must only contains these keys [${args.in}]`, 'array.not': (name) => `${name} contains forbidden value`, 'array.unique': (name) => `${name} can not contains duplicated value`, 'array.oneOf': (name) => `${name} contains forbidden items`, 'array.itemInvalid': (name) => `${name} does not match any of the allowed types`, }; /** * Array class */ class TypeArray extends base_1.TypeBase { /** * Constructor */ constructor() { super(); this.name = 'array'; this.typeof(); } _cast() { throw new Error('not available for this validator'); } /** * Test to validate the type of the value * * @return {this} */ typeof() { this.test('typeof', (val) => { return Array.isArray(val); }); return this; } /** * Force an array to contains at least a number of items equal to the value passed. * * @param {number} min * @return {this} */ min(min) { this.test('min', (arr) => { return arr.length >= min; }, { min }); return this; } /** * Force an array to contains at most a number of items equal to the value passed. * * @param {number} max * @return {this} */ max(max) { this.test('max', (arr) => { return arr.length <= max; }, { max }); return this; } in(...array) { let only = array; // handle someone passing literal array instead of multiple args if (array.length === 1 && Array.isArray(array[0])) { only = array[0]; } this.test('in', (arr) => { return (0, arraydiff_1.default)(arr, only).length === 0; }, { in: only }); return this; } not(...array) { let only = array; // handle someone passing literal array instead of multiple args if (array.length === 1 && Array.isArray(array[0])) { only = array[0]; } this.test('not', (arr) => { return (0, arraydiff_1.default)(only, arr).length === only.length; }, { not: only }); return this; } /** * Force an array to only have each item once * * @return {this} */ unique() { this.test('unique', (arr) => { const a = new Set(arr); return a.size === arr.length; }); return this; } /** * Force all array's items to match one of the template * * @param {...Validator} templates * @return {this} */ oneOf(...templates) { this.test('oneOf', (arr) => __awaiter(this, void 0, void 0, function* () { const errors = []; yield Promise.all(arr.map((value, index) => __awaiter(this, void 0, void 0, function* () { let error; const label = 'item'; for (let i = 0; i < templates.length; i++) { const test = yield templates[i].required().validate(value); if (test) { error = { label, test, position: index }; } else { // early break if one template matched (returned no error) return; } } // Help typescript understand we have error here if (!error) { return; } // if multiples templates, return a generic message if (templates.length > 1) { error = { label, test: this.createTestResult(this.createTest({ type: 'array.itemInvalid', }), false), position: index, }; errors.push(error); } else { errors.push(error); } }))); return { valid: errors.length <= 0, error: 'not_matching', errors, }; }), { templates }); return this; } } exports.TypeArray = TypeArray; const def = { Class: TypeArray, messages: exports.messages, }; exports.default = def;