推荐一个 Node.js 参数校验模块 - minijoi - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zurmokeeper
V2EX    Node.js

推荐一个 Node.js 参数校验模块 - minijoi

  •  
  •   zurmokeeper 2022-03-19 13:23:20 +08:00 7915 次点击
    这是一个创建于 1353 天前的主题,其中的信息可能已经有所发展或是发生改变。

    推荐一个 Node.js 参数校验模块 - minijoi

    初衷:

    由于在使用 Joi 的时候,校验时每次都要写模式规则 string.trim().required() 等等。由于参数校验是频繁且必须的,写的越来越多,代码既不好看,也不好维护,模式规则也不好记忆,并且 joi throw 的错误还需要单独去处理。所以对日常最常用的校验,封装了joi 的 API,并且可以在调用的时候同时传入自定义的 Error,使用 joi 友好的报错堆栈提示信息 同时 throw 我们自定义的Error, 无须再单独处理 joi 的 Error。所以就有了 miniJoi ,就是简单版的 joi

    欢迎提 IssuePR , 代码的测试用例在tests目录下,写好测试用例,执行命令为:

    pnpm run coverage(推荐) npm run coverage yarn run coverage 

    控制台会输出用例情况和代码覆盖率。开发者也可以对 miniJoi 进行二次开发,打造更符合自己应用模块。

    minijoi

    const miniJoi = require('minijoi'); miniJoi.requireAndNotEmptyForStr(value , options) options : { error : new Error("This is an Error") //公有 pattern : /^1[3456789]\d{9}$/ // email ID URL phone name mode : 'strict' //phone version : 'ipv6' //IP generation : 'first' //ID } 

    友好的堆栈提示,在 Joi 的基础上,报错的同时把要校验的参数类型也一起告诉给开发者,开发者可以清楚的看到输入的值和类型, _original 字段的值就是输入的值,如下:

    Error [ValidationError]: "value" is not allowed to be empty, But the type of the argument passed in is [String], Please check the value in the "_original" field. at Object.exports.process (D:\data\git\minijoi\node_modules\.pnpm\[email protected]\node_modules\joi\lib\errors.js:184:16) at Object.internals.entry (D:\data\git\minijoi\node_modules\.pnpm\[email protected]\node_modules\joi\lib\validator.js:150:26) at Object.exports.entry (D:\data\git\minijoi\node_modules\.pnpm\[email protected]\node_modules\joi\lib\validator.js:27:30) at internals.Base.validate (D:\data\git\minijoi\node_modules\.pnpm\[email protected]\node_modules\joi\lib\base.js:548:26) at validate (D:\data\git\minijoi\apply.js:12:37) at Object.requireAndNotEmptyForStr (D:\data\git\minijoi\apply.js:39:12) at Object.<anonymous> (D:\data\git\minijoi\test.js:101:7) at Module._compile (internal/modules/cjs/loader.js:1072:14) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1101:10) at Module.load (internal/modules/cjs/loader.js:937:32) { _original: '', details: [ { message: '"value" is not allowed to be empty, But the type of the argument passed in is [String], Please check the value in the "_original" field.', path: [], type: 'string.empty', context: { label: 'value', value: '' } } ] } 

    Node.js 版本要求:

    支持 Node.js V10,V12, V14, V16

    API 如下:

    开发者可自定义 Error ,调用 API 时传 error 参数就可以了,miniJoi 会自动抛出开发者自定义 Error ,默认输出上面的错误信息。

    字符串必填且非空

    miniJoi.requireAndNotEmptyForStr(value) miniJoi.requireAndNotEmptyForStr(value , {error : new Error("This is an Error")}) 

    字符串必填可以为空

    miniJoi.requireAndIsEmptyForStr(value) miniJoi.requireAndIsEmptyForStr(value , {error : new Error("This is an Error")}) 

    必填字符串枚举

    miniJoi.requireAndEnumForStr(value , ["test"]) miniJoi.requireAndEnumForStr(value , ["test","test1"] , {error : new Error("This is an Error")}) 

    必填字符串特定长度

    miniJoi.length(value , limit) miniJoi.length(value , limit , {error : new Error("This is an Error")}) 

    必填字符串最大长度

    miniJoi.max(value , limit) miniJoi.max(value , limit , {error : new Error("This is an Error")}) 

    必填字符串最小长度

    miniJoi.min(value , limit) miniJoi.min(value , limit , {error : new Error("This is an Error")}) 

    必填字符串中文姓名

    miniJoi.name(value ) miniJoi.name(value , {error : new Error("This is an Error")}) miniJoi.name(value , {pattern : xxxx}) 如 miniJoi 提供的中文姓名校验功能不符合开发者的要求,开发者可自定义传入正则表达式 

    必填字符串且合法邮箱

    miniJoi.requireEmail(value ) miniJoi.requireEmail(value , {error : new Error("This is an Error")}) 输入 pattern 字段,则使用 pattern miniJoi.requireEmail(value , { error : new Error("This is an Error"), pattern : /^1[3456789]\d{9}$/ }) 如 miniJoi 提供的邮箱校验功能不符合开发者的要求,开发者可自定义传入正则表达式 

    必填字符串且合法电话号码 mode 字段参考 anyrule

    miniJoi.requirePhone(value ) miniJoi.requirePhone(value , {error : new Error("This is an Error")}) 输入 pattern 字段,则使用 pattern mode 'strict'||'loose' strict 表示严谨 loose 表示宽松 默认为(最宽松), 只要是 1 开头即可 miniJoi.requirePhone(value , { error : new Error("This is an Error"), pattern : /^1[3456789]\d{9}$/ mode : 'strict' }) 如 miniJoi 提供的电话号码校验功能不符合开发者的要求,开发者可自定义传入正则表达式 

    必填字符串且合法 IP

    miniJoi.requireIP(value ) miniJoi.requireIP(value , {error : new Error("This is an Error")}) 输入 pattern 字段,则使用 pattern version 'ipv4'||'ipv6' ipv4 表示只校验 ipv4 ipv6 表示只校验 ipv6 默认同时校验 ipv4 和 ipv6 miniJoi.requireIP(value , { error : new Error("This is an Error"), version : 'ipv6' }) 如 miniJoi 提供的 IP 校验功能不符合开发者的要求,开发者可自定义传入正则表达式 

    必填字符串且合法 Url

    miniJoi.requireUrl(value ) miniJoi.requireUrl(value , {error : new Error("This is an Error")}) 输入 pattern 字段,则使用 pattern miniJoi.requireUrl(value , { error : new Error("This is an Error"), pattern : /^1[3456789]\d{9}$/ }) 如 miniJoi 提供的 Url 校验功能不符合开发者的要求,开发者可自定义传入正则表达式 

    必填字符串且合法身份证

    miniJoi.requireID(value ) miniJoi.requireID(value , {error : new Error("This is an Error")}) 输入 pattern 字段,则使用 pattern generation : "first" || "second" first 表示只校验一代身份证 second 表示只校验二代身份证 默认同时校验一代和二代 miniJoi.requireID(value , { error : new Error("This is an Error"), pattern : /^1[3456789]\d{9}$/ generation : "first" }) 如 miniJoi 提供的身份证校验功能不符合开发者的要求,开发者可自定义传入正则表达式 

    必填数字

    miniJoi.requireForNum(value) miniJoi.requireForNum(value , {error : new Error("This is an Error")}) 

    必填整数

    miniJoi.requireForInt(value) miniJoi.requireForInt(value , {error : new Error("This is an Error")}) 

    必填数字枚举

    miniJoi.requireAndEnumForNum(value) miniJoi.requireAndEnumForNum(value ,[1,2], {error : new Error("This is an Error")}) 

    必填数字小数位不大于 limit 位

    miniJoi.requireAndPrecision(value) miniJoi.requireAndPrecision(value , limit , {error : new Error("This is an Error")}) 2.2 PASS 2.22 PASS 2.222 FAIL 

    必填数字范围 API

    miniJoi.requireForRangeNum(value ,op, limit ) miniJoi.requireForRangeNum(value ,op, limit , {error : new Error("This is an Error")}) op 的值为 gt(>) || gte(>=) || lt(<) || lte(<=) 比如需要参数 > 0 , 则 miniJoi.requireForRangeNum(value ,"gt" , 0 ) 可代表正数 参数 >= 0 miniJoi.requireForRangeNum(value ,"gte" , 0 ) 参数 <= 0 miniJoi.requireForRangeNum(value ,"lte" , 0 ) 参数 < 0 miniJoi.requireForRangeNum(value ,"lt" , 0 ) 可代表负数 必填数字范围 API miniJoi.requireForRangeNum(value ,op, rangeArr ) miniJoi.requireForRangeNum(value ,op, rangeArr , {error : new Error("This is an Error")}) op 的值为 left-close-right-close `[0,100]` 简称 l-c-r-c left-close-right-open `[0,100)` 简称 l-c-r-o left-open-right-open `(0,100)` 简称 l-o-r-o left-open-right-close `(0,100]` 简称 l-o-r-c 比如需要参数 > 0 and <= 100 , 则 miniJoi.requireForRangeNum(value ,"left-open-right-close" , [0,100] ) miniJoi.requireForRangeNum(value ,"l-o-r-c" , [0,100] ) 比如需要参数 >= 0 and <= 100 , 则 miniJoi.requireForRangeNum(value ,"left-close-right-close" , [0,100] ) miniJoi.requireForRangeNum(value ,"l-c-r-c" , [0,100] ) 比如需要参数 > 0 and < 100 , 则 miniJoi.requireForRangeNum(value ,"left-open-right-open" , [0,100] ) miniJoi.requireForRangeNum(value ,"l-o-r-o" , [0,100] ) 比如需要参数 >= 0 and < 100 , 则 miniJoi.requireForRangeNum(value ,"left-close-right-open" , [0,100] ) miniJoi.requireForRangeNum(value ,"l-c-r-o" , [0,100] ) 

    必填整数范围 API

    miniJoi.requireForRangeInt(value ,op, limit ) miniJoi.requireForRangeInt(value ,op, limit , {error : new Error("This is an Error")}) op 的值为 gt(>) || gte(>=) || lt(<) || lte(<=) 比如需要参数 > 0 , 则 miniJoi.requireForRangeInt(value ,"gt" , 0 ) 可代表正整数 参数 >= 0 miniJoi.requireForRangeInt(value ,"gte" , 0 ) 参数 <= 0 miniJoi.requireForRangeInt(value ,"lte" , 0 ) 参数 < 0 miniJoi.requireForRangeInt(value ,"lt" , 0 ) 可代表负整数 必填整数范围 API miniJoi.requireForRangeInt(value ,op, rangeArr ) miniJoi.requireForRangeInt(value ,op, rangeArr , {error : new Error("This is an Error")}) 

    必填布尔

    miniJoi.requireForBool(value) miniJoi.requireForBool(value , {error : new Error("This is an Error")}) 

    数组必填且非空

    miniJoi.requireAndNotEmptyForArr(value) miniJoi.requireAndNotEmptyForArr(value , {error : new Error("This is an Error")}) 

    数组必填可以为空

    miniJoi.requireAndIsEmptyForArr(value) miniJoi.requireAndIsEmptyForArr(value , {error : new Error("This is an Error")}) 

    对象必填且非空

    miniJoi.requireAndNotEmptyForObj(value) miniJoi.requireAndNotEmptyForObj(value , {error : new Error("This is an Error")}) 

    对象必填可以为空

    miniJoi.requireAndIsEmptyForObj(value) miniJoi.requireAndIsEmptyForObj(value , {error : new Error("This is an Error")}) 
    2 条回复    2022-03-30 16:50:11 +08:00
    qfdk
        1
    qfdk  
    PRO
       2022-03-29 15:05:44 +08:00
    我们这里一直用的 https://express-validator.github.io/ 在 Express 里面非常好用, 中间件处理起来也舒服
    KouShuiYu
        2
    KouShuiYu  
       2022-03-30 16:50:11 +08:00
    还是喜欢用 json 配置,之前一直用 https://github.com/node-modules/parameter
    但是它没有使用 ts ,也缺乏维护我自己了一个 https://github.com/ckpack/parameter
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2298 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 15:57 PVG 23:57 LAX 07:57 JFK 10:57
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86