V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zurmokeeper
V2EX  ›  Node.js

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

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

    推荐一个 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  
       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   ·   实用小工具   ·   2986 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 00:16 · PVG 08:16 · LAX 16:16 · JFK 19:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.