all files / src/ helpers.js

99.15% Statements 116/117
94.44% Branches 119/126
100% Functions 22/22
100% Lines 96/96
1 statement, 1 function, 11 branches Ignored     
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 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176                       26× 26×   26× 52× 36×             792× 792× 499×   499× 49×     743× 702× 702×           27×     742×     1207×     31×   31× 31× 31× 36× 36×   36× 17×     19× 19× 19× 19×       387× 338×   49×   49× 12×   49× 14× 10×     35×     18×     18× 18×   18× 870× 870×         342× 342×         133× 133× 71× 71× 71× 71× 1569× 1569× 74×   1569× 145×     71× 35× 19× 19×   16×               36×         910× 910× 910× 966× 966× 966×         910×     968×     1017×  
import format from './format'
import Validators from './index'
 
export const HAS_PROP = ({}).hasOwnProperty
export const TO_STRING = ({}).toString
 
export var DEFAULT_OPTIONS = {
  allowBlank: false,
  urlProtocols: ['http', 'https'],
  dateFormat: 'yyyy-mm-dd', // ISO
  dateYmd: 'ymd',
  accept: ['1', 'true'],
  caseSensitive: true       // confirmation, inclusion, exclusion
};
 
 
export function regFormat (func, messageType) {
  return memoize(function(options) {
    options = options || {}
    let msg = options.msg || options.message
 
    return prepare(options['if'], options.unless, options.allowBlank, function (value) {
      if (!value.match(func(options))) {
        return Validators.formatMessage(prepareMsg(msg, messageType))
      }
    })
  })
}
 
 
export function prepare (ifCond, unlessCond, allowBlank, func) {
  return function (value, allValues={}, ...args) {
    if (!value || 'object' !== typeof value) {
      value = null == value ? '' : '' + value
 
      if ((null != allowBlank ? allowBlank : Validators.defaultOptions.allowBlank) && !value.trim()) {
        return
      }
    }
    if (('function' !== typeof ifCond || ifCond(allValues, value)) &&
        ('function' !== typeof unlessCond || !unlessCond(allValues, value))) {
      return func(value, allValues, ...args)
    }
  }
}
 
export function trunc (num) {
  /* istanbul ignore next */
  return Math.trunc ? Math.trunc(num) : num < 0 ? Math.ceil(num) : Math.floor(num)
}
 
export function selectNum (var1, var2) {
  return isNumber(var1) ? +var1 : (arguments.length > 1 && isNumber(var2) ? +var2 : null)
}
 
export function isNumber (num) {
  return !isNaN(num) && (0 != num || '' !== ('' + num).trim())
}
 
export function formatMsg (msg) {
  if (msg.props) {
    msg = msg.props
  }
  let text = msg.defaultMessage || msg.id || ''
  let rules = Validators.pluralRules
  return !msg.values ? text : parseMsg(text, function(part) {
    let parts = part.split(',')
    let count = msg.values[parts[0]]
    // {value} OR {count, number}
    if (parts.length <= 2) {
      return null == count ? '' : ('' + count)
    }
    // plural
    let plural = parts.slice(2).join(',').trim()
    let info = {}
    let result = parseMsg(plural, null, rules[+count] || 'other', info)
    return info.found ? result : parseMsg(plural, null, 'other', {})
  })
}
 
export function prepareMsg (msg, type, values) {
  if (null == msg) {
    return defaultMessage(type, values)
  }
  if (HAS_PROP.call(msg, 'props') && isReactElement(msg)) {
    msg = msg.props
  }
  if (null != msg[type]) {
    msg = msg[type]
  }
  if (isObject(msg)) {
    if (HAS_PROP.call(msg, 'id') || HAS_PROP.call(msg, 'defaultMessage')) {
      return Object.assign({}, msg, { values: values })
    }
    return defaultMessage(type, values)
  }
  return { id: msg, defaultMessage: msg, values: values }
}
 
export function toObjectMsg (msg) {
  if (null == msg) return null
  return isObject(msg) ? msg : { id: msg, defaultMessage: msg }
}
 
export function memoize (func) {
  Eif (!func.cache) {
    func.cache = {}
  }
  return function(options) {
    let key = stringify(options)
    return HAS_PROP.call(func.cache, key) ? func.cache[key] : (func.cache[key] = func(options))
  }
}
 
// private
function defaultMessage (type, values) {
  let msg = Validators.messages[type]
  return 'string' === typeof msg
    ? { defaultMessage: msg, values: values }
    : Object.assign({}, msg, { values: values })
}
 
function parseMsg (msg, func, pattern, info) {
  let start = msg.indexOf('{')
  if (start < 0) return pattern ? '' : msg
  let index = start
  let count = 1
  let len = msg.length
  while (count > 0 && index < len) {
    ++index;
    if ('{' === msg.charAt(index)) {
      ++count;
    }
    if ('}' === msg.charAt(index)) {
      --count;
    }
  }
  if (pattern) {
    if (pattern === msg.slice(0, start).trim()) {
      info.found = true
      return msg.slice(start + 1, index).trim()
    }
    return parseMsg(msg.slice(index + 1), null, pattern, info)
  }
 
  // func gets all '{.*}' parts
  // e.g:
  // - {count}
  // - {count, plural, one {1 thing} other {many things}}
  // - ...
  return msg.slice(0, start) +
    parseMsg(func(msg.slice(start + 1, index).trim()), func) +
    parseMsg(msg.slice(index + 1), func)
}
 
function stringify (options) {
  let arr = []
  let value
  for (var k in options) {
    Eif (HAS_PROP.call(options, k)) {
      value = options[k]
      arr.push(k, isReactElement(value)
        ? stringify(value.props)
        : isObject(value) ? stringify(value) : value.toString())
    }
  }
  return JSON.stringify(arr)
}
 
function isReactElement (object) {
  return typeof object === 'object' && object !== null && '$$typeof' in object;
}
 
function isObject (obj) {
  return 'object' === typeof obj && '[object Object]' === TO_STRING.call(obj) && null !== obj;
}