@hy_ong/zod-kit 0.0.5 → 0.1.0
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/.claude/settings.local.json +9 -1
- package/README.md +465 -97
- package/dist/index.cjs +1690 -179
- package/dist/index.d.cts +2791 -28
- package/dist/index.d.ts +2791 -28
- package/dist/index.js +1672 -178
- package/package.json +2 -1
- package/src/i18n/locales/en.json +62 -0
- package/src/i18n/locales/zh-TW.json +62 -0
- package/src/index.ts +4 -0
- package/src/validators/common/boolean.ts +101 -4
- package/src/validators/common/date.ts +141 -6
- package/src/validators/common/datetime.ts +680 -0
- package/src/validators/common/email.ts +120 -4
- package/src/validators/common/file.ts +391 -0
- package/src/validators/common/id.ts +230 -18
- package/src/validators/common/number.ts +132 -4
- package/src/validators/common/password.ts +187 -8
- package/src/validators/common/text.ts +130 -6
- package/src/validators/common/time.ts +607 -0
- package/src/validators/common/url.ts +153 -6
- package/src/validators/taiwan/business-id.ts +138 -9
- package/src/validators/taiwan/fax.ts +164 -10
- package/src/validators/taiwan/mobile.ts +151 -10
- package/src/validators/taiwan/national-id.ts +233 -17
- package/src/validators/taiwan/postal-code.ts +1048 -0
- package/src/validators/taiwan/tel.ts +167 -10
- package/tests/common/boolean.test.ts +38 -38
- package/tests/common/date.test.ts +65 -65
- package/tests/common/datetime.test.ts +675 -0
- package/tests/common/email.test.ts +24 -28
- package/tests/common/file.test.ts +475 -0
- package/tests/common/id.test.ts +80 -113
- package/tests/common/number.test.ts +24 -25
- package/tests/common/password.test.ts +28 -35
- package/tests/common/text.test.ts +36 -37
- package/tests/common/time.test.ts +510 -0
- package/tests/common/url.test.ts +67 -67
- package/tests/taiwan/business-id.test.ts +22 -22
- package/tests/taiwan/fax.test.ts +33 -42
- package/tests/taiwan/mobile.test.ts +32 -41
- package/tests/taiwan/national-id.test.ts +31 -31
- package/tests/taiwan/postal-code.test.ts +751 -0
- package/tests/taiwan/tel.test.ts +33 -42
- package/debug.js +0 -21
- package/debug.ts +0 -16
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { describe, it, expect, beforeEach } from "vitest"
|
|
2
2
|
import { nationalId, setLocale, validateTaiwanNationalId, validateCitizenId, validateOldResidentId, validateNewResidentId } from "../../src"
|
|
3
3
|
|
|
4
|
-
describe("Taiwan nationalId() validator", () => {
|
|
4
|
+
describe("Taiwan nationalId(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 = nationalId()
|
|
9
|
+
const schema = nationalId(true)
|
|
10
10
|
|
|
11
11
|
// Valid citizen IDs (身分證字號)
|
|
12
12
|
expect(schema.parse("A123456789")).toBe("A123456789")
|
|
@@ -25,7 +25,7 @@ describe("Taiwan nationalId() validator", () => {
|
|
|
25
25
|
})
|
|
26
26
|
|
|
27
27
|
it("should reject invalid Taiwan national IDs", () => {
|
|
28
|
-
const schema = nationalId()
|
|
28
|
+
const schema = nationalId(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() validator", () => {
|
|
|
39
39
|
})
|
|
40
40
|
|
|
41
41
|
it("should handle case conversion", () => {
|
|
42
|
-
const schema = nationalId()
|
|
42
|
+
const schema = nationalId(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() validator", () => {
|
|
|
48
48
|
|
|
49
49
|
describe("type-specific validation", () => {
|
|
50
50
|
it("should validate only citizen IDs when type is 'citizen'", () => {
|
|
51
|
-
const schema = nationalId({ type: "citizen" })
|
|
51
|
+
const schema = nationalId(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() validator", () => {
|
|
|
60
60
|
})
|
|
61
61
|
|
|
62
62
|
it("should validate only resident IDs when type is 'resident'", () => {
|
|
63
|
-
const schema = nationalId({ type: "resident" })
|
|
63
|
+
const schema = nationalId(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() validator", () => {
|
|
|
76
76
|
})
|
|
77
77
|
|
|
78
78
|
it("should validate both types when type is 'both' (default)", () => {
|
|
79
|
-
const schema = nationalId({ type: "both" })
|
|
79
|
+
const schema = nationalId(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() validator", () => {
|
|
|
87
87
|
|
|
88
88
|
describe("allowOldResident option", () => {
|
|
89
89
|
it("should allow old resident IDs by default", () => {
|
|
90
|
-
const schema = nationalId({ type: "resident" })
|
|
90
|
+
const schema = nationalId(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() validator", () => {
|
|
|
100
100
|
})
|
|
101
101
|
|
|
102
102
|
it("should reject old resident IDs when allowOldResident=false", () => {
|
|
103
|
-
const schema = nationalId({ type: "resident", allowOldResident: false })
|
|
103
|
+
const schema = nationalId(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() validator", () => {
|
|
|
113
113
|
})
|
|
114
114
|
|
|
115
115
|
it("should work with type='both' and allowOldResident=false", () => {
|
|
116
|
-
const schema = nationalId({ type: "both", allowOldResident: false })
|
|
116
|
+
const schema = nationalId(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() validator", () => {
|
|
|
129
129
|
})
|
|
130
130
|
|
|
131
131
|
it("should not affect citizen IDs validation", () => {
|
|
132
|
-
const schemaWithOld = nationalId({ type: "citizen", allowOldResident: true })
|
|
133
|
-
const schemaWithoutOld = nationalId({ type: "citizen", allowOldResident: false })
|
|
132
|
+
const schemaWithOld = nationalId(true, { type: "citizen", allowOldResident: true })
|
|
133
|
+
const schemaWithoutOld = nationalId(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() validator", () => {
|
|
|
211
211
|
|
|
212
212
|
describe("required/optional behavior", () => {
|
|
213
213
|
it("should handle required=true (default)", () => {
|
|
214
|
-
const schema = nationalId()
|
|
214
|
+
const schema = nationalId(true)
|
|
215
215
|
|
|
216
216
|
expect(() => schema.parse("")).toThrow("Required")
|
|
217
217
|
expect(() => schema.parse(null)).toThrow()
|
|
@@ -219,7 +219,7 @@ describe("Taiwan nationalId() validator", () => {
|
|
|
219
219
|
})
|
|
220
220
|
|
|
221
221
|
it("should handle required=false", () => {
|
|
222
|
-
const schema = nationalId(
|
|
222
|
+
const schema = nationalId(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() validator", () => {
|
|
|
228
228
|
})
|
|
229
229
|
|
|
230
230
|
it("should use default values", () => {
|
|
231
|
-
const requiredSchema = nationalId({ defaultValue: "A123456789" })
|
|
232
|
-
const optionalSchema = nationalId(
|
|
231
|
+
const requiredSchema = nationalId(true, { defaultValue: "A123456789" })
|
|
232
|
+
const optionalSchema = nationalId(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() validator", () => {
|
|
|
238
238
|
|
|
239
239
|
describe("transform function", () => {
|
|
240
240
|
it("should apply custom transform", () => {
|
|
241
|
-
const schema = nationalId({
|
|
241
|
+
const schema = nationalId(true, {
|
|
242
242
|
transform: (val) => val.replace(/[-\s]/g, "").toUpperCase(),
|
|
243
243
|
})
|
|
244
244
|
|
|
@@ -247,7 +247,7 @@ describe("Taiwan nationalId() validator", () => {
|
|
|
247
247
|
})
|
|
248
248
|
|
|
249
249
|
it("should apply transform before validation", () => {
|
|
250
|
-
const schema = nationalId({
|
|
250
|
+
const schema = nationalId(true, {
|
|
251
251
|
transform: (val) => val.replace(/\s+/g, "").toUpperCase(),
|
|
252
252
|
})
|
|
253
253
|
|
|
@@ -258,7 +258,7 @@ describe("Taiwan nationalId() validator", () => {
|
|
|
258
258
|
|
|
259
259
|
describe("input preprocessing", () => {
|
|
260
260
|
it("should handle string conversion and case normalization", () => {
|
|
261
|
-
const schema = nationalId()
|
|
261
|
+
const schema = nationalId(true)
|
|
262
262
|
|
|
263
263
|
// Test automatic uppercase conversion
|
|
264
264
|
expect(schema.parse("a123456789")).toBe("A123456789")
|
|
@@ -266,7 +266,7 @@ describe("Taiwan nationalId() validator", () => {
|
|
|
266
266
|
})
|
|
267
267
|
|
|
268
268
|
it("should trim whitespace", () => {
|
|
269
|
-
const schema = nationalId()
|
|
269
|
+
const schema = nationalId(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() validator", () => {
|
|
|
276
276
|
describe("i18n support", () => {
|
|
277
277
|
it("should use English messages by default", () => {
|
|
278
278
|
setLocale("en")
|
|
279
|
-
const schema = nationalId()
|
|
279
|
+
const schema = nationalId(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() validator", () => {
|
|
|
284
284
|
|
|
285
285
|
it("should use Chinese messages when locale is zh-TW", () => {
|
|
286
286
|
setLocale("zh-TW")
|
|
287
|
-
const schema = nationalId()
|
|
287
|
+
const schema = nationalId(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 = nationalId({
|
|
294
|
+
const schema = nationalId(true, {
|
|
295
295
|
i18n: {
|
|
296
296
|
en: {
|
|
297
297
|
required: "National ID is required",
|
|
@@ -316,7 +316,7 @@ describe("Taiwan nationalId() validator", () => {
|
|
|
316
316
|
|
|
317
317
|
describe("real world Taiwan national IDs", () => {
|
|
318
318
|
it("should validate known citizen ID patterns", () => {
|
|
319
|
-
const schema = nationalId({ type: "citizen" })
|
|
319
|
+
const schema = nationalId(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() validator", () => {
|
|
|
334
334
|
})
|
|
335
335
|
|
|
336
336
|
it("should validate known old resident ID patterns", () => {
|
|
337
|
-
const schema = nationalId({ type: "resident" })
|
|
337
|
+
const schema = nationalId(true, { type: "resident" })
|
|
338
338
|
|
|
339
339
|
// Test old format resident IDs
|
|
340
340
|
const validOldResidentIds = [
|
|
@@ -352,7 +352,7 @@ describe("Taiwan nationalId() validator", () => {
|
|
|
352
352
|
})
|
|
353
353
|
|
|
354
354
|
it("should validate known new resident ID patterns", () => {
|
|
355
|
-
const schema = nationalId({ type: "resident" })
|
|
355
|
+
const schema = nationalId(true, { type: "resident" })
|
|
356
356
|
|
|
357
357
|
// Test new format resident IDs
|
|
358
358
|
const validNewResidentIds = [
|
|
@@ -370,7 +370,7 @@ describe("Taiwan nationalId() validator", () => {
|
|
|
370
370
|
})
|
|
371
371
|
|
|
372
372
|
it("should reject common invalid patterns", () => {
|
|
373
|
-
const schema = nationalId()
|
|
373
|
+
const schema = nationalId(true)
|
|
374
374
|
|
|
375
375
|
const invalidIds = [
|
|
376
376
|
"A000000000", // All zeros
|
|
@@ -393,7 +393,7 @@ describe("Taiwan nationalId() validator", () => {
|
|
|
393
393
|
|
|
394
394
|
describe("edge cases", () => {
|
|
395
395
|
it("should handle all valid city codes", () => {
|
|
396
|
-
const schema = nationalId({ type: "citizen" })
|
|
396
|
+
const schema = nationalId(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() validator", () => {
|
|
|
412
412
|
})
|
|
413
413
|
|
|
414
414
|
it("should handle empty and whitespace inputs", () => {
|
|
415
|
-
const schema = nationalId()
|
|
416
|
-
const optionalSchema = nationalId(
|
|
415
|
+
const schema = nationalId(true)
|
|
416
|
+
const optionalSchema = nationalId(false)
|
|
417
417
|
|
|
418
418
|
expect(() => schema.parse("")).toThrow("Required")
|
|
419
419
|
expect(() => schema.parse(" ")).toThrow("Required")
|
|
@@ -425,7 +425,7 @@ describe("Taiwan nationalId() validator", () => {
|
|
|
425
425
|
})
|
|
426
426
|
|
|
427
427
|
it("should preserve valid format after transformation", () => {
|
|
428
|
-
const schema = nationalId({
|
|
428
|
+
const schema = nationalId(true, {
|
|
429
429
|
transform: (val) => val.replace(/[^A-Z0-9]/g, "").toUpperCase(),
|
|
430
430
|
})
|
|
431
431
|
|