<commit_before>
/**
  Module dependencies
  @ignore
*/

import is from '../is'
import * as Rules from '../rules'
import setDefault from '../default'
import checkValue from './checkValue'

/**
  Expose the module
  @ignore
*/

export {validate, checkValue}

/**
  Validates `data` against a model's rules.

  If passed "opts" `{sparse:true}`, validation is only run on the fields in
  the data objected provided. Default is `false`, so validation is run on
  all fields in the provided `model`

  If passed "opts" `{strict: true}`, validation ensures all keys on the data
  payload are valid (ie. have an associated model field), before running
  normal validation

  Returns:

  ```
  {
    valid: {Boolean},
    // Error object if data is object, array if scalar
    errors: {Object|Array}
  }
  ```

  Example:

  ```
  validate({type:'string'}, '1')
  // -> {valid:true, errors:[]}

  validate({name:{type:'string'}}, {name:'Zim'})
  // -> {valid: true, errors:{}}
  ```

  @param {Model} model The data structure rules used for validation
  @param {Object} [opts] Optional options `{sparse:true}` to only parse data keys
  @param {Object|Mixed} data The data item to validate

  @return {Object} Validation object `{valid:$bool, errors:$Object|Array}`

  @memberof Skematic
  @alias validate
*/

function validate (model, data, opts = {}) {
  if (opts.keyCheckOnly) return _checkKeys(model, data)

  // Strict checks that the data keys are valid AND runs normal validation if so
  if (opts.strict) {
    const checkedKeys = _checkKeys(model, data)
    if (!checkedKeys.valid) return checkedKeys
  }

  if (opts.sparse) return _sparse(data, model)
  else return _validate(data, model)
}

/**
  Checks that the keys on the data object

  @param {Model} model The data structure rules used for validation
  @param {Object|Mixed} data The data item to validate

  @return {Object} Validation object `{valid:$bool, errors:$Object|Array}`
  @private
*/

function _checkKeys (model, data) {
  let ret = {
    valid: true,
    errors: {}
  }

  if (!is.object(data)) {
    return {valid: false, errors: {data: ['Invalid data']}}
  }

  const MAX_USER_KEY_LEN = 16
  for (let key in data) {
    if (!model[key]) {
      ret.valid = false

      // Sanitize user keylength
      const shortKey = key.length > MAX_USER_KEY_LEN
        ? key.substr(0, MAX_USER_KEY_LEN - 3) + '...'
        : key

      ret.errors[shortKey] = [`Invalid key: ${shortKey}`]
    }
  }

  return ret
}

/**
  Internal method that handles the validation of arbitrary `data`.
<commit_msg>Boost validate keycheck max length to 48<commit_after>
/**
  Module dependencies
  @ignore
*/

import is from '../is'
import * as Rules from '../rules'
import setDefault from '../default'
import checkValue from './checkValue'

/**
  Expose the module
  @ignore
*/

export {validate, checkValue}

/**
  Validates `data` against a model's rules.

  If passed "opts" `{sparse:true}`, validation is only run on the fields in
  the data objected provided. Default is `false`, so validation is run on
  all fields in the provided `model`

  If passed "opts" `{strict: true}`, validation ensures all keys on the data
  payload are valid (ie. have an associated model field), before running
  normal validation

  Returns:

  ```
  {
    valid: {Boolean},
    // Error object if data is object, array if scalar
    errors: {Object|Array}
  }
  ```

  Example:

  ```
  validate({type:'string'}, '1')
  // -> {valid:true, errors:[]}

  validate({name:{type:'string'}}, {name:'Zim'})
  // -> {valid: true, errors:{}}
  ```

  @param {Model} model The data structure rules used for validation
  @param {Object} [opts] Optional options `{sparse:true}` to only parse data keys
  @param {Object|Mixed} data The data item to validate

  @return {Object} Validation object `{valid:$bool, errors:$Object|Array}`

  @memberof Skematic
  @alias validate
*/

function validate (model, data, opts = {}) {
  if (opts.keyCheckOnly) return _checkKeys(model, data)

  // Strict checks that the data keys are valid AND runs normal validation if so
  if (opts.strict) {
    const checkedKeys = _checkKeys(model, data)
    if (!checkedKeys.valid) return checkedKeys
  }

  if (opts.sparse) return _sparse(data, model)
  else return _validate(data, model)
}

/**
  Checks that the keys on the data object

  @param {Model} model The data structure rules used for validation
  @param {Object|Mixed} data The data item to validate

  @return {Object} Validation object `{valid:$bool, errors:$Object|Array}`
  @private
*/

function _checkKeys (model, data) {
  let ret = {
    valid: true,
    errors: {}
  }

  if (!is.object(data)) {
    return {valid: false, errors: {data: ['Invalid data']}}
  }

  const MAX_USER_KEY_LEN = 48
  for (let key in data) {
    if (!model[key]) {
      ret.valid = false

      // Sanitize user keylength
      const shortKey = key.length > MAX_USER_KEY_LEN
        ? key.substr(0, MAX_USER_KEY_LEN - 3) + '...'
        : key

      ret.errors[shortKey] = [`Invalid key: ${shortKey}`]
    }
  }

  return ret
}

/**
  Internal method that handles the validation of arbitrary `data`.

{'fraction_non_alphanumeric': 0.1276016339233612, 'fraction_numerical': 0.002334176230305388, 'mean_word_length': 3.331929233361415, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1172602', 'n_tokens_mistral': 1625, 'n_tokens_neox': 1574, 'n_words': 574}