nope-validator
Version:
Fast and simple JS validator
126 lines (123 loc) • 4.41 kB
JavaScript
import { runValidators, pathToArray, getFromPath } from './utils.js';
class NopeObject {
constructor(objectShape) {
this.validationRules = [];
this._type = 'object';
this.objectShape = objectShape || {};
}
getType() {
return this._type;
}
shape(shape) {
Object.assign(this.objectShape, shape);
return this;
}
extend(Base) {
Object.assign(this.objectShape, Base.objectShape);
return this;
}
noUnknown(message = 'Input contains invalid keys') {
const rule = (entry) => {
let objectIsDefined = false;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
for (const _ in this.objectShape) {
objectIsDefined = true;
break;
}
if (!objectIsDefined) {
throw Error('noUnknown must be used with a schema');
}
let unknownKeys = false;
for (const key in entry) {
unknownKeys = unknownKeys || !(key in this.objectShape);
}
if (unknownKeys) {
return message;
}
};
this.validationRules.push(rule);
return this;
}
validate(entry, context, options) {
for (const rule of this.validationRules) {
const localErrors = rule(entry);
if (localErrors) {
return localErrors;
}
}
let areErrors = false;
const abortEarly = options === null || options === void 0 ? void 0 : options.abortEarly;
const errors = {};
const ctx = Object.assign({ ___parent: context }, entry);
for (const key in this.objectShape) {
const validator = this.objectShape[key];
const error = validator.validate(entry[key], ctx, options);
if (error) {
areErrors = true;
errors[key] = error;
if (abortEarly) {
return errors;
}
}
}
if (areErrors) {
return errors;
}
return undefined;
}
validateAsync(entry, context, options) {
return runValidators(this.validationRules, entry, context).then((localError) => {
if (localError) {
return localError;
}
const keys = [];
const results = [];
const ctx = Object.assign({ ___parent: context }, entry);
for (const key in this.objectShape) {
const validator = this.objectShape[key];
const error = validator.validateAsync(entry[key], ctx, options);
keys.push(key);
results.push(error);
}
return Promise.all(results).then((resolvedErrors) => {
const errors = {};
let areErrors = false;
for (let i = 0; i < keys.length; i++) {
const error = resolvedErrors[i];
if (error) {
areErrors = true;
errors[keys[i]] = error;
}
}
if (areErrors) {
return errors;
}
return undefined;
});
});
}
validateAt(path, entry) {
var _a, _b;
const arrayPath = pathToArray(path);
let validator = this.objectShape;
for (const p of arrayPath) {
if (!isNaN(parseInt(p, 10))) {
continue;
}
if ((_a = validator[p]) === null || _a === void 0 ? void 0 : _a.objectShape) {
validator = validator[p].objectShape;
}
else if ((_b = validator[p]) === null || _b === void 0 ? void 0 : _b.ofShape) {
validator = validator[p].ofShape.objectShape || validator[p].ofShape;
}
else {
validator = validator[p];
}
}
const parentValue = getFromPath(path, entry, true);
const value = getFromPath(path, entry);
return validator.validate(value, parentValue);
}
}
export { NopeObject };
//# sourceMappingURL=NopeObject.js.map