all files / src/lib/ model.js

100% Statements 31/31
92.31% Branches 24/26
100% Functions 7/7
100% Lines 25/25
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96                                                    14×                                                                                            
/**
 * Exports Joi so no additional import/require needed
 */
export const obey = require('obey')
 
/**
 * Exports the core model object
 * @namespace model
 */
export const model = {}
 
/**
 * Stores the models and their versions in memory
 * @property {Object}
 */
model.store = {}
 
/**
 * Adds a model to the store
 * @param {Object} m The model to add
 */
model.add = (m) => {
  // Ensure required properties
  if (!m.name || !m.tableName || !m.version || !m.schema) {
    throw new Error('Model must contain a name, tableName, version and schema')
  }
  // Check if model exists
  if (!model.store[m.name]) {
    // Create new store entry
    model.store[m.name] = {}
  }
  // Build model object
  let modelObj = {}
  Object.keys(m).forEach((prop) => {
    if (prop !== 'version' && prop !== 'name') {
      if (prop === 'schema' && typeof m.schema.validate !== 'function') {
        // Build model
        modelObj.schema = obey.model(m.schema)
      } else {
        modelObj[prop] = m[prop]
      }
    }
  })
  // Append to existing store entry with version and schema
  model.store[m.name][m.version] = modelObj
}
 
/**
 * Initializes a model
 * @memberof model
 * @param {String} m The model name
 */
model.init = (m) => {
  // Ensure model is defined
  if (!model.store[m]) {
    throw new Error('Model not defined')
  }
  // Get model object
  const defaultVersion = Object.keys(model.store[m]).pop()
  return {
    name: m,
    tableName: model.store[m][defaultVersion].tableName,
    defaultVersion,
    schemas: model.store[m],
    validate: function(data, version, partial = false) {
      const v = version || this.defaultVersion
      // Return validation
      return this.schemas[v].schema.validate(data, { partial })
        .catch(err => model.formatValidationError(err))
    },
    sanitize: function(data) {
      return data
    }
  }
}
 
/**
 * Formats validation error
 * @memberof model
 * @param {Object} err The error returned from failing Joi validation
 * @returns {String|Object} The formatted validation error
 */
model.formatValidationError = (err) => {
  if (model.customValidationError) {
    // A custom formatter is defined
    throw model.customValidationError(err)
  }
  throw err
}
 
/**
 * Placeholder for custom formatter function
 * @memberof model
 */
model.customValidationError = false