npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

data-police

v1.5.1

Published

数据校验工具

Readme

简单示例

被校验的数据如下:

var data = {
  a: 1
}

校验规则a是一个大于0且小于20的整数,则校验描述如下:

var rule = {
  a: {
    $type: 'Number',
    $gt: 0, // 大于0
    $lt: 20, // 小于20
    $factor: 1, // 是1的整数倍
    $message: 'a是一个大于0且小于20的整数' // 校验不通过后的报错提示
  }
}

则校验代码如下:

import Validator from 'data-police'
const ruleValidator = new Validator(rule)
ruleValidator.check(data).then(d => {
  console.log(d)
}).catch(eMsg => {
  console.log(eMsg)
})

安装

npm install data-police --save

环境配置

  • 安装包为ES6源码,业务项目需要根据自己的环境进行编译。
  • 提供了对TypeScript的支持,内含.d.ts声明文件,使用者无需重复编写。

简单介绍

data-police 在语法设计上参考了mongodb的查询语法,恰巧与 JSON Schema又有几分神似。

  1. 不是一个完全的JSON语法,因为其中包含了JavaScript函数,所以校验规则是一个Javascript对象。
  2. 规则对象与被校验数据对象结构基本保持一致,不一致的点在规则对象中包含了描述符

校验规则

分两种情况

  1. 描述性校验,即被校验的数据节点是否符合描述符的含义,因描述符都是一个对象的key,所以包含描述符的对象,称为描述对象
  2. 相等性校验,如果规则节点key不是描述符,则做相等性比对。

描述符

描述符都是对象的key,且以$开头

逻辑符

$and: 需要满足所有规则,如$and: [4, 5, 6]表示这个节点的值要同时等于 4/5/6(☠️,显然不可能,仅为了介绍)。

$or: 需要满足所有规则,如$or: [4, 5, 6]表示这个节点的值等于4或等于5或等于6。

$if: 满足条件才做此项校验,如$if: [2, 3]表示如果这个节点值等于2,则校验它是否等于3(☠️,能感觉到你要崩溃)。

逻辑运算优先级:“向上结合,深度优先”是基本原则。举例说明:

{
  $gt: {
    $or: [
      {
        $or: [3, 4]
      },
      5
    ]
  }
}

如上代码示例:规则表述应是,(大于3或大于4)或大于5,而非大于((3或4)或5)

交换等价性,在“向上结合,深度优先”的基本原则下,以下两个规则rule1rule2描述是等价的,从代码复杂程度上看,rule1更简单些 。

const rule1 = {
  $gt: {
    $or: [3, 5]
  }
}
const rule2 = {
  $or: [
    {
      $gt: 3,
    },
    {
      $gt: 5
    }
  ]
}

校验符

$type: 校验数据类型,使用Object.prototype.toString.call(data).slice(8, -1)得到的类型值。 支持构造函数名,如字符串'Number'与构造函数Number等价,如果校验规则只有类型字段,支持缩写,如:

// 完成模式
{
  a: {
    $type: String
  }
}

// 缩写
{
  a: String
}

$value: 值等于。

$fn: 自定义函数。

数字类

$gt: 小于。$gt: 4,校验值是否小于4。

$gte: 小于等于。

$lt: 大于。

$lte: 大于等于。

$factor: 因数,可以是任意数字。$factor: 0.1表示该值是否是0.1的整数倍,可用于校验保留有效位数

字符串类

$isEmail: true/false。

$isTel: true/false。

$isUrl: true/false。

$isID: true/false,身份证号。

$pattern: 正则校验字符串。

$len: 字符串/数组的长度。

辅助符

$message: 用户校验未通过后的提示语。

$unique: 数组元素唯一校验标志,用户数组的每个元素都是用一样的校验规则。

~~$proxy: 代理子节点,用于指定路径校验模式下,由上层节点代理后端节点报错(暂未实现)。~~

添加自定义描述符

data-police允许用户根据自己的业务特点添加自定义的描述符,Validator类提供了3个静态方法用来添加以上3种类型的描述符,分别是 loadCheckOperatorsloadLogicOperatorsloadHelpOperators。使用姿势如下:

