altheia-async-data-validator
Version:
A very simple, fast and customizable async data validator
168 lines (167 loc) • 5.72 kB
JavaScript
;
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;