ts-modelcheck
数据模型校验
Install
yarn add ts-modelcheck
Usage
import Model from 'ts-modelcheck';
const data = {
foo: 'bar',
};
const descriptor = {
type: Object,
fields: {
foo: {
type: String,
},
},
};
const model = new Model(data, descriptor);
model.validate().then(() => {
// 根据descriptor构建新的数据结构
const newData = model.buildPlainData();
console.log(newData);
}).catch((err) => {
console.error(err);
});
Constructor
new Model(<data>, <descriptor>, [option]);
Descripotor
export type ModelCheckMessageFieldValueFnType = (
value: any,
key: PropertyKey,
ctx: Model,
) => string;
export type ModelCheckMessageFieldValueType = string
| Error
| ModelCheckMessageFieldValueFnType;
export type ModelCheckMessageObjectType = {
default?: ModelCheckMessageFieldValueType;
type?: ModelCheckMessageFieldValueType;
exist?: ModelCheckMessageFieldValueType;
required?: ModelCheckMessageFieldValueType;
transformer?: ModelCheckMessageFieldValueType;
validator?: ModelCheckMessageFieldValueType;
};
export type ModelCheckMessageType = ModelCheckMessageFieldValueType
| ModelCheckMessageObjectType;
export type ModelCheckMessageFieldType = 'type' | 'exist' | 'required' | 'transformer' | 'validator';
export interface ModelCheckDescriptor {
// 数据类型。例如 Number 或 [Number, String]。甚至某个具体的值,例如 ['foo']
type?: any,
// 属性是否存在。默认true
exist?: boolean | ((value: any, key: PropertyKey, ctx: Model) => boolean);
// 是否必需。空数组,空字符串,null,undefined,空字符都视为无效数据
required?: boolean | ((value: any, key: PropertyKey, ctx: Model) => boolean);
// 错误提示信息
// 错误信息可使用 `$(value)` 指代数据,`$(key)` 指代属性名
// 例如:message: '$(value) not passed the validator at $(key)'
message?: ModelCheckMessageType;
// 转换值
transformer?: (value: any, key: PropertyKey, ctx: Model) => any;
// 转换后的校验
validator?: (value: any, key: PropertyKey, ctx: Model) => boolean | Error;
// 子字段
fields?: Record<string, ModelCheckDescriptor | null>
| ((value: any, key: PropertyKey, ctx: Model) => ModelCheckDescriptor | null);
}
Option
export interface ModelCheckOption {
// 当有一个校验失败时,后续的校验不再执行
abortRestValidatesWhenErrorOccured?: boolean;
// 自定义获取对象键名的方法
getObjectKeys?: (obj: any) => PropertyKey[];
// 获取键名的范围
// names: 所有可遍历属性,不包含 symbol 属性
// enumerable: 所有可遍历属性。包含 symbol 属性
keysRange?: 'names' | 'enumerable';
// 是否只处理descriptor中声明的字段。这在构建一个新的数据时很有用,可以排除掉不相关的数据字段
pure?: boolean;
}
Static Properties
DefaultOption
默认配置
static DefaultOption: ModelCheckOption = {
abortRestValidatesWhenErrorOccured: true,
keysRange: 'names',
pure: false,
};
Properties
descriptor
- type:
ModelCheckDescriptor
rawData
- type:
any
data
可能是已被transformer转换后的数据
- type:
any
key
当前属性名。$root
代表最顶级的节点
- type:
PropertyKey
- default:
$root
keyPath
属性路径,不包含当前键名
- type:
PropertyKey[]
option
- type:
ModelCheckOption
validateFailedMessages
当前属性校验失败的信息
- type:
Array<{ type: ModelCheckMessageFieldType; message: string; err?: Error; }>
$fields
子字段数据
- type:
Model[]
fieldsSetted
- type:
boolean
$host
父级数据。$host为null表示已经是最顶级的节点了
- type:
Model | null
$root
根节点
- type:
Model
- default:
this
exist
属性是否存在。默认null,则意味着尚未进行 checkExist 判断
- type:
null | boolean
validated
- type:
boolean
prune
如果 option.pure 为true,则在构建数据时此field会被剪掉
- type:
boolean
getObjectKeys
获取键名的方法。一般为 Object.keys
- type:
(obj: any) => PropertyKey[]
Methods
validate
进行数据校验,如果校验失败则会抛出错误
- 返回值:
Promise\<unknown\>
buildPlainData
根据descrptor返回一个新的数据,请在validate
成功后再调用。这在发送数据给服务器时很有用,可以过滤掉无关数据
- 参数
- prune
- type: boolean 是否剪掉不在descriptor中定义的字段
- prune
getValidateFailedMessages
获取校验失败的信息
- 返回值:ModelCheckErrors
export type ModelCheckErrors = Array<{
field: PropertyKey;
errors: Array<{
type: ModelCheckMessageFieldType;
message: string;
err?: Error;
}>;
fields: ModelCheckErrors;
}>
clearValidates
清除校验数据
clearFields
清除子级字段数据
Test
更多用法可查看__tests__
目录下的测试用例
yarn test
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 98.84 | 89.84 | 100 | 98.84 |
index.js | 98.84 | 89.84 | 100 | 98.84 | 19-21,166-167,193
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 121 passed, 121 total
说明
- 代码使用
esbuild
构建。如果需要支持es5
请在使用的项目中配置babel
进行转译 - 请自行提供
polyfill
来支持Promise
,Set
,...
等新特性
参与贡献
- Fork 本仓库
- 新建 Feat_xxx 分支
- 提交代码
- 新建 Pull Request