const Base = require('./base.js') const util = require('util') const validate = require('../validate.js') class TypeArray extends Base { constructor () { super() this._type = 'object' this._empty = false this._min = null this._max = null /** * @type {Base[]} */ this._itemTypes = [] } /** * set allow empty */ empty () { this._empty = true return this } /** * set min length * @param {number} num */ min (num) { if (!isFinite(num) || num === true || num === false) throw new Error('input wrong') if (this._max !== null && this._max <= num) throw new Error(`num >= ${this._max}`) if (num < 0) throw new Error('array length must >= 0') this._min = parseFloat(num) return this } items (...args) { this._itemTypes.push(...args) return this } /** * set max length * @param {number} num */ max (num) { if (!isFinite(num) || num === true || num === false) throw new Error('input wrong') if (this._min !== null && this._min >= num) throw new Error(`num <= ${this._min}`) this._max = parseFloat(num) return this } validate (value) { if (value === undefined && this._required) return `required` if (value === undefined) return null /* eslint-disable-next-line */ if (typeof value !== this._type) return `${util.inspect(value, false, null)} type not array` if (!Array.isArray(value)) return `${util.inspect(value, false, null)} type not array` if (!this._empty && value.length === 0) return `not allow empty` if (this._min !== null && value.length < this._min) return `value length < ${this._min}` if (this._max !== null && value.length > this._max) return `value length > ${this._max}` if (this._itemTypes.length > 0) { for (const item of value) { let verified = false let fail = '' for (const type of this._itemTypes) { const result = type.validate(item) if (result) { fail = result } else { verified = true fail = '' break } } if (!verified || fail) return fail || `item type not match` } } return null } } module.exports = TypeArray