2.1.7 • Published 3 years ago

super-inspector v2.1.7

Weekly downloads
13
License
MIT
Repository
github
Last release
3 years ago

Super Inspector

npm size license Coverage Status jslib

🔎🔎🔎 一个为开发动态和复杂表单而生的验证库,还为了你优雅的代码

特性

  1. 支持动态联合验证,通过声明依赖关系决定需要验证的值
  2. 支持定义通用错误类型
  3. 支持多层级嵌套验证器
  4. 支持异步验证
  5. 支持TypeScript

例子

可拷贝至本地并使用浏览器运行

Vue -> vue.example.html

React -> react.example.html

安装

$ npm install --save super-inspector

使用

导入

commonjs(Node.js)

var SuperInspector = require('super-inspector').default;

ES6 Module

import SuperInspector from 'super-inspector';

浏览器

<script src="https://unpkg.com/super-inspector/dist/super-inspector.umd.js"></script>

创建对象

在原config对象上修改

let sp = new SuperInspector(config => {
  // throwError为true时,验证失败将会抛出错误
  // throwError为false时,调用验证函数将返回验证结果(成功或失败)
  // 默认为false
  config.throwError = false;

  // 可自定义任意名称的通用错误集合
  // 具体使用见api介绍
  config.errors.falsy = (value, rule, key, extra, depValue) => {
    return key + ' is required but got empty';
  }

  // 当验证规则中required: true时,falsyValues数组中的值将被作为判断是否为空的参考值
  // 默认为[undefined, null]
  config.falsyValues.push('');

  // 如果验证失败,抛出或返回错误前将调用transformError钩子函数转换数据
  config.transformError = errors => {
    return errors.map(({ key, error }) => `[${key}]${error}`).join('\n');
  }
});

返回新的config对象

let sp = new SuperInspector(config => {
  return {
    errors: {
      falsy: '参数必填',
    },
    throwError: true,
  };
});

验证单个值

// 调用inspect将返回Promise对象
// 验证通过时,result的值为{code: 'ok', error: ''}
// 验证失败时,result的值为{code: 'fail', error: '错误信息'}
let result = await sp.inspect(1314520, Number);

批量验证多个值

// 调用batchInspect将返回Promise对象
let result = await sp.batchInspect({
  username: 'John123',
  password: 'qwertyu12',
}, {
  username: String,
  password: /^.{8,20}$/,
});

动态联合验证

// 以登录举例,当loginType的值为username时,username、password才会进行验证
// 当loginType的值为mobile时,mobileNumber和captcha才会进行验证
// 具体验证规则可查看api介绍
let result = await sp.batchInspect({
  loginType: 'username',
  username: 'John123',
  password: 'qwertyu12',

  mobileNumber: '',
  captcha: '',
}, {
  loginType: /^(username|mobile)$/,
  username: {
    // required默认为true,因此这边也可以省略
    required: true,
    validator: String,
    deps: {
      // 表示当loginType的值符合次正则表达式时,username值才会进行验证
      // 也可以设置多个依赖项,只要其中一项验证通过,该值会进行验证
      loginType: /^username$/
    },
  },
  password: {
    validator: /^.{8,20}$/,
    deps: {
      loginType: /^username$/
    }
  },
  mobileNumber: {
    validator: /^.{8,20}$/,
    deps: {
      loginType: /^mobile$/
    }
  },
  captcha: {
    validator: /[0-9]{6}/,
    deps: {
      loginType: /^mobile$/
    }
  },
});

自定义验证器

同步

// 自定义函数参数分别为:验证值、验证规则、验证key(调用只有batchInspect时才有值)、依赖项的值(验证规则声明了依赖项时才有值)
// 通过new Error抛出错误不会被验证库捕获,因此只能通过this.throw抛出抛出错误表示验证失败
// 不抛出错误表示验证通过
let result = await sp.inspect(
  '[1,2,3].join(",")',
  function(value, rule, key, depValue) {
    if (!value) {
      // 抛出自定义内容的错误(表示验证失败)
      this.throw(key + '的值不能为空');
    }
    else if (/<[a-zA-Z]{1,10}>/.test(value)) {
      // 抛出一个通用异常(创建对象时配置)表示验证失败
      this.throw.containHtmls();
    }
  }
);

异步

// 声明异步函数,也可以声明一个返回promise对象的普通函数
let result = await sp.inspect(
  'john@gmail.com',
  async function(value, rule, key, depValue) {
    let validRes = await fetch('https://host?email=' + value)
    .then(response => response.json());
    if (validRes.code !== 200) {
      this.throw('邮箱地址已被占用');
    }
  }
);

内置的验证器

数组验证器(验证数组项)

import { $Array } from 'super-inspector';
// 验证数组每项的值是否为图片(数组简单项)
let result1 = await sp.inspect([
  'https://img1.png',
  'https://img2.jpg'
], $Array(/(png|jpg|jpeg|webp)$/));

