UNPKG

@trusthab/composable-resources

Version:

migrating https://github.com/knetikmedia/hab-api/tree/integration/app/resources/composable

102 lines (82 loc) 2.38 kB
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); };