@gitlon/validate 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +350 -0
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
# @gitlon/validate
|
|
2
|
+
|
|
3
|
+
常用表单与业务校验函数。全部函数为独立命名导出,返回 `boolean`,不生成错误文案。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @gitlon/validate
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
也可安装聚合包:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pnpm add gitlon
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## 导入
|
|
18
|
+
|
|
19
|
+
直接使用子包:
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import {
|
|
23
|
+
isBankCard,
|
|
24
|
+
isChinese,
|
|
25
|
+
isDate,
|
|
26
|
+
isEmail,
|
|
27
|
+
isEmpty,
|
|
28
|
+
isEnglish,
|
|
29
|
+
isIdCard,
|
|
30
|
+
isInteger,
|
|
31
|
+
isNumber,
|
|
32
|
+
isPassword,
|
|
33
|
+
isPhone,
|
|
34
|
+
isPositiveNumber,
|
|
35
|
+
isUrl,
|
|
36
|
+
} from '@gitlon/validate'
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
通过主包使用:
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import { isEmail, isPassword, isPhone } from 'gitlon'
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## API 总览
|
|
46
|
+
|
|
47
|
+
| 函数 | 校验内容 |
|
|
48
|
+
| --- | --- |
|
|
49
|
+
| `isEmpty` | 空值、空白字符串、空数组、无可枚举属性对象 |
|
|
50
|
+
| `isNumber` | 有限数字或可转换为有限数字的值 |
|
|
51
|
+
| `isInteger` | 整数或整数字符串 |
|
|
52
|
+
| `isPositiveNumber` | 大于 0 的数字或数字字符串 |
|
|
53
|
+
| `isEmail` | 常用邮箱格式 |
|
|
54
|
+
| `isPhone` | 中国大陆 11 位手机号 |
|
|
55
|
+
| `isUrl` | 绝对 HTTP/HTTPS URL |
|
|
56
|
+
| `isIdCard` | 中国大陆 18 位身份证格式及校验码 |
|
|
57
|
+
| `isBankCard` | 12~19 位银行卡号及 Luhn 校验码 |
|
|
58
|
+
| `isDate` | JavaScript 可解析日期 |
|
|
59
|
+
| `isChinese` | 仅连续中文字符 |
|
|
60
|
+
| `isEnglish` | 仅连续英文字母 |
|
|
61
|
+
| `isPassword` | 可配置长度和字符要求的密码 |
|
|
62
|
+
|
|
63
|
+
所有函数签名均接收 `unknown`,便于直接校验表单值:
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
function isEmail(value: unknown): boolean
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## 空值
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
isEmpty(null) // true
|
|
73
|
+
isEmpty(undefined) // true
|
|
74
|
+
isEmpty('') // true
|
|
75
|
+
isEmpty(' ') // true
|
|
76
|
+
isEmpty([]) // true
|
|
77
|
+
isEmpty({}) // true
|
|
78
|
+
|
|
79
|
+
isEmpty(0) // false
|
|
80
|
+
isEmpty(false) // false
|
|
81
|
+
isEmpty([0]) // false
|
|
82
|
+
isEmpty({ id: 1 }) // false
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
function isEmpty(value: unknown): boolean
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
规则:
|
|
90
|
+
|
|
91
|
+
- 字符串先执行 `trim()`,再判断是否为空。
|
|
92
|
+
- 数组按 `length` 判断。
|
|
93
|
+
- 对象按自身可枚举属性数量判断。
|
|
94
|
+
- `Date`、`Map`、`Set` 等没有自身可枚举属性的对象会被视为空;该函数主要面向字符串、数组和普通对象。
|
|
95
|
+
|
|
96
|
+
## 数字
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
isNumber(12) // true
|
|
100
|
+
isNumber(-12.5) // true
|
|
101
|
+
isNumber('12.5') // true
|
|
102
|
+
isNumber('1e3') // true
|
|
103
|
+
|
|
104
|
+
isNumber('') // false
|
|
105
|
+
isNumber(' ') // false
|
|
106
|
+
isNumber('12px') // false
|
|
107
|
+
isNumber(NaN) // false
|
|
108
|
+
isNumber(Infinity) // false
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
function isNumber(value: unknown): boolean
|
|
113
|
+
function isInteger(value: unknown): boolean
|
|
114
|
+
function isPositiveNumber(value: unknown): boolean
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
整数和正数示例:
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
isInteger(12) // true
|
|
121
|
+
isInteger('12') // true
|
|
122
|
+
isInteger(12.5) // false
|
|
123
|
+
|
|
124
|
+
isPositiveNumber(1) // true
|
|
125
|
+
isPositiveNumber('1') // true
|
|
126
|
+
isPositiveNumber(0) // false
|
|
127
|
+
isPositiveNumber(-1) // false
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
`isPositiveNumber` 使用严格大于 `0` 的规则。
|
|
131
|
+
|
|
132
|
+
## 邮箱
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
isEmail('user@example.com') // true
|
|
136
|
+
isEmail('user+tag@test.cn') // true
|
|
137
|
+
|
|
138
|
+
isEmail('user@example') // false
|
|
139
|
+
isEmail('@example.com') // false
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
function isEmail(value: unknown): boolean
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
用于常见表单邮箱格式判断,不追求覆盖完整 RFC 邮箱语法。
|
|
147
|
+
|
|
148
|
+
## 手机号
|
|
149
|
+
|
|
150
|
+
```ts
|
|
151
|
+
isPhone('13812345678') // true
|
|
152
|
+
isPhone('19812345678') // true
|
|
153
|
+
|
|
154
|
+
isPhone('138 1234 5678') // false
|
|
155
|
+
isPhone('12812345678') // false
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
```ts
|
|
159
|
+
function isPhone(value: unknown): boolean
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
只接受未经分隔的中国大陆 11 位手机号,规则为 `1[3-9]xxxxxxxxx`。如需先清理和分组显示,使用 `@gitlon/format` 的 `formatPhone`。
|
|
163
|
+
|
|
164
|
+
## URL
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
isUrl('https://example.com') // true
|
|
168
|
+
isUrl('http://localhost:3000/a') // true
|
|
169
|
+
|
|
170
|
+
isUrl('ftp://example.com') // false
|
|
171
|
+
isUrl('/users/1') // false
|
|
172
|
+
isUrl('example.com') // false
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
```ts
|
|
176
|
+
function isUrl(value: unknown): boolean
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
只接受带 `http://` 或 `https://` 协议的绝对 URL。相对路径和其他协议返回 `false`。
|
|
180
|
+
|
|
181
|
+
## 身份证
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
isIdCard('11010519491231002X') // true
|
|
185
|
+
isIdCard('11010519491231002x') // true
|
|
186
|
+
|
|
187
|
+
isIdCard('110105194912310021') // false
|
|
188
|
+
isIdCard('110105491231002') // false
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
```ts
|
|
192
|
+
function isIdCard(value: unknown): boolean
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
校验:
|
|
196
|
+
|
|
197
|
+
- 18 位格式;
|
|
198
|
+
- 前 17 位为数字;
|
|
199
|
+
- 末位为数字或 `X`;
|
|
200
|
+
- 加权校验码。
|
|
201
|
+
|
|
202
|
+
不校验行政区划、出生日期是否真实存在,也不代表身份证真实有效。
|
|
203
|
+
|
|
204
|
+
## 银行卡
|
|
205
|
+
|
|
206
|
+
```ts
|
|
207
|
+
isBankCard('4111111111111111') // true
|
|
208
|
+
isBankCard('5555555555554444') // true
|
|
209
|
+
|
|
210
|
+
isBankCard('123456789012') // false
|
|
211
|
+
isBankCard('4111 1111 1111 1111') // false
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
```ts
|
|
215
|
+
function isBankCard(value: unknown): boolean
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
只接受 12~19 位纯数字,并执行 Luhn 校验。不识别发卡行,也不保证卡号真实存在。含空格或横线的展示值需先清理。
|
|
219
|
+
|
|
220
|
+
## 日期
|
|
221
|
+
|
|
222
|
+
```ts
|
|
223
|
+
isDate('2026-09-15') // true
|
|
224
|
+
isDate('2026-09-15T10:30:00') // true
|
|
225
|
+
isDate(new Date()) // true
|
|
226
|
+
isDate(Date.now()) // true
|
|
227
|
+
|
|
228
|
+
isDate('not-a-date') // false
|
|
229
|
+
isDate(null) // false
|
|
230
|
+
isDate('') // false
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
```ts
|
|
234
|
+
function isDate(value: unknown): boolean
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
字符串和数字交给原生 `Date` 解析。解析规则及结果可能受运行环境和时区影响;需要严格格式校验时,应在业务层明确格式后再判断。
|
|
238
|
+
|
|
239
|
+
## 中文与英文
|
|
240
|
+
|
|
241
|
+
```ts
|
|
242
|
+
isChinese('你好世界') // true
|
|
243
|
+
isChinese('你好 world') // false
|
|
244
|
+
isChinese('中文123') // false
|
|
245
|
+
|
|
246
|
+
isEnglish('Hello') // true
|
|
247
|
+
isEnglish('hello world') // false
|
|
248
|
+
isEnglish('hello123') // false
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
```ts
|
|
252
|
+
function isChinese(value: unknown): boolean
|
|
253
|
+
function isEnglish(value: unknown): boolean
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
- `isChinese` 只接受 `\u4e00`~`\u9fff` 范围内的连续字符。
|
|
257
|
+
- `isEnglish` 只接受 `A-Z`、`a-z` 连续字母。
|
|
258
|
+
- 空格、数字和标点均不通过。
|
|
259
|
+
|
|
260
|
+
## 密码
|
|
261
|
+
|
|
262
|
+
默认要求 6~20 位,同时包含字母和数字:
|
|
263
|
+
|
|
264
|
+
```ts
|
|
265
|
+
isPassword('Gitlon123') // true
|
|
266
|
+
isPassword('123456') // false:缺少字母
|
|
267
|
+
isPassword('abcdef') // false:缺少数字
|
|
268
|
+
isPassword('abc') // false:长度不足
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
自定义规则:
|
|
272
|
+
|
|
273
|
+
```ts
|
|
274
|
+
isPassword('Gitlon!123', {
|
|
275
|
+
minLength: 8,
|
|
276
|
+
maxLength: 30,
|
|
277
|
+
requireLetter: true,
|
|
278
|
+
requireNumber: true,
|
|
279
|
+
requireSpecial: true,
|
|
280
|
+
})
|
|
281
|
+
// true
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
```ts
|
|
285
|
+
interface PasswordValidateOptions {
|
|
286
|
+
minLength?: number
|
|
287
|
+
maxLength?: number
|
|
288
|
+
requireLetter?: boolean
|
|
289
|
+
requireNumber?: boolean
|
|
290
|
+
requireSpecial?: boolean
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
function isPassword(value: unknown, options?: PasswordValidateOptions): boolean
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
| 选项 | 默认值 | 说明 |
|
|
297
|
+
| --- | --- | --- |
|
|
298
|
+
| `minLength` | `6` | 最小长度 |
|
|
299
|
+
| `maxLength` | `20` | 最大长度 |
|
|
300
|
+
| `requireLetter` | `true` | 至少包含一个英文字母 |
|
|
301
|
+
| `requireNumber` | `true` | 至少包含一个数字 |
|
|
302
|
+
| `requireSpecial` | `false` | 至少包含一个非字母、非数字字符 |
|
|
303
|
+
|
|
304
|
+
不限制特殊字符集合,也不检查弱密码、连续字符、泄露密码或业务账号信息。
|
|
305
|
+
|
|
306
|
+
## 类型导入
|
|
307
|
+
|
|
308
|
+
```ts
|
|
309
|
+
import type { PasswordValidateOptions } from '@gitlon/validate'
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
使用聚合包时:
|
|
313
|
+
|
|
314
|
+
```ts
|
|
315
|
+
import type { PasswordValidateOptions } from 'gitlon'
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
## 表单示例
|
|
319
|
+
|
|
320
|
+
```ts
|
|
321
|
+
import { isEmail, isEmpty, isPassword, isPhone } from '@gitlon/validate'
|
|
322
|
+
|
|
323
|
+
interface RegisterForm {
|
|
324
|
+
email: string
|
|
325
|
+
password: string
|
|
326
|
+
phone: string
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
function validateRegister(form: RegisterForm): Record<string, string> {
|
|
330
|
+
const errors: Record<string, string> = {}
|
|
331
|
+
|
|
332
|
+
if (isEmpty(form.email)) {
|
|
333
|
+
errors.email = '请输入邮箱'
|
|
334
|
+
} else if (!isEmail(form.email)) {
|
|
335
|
+
errors.email = '邮箱格式错误'
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
if (!isPhone(form.phone)) {
|
|
339
|
+
errors.phone = '手机号格式错误'
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
if (!isPassword(form.password)) {
|
|
343
|
+
errors.password = '密码需为 6~20 位且包含字母和数字'
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
return errors
|
|
347
|
+
}
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
校验函数只判断当前值是否符合格式,不负责错误文案、异步请求、唯一性校验或真实性校验。
|