@hy_ong/zod-kit 0.1.2 → 0.1.4
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/dist/index.cjs +485 -267
- package/dist/index.d.cts +107 -106
- package/dist/index.d.ts +107 -106
- package/dist/index.js +479 -261
- package/package.json +1 -1
- package/src/validators/common/date.ts +26 -16
- package/src/validators/common/datetime.ts +46 -28
- package/src/validators/common/email.ts +57 -15
- package/src/validators/common/id.ts +40 -26
- package/src/validators/common/number.ts +80 -43
- package/src/validators/common/password.ts +30 -18
- package/src/validators/common/text.ts +48 -14
- package/src/validators/common/time.ts +34 -22
- package/src/validators/common/url.ts +40 -23
- package/src/validators/taiwan/business-id.ts +24 -28
- package/src/validators/taiwan/fax.ts +29 -28
- package/src/validators/taiwan/mobile.ts +29 -28
- package/src/validators/taiwan/national-id.ts +27 -27
- package/src/validators/taiwan/postal-code.ts +51 -45
- package/src/validators/taiwan/tel.ts +29 -28
- package/tests/taiwan/business-id.test.ts +23 -23
- package/tests/taiwan/fax.test.ts +34 -34
- package/tests/taiwan/mobile.test.ts +33 -33
- package/tests/taiwan/national-id.test.ts +32 -32
- package/tests/taiwan/postal-code.test.ts +62 -62
- package/tests/taiwan/tel.test.ts +34 -34
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { describe, it, expect, beforeEach } from "vitest"
|
|
2
|
-
import {
|
|
2
|
+
import { twMobile, setLocale, validateTaiwanMobile } from "../../src"
|
|
3
3
|
|
|
4
|
-
describe("Taiwan
|
|
4
|
+
describe("Taiwan twMobile(true) validator", () => {
|
|
5
5
|
beforeEach(() => setLocale("en"))
|
|
6
6
|
|
|
7
7
|
describe("basic functionality", () => {
|
|
8
8
|
it("should validate correct Taiwan mobile phone numbers", () => {
|
|
9
|
-
const schema =
|
|
9
|
+
const schema = twMobile(true)
|
|
10
10
|
|
|
11
11
|
// Valid Taiwan mobile phone numbers
|
|
12
12
|
expect(schema.parse("0901234567")).toBe("0901234567")
|
|
@@ -22,7 +22,7 @@ describe("Taiwan mobile(true) validator", () => {
|
|
|
22
22
|
})
|
|
23
23
|
|
|
24
24
|
it("should reject invalid Taiwan mobile phone numbers", () => {
|
|
25
|
-
const schema =
|
|
25
|
+
const schema = twMobile(true)
|
|
26
26
|
|
|
27
27
|
// Invalid formats
|
|
28
28
|
expect(() => schema.parse("123456789")).toThrow("Invalid Taiwan mobile phone format") // Missing leading 09
|
|
@@ -36,7 +36,7 @@ describe("Taiwan mobile(true) validator", () => {
|
|
|
36
36
|
})
|
|
37
37
|
|
|
38
38
|
it("should handle whitespace trimming", () => {
|
|
39
|
-
const schema =
|
|
39
|
+
const schema = twMobile(true)
|
|
40
40
|
|
|
41
41
|
expect(schema.parse(" 0901234567 ")).toBe("0901234567")
|
|
42
42
|
expect(schema.parse("\t0911234567\n")).toBe("0911234567")
|
|
@@ -45,7 +45,7 @@ describe("Taiwan mobile(true) validator", () => {
|
|
|
45
45
|
|
|
46
46
|
describe("whitelist functionality", () => {
|
|
47
47
|
it("should accept any string in whitelist regardless of format", () => {
|
|
48
|
-
const schema =
|
|
48
|
+
const schema = twMobile(true, {
|
|
49
49
|
whitelist: ["custom-phone", "emergency-contact", "0801234567"],
|
|
50
50
|
})
|
|
51
51
|
|
|
@@ -60,7 +60,7 @@ describe("Taiwan mobile(true) validator", () => {
|
|
|
60
60
|
})
|
|
61
61
|
|
|
62
62
|
it("should reject values not in whitelist when whitelist is provided", () => {
|
|
63
|
-
const schema =
|
|
63
|
+
const schema = twMobile(true, {
|
|
64
64
|
whitelist: ["allowed-value", "0901234567"],
|
|
65
65
|
})
|
|
66
66
|
|
|
@@ -69,7 +69,7 @@ describe("Taiwan mobile(true) validator", () => {
|
|
|
69
69
|
})
|
|
70
70
|
|
|
71
71
|
it("should work with empty whitelist", () => {
|
|
72
|
-
const schema =
|
|
72
|
+
const schema = twMobile(true, {
|
|
73
73
|
whitelist: [],
|
|
74
74
|
})
|
|
75
75
|
|
|
@@ -79,7 +79,7 @@ describe("Taiwan mobile(true) validator", () => {
|
|
|
79
79
|
})
|
|
80
80
|
|
|
81
81
|
it("should prioritize whitelist over format validation", () => {
|
|
82
|
-
const schema =
|
|
82
|
+
const schema = twMobile(false, { whitelist: ["not-a-phone", "123", ""] })
|
|
83
83
|
|
|
84
84
|
// These should be accepted despite being invalid mobile phone formats
|
|
85
85
|
expect(schema.parse("not-a-phone")).toBe("not-a-phone")
|
|
@@ -90,7 +90,7 @@ describe("Taiwan mobile(true) validator", () => {
|
|
|
90
90
|
|
|
91
91
|
describe("required/optional behavior", () => {
|
|
92
92
|
it("should handle required=true (default)", () => {
|
|
93
|
-
const schema =
|
|
93
|
+
const schema = twMobile(true)
|
|
94
94
|
|
|
95
95
|
expect(() => schema.parse("")).toThrow("Required")
|
|
96
96
|
expect(() => schema.parse(null)).toThrow()
|
|
@@ -98,7 +98,7 @@ describe("Taiwan mobile(true) validator", () => {
|
|
|
98
98
|
})
|
|
99
99
|
|
|
100
100
|
it("should handle required=false", () => {
|
|
101
|
-
const schema =
|
|
101
|
+
const schema = twMobile(false)
|
|
102
102
|
|
|
103
103
|
expect(schema.parse("")).toBe(null)
|
|
104
104
|
expect(schema.parse(null)).toBe(null)
|
|
@@ -107,15 +107,15 @@ describe("Taiwan mobile(true) validator", () => {
|
|
|
107
107
|
})
|
|
108
108
|
|
|
109
109
|
it("should use default values", () => {
|
|
110
|
-
const requiredSchema =
|
|
111
|
-
const optionalSchema =
|
|
110
|
+
const requiredSchema = twMobile(true, { defaultValue: "0901234567" })
|
|
111
|
+
const optionalSchema = twMobile(false, { defaultValue: "0901234567" })
|
|
112
112
|
|
|
113
113
|
expect(requiredSchema.parse("")).toBe("0901234567")
|
|
114
114
|
expect(optionalSchema.parse("")).toBe("0901234567")
|
|
115
115
|
})
|
|
116
116
|
|
|
117
117
|
it("should handle whitelist with optional fields", () => {
|
|
118
|
-
const schema =
|
|
118
|
+
const schema = twMobile(false, { whitelist: ["custom-value", "0901234567"] })
|
|
119
119
|
|
|
120
120
|
expect(schema.parse("")).toBe(null)
|
|
121
121
|
expect(schema.parse("custom-value")).toBe("custom-value")
|
|
@@ -126,7 +126,7 @@ describe("Taiwan mobile(true) validator", () => {
|
|
|
126
126
|
|
|
127
127
|
describe("transform function", () => {
|
|
128
128
|
it("should apply custom transform", () => {
|
|
129
|
-
const schema =
|
|
129
|
+
const schema = twMobile(true, {
|
|
130
130
|
transform: (val) => val.replace(/[-\s]/g, ""),
|
|
131
131
|
})
|
|
132
132
|
|
|
@@ -135,7 +135,7 @@ describe("Taiwan mobile(true) validator", () => {
|
|
|
135
135
|
})
|
|
136
136
|
|
|
137
137
|
it("should apply transform before validation", () => {
|
|
138
|
-
const schema =
|
|
138
|
+
const schema = twMobile(true, {
|
|
139
139
|
transform: (val) => val.replace(/\s+/g, ""),
|
|
140
140
|
})
|
|
141
141
|
|
|
@@ -145,13 +145,13 @@ describe("Taiwan mobile(true) validator", () => {
|
|
|
145
145
|
|
|
146
146
|
it("should work with whitelist after transform", () => {
|
|
147
147
|
// First test basic transform without allowlist
|
|
148
|
-
const basicSchema =
|
|
148
|
+
const basicSchema = twMobile(true, {
|
|
149
149
|
transform: (val) => val.replace(/[-\s]/g, ""),
|
|
150
150
|
})
|
|
151
151
|
expect(basicSchema.parse("090-123-4567")).toBe("0901234567")
|
|
152
152
|
|
|
153
153
|
// Then test with whitelist - use simple value that transforms won't affect
|
|
154
|
-
const whitelistSchema =
|
|
154
|
+
const whitelistSchema = twMobile(true, {
|
|
155
155
|
transform: (val) => val.replace(/[-\s]/g, ""),
|
|
156
156
|
whitelist: ["0901234567", "customvalue"],
|
|
157
157
|
})
|
|
@@ -163,14 +163,14 @@ describe("Taiwan mobile(true) validator", () => {
|
|
|
163
163
|
|
|
164
164
|
describe("input preprocessing", () => {
|
|
165
165
|
it("should handle string conversion", () => {
|
|
166
|
-
const schema =
|
|
166
|
+
const schema = twMobile(true)
|
|
167
167
|
|
|
168
168
|
// Test string conversion of numbers
|
|
169
169
|
expect(() => schema.parse(901234567)).toThrow("Invalid Taiwan mobile phone format") // Invalid because missing leading 0
|
|
170
170
|
})
|
|
171
171
|
|
|
172
172
|
it("should trim whitespace", () => {
|
|
173
|
-
const schema =
|
|
173
|
+
const schema = twMobile(true)
|
|
174
174
|
|
|
175
175
|
expect(schema.parse(" 0901234567 ")).toBe("0901234567")
|
|
176
176
|
expect(schema.parse("\t0911234567\n")).toBe("0911234567")
|
|
@@ -207,7 +207,7 @@ describe("Taiwan mobile(true) validator", () => {
|
|
|
207
207
|
describe("i18n support", () => {
|
|
208
208
|
it("should use English messages by default", () => {
|
|
209
209
|
setLocale("en")
|
|
210
|
-
const schema =
|
|
210
|
+
const schema = twMobile(true)
|
|
211
211
|
|
|
212
212
|
expect(() => schema.parse("")).toThrow("Required")
|
|
213
213
|
expect(() => schema.parse("0801234567")).toThrow("Invalid Taiwan mobile phone format")
|
|
@@ -215,7 +215,7 @@ describe("Taiwan mobile(true) validator", () => {
|
|
|
215
215
|
|
|
216
216
|
it("should use Chinese messages when locale is zh-TW", () => {
|
|
217
217
|
setLocale("zh-TW")
|
|
218
|
-
const schema =
|
|
218
|
+
const schema = twMobile(true)
|
|
219
219
|
|
|
220
220
|
expect(() => schema.parse("")).toThrow("必填")
|
|
221
221
|
expect(() => schema.parse("0801234567")).toThrow("無效的手機號碼格式")
|
|
@@ -223,7 +223,7 @@ describe("Taiwan mobile(true) validator", () => {
|
|
|
223
223
|
|
|
224
224
|
it("should support whitelist error messages", () => {
|
|
225
225
|
setLocale("en")
|
|
226
|
-
const schema =
|
|
226
|
+
const schema = twMobile(true, {
|
|
227
227
|
whitelist: ["0901234567"],
|
|
228
228
|
})
|
|
229
229
|
|
|
@@ -234,7 +234,7 @@ describe("Taiwan mobile(true) validator", () => {
|
|
|
234
234
|
})
|
|
235
235
|
|
|
236
236
|
it("should support custom i18n messages", () => {
|
|
237
|
-
const schema =
|
|
237
|
+
const schema = twMobile(true, {
|
|
238
238
|
i18n: {
|
|
239
239
|
en: {
|
|
240
240
|
required: "Mobile phone is required",
|
|
@@ -259,7 +259,7 @@ describe("Taiwan mobile(true) validator", () => {
|
|
|
259
259
|
})
|
|
260
260
|
|
|
261
261
|
it("should support custom whitelist messages", () => {
|
|
262
|
-
const schema =
|
|
262
|
+
const schema = twMobile(true, {
|
|
263
263
|
whitelist: ["0901234567"],
|
|
264
264
|
i18n: {
|
|
265
265
|
en: {
|
|
@@ -281,7 +281,7 @@ describe("Taiwan mobile(true) validator", () => {
|
|
|
281
281
|
|
|
282
282
|
describe("real world Taiwan mobile phone numbers", () => {
|
|
283
283
|
it("should validate all carrier prefixes", () => {
|
|
284
|
-
const schema =
|
|
284
|
+
const schema = twMobile(true)
|
|
285
285
|
|
|
286
286
|
// Test all valid Taiwan mobile prefixes (090-099)
|
|
287
287
|
const validPrefixes = ["090", "091", "092", "093", "094", "095", "096", "097", "098", "099"]
|
|
@@ -293,7 +293,7 @@ describe("Taiwan mobile(true) validator", () => {
|
|
|
293
293
|
})
|
|
294
294
|
|
|
295
295
|
it("should reject non-mobile phone prefixes", () => {
|
|
296
|
-
const schema =
|
|
296
|
+
const schema = twMobile(true)
|
|
297
297
|
|
|
298
298
|
// Test invalid prefixes
|
|
299
299
|
const invalidPrefixes = ["080", "081", "082", "083", "084", "085", "086", "087", "088", "089"]
|
|
@@ -305,7 +305,7 @@ describe("Taiwan mobile(true) validator", () => {
|
|
|
305
305
|
})
|
|
306
306
|
|
|
307
307
|
it("should validate realistic phone number patterns", () => {
|
|
308
|
-
const schema =
|
|
308
|
+
const schema = twMobile(true)
|
|
309
309
|
|
|
310
310
|
const realPhoneNumbers = ["0901234567", "0912345678", "0923456789", "0934567890", "0945678901", "0956789012", "0967890123", "0978901234", "0989012345", "0990123456"]
|
|
311
311
|
|
|
@@ -317,15 +317,15 @@ describe("Taiwan mobile(true) validator", () => {
|
|
|
317
317
|
|
|
318
318
|
describe("edge cases", () => {
|
|
319
319
|
it("should handle various input types", () => {
|
|
320
|
-
const schema =
|
|
320
|
+
const schema = twMobile(true)
|
|
321
321
|
|
|
322
322
|
// Test different input types that should be converted to string
|
|
323
323
|
expect(schema.parse("0901234567")).toBe("0901234567")
|
|
324
324
|
})
|
|
325
325
|
|
|
326
326
|
it("should handle empty and whitespace inputs", () => {
|
|
327
|
-
const schema =
|
|
328
|
-
const optionalSchema =
|
|
327
|
+
const schema = twMobile(true)
|
|
328
|
+
const optionalSchema = twMobile(false)
|
|
329
329
|
|
|
330
330
|
expect(() => schema.parse("")).toThrow("Required")
|
|
331
331
|
expect(() => schema.parse(" ")).toThrow("Required")
|
|
@@ -337,7 +337,7 @@ describe("Taiwan mobile(true) validator", () => {
|
|
|
337
337
|
})
|
|
338
338
|
|
|
339
339
|
it("should preserve valid format after transformation", () => {
|
|
340
|
-
const schema =
|
|
340
|
+
const schema = twMobile(true, {
|
|
341
341
|
transform: (val) => val.replace(/[^0-9]/g, ""),
|
|
342
342
|
})
|
|
343
343
|
|
|
@@ -348,7 +348,7 @@ describe("Taiwan mobile(true) validator", () => {
|
|
|
348
348
|
})
|
|
349
349
|
|
|
350
350
|
it("should work with complex whitelist scenarios", () => {
|
|
351
|
-
const schema =
|
|
351
|
+
const schema = twMobile(false, { whitelist: ["0901234567", "emergency", "custom-contact-123", ""] })
|
|
352
352
|
|
|
353
353
|
// Allowlist scenarios
|
|
354
354
|
expect(schema.parse("0901234567")).toBe("0901234567")
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { describe, it, expect, beforeEach } from "vitest"
|
|
2
|
-
import {
|
|
2
|
+
import { twNationalId, setLocale, validateTaiwanNationalId, validateCitizenId, validateOldResidentId, validateNewResidentId } from "../../src"
|
|
3
3
|
|
|
4
|
-
describe("Taiwan
|
|
4
|
+
describe("Taiwan twNationalId(true) validator", () => {
|
|
5
5
|
beforeEach(() => setLocale("en"))
|
|
6
6
|
|
|
7
7
|
describe("basic functionality", () => {
|
|
8
8
|
it("should validate correct Taiwan national IDs (both types)", () => {
|
|
9
|
-
const schema =
|
|
9
|
+
const schema = twNationalId(true)
|
|
10
10
|
|
|
11
11
|
// Valid citizen IDs (身分證字號)
|
|
12
12
|
expect(schema.parse("A123456789")).toBe("A123456789")
|
|
@@ -25,7 +25,7 @@ describe("Taiwan nationalId(true) validator", () => {
|
|
|
25
25
|
})
|
|
26
26
|
|
|
27
27
|
it("should reject invalid Taiwan national IDs", () => {
|
|
28
|
-
const schema =
|
|
28
|
+
const schema = twNationalId(true)
|
|
29
29
|
|
|
30
30
|
// Invalid formats
|
|
31
31
|
expect(() => schema.parse("A12345678")).toThrow("Invalid Taiwan National ID") // Too short
|
|
@@ -39,7 +39,7 @@ describe("Taiwan nationalId(true) validator", () => {
|
|
|
39
39
|
})
|
|
40
40
|
|
|
41
41
|
it("should handle case conversion", () => {
|
|
42
|
-
const schema =
|
|
42
|
+
const schema = twNationalId(true)
|
|
43
43
|
|
|
44
44
|
expect(schema.parse("a123456789")).toBe("A123456789")
|
|
45
45
|
expect(schema.parse("b123456780")).toBe("B123456780")
|
|
@@ -48,7 +48,7 @@ describe("Taiwan nationalId(true) validator", () => {
|
|
|
48
48
|
|
|
49
49
|
describe("type-specific validation", () => {
|
|
50
50
|
it("should validate only citizen IDs when type is 'citizen'", () => {
|
|
51
|
-
const schema =
|
|
51
|
+
const schema = twNationalId(true, { type: "citizen" })
|
|
52
52
|
|
|
53
53
|
// Should accept citizen IDs
|
|
54
54
|
expect(schema.parse("A123456789")).toBe("A123456789")
|
|
@@ -60,7 +60,7 @@ describe("Taiwan nationalId(true) validator", () => {
|
|
|
60
60
|
})
|
|
61
61
|
|
|
62
62
|
it("should validate only resident IDs when type is 'resident'", () => {
|
|
63
|
-
const schema =
|
|
63
|
+
const schema = twNationalId(true, { type: "resident" })
|
|
64
64
|
|
|
65
65
|
// Should accept old resident IDs
|
|
66
66
|
expect(schema.parse("AA00000001")).toBe("AA00000001")
|
|
@@ -76,7 +76,7 @@ describe("Taiwan nationalId(true) validator", () => {
|
|
|
76
76
|
})
|
|
77
77
|
|
|
78
78
|
it("should validate both types when type is 'both' (default)", () => {
|
|
79
|
-
const schema =
|
|
79
|
+
const schema = twNationalId(true, { type: "both" })
|
|
80
80
|
|
|
81
81
|
// Should accept all valid formats
|
|
82
82
|
expect(schema.parse("A123456789")).toBe("A123456789") // Citizen
|
|
@@ -87,7 +87,7 @@ describe("Taiwan nationalId(true) validator", () => {
|
|
|
87
87
|
|
|
88
88
|
describe("allowOldResident option", () => {
|
|
89
89
|
it("should allow old resident IDs by default", () => {
|
|
90
|
-
const schema =
|
|
90
|
+
const schema = twNationalId(true, { type: "resident" })
|
|
91
91
|
|
|
92
92
|
// Should accept old resident IDs (default allowOldResident=true)
|
|
93
93
|
expect(schema.parse("AA00000001")).toBe("AA00000001")
|
|
@@ -100,7 +100,7 @@ describe("Taiwan nationalId(true) validator", () => {
|
|
|
100
100
|
})
|
|
101
101
|
|
|
102
102
|
it("should reject old resident IDs when allowOldResident=false", () => {
|
|
103
|
-
const schema =
|
|
103
|
+
const schema = twNationalId(true, { type: "resident", allowOldResident: false })
|
|
104
104
|
|
|
105
105
|
// Should reject old resident IDs
|
|
106
106
|
expect(() => schema.parse("AA00000001")).toThrow("Invalid Taiwan National ID")
|
|
@@ -113,7 +113,7 @@ describe("Taiwan nationalId(true) validator", () => {
|
|
|
113
113
|
})
|
|
114
114
|
|
|
115
115
|
it("should work with type='both' and allowOldResident=false", () => {
|
|
116
|
-
const schema =
|
|
116
|
+
const schema = twNationalId(true, { type: "both", allowOldResident: false })
|
|
117
117
|
|
|
118
118
|
// Should accept citizen IDs
|
|
119
119
|
expect(schema.parse("A123456789")).toBe("A123456789")
|
|
@@ -129,8 +129,8 @@ describe("Taiwan nationalId(true) validator", () => {
|
|
|
129
129
|
})
|
|
130
130
|
|
|
131
131
|
it("should not affect citizen IDs validation", () => {
|
|
132
|
-
const schemaWithOld =
|
|
133
|
-
const schemaWithoutOld =
|
|
132
|
+
const schemaWithOld = twNationalId(true, { type: "citizen", allowOldResident: true })
|
|
133
|
+
const schemaWithoutOld = twNationalId(true, { type: "citizen", allowOldResident: false })
|
|
134
134
|
|
|
135
135
|
// Both should accept citizen IDs
|
|
136
136
|
expect(schemaWithOld.parse("A123456789")).toBe("A123456789")
|
|
@@ -211,7 +211,7 @@ describe("Taiwan nationalId(true) validator", () => {
|
|
|
211
211
|
|
|
212
212
|
describe("required/optional behavior", () => {
|
|
213
213
|
it("should handle required=true (default)", () => {
|
|
214
|
-
const schema =
|
|
214
|
+
const schema = twNationalId(true)
|
|
215
215
|
|
|
216
216
|
expect(() => schema.parse("")).toThrow("Required")
|
|
217
217
|
expect(() => schema.parse(null)).toThrow()
|
|
@@ -219,7 +219,7 @@ describe("Taiwan nationalId(true) validator", () => {
|
|
|
219
219
|
})
|
|
220
220
|
|
|
221
221
|
it("should handle required=false", () => {
|
|
222
|
-
const schema =
|
|
222
|
+
const schema = twNationalId(false)
|
|
223
223
|
|
|
224
224
|
expect(schema.parse("")).toBe(null)
|
|
225
225
|
expect(schema.parse(null)).toBe(null)
|
|
@@ -228,8 +228,8 @@ describe("Taiwan nationalId(true) validator", () => {
|
|
|
228
228
|
})
|
|
229
229
|
|
|
230
230
|
it("should use default values", () => {
|
|
231
|
-
const requiredSchema =
|
|
232
|
-
const optionalSchema =
|
|
231
|
+
const requiredSchema = twNationalId(true, { defaultValue: "A123456789" })
|
|
232
|
+
const optionalSchema = twNationalId(false, { defaultValue: "A123456789" })
|
|
233
233
|
|
|
234
234
|
expect(requiredSchema.parse("")).toBe("A123456789")
|
|
235
235
|
expect(optionalSchema.parse("")).toBe("A123456789")
|
|
@@ -238,7 +238,7 @@ describe("Taiwan nationalId(true) validator", () => {
|
|
|
238
238
|
|
|
239
239
|
describe("transform function", () => {
|
|
240
240
|
it("should apply custom transform", () => {
|
|
241
|
-
const schema =
|
|
241
|
+
const schema = twNationalId(true, {
|
|
242
242
|
transform: (val) => val.replace(/[-\s]/g, "").toUpperCase(),
|
|
243
243
|
})
|
|
244
244
|
|
|
@@ -247,7 +247,7 @@ describe("Taiwan nationalId(true) validator", () => {
|
|
|
247
247
|
})
|
|
248
248
|
|
|
249
249
|
it("should apply transform before validation", () => {
|
|
250
|
-
const schema =
|
|
250
|
+
const schema = twNationalId(true, {
|
|
251
251
|
transform: (val) => val.replace(/\s+/g, "").toUpperCase(),
|
|
252
252
|
})
|
|
253
253
|
|
|
@@ -258,7 +258,7 @@ describe("Taiwan nationalId(true) validator", () => {
|
|
|
258
258
|
|
|
259
259
|
describe("input preprocessing", () => {
|
|
260
260
|
it("should handle string conversion and case normalization", () => {
|
|
261
|
-
const schema =
|
|
261
|
+
const schema = twNationalId(true)
|
|
262
262
|
|
|
263
263
|
// Test automatic uppercase conversion
|
|
264
264
|
expect(schema.parse("a123456789")).toBe("A123456789")
|
|
@@ -266,7 +266,7 @@ describe("Taiwan nationalId(true) validator", () => {
|
|
|
266
266
|
})
|
|
267
267
|
|
|
268
268
|
it("should trim whitespace", () => {
|
|
269
|
-
const schema =
|
|
269
|
+
const schema = twNationalId(true)
|
|
270
270
|
|
|
271
271
|
expect(schema.parse(" A123456789 ")).toBe("A123456789")
|
|
272
272
|
expect(schema.parse("\tZ187654324\n")).toBe("Z187654324")
|
|
@@ -276,7 +276,7 @@ describe("Taiwan nationalId(true) validator", () => {
|
|
|
276
276
|
describe("i18n support", () => {
|
|
277
277
|
it("should use English messages by default", () => {
|
|
278
278
|
setLocale("en")
|
|
279
|
-
const schema =
|
|
279
|
+
const schema = twNationalId(true)
|
|
280
280
|
|
|
281
281
|
expect(() => schema.parse("")).toThrow("Required")
|
|
282
282
|
expect(() => schema.parse("A123456788")).toThrow("Invalid Taiwan National ID")
|
|
@@ -284,14 +284,14 @@ describe("Taiwan nationalId(true) validator", () => {
|
|
|
284
284
|
|
|
285
285
|
it("should use Chinese messages when locale is zh-TW", () => {
|
|
286
286
|
setLocale("zh-TW")
|
|
287
|
-
const schema =
|
|
287
|
+
const schema = twNationalId(true)
|
|
288
288
|
|
|
289
289
|
expect(() => schema.parse("")).toThrow("必填")
|
|
290
290
|
expect(() => schema.parse("A123456788")).toThrow("無效的身分證字號")
|
|
291
291
|
})
|
|
292
292
|
|
|
293
293
|
it("should support custom i18n messages", () => {
|
|
294
|
-
const schema =
|
|
294
|
+
const schema = twNationalId(true, {
|
|
295
295
|
i18n: {
|
|
296
296
|
en: {
|
|
297
297
|
required: "National ID is required",
|
|
@@ -316,7 +316,7 @@ describe("Taiwan nationalId(true) validator", () => {
|
|
|
316
316
|
|
|
317
317
|
describe("real world Taiwan national IDs", () => {
|
|
318
318
|
it("should validate known citizen ID patterns", () => {
|
|
319
|
-
const schema =
|
|
319
|
+
const schema = twNationalId(true, { type: "citizen" })
|
|
320
320
|
|
|
321
321
|
// Test various city codes and gender combinations
|
|
322
322
|
const validCitizenIds = [
|
|
@@ -334,7 +334,7 @@ describe("Taiwan nationalId(true) validator", () => {
|
|
|
334
334
|
})
|
|
335
335
|
|
|
336
336
|
it("should validate known old resident ID patterns", () => {
|
|
337
|
-
const schema =
|
|
337
|
+
const schema = twNationalId(true, { type: "resident" })
|
|
338
338
|
|
|
339
339
|
// Test old format resident IDs
|
|
340
340
|
const validOldResidentIds = [
|
|
@@ -352,7 +352,7 @@ describe("Taiwan nationalId(true) validator", () => {
|
|
|
352
352
|
})
|
|
353
353
|
|
|
354
354
|
it("should validate known new resident ID patterns", () => {
|
|
355
|
-
const schema =
|
|
355
|
+
const schema = twNationalId(true, { type: "resident" })
|
|
356
356
|
|
|
357
357
|
// Test new format resident IDs
|
|
358
358
|
const validNewResidentIds = [
|
|
@@ -370,7 +370,7 @@ describe("Taiwan nationalId(true) validator", () => {
|
|
|
370
370
|
})
|
|
371
371
|
|
|
372
372
|
it("should reject common invalid patterns", () => {
|
|
373
|
-
const schema =
|
|
373
|
+
const schema = twNationalId(true)
|
|
374
374
|
|
|
375
375
|
const invalidIds = [
|
|
376
376
|
"A000000000", // All zeros
|
|
@@ -393,7 +393,7 @@ describe("Taiwan nationalId(true) validator", () => {
|
|
|
393
393
|
|
|
394
394
|
describe("edge cases", () => {
|
|
395
395
|
it("should handle all valid city codes", () => {
|
|
396
|
-
const schema =
|
|
396
|
+
const schema = twNationalId(true, { type: "citizen" })
|
|
397
397
|
|
|
398
398
|
// Test all valid city codes
|
|
399
399
|
const cityCodes = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
|
|
@@ -412,8 +412,8 @@ describe("Taiwan nationalId(true) validator", () => {
|
|
|
412
412
|
})
|
|
413
413
|
|
|
414
414
|
it("should handle empty and whitespace inputs", () => {
|
|
415
|
-
const schema =
|
|
416
|
-
const optionalSchema =
|
|
415
|
+
const schema = twNationalId(true)
|
|
416
|
+
const optionalSchema = twNationalId(false)
|
|
417
417
|
|
|
418
418
|
expect(() => schema.parse("")).toThrow("Required")
|
|
419
419
|
expect(() => schema.parse(" ")).toThrow("Required")
|
|
@@ -425,7 +425,7 @@ describe("Taiwan nationalId(true) validator", () => {
|
|
|
425
425
|
})
|
|
426
426
|
|
|
427
427
|
it("should preserve valid format after transformation", () => {
|
|
428
|
-
const schema =
|
|
428
|
+
const schema = twNationalId(true, {
|
|
429
429
|
transform: (val) => val.replace(/[^A-Z0-9]/g, "").toUpperCase(),
|
|
430
430
|
})
|
|
431
431
|
|