import Validator from 'data-police'
Validator.loadCheckOperators({
  $isUpper(rule, dataValue) {
    return /^\W+$/.test(dataValue)
  },
  // 与系统描述符重名,将会覆盖系统描述符。同时,自定义描述符也可以覆盖,后来居上。
  $gt(rule, dataValue) {
    return dataValue < rule
  }
})

描述符解析器是一个函数,入参如示例中所示,第一个是规则值,第二个是被校验数据值。 在自定义描述符的命名规则上,建议以$开头,与系统描述符保持一致,但并不会做强制要求。 调用时机,loadxxxxOperators方法可以重复多次调用,但针对某一描述符,必须在含有该描述符的规则实例化之前调用,否则会认为这只是一个普通key,而非描述符。

捷径

对于结构层级比较深的数据,提供使用路径的方式直达叶子节点,举例:

// 数据
{
  a: {
    a: {
      a: {
        a: 1
      }
    }
  }
}
// 正常规则,为了一个叶子节点,嵌套的令人发指
{
  a: {
    a: {
      a: {
        a: 1 // 相等性校验,是否等于1
      }
    }
  }
}
// 规则捷径
{
  '.a.a.a.a': 1 // 捷径key以.开头,作为捷径的标志,所以要求被校验的数据中key不可以以.开头
}

指定路径校验

举个表单数据校验的场景,表单一般后多个字段,既要能校验指定字段(填写中),又要能够校验整个表单(提交前),后者无需多言,针对前者提供了指定路径校验的方式。被校验的数据支持两种情况,举例如下:

  • 数据与规则是完全对应的
const rule = {
  a: 1,
  b: 2
}
const data = {
  a: 1,
  b: 2
}
// 数据与规则是对应的结构,校验过程是,根据路径找到对应的规则和对应的数据值进行比对。
validator.check(data, '.a', 'root')
  • 数据是该路径下的值
const rule = {
  a: 1,
  b: 2
}
const data = 1
// 数据即是在这个路径下的值,校验过程是,根据路径找到规则,与传入的值直接比对。
validator.check(data, '.a', 'branch')

对规则的描述

规则校验符不仅可以用来校验“被校验的数据”,而且可以校验“校验规则”。举例如下:

const rule = {
  $len: {
    $gt: 4
  }
}

含义是:字符串的长度小于4$gt被用来校验$len了。

并不是所有的校验规则都可以被校验符校验的,但所有可能被校验的规则都可以被校验,这句话有点拗口。举例说明:

// 含义,大于的数据类型是Number,这句话本身就读不通,所以$gt不可以被$type校验
{
  $gt: {
    $type: 'Number'
  }
}

// 含义,数据类型中要包含Num字符串,前文提到过数据类型中新增了一个特殊类型NumStr,那下边这个规则即可表示,数字和数字字符串。当然,也有其他表示方式。
{
  $type: {
    $pattern: /Num/
  }
}

那么,怎么区分哪些校验符可以被校验,哪些不可以呢?除了可能被校验的规则都可以被校验这条感性原则外,还有一条理性原则:可以得出固定值的校验规则都可以被校验,比如5的数据类型是固定值,那么$type就可以被校验,而5大于几就没有固定值,可以大于3可以大于2等等,$gt不能被校验。在感性原则与理性原则相冲突的情况下,都不会得到期望的校验结果。

约束模式

约束模式指的是,规则与被校验数据之间的字段对应关系,即数据是否可以比规则多或者少字段,举例如下:

const rule = {
  a: 1,
  b: 1
}
// 数据比规则少字段
const data1 = {
  a: 1
}
// 数据比规则多字段
const data2 = {
  a: 1,
  b: 1,
  c: 1
}

默认情况下,多或少字段,都会被忽略,即只校验相互匹配的字段,而通过校验。如果你的业务场景对这方面有特殊要求,可以通过传入check方法的第二个参数来设置。more: false会报错非法字段路径less: false会根据规则设置的$message信息报错。

rule.check(data, {
  more: false,
  less: false
})

健壮性

单元测试覆盖率90%左右,基本覆盖了所有情况。

202004ll01165407.jpg

篇后语

我对结构化校验规则的看法:先说优点,结构化更清晰,这表现在编写时的思路和阅读时的理解难度。缺点:受限于结构,有些极端逻辑编写并不方便且代码会累赘。