@trusthab/composable-resources
Version:
migrating https://github.com/knetikmedia/hab-api/tree/integration/app/resources/composable
102 lines (82 loc) • 2.38 kB
JavaScript
const composer = require('../mixin_loader');
const Q = require('q');
const _ = require('lodash');
const { Validator } = require('jsonschema');
const typeConversion = {
list: 'array',
text: 'string',
integer: 'number',
double: 'number',
boolean: 'boolean'
};
module.exports = (App) => {
const {
Errors: { RecordInvalid }
} = require('@knetik/micro-lib')(App);
const SharedSchemas = App.get('Validators.SharedSchemas');
const { underscore } = require('inflected');
class ValidatableResource {
// this.errors = [] || [ValidationError];
static mixinSetup(resource) {
Object.defineProperty(resource.prototype, 'errors', {
value: [],
writable: true
});
}
hasErrors() {
return !!this.errors.length;
}
schema() {
return this.constructor.schema();
}
valid() {
const validator = new Validator();
SharedSchemas.forEach(
SharedSchema => validator.addSchema(SharedSchema, SharedSchema.id)
);
const validation = validator.validate(this.serialize(), this.schema());
this.errors = validation.errors;
return Q(!this.hasErrors());
}
static schema() {
const _schema = {
id: `/${this.name}`,
type: 'object',
properties: {}
};
const keys = Object.keys(this.mapping);
keys.forEach((key) => {
const value = _.cloneDeep(this.mapping[key]);
if (value.schema_ignore) { return; }
if (value.$ref) {
_schema.properties[key] = { $ref: value.$ref };
}
value.type = [typeConversion[value.type]];
if (value.or) {
value.type = _.compact(_.concat(value.type, value.or));
}
_.unset(value, 'or');
_.unset(value, 'get_method');
_.unset(value, 'weight');
_.unset(value, 'path');
_schema.properties[key] = value;
});
return _schema;
}
static validate(params) {
const Resource = this;
const resource = Resource.deserialize(params);
return resource.valid()
.then((valid) => {
if (!valid) {
throw new RecordInvalid({
message: 'Validation Error',
details: resource.errors
});
}
return true;
});
}
}
return composer(ValidatableResource, App);
};