Why?

在开发中,经常遇到数据校验,需要一个简单的,精准的优雅校验数据库对一些数据进行校验。

场景如下:

  • 配置文件校验
  • 与他人对接的数据校验
  • 接口参数的校验
  • and so on...

社区找了一遍,好像并没有我想要的,索性就自己写一个,撸起袖子就是干。

本文主要讲解如何使用,以及实现原理。

API预览

const Struct = require("@axetroy/struct");

const data = {
  name: "axetroy",
  age: 18
};

const struct = new Struct({
  name: Struct.type.string,
  age: Struct.type.int
});

const err = struct.validate(data);

console.log(err); // undefined, because the data pass the validator

实现原理

  1. 构造Struct对象,传入各字段的类型
  2. 类型定义使用Struct.type.xxx
  3. 调用struct.validate(data)进行校验

解析:

Struct.type返回的是 new Type(), 而Type对象的原型上,定义了一系列内置方法。

访问Struct.type.string其实就是访问了new Type().string, 会产生一个校验器,加入到type的队列里面,返回返回this,方便链式调用

在运行struct.validate(data)的时候,获取字段对应的Type, 然后逐一执行队列里面的函数,全部通过才算通过,返回undefined, 否则返回错误。

支持的类型

内置支持了int, float, string,等等。以及支持对象嵌套的校验,支持数组校验。

内置的不够? 那就来自定义吧

调用Struct.define(name, func), 在Type.prototype上添加相应的方法。

例如Struct.define("email", func),那么可以这么添加校验器Struct.type.email

一个字段可以有多个校验器(链式调用)

完整例子如下:

const Struct = require("../index");

Struct.define("email", function(input) {
  return /^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/.test(
    input
  );
});

const data = {
  name: "axetroy",
  age: 18,
  email: "xxx@axetroy.com"
};

const struct = truct({
  name: Struct.type.string,
  age: Struct.type.int,
  email: Struct.type.string.email // check string first, and then check email
});

const err = struct.validate(data);

console.log(err); // undefined, because the data pass the validator

你甚至可以定义一个带参数的类型校验, 这里有demo

最后

代码已经过测试,覆盖率接近100%,可放心食用

顺便弱弱的问一句,object.hasOwnProperty(key)分支的测试,为什么老是没有覆盖

欢迎大牛们来搞,issue or PR

https://github.com/axetroy/struct

原文地址: http://axetroy.xyz/#/post/136