blow-data
Version:
Data access layer for Blow.
75 lines (74 loc) • 2.52 kB
JavaScript
;
const Joi = require('joi');
const util_1 = require('util');
const rxjs_1 = require('rxjs');
const ValidationResult_1 = require('./ValidationResult');
class Validator {
constructor(syncSchema, asyncSchema) {
this._syncSchema = syncSchema;
this._asyncSchema = asyncSchema;
}
_syncValidate(data) {
if (!this._syncSchema) {
return rxjs_1.Observable.of([]);
}
const validationOptions = {
abortEarly: false,
allowUnknown: true
};
const result = Joi.validate(data, this._syncSchema, validationOptions);
if (!result.error) {
return rxjs_1.Observable.of([]);
}
return rxjs_1.Observable.of(result.error.details.map(r => {
r['property'] = r['path'];
const type = r['type'].split('.');
if (type.length > 1) {
type.shift();
}
r['type'] = type.join('.');
delete r['context'];
delete r['path'];
return r;
}));
}
_asyncValidate(data) {
if (!this._asyncSchema) {
return rxjs_1.Observable.of([]);
}
return rxjs_1.Observable.from(Object.keys(this._asyncSchema))
.mergeMap(propertyName => {
return rxjs_1.Observable.from(this._asyncSchema[propertyName])
.mergeMap(validator => {
const result = validator.bind(data)(propertyName);
if (util_1.isFunction(result.subscribe)) {
return result;
}
return rxjs_1.Observable.of(result);
})
.map(errorMessage => {
if (errorMessage) {
return {
property: propertyName,
type: 'custom',
message: errorMessage
};
}
return null;
});
})
.toArray()
.map(result => result.reduce((aggr, curr) => {
if (curr) {
aggr.push(curr);
}
return aggr;
}, []));
}
validate(data) {
const mapResults = (sync, async) => sync.concat(async);
return rxjs_1.Observable.combineLatest(this._syncValidate(data), this._asyncValidate(data), mapResults)
.map(resultRaw => new ValidationResult_1.ValidationResult(resultRaw));
}
}
exports.Validator = Validator;