Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

check-data

Package Overview
Dependencies
Maintainers
1
Versions
75
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

check-data - npm Package Compare versions

Comparing version 4.1.0 to 4.1.1

lib/common.js

2

History.md

@@ -34,2 +34,4 @@ ## 版本更新

* 验证表达式中支持赋值全等表达式
* 新增严格模式Check.strict()方法

@@ -36,0 +38,0 @@

337

index.js
"use strict"
let filterNull = require('filter-null')
let Types = require('./lib/type')
let symbols = require('./lib/symbol')
let common = require('./lib/common')
let Types = require('./type')
let symbols = require('./symbol')
class Parser {

@@ -53,217 +53,253 @@

// 选项值为验证表达式
if (options.type) {
return this.Object(data, options, key)
// 优先使用别名
let field = options.name || key
}
// 空值处理
if (this.isNull(data, options.ignore)) {
// 选项值为数据类型(值为构造函数或字符串,字符串表示自定义类型)
else if (Types[options]) {
// 默认值
if (options.default) {
data = options.default
}
if (this.isNull(data)) {
// 严格模式下,禁止空值
if (this.mode === 'strict') {
return { error: "值不允许为空" }
}
return {}
}
// 禁止空值
else if (options.allowNull === false) {
return { error: `值不允许为空` }
}
let { error, data: subData } = Types[options].type({ data })
// 允许空值
else if (options.allowNull === true) {
return {}
}
if (error) {
return { error: `值${error}` }
} else {
return { data: subData }
}
// 严格模式下,禁止空值
else if (this.mode === 'strict') {
return { error: `值不允许为空` }
}
}
else {
return {}
}
// 选项值为严格匹配的精确值类型
else if (data === options) {
}
return { data }
let checks = Types[options.type]
}
// type为内置数据类型
if (checks) {
// 精确值匹配失败
else {
for (let name in options) {
let check = checks[name]
if (check) {
let option = options[name]
let { error, data: subData } = check({ data, option, origin: this.origin })
if (error) {
return {
error: `${error}`
}
}
data = subData
}
}
return { error: `值必须为${options}` }
return { data }
}
}
}
// 不支持的数据类型
else {
return {
error: `${field}参数配置错误,不支持${options.type}类型`
}
}
/**
* 验证表达式
* @param {*} data
* @param {*} options
* @param {*} key
*/
expression(data, options, key) {
// 优先使用别名
let field = options.name || key
// 空值处理
if (this.isNull(data, options.ignore)) {
// 默认值
if (options.default) {
data = options.default
}
// 选项值为数组结构
else if (Array.isArray(options)) {
// 禁止空值
else if (options.allowNull === false) {
return { error: `值不允许为空` }
}
if (!Array.isArray(data)) {
// 宽松模式下,跳过空值
if (this.mode === 'loose') {
if (this.isNull(data)) return {}
}
return {
error: `${key}必须为数组类型`
}
// 允许空值
else if (options.allowNull === true) {
return {}
}
}
// 严格模式下,禁止空值
else if (this.mode === 'strict') {
return { error: `值不允许为空` }
}
let dataArray = []
let itemKey = 0
else {
return {}
}
// options为单数时采用通用匹配
if (options.length === 1) {
}
let [option] = options
let checks = Types[options.type]
for (let itemData of data) {
// type为内置数据类型
if (checks) {
// 子集递归验证
let { error, data: subData } = this.recursion(itemData, option, itemKey)
if (error) {
return {
error: `[${itemKey}]${error}`
}
} else {
dataArray.push(subData)
for (let name in options) {
let check = checks[name]
if (check) {
let option = options[name]
let { error, data: subData } = check({ data, option, origin: this.origin })
if (error) {
return {
error: `${error}`
}
itemKey++
}
data = subData
}
}
// options为复数时采用精确匹配
else {
return { data }
for (let option of options) {
}
let itemData = data[itemKey]
// 不支持的数据类型
else {
return {
error: `${field}参数配置错误,不支持${options.type}类型`
}
}
// 子集递归验证
let { error, data: subData } = this.recursion(itemData, option, itemKey)
}
if (error) {
return {
error: `[${itemKey}]${error}`
}
} else {
dataArray.push(subData)
}
/**
* 对象结构
* @param {*} data
* @param {*} options
* @param {*} key
*/
Object(data, options, key) {
itemKey++
// 选项值为验证表达式
if (options.type) {
}
return this.expression(data, options, key)
}
}
return {
data: dataArray
}
// 选项值为数组结构
else if (Array.isArray(options)) {
}
return this.Array(data, options, key)
// 选项值为对象结构
else {
}
if (typeof data !== 'object') {
// 宽松模式下,跳过空值
if (this.mode === 'loose') {
if (this.isNull(data)) return {}
}
return {
error: `值必须为Object类型`
}
// 选项值为对象结构
else {
if (typeof data !== 'object') {
// 宽松模式下,跳过空值
if (this.mode === 'loose') {
if (this.isNull(data)) return {}
}
return {
error: `值必须为Object类型`
}
}
let dataObj = {}
let dataObj = {}
for (let subKey in options) {
for (let subKey in options) {
let itemData = data[subKey]
let itemOptions = options[subKey]
let { error, data: subData } = this.recursion(itemData, itemOptions, subKey)
let itemData = data[subKey]
let itemOptions = options[subKey]
let { error, data: subData } = this.recursion(itemData, itemOptions, subKey)
if (error) {
// 非根节点
if (key) {
return {
error: `.${subKey}${error}`
}
} else {
return {
error: `${subKey}${error}`
}
if (error) {
// 非根节点
if (key) {
return {
error: `.${subKey}${error}`
}
} else {
dataObj[subKey] = subData
return {
error: `${subKey}${error}`
}
}
} else {
dataObj[subKey] = subData
}
return { data: dataObj }
}
return { data: dataObj }
}
// 选项值为数据类型(值为构造函数或字符串,字符串表示自定义类型)
else if (Types[options]) {
}
if (this.isNull(data)) {
// 严格模式下,禁止空值
if (this.mode === 'strict') {
return { error: "值不允许为空" }
}
return {}
}
/**
* 数组结构
* @param {*} data
* @param {*} options
* @param {*} key
*/
Array(data, options, key) {
let { error, data: subData } = Types[options].type({ data })
if (error) {
return { error: `值${error}` }
} else {
return { data: subData }
if (!Array.isArray(data)) {
// 宽松模式下,跳过空值
if (this.mode === 'loose') {
if (this.isNull(data)) return {}
}
return {
error: `${key}必须为数组类型`
}
}
// 选项值为严格匹配的精确值类型
else if (data === options) {
let dataArray = []
let itemKey = 0
return { data }
// options为单数时采用通用匹配
if (options.length === 1) {
let [option] = options
for (let itemData of data) {
// 子集递归验证
let { error, data: subData } = this.recursion(itemData, option, itemKey)
if (error) {
return {
error: `[${itemKey}]${error}`
}
} else {
dataArray.push(subData)
}
itemKey++
}
}
// 精确值匹配失败
// options为复数时采用精确匹配
else {
return { error: `值必须为${options}` }
for (let option of options) {
let itemData = data[itemKey]
// 子集递归验证
let { error, data: subData } = this.recursion(itemData, option, itemKey)
if (error) {
return {
error: `[${itemKey}]${error}`
}
} else {
dataArray.push(subData)
}
itemKey++
}
}
return {
data: dataArray
}
}

@@ -350,2 +386,3 @@

Types[symbol] = options
Object.assign(Types[symbol], common)
}

@@ -352,0 +389,0 @@

{
"name": "check-data",
"version": "4.1.0",
"version": "4.1.1",
"description": "JS数据验证、转换递归器",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -0,1 +1,3 @@

功能强大JS数据模型验证、处理工具
### Install

@@ -7,8 +9,62 @@

### 使用方法
## 示例
check-data支持常规模式、严格模式、宽松模式,默认使用常规模式。
```js
let sample = {
"name": "test",
"num": "123456789987",
"ObjectId": "59c8aea808deec3fc8da56b6",
"files": ["abc.js", "null", "edb.js"],
"user": {
"username": "莉莉",
"age": 18,
"address": [
{ "city": "深圳" },
{ "city": "北京" }
],
},
"money": "2"
}
> 引入严格模式和宽松模式的主要目的是为了弥补验证表达式的设计缺陷,在数组、对象结构中使用子表达式时无法声明节点自身是否允许为空值。
let { mongoId, email } = Check.types
let { error, data } = Check(sample, {
"ObjectId": mongoId,
"name": String,
"email": email,
"num": String,
"files": [String],
"user": {
"username": "莉莉",
"age": Number,
"address": [
{ "city": String },
{ "city": "北京" }
],
},
"money": "2"
})
```
## 功能特性
* 采用全镜像数据模型设计,相比其它数据验证器拥有更好的数据结构表现能力和聚合能力。
* 支持对象和数组的无限嵌套,只管按你的数据结构去建模就好了,不必担心数据复杂度、层级深度的问题。
* 可以直接复制你的数据进行快速建模,只需要将值替换为类型后就得到了一个基础的验证模型,甚至有时候连值都不用不替换。
* check-data不仅仅只是数据验证器,同时还拥有很好的数据处理能力,可以在验证前、后灵活的对数据进行扩展。另外,基于js对象的树状结构使代码看起来高度类聚,大大降低了碎片化率。
* 拥有足够的容错能力,在验证期间你几乎不需要使用try/catch来捕获异常,返回值中的path错误定位信息可以帮助快速追踪错误来源。
* 当内置数据类型无法满足需求时,可以通过check.use()方法扩展自定义的数据类型。
## 验证模式
check-data支持常规、严格、宽松三种验证模式,多数情况下只需要使用常规模式即可。
引入严格模式和宽松模式的主要原因是为了弥补js对象结构自身的表达分歧,在数组、对象结构中包含子表达式时没有额外的结构来定义空值。
#### 常规模式

@@ -180,10 +236,2 @@

}
},
in({ data, option: arr }) {
let result = arr.indexOf(data)
if (result === -1) {
return { error: `值必须为${arr}中的一个` }
} else {
return { data }
}
}

@@ -262,3 +310,3 @@ })

let { error, data } = Check(sample, {
a: [{ "type": String }],
a: [String],
b: [{

@@ -265,0 +313,0 @@ "type": Number,

@@ -14,2 +14,17 @@ "use strict"

},
max({ data, option: max }) {
if (data > max) {
return { error: `不能大于${max}` }
} else {
return { data }
}
},
in({ data, option: arr }) {
let result = arr.indexOf(data)
if (result === -1) {
return { error: `值必须为${arr}中的一个` }
} else {
return { data }
}
}
})

@@ -29,11 +44,6 @@

"18955535547",
"13055655547",
"18655655512",
"15055655512"
],
"mobileArr2": [
"13055656647",
"18655655512",
"15055699512",
"15855155547"
"18655655512"
],

@@ -49,3 +59,6 @@ }

"type": int,
"allowNull": false
"allowNull": false,
set(value) {
return value * 2
}
},

@@ -58,11 +71,12 @@ "email": {

},
"mobileArr": [mobilePhone],
"mobileArr2": [
"mobileArr": [
mobilePhone,
"18655655512",
mobilePhone,
{
type: mobilePhone,
"type": mobilePhone,
"allowNull": false
}
],
"mobileArr2": [
mobilePhone,
"18655655512"
]

@@ -73,4 +87,11 @@ })

t.deepEqual(sample, data, error);
t.deepEqual({
id: '5687862c08d67e29cd000001',
age: 56,
email: 'erer@gmail.com',
mobile: '15855555547',
mobileArr: ['15855155547', '18955535547'],
mobileArr2: ['13055656647', '18655655512']
}, data, error);
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc