推薦一個Node.js引數校驗模組 - minijoi

神話發表於2021-12-18

推薦一個Node.js引數校驗模組 - minijoi

初衷:

由於在使用 Joi 的時候,校驗時每次都要寫模式規則 string.trim().required() 等等。由於引數校驗是頻繁且必須的,寫的越來越多,程式碼既不好看,也不好維護,模式規則也不好記憶,並且 joi throw 的錯誤還需要單獨去處理。所以對日常最常用的校驗,封裝了joi的API,並且可以在呼叫的時候同時傳入自定義的Error,使用 joi 友好的報錯堆疊提示資訊 同時 throw 我們自定義的Error, 無須再單獨處理 joi 的 Error。所以就有了 miniJoi ,就是簡單版的joi

歡迎提 Issue 和 PR , 程式碼的測試用例在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\joi@17.4.2\node_modules\joi\lib\errors.js:184:16)
    at Object.internals.entry (D:\data\git\minijoi\node_modules\.pnpm\joi@17.4.2\node_modules\joi\lib\validator.js:150:26)
    at Object.exports.entry (D:\data\git\minijoi\node_modules\.pnpm\joi@17.4.2\node_modules\joi\lib\validator.js:27:30)
    at internals.Base.validate (D:\data\git\minijoi\node_modules\.pnpm\joi@17.4.2\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")})

相關文章