Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c767e73f0a | |||
| 7d8256a6d6 | |||
| b282f241a6 | |||
| 0bfa3b32bd | |||
| b684a0e35e | |||
| d18c7cbad4 | |||
| 4ae4427e8e | |||
| a0e117c540 | |||
| 109f8a9655 | |||
| 8645d9914b | |||
| c1b8985461 | |||
| 8c3f9da11a | |||
| ca57604da8 | |||
| 1f605ce18e | |||
| 057466c952 | |||
| 47348064c2 | |||
| 93fe5b3f7f | |||
| 0dae994202 | |||
| d2456c2844 | |||
| 564578c160 | |||
| 70cc973927 | |||
| 81bde1577c | |||
| cdbecea36d | |||
| 464e42ba1c | |||
| a6d39d487a | |||
| e399cb0e30 | |||
| 1482049efc | |||
| 6a092ce0b7 | |||
| 46b19757bd | |||
| 0dabcea445 |
+28
-1
@@ -1,5 +1,32 @@
|
||||
# ChangeLog
|
||||
|
||||
## 2020-06-03
|
||||
## 2020-07-05 (0.0.7)
|
||||
|
||||
- fix array check contains type
|
||||
|
||||
## 2020-07-04 (0.0.6)
|
||||
|
||||
- add array validate contains type
|
||||
|
||||
## 2020-06-11 (0.0.5)
|
||||
|
||||
- modify types require method
|
||||
|
||||
## 2020-06-11 (0.0.4)
|
||||
|
||||
- modify types export
|
||||
- add package repository
|
||||
|
||||
## 2020-06-10 (0.0.3)
|
||||
|
||||
- add types init value
|
||||
|
||||
## 2020-06-10 (0.0.2)
|
||||
|
||||
- add string type pattern check function
|
||||
- add object type child validate
|
||||
- modify test
|
||||
|
||||
## 2020-06-03 (0.0.1)
|
||||
|
||||
- first version
|
||||
|
||||
@@ -1,47 +1,23 @@
|
||||
const types = require('./types/index.js')
|
||||
const BaseType = require('./types/base.js') // eslint-disable-line
|
||||
const TypeBase = require('./types/base.js')
|
||||
const TypeString = require('./types/string.js')
|
||||
const TypeNumber = require('./types/number.js')
|
||||
const TypeBoolean = require('./types/boolean.js')
|
||||
const TypeArray = require('./types/array.js')
|
||||
const TypeObject = require('./types/object.js')
|
||||
const validate = require('./validate.js')
|
||||
const validator = {}
|
||||
module.exports = validator
|
||||
|
||||
validator.Base = types.Base
|
||||
validator.string = () => new types.StringType()
|
||||
validator.number = () => new types.NumberType()
|
||||
validator.boolean = () => new types.BooleanType()
|
||||
validator.array = () => new types.ArrayType()
|
||||
validator.object = () => new types.ObjectType()
|
||||
|
||||
/**
|
||||
* @exports
|
||||
* @typedef SchemaField
|
||||
* @property {BaseType} type
|
||||
* @property {SchemaField} children
|
||||
*/
|
||||
/**
|
||||
* @exports
|
||||
* @typedef {Object<string, SchemaField|BaseType>} Schema
|
||||
*/
|
||||
validator.Base = TypeBase
|
||||
validator.string = (...args) => new TypeString(...args)
|
||||
validator.number = (...args) => new TypeNumber(...args)
|
||||
validator.boolean = (...args) => new TypeBoolean(...args)
|
||||
validator.array = (...args) => new TypeArray(...args)
|
||||
validator.object = (...args) => new TypeObject(...args)
|
||||
|
||||
/**
|
||||
* validate
|
||||
* @param {Object} src
|
||||
* @param {Schema} schema
|
||||
* @param {import('./type.js').Schema} schema
|
||||
*/
|
||||
validator.validate = function (src, schema) {
|
||||
if (typeof src !== 'object' || typeof schema !== 'object') throw new Error('source or schema not object')
|
||||
|
||||
for (const it in schema) {
|
||||
if (schema[it] instanceof BaseType) {
|
||||
const result = schema[it].validate(src[it])
|
||||
if (result) throw new Error(`field [${it}]: ${result}`)
|
||||
} else if (typeof schema[it] === 'object' && 'type' in schema[it] && schema[it].type instanceof BaseType) {
|
||||
const result = schema[it].type.validate(src[it])
|
||||
if (result) throw new Error(`field [${it}]: ${result}`)
|
||||
} else {
|
||||
throw new Error('not get any check schema type')
|
||||
}
|
||||
|
||||
if (typeof schema[it] === 'object' && 'children' in schema[it]) {
|
||||
validator.validate(src[it], schema[it].children)
|
||||
}
|
||||
}
|
||||
}
|
||||
validator.validate = validate
|
||||
|
||||
Generated
+1535
File diff suppressed because it is too large
Load Diff
+7
-2
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mtfos-validator",
|
||||
"version": "0.0.1",
|
||||
"version": "0.0.7",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
@@ -10,6 +10,11 @@
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"jest": "^26.0.1"
|
||||
"jest": "^26.0.1",
|
||||
"standard": "^12.0.1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://git.trj.tw/nodejs/validator.git"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
const BaseType = require('./types/base.js') // eslint-disable-line
|
||||
|
||||
/**
|
||||
* @exports
|
||||
* @typedef SchemaField
|
||||
* @property {BaseType} type
|
||||
* @property {SchemaField} children
|
||||
*/
|
||||
/**
|
||||
* @exports
|
||||
* @typedef {Object<string, SchemaField|BaseType>} Schema
|
||||
*/
|
||||
module.exports = {}
|
||||
@@ -1,5 +1,6 @@
|
||||
const Base = require('./base.js')
|
||||
const util = require('util')
|
||||
const validate = require('../validate.js')
|
||||
|
||||
class TypeArray extends Base {
|
||||
constructor () {
|
||||
@@ -8,6 +9,10 @@ class TypeArray extends Base {
|
||||
this._empty = false
|
||||
this._min = null
|
||||
this._max = null
|
||||
/**
|
||||
* @type {Base[]}
|
||||
*/
|
||||
this._itemTypes = []
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -30,6 +35,11 @@ class TypeArray extends Base {
|
||||
return this
|
||||
}
|
||||
|
||||
items (...args) {
|
||||
this._itemTypes.push(...args)
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* set max length
|
||||
* @param {number} num
|
||||
@@ -50,6 +60,25 @@ class TypeArray extends Base {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
+17
-4
@@ -1,5 +1,7 @@
|
||||
/* eslint-disable no-undef */
|
||||
const TypeArray = require('./array.js')
|
||||
const TypeString = require('./string.js')
|
||||
const TypeObject = require('./object.js')
|
||||
|
||||
describe('test validate schema type array', () => {
|
||||
function throwFunc (val) {
|
||||
@@ -18,7 +20,7 @@ describe('test validate schema type array', () => {
|
||||
it('test type array with required', async () => {
|
||||
const arr = new TypeArray().required()
|
||||
|
||||
arr.validate([1, 2])
|
||||
throwFunc(arr.validate([1, 2]))
|
||||
|
||||
expect(throwFunc(arr.validate(undefined))).toThrow()
|
||||
})
|
||||
@@ -26,7 +28,7 @@ describe('test validate schema type array', () => {
|
||||
it('test type array with empty', async () => {
|
||||
const arr = new TypeArray().empty()
|
||||
|
||||
arr.validate([])
|
||||
throwFunc(arr.validate([]))
|
||||
})
|
||||
|
||||
it('test type array without empty', async () => {
|
||||
@@ -43,7 +45,7 @@ describe('test validate schema type array', () => {
|
||||
expect(() => new TypeArray().min(-1)).toThrow()
|
||||
expect(() => new TypeArray().max(1).min(2)).toThrow()
|
||||
|
||||
arr.validate([1, 2])
|
||||
throwFunc(arr.validate([1, 2]))
|
||||
|
||||
expect(throwFunc(arr.validate([1]))).toThrow()
|
||||
})
|
||||
@@ -55,8 +57,19 @@ describe('test validate schema type array', () => {
|
||||
expect(() => new TypeArray().max(false)).toThrow()
|
||||
expect(() => new TypeArray().min(5).max(3)).toThrow()
|
||||
|
||||
arr.validate([1])
|
||||
throwFunc(arr.validate([1]))
|
||||
|
||||
expect(throwFunc(arr.validate([1, 2, 3]))).toThrow()
|
||||
})
|
||||
|
||||
it('test array contains value', async () => {
|
||||
const arr = new TypeArray().items(new TypeString())
|
||||
|
||||
expect(throwFunc(arr.validate([1, 2, 3]))).toThrow()
|
||||
throwFunc(arr.validate(['asd']))
|
||||
|
||||
const arr2 = new TypeArray().items(new TypeString(), new TypeObject())
|
||||
expect(throwFunc(arr2.validate([123, true]))).toThrow()
|
||||
throwFunc(arr2.validate(['asd', '33', {}]))
|
||||
})
|
||||
})
|
||||
|
||||
+2
-1
@@ -1,7 +1,8 @@
|
||||
/**
|
||||
* type builder interface
|
||||
*
|
||||
* @interface
|
||||
* @class
|
||||
* @exports
|
||||
*/
|
||||
class BaseType {
|
||||
constructor () {
|
||||
|
||||
@@ -11,7 +11,7 @@ describe('test validate schema type boolean', () => {
|
||||
it('test type boolean required', async () => {
|
||||
const bool = new TypeBoolean().required()
|
||||
|
||||
bool.validate(true)
|
||||
throwFunc(bool.validate(true))
|
||||
|
||||
expect(throwFunc(bool.validate(undefined))).toThrow()
|
||||
expect(throwFunc(bool.validate({}))).toThrow()
|
||||
|
||||
+8
-15
@@ -1,15 +1,8 @@
|
||||
const Base = require('./base.js')
|
||||
const StringType = require('./string.js')
|
||||
const NumberType = require('./number.js')
|
||||
const BooleanType = require('./boolean.js')
|
||||
const ObjectType = require('./object.js')
|
||||
const ArrayType = require('./array.js')
|
||||
|
||||
module.exports = {
|
||||
Base,
|
||||
StringType,
|
||||
NumberType,
|
||||
BooleanType,
|
||||
ObjectType,
|
||||
ArrayType
|
||||
}
|
||||
const types = {}
|
||||
module.exports = types
|
||||
types.Base = require('./base.js')
|
||||
types.StringType = require('./string.js')
|
||||
types.NumberType = require('./number.js')
|
||||
types.BooleanType = require('./boolean.js')
|
||||
types.ObjectType = require('./object.js')
|
||||
types.ArrayType = require('./array.js')
|
||||
|
||||
@@ -11,7 +11,9 @@ describe('test validate schema type number', () => {
|
||||
it('test type number with required', async () => {
|
||||
const num = new TypeNumber().required()
|
||||
|
||||
num.validate(1)
|
||||
throwFunc(num.validate(1))
|
||||
|
||||
throwFunc(num.validate(1.23))
|
||||
|
||||
expect(throwFunc(num.validate(undefined))).toThrow()
|
||||
expect(throwFunc(num.validate({}))).toThrow()
|
||||
@@ -24,7 +26,7 @@ describe('test validate schema type number', () => {
|
||||
expect(() => new TypeNumber().min(false)).toThrow()
|
||||
expect(() => new TypeNumber().max(1).min(2)).toThrow()
|
||||
|
||||
num.validate(2)
|
||||
throwFunc(num.validate(2))
|
||||
|
||||
expect(throwFunc(num.validate(-1))).toThrow()
|
||||
})
|
||||
@@ -36,7 +38,7 @@ describe('test validate schema type number', () => {
|
||||
expect(() => new TypeNumber().max(false)).toThrow()
|
||||
expect(() => new TypeNumber().min(3).max(2)).toThrow()
|
||||
|
||||
num.validate(2)
|
||||
throwFunc(num.validate(2))
|
||||
|
||||
expect(throwFunc(num.validate(3))).toThrow()
|
||||
})
|
||||
|
||||
+18
-1
@@ -1,10 +1,20 @@
|
||||
const Base = require('./base.js')
|
||||
const util = require('util')
|
||||
const validate = require('../validate.js')
|
||||
|
||||
/**
|
||||
* @typedef {import('../type.js').Schema} Schema
|
||||
*/
|
||||
|
||||
class TypeObject extends Base {
|
||||
constructor () {
|
||||
/**
|
||||
* @param {Object<string, Schema>} child
|
||||
*/
|
||||
constructor (child) {
|
||||
super()
|
||||
if (child && typeof child !== 'object') throw new Error('child type wrong')
|
||||
this._type = 'object'
|
||||
this._child = child && Object.keys(child).length > 0 ? child : null
|
||||
}
|
||||
|
||||
validate (value) {
|
||||
@@ -12,6 +22,13 @@ class TypeObject extends Base {
|
||||
if (value === undefined) return null
|
||||
/* eslint-disable-next-line */
|
||||
if (typeof value !== this._type) return `${util.inspect(value, false, null)} type not ${this._type}`
|
||||
if (this._child !== null) {
|
||||
try {
|
||||
validate(value, this._child)
|
||||
} catch (err) {
|
||||
return err.message
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
+12
-1
@@ -1,5 +1,6 @@
|
||||
/* eslint-disable no-undef */
|
||||
const TypeObject = require('./object.js')
|
||||
const TypeString = require('./string.js')
|
||||
|
||||
describe('test validate type schema object', () => {
|
||||
function throwFunc (val) {
|
||||
@@ -11,9 +12,19 @@ describe('test validate type schema object', () => {
|
||||
it('test object type with required', async () => {
|
||||
const obj = new TypeObject().required()
|
||||
|
||||
obj.validate({})
|
||||
throwFunc(obj.validate({}))
|
||||
|
||||
expect(throwFunc(obj.validate(undefined))).toThrow()
|
||||
expect(throwFunc(obj.validate(false))).toThrow()
|
||||
})
|
||||
|
||||
it('test object type with child', async () => {
|
||||
const obj = new TypeObject({
|
||||
name: new TypeString()
|
||||
}).required()
|
||||
|
||||
throwFunc(obj.validate({ name: 'asd' }))
|
||||
|
||||
expect(throwFunc(obj.validate({ name: 123 }))).toThrow()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -11,6 +11,7 @@ class TypeString extends Base {
|
||||
this._max = null
|
||||
this._min = null
|
||||
this._empty = false
|
||||
this._regexp = null
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -43,6 +44,17 @@ class TypeString extends Base {
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* set test pattern with regexp
|
||||
* @param {RegExp} regexp
|
||||
*/
|
||||
pattern (regexp) {
|
||||
if (!(regexp instanceof RegExp)) throw new Error('input wrong')
|
||||
if (this._regexp !== null) throw new Error('regexp pattern already exist')
|
||||
this._regexp = regexp
|
||||
return this
|
||||
}
|
||||
|
||||
validate (value) {
|
||||
if (value === undefined && this._required) return `required`
|
||||
if (value === undefined) return null
|
||||
@@ -52,6 +64,7 @@ class TypeString extends Base {
|
||||
const len = value.length
|
||||
if (this._min !== null && len < this._min) return `value length < ${this._min}`
|
||||
if (this._max !== null && len > this._max) return `value length > ${this._max}`
|
||||
if (this._regexp !== null && !this._regexp.test(value)) return `value pattern not match ${this._regexp.toString()}`
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
+14
-6
@@ -10,24 +10,24 @@ describe('test validate type schema string', () => {
|
||||
|
||||
it('test string type without required', async () => {
|
||||
const str = new TypeString()
|
||||
str.validate(undefined)
|
||||
throwFunc(str.validate(undefined))
|
||||
})
|
||||
|
||||
it('test string type with required', async () => {
|
||||
const str = new TypeString().required()
|
||||
str.validate('123')
|
||||
throwFunc(str.validate('123'))
|
||||
|
||||
expect(throwFunc(str.validate(undefined))).toThrow()
|
||||
})
|
||||
|
||||
it('test string type with empty', async () => {
|
||||
const str = new TypeString().empty().required()
|
||||
str.validate('')
|
||||
throwFunc(str.validate(''))
|
||||
})
|
||||
|
||||
it('test string type without empty', async () => {
|
||||
const str = new TypeString().required()
|
||||
str.validate('asd')
|
||||
throwFunc(str.validate('asd'))
|
||||
|
||||
expect(throwFunc(str.validate(''))).toThrow()
|
||||
})
|
||||
@@ -39,7 +39,7 @@ describe('test validate type schema string', () => {
|
||||
expect(() => new TypeString().min(false)).toThrow()
|
||||
expect(() => new TypeString().max(2).min(3)).toThrow()
|
||||
|
||||
str.validate('asd')
|
||||
throwFunc(str.validate('asd'))
|
||||
|
||||
expect(throwFunc(str.validate('a'))).toThrow()
|
||||
})
|
||||
@@ -51,8 +51,16 @@ describe('test validate type schema string', () => {
|
||||
expect(() => new TypeString().max(false)).toThrow()
|
||||
expect(() => new TypeString().min(2).max(1)).toThrow()
|
||||
|
||||
str.validate('a')
|
||||
throwFunc(str.validate('a'))
|
||||
|
||||
expect(throwFunc(str.validate('asd'))).toThrow()
|
||||
})
|
||||
|
||||
it('test string type with pattern', async () => {
|
||||
const str = new TypeString().required().pattern(/^asd$/)
|
||||
|
||||
expect(throwFunc(str.validate('dsa'))).toThrow()
|
||||
|
||||
throwFunc(str.validate('asd'))
|
||||
})
|
||||
})
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
const BaseType = require('./types/base.js')
|
||||
|
||||
/**
|
||||
* validate
|
||||
* @param {Object} src
|
||||
* @param {import('./type.js').Schema} schema
|
||||
*/
|
||||
function validate (src, schema) {
|
||||
if (typeof src !== 'object' || typeof schema !== 'object') throw new Error('source or schema not object')
|
||||
for (const it in schema) {
|
||||
if (schema[it] instanceof BaseType) {
|
||||
const result = schema[it].validate(src[it])
|
||||
if (result) throw new Error(`field [${it}]: ${result}`)
|
||||
} else if (typeof schema[it] === 'object' && 'type' in schema[it] && schema[it].type instanceof BaseType) {
|
||||
const result = schema[it].type.validate(src[it])
|
||||
if (result) throw new Error(`field [${it}]: ${result}`)
|
||||
} else {
|
||||
throw new Error('not get any check schema type')
|
||||
}
|
||||
|
||||
if (typeof schema[it] === 'object' && 'children' in schema[it]) {
|
||||
validate(src[it], schema[it].children)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = validate
|
||||
@@ -23,4 +23,21 @@ describe('test validator validate', () => {
|
||||
|
||||
expect(() => validator.validate(data, schema)).toThrow()
|
||||
})
|
||||
|
||||
test('validate test 3', () => {
|
||||
const data = {
|
||||
str: '123',
|
||||
strWithPattern: 'asd',
|
||||
objWithChild: {
|
||||
name: 'asd'
|
||||
}
|
||||
}
|
||||
const schema = {
|
||||
str: validator.string().required(),
|
||||
strWithPattern: validator.string().pattern(/^asd$/).required(),
|
||||
objWithChild: validator.object({ name: validator.string().required() }).required()
|
||||
}
|
||||
|
||||
validator.validate(data, schema)
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user