// 验证批量添加的人员信息(数组复杂项)
let result2 = await sp.inspect([
  { avatar: '', name: 'Ann', age: 24 },
  { avatar: 'https://avatar1.png', name: 'Tom', age: 26 },
], $Array({
  avatar: { required: false, validator: /^(png|jpg|jpeg|webp)$/ },
  name: String,
  age: Number
}));

对象验证器(验证对象值)

import { $Object } from 'super-inspector';
// 验证每个人的头像是否为图片(对象简单值)
let result1 = await sp.inspect({
  avatar_Ann: 'https://img1.png',
  avatar_Tom: 'https://img2.jpg'
}, $Object(/(png|jpg|jpeg|bmp|webp)$/));

// 验证每个人的位置是否正确(对象复杂值)
let reuslt2 = await sp.inspect({
  coordinate_Ann: { lat: 24.443729, lng: 118.128319 },
  coordinate_Ann: { lat: 32.827119, lng: 120.293013 },
}, $Object({
  lat: Number,
  lng: Number
}));

联合验证器(等价于"或")

import { $Union } from 'super-inspector';
// 满足$Union中其中一个验证规则可通过
let result1 = await sp.inspect(
  'https://img1.png',
  $Union(/png$/, /jpg$/, /jpeg$/, /webp$/)
);

// 与$Array嵌套使用
let res = await sp.inspect([
  'https://img1.png',
  'https://img2.jpg'
], $Array(
  $Union(/png$/, /jpg$/, /jpeg$/, /webp$/)
));

交叉验证器(等价于"与")

import { $Intersect } from 'super-inspector';
// 满足$Intersect中所有验证规则才可通过
let res = await sp.inspect('javascript', $Intersect(String, function(value) {
  if (value.length < 8) {
    this.throw('必须填写至少8个字符');
  }
}));

错误类型

针对错误信息的需求,super-inspector提供了3种错误类型 1. 多个表单项需要返回相同的错误信息时,在创建对象时定义若干个通用错误类型

// 创建验证对象
let sp = new SuperInspector(config => {
  // 固定错误使用字符串
  config.errors.containHtmls = '不能包含html标签';
  // 动态错误使用函数,函数必须返回字符串
  // extra为调用错误抛出函数时传入的额外数据
  config.errors.exceedLength10 = (value, rule, key, extra, depValue) => {
    return (rule.label || key) + '的长度不能超过10' + '(当前长度为' + value.length + ')';
  }
});

// 在自定义验证器中抛出通用错误
function customValidator(value) {
  if (value.length > 10) {
    this.throw.exceedLength10();
  }
}
  1. 自定义验证器中抛出任意的错误信息
function customerValidator() {
  this.throw('自定义的错误信息');
}
  1. 特定表单项需要返回特定的错误信息时,可在验证规则中指定替换的错误信息
// 当自定义验证器中抛出错误时,result内的信息会被替换为error字段中的信息
let result = await sp.inspect(
  '[1,2,3].join(",")',
  {
    error: '文本信息不能为空,且不能包含html标签信息',
    validator: function(value, rule, key, depValue) {
      if (!value) {
        // 抛出自定义内容的错误(表示验证失败)
        this.throw(key + '的值不能为空');
      }
      else if (/<[a-zA-Z]{1,10}>/.test(value)) {
        // 抛出一个通用异常(创建对象时配置)表示验证失败
        this.throw.containHtmls();
      }
    }
  }
);

导出参与验证的项

在动态表单中,我们通常需要将不参与验证的表单项隐藏,affectedItems函数将会告诉我们哪些表单项需要参与验证,哪些不需要

// result的值为{ loginType: true, username: true, password: true, mobileNumber: false, captcha: false }
// 我们可根据此数据隐藏值为false的表单项
let result = await sp.affectedItems({
  loginType: 'username',
  username: 'John123',
  password: 'qwertyu12',

  mobileNumber: '',
  captcha: '',
}, {
  loginType: /^(username|mobile)$/,
  username: {
    // required默认为true,因此这边也可以省略
    required: true,
    validator: String,
    deps: {
      // 表示当loginType的值符合次正则表达式时,username值才会进行验证
      // 也可以设置多个依赖项,只要其中一项验证通过,该值会进行验证
      loginType: /^username$/
    },
  },
  password: {
    validator: /^.{8,20}$/,
    deps: {
      loginType: /^username$/
    }
  },
  mobileNumber: {
    validator: /^.{8,20}$/,
    deps: {
      loginType: /^mobile$/
    }
  },
  captcha: {
    validator: /[0-9]{6}/,
    deps: {
      loginType: /^mobile$/
    }
  },
});

APIs

点此查看API文档

后项

2.1.6

3 years ago

2.1.5

3 years ago

2.1.7

3 years ago

2.1.2

3 years ago

2.1.1

3 years ago

2.1.3

3 years ago

2.1.0

3 years ago

2.0.3

3 years ago

2.0.1

3 years ago

2.0.0

3 years ago

1.0.2

4 years ago

1.0.1

4 years ago

1.0.0

4 years ago

0.2.2

4 years ago

1.2.2

4 years ago

0.2.1

4 years ago

0.1.1

4 years ago

0.1.0

4 years ago