@hy_ong/zod-kit 0.0.6 → 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.
Files changed (42) hide show
  1. package/.claude/settings.local.json +4 -1
  2. package/dist/index.cjs +93 -89
  3. package/dist/index.d.cts +235 -169
  4. package/dist/index.d.ts +235 -169
  5. package/dist/index.js +93 -89
  6. package/package.json +2 -1
  7. package/src/validators/common/boolean.ts +17 -14
  8. package/src/validators/common/date.ts +21 -14
  9. package/src/validators/common/datetime.ts +21 -14
  10. package/src/validators/common/email.ts +18 -15
  11. package/src/validators/common/file.ts +20 -13
  12. package/src/validators/common/id.ts +14 -14
  13. package/src/validators/common/number.ts +18 -15
  14. package/src/validators/common/password.ts +21 -14
  15. package/src/validators/common/text.ts +21 -17
  16. package/src/validators/common/time.ts +21 -14
  17. package/src/validators/common/url.ts +22 -15
  18. package/src/validators/taiwan/business-id.ts +18 -11
  19. package/src/validators/taiwan/fax.ts +23 -14
  20. package/src/validators/taiwan/mobile.ts +23 -14
  21. package/src/validators/taiwan/national-id.ts +11 -12
  22. package/src/validators/taiwan/postal-code.ts +16 -17
  23. package/src/validators/taiwan/tel.ts +23 -14
  24. package/tests/common/boolean.test.ts +38 -38
  25. package/tests/common/date.test.ts +65 -65
  26. package/tests/common/datetime.test.ts +100 -118
  27. package/tests/common/email.test.ts +24 -28
  28. package/tests/common/file.test.ts +47 -51
  29. package/tests/common/id.test.ts +80 -113
  30. package/tests/common/number.test.ts +24 -25
  31. package/tests/common/password.test.ts +28 -35
  32. package/tests/common/text.test.ts +36 -37
  33. package/tests/common/time.test.ts +64 -82
  34. package/tests/common/url.test.ts +67 -67
  35. package/tests/taiwan/business-id.test.ts +22 -22
  36. package/tests/taiwan/fax.test.ts +33 -42
  37. package/tests/taiwan/mobile.test.ts +32 -41
  38. package/tests/taiwan/national-id.test.ts +31 -31
  39. package/tests/taiwan/postal-code.test.ts +142 -96
  40. package/tests/taiwan/tel.test.ts +33 -42
  41. package/debug.js +0 -21
  42. package/debug.ts +0 -16
@@ -1,14 +1,14 @@
1
1
  import { describe, it, expect, beforeEach } from "vitest"
2
2
  import { time, setLocale, validateTimeFormat, parseTimeToMinutes, normalizeTime } from "../../src"
3
3
 
4
- describe("Taiwan time() validator", () => {
4
+ describe("Taiwan time(true) validator", () => {
5
5
  beforeEach(() => setLocale("en"))
6
6
 
7
7
  describe("basic functionality", () => {
8
8
  it("should validate correct time formats", () => {
9
- const schema24 = time({ format: "HH:mm" })
10
- const schema12 = time({ format: "hh:mm A" })
11
- const schemaWithSeconds = time({ format: "HH:mm:ss" })
9
+ const schema24 = time(true, { format: "HH:mm" })
10
+ const schema12 = time(true, { format: "hh:mm A" })
11
+ const schemaWithSeconds = time(true, { format: "HH:mm:ss" })
12
12
 
13
13
  // 24-hour format
14
14
  expect(schema24.parse("09:30")).toBe("09:30")
@@ -29,8 +29,8 @@ describe("Taiwan time() validator", () => {
29
29
  })
30
30
 
31
31
  it("should validate single digit hour format", () => {
32
- const schemaH = time({ format: "H:mm" })
33
- const schemah = time({ format: "h:mm A" })
32
+ const schemaH = time(true, { format: "H:mm" })
33
+ const schemah = time(true, { format: "h:mm A" })
34
34
 
35
35
  // Single digit 24-hour
36
36
  expect(schemaH.parse("9:30")).toBe("9:30")
@@ -42,7 +42,7 @@ describe("Taiwan time() validator", () => {
42
42
  })
43
43
 
44
44
  it("should reject invalid time formats", () => {
45
- const schema = time({ format: "HH:mm" })
45
+ const schema = time(true, { format: "HH:mm" })
46
46
 
47
47
  // Invalid formats
48
48
  expect(() => schema.parse("25:30")).toThrow("Must be in HH:mm format")
@@ -54,7 +54,7 @@ describe("Taiwan time() validator", () => {
54
54
  })
55
55
 
56
56
  it("should handle whitespace trimming", () => {
57
- const schema = time({ format: "HH:mm" })
57
+ const schema = time(true, { format: "HH:mm" })
58
58
 
59
59
  expect(schema.parse(" 14:30 ")).toBe("14:30")
60
60
  expect(schema.parse("\t09:15\n")).toBe("09:15")
@@ -63,9 +63,9 @@ describe("Taiwan time() validator", () => {
63
63
 
64
64
  describe("whitelist functionality", () => {
65
65
  it("should accept any string in whitelist regardless of format", () => {
66
- const schema = time({
66
+ const schema = time(true, {
67
67
  format: "HH:mm",
68
- whitelist: ["anytime", "flexible", "TBD"]
68
+ whitelist: ["anytime", "flexible", "TBD"],
69
69
  })
70
70
 
71
71
  expect(schema.parse("anytime")).toBe("anytime")
@@ -75,10 +75,10 @@ describe("Taiwan time() validator", () => {
75
75
  })
76
76
 
77
77
  it("should reject values not in whitelist when whitelistOnly is true", () => {
78
- const schema = time({
78
+ const schema = time(true, {
79
79
  format: "HH:mm",
80
80
  whitelist: ["morning", "14:30"],
81
- whitelistOnly: true
81
+ whitelistOnly: true,
82
82
  })
83
83
 
84
84
  expect(schema.parse("morning")).toBe("morning")
@@ -90,9 +90,9 @@ describe("Taiwan time() validator", () => {
90
90
  })
91
91
 
92
92
  it("should work with empty whitelist", () => {
93
- const schema = time({
93
+ const schema = time(true, {
94
94
  format: "HH:mm",
95
- whitelist: []
95
+ whitelist: [],
96
96
  })
97
97
 
98
98
  // With empty whitelist, should still validate time format
@@ -101,11 +101,7 @@ describe("Taiwan time() validator", () => {
101
101
  })
102
102
 
103
103
  it("should prioritize whitelist over format validation", () => {
104
- const schema = time({
105
- required: false,
106
- format: "HH:mm",
107
- whitelist: ["not-a-time", "123", ""]
108
- })
104
+ const schema = time(false, { format: "HH:mm", whitelist: ["not-a-time", "123", ""] })
109
105
 
110
106
  expect(schema.parse("not-a-time")).toBe("not-a-time")
111
107
  expect(schema.parse("123")).toBe("123")
@@ -115,7 +111,7 @@ describe("Taiwan time() validator", () => {
115
111
 
116
112
  describe("required/optional behavior", () => {
117
113
  it("should handle required=true (default)", () => {
118
- const schema = time({ format: "HH:mm" })
114
+ const schema = time(true, { format: "HH:mm" })
119
115
 
120
116
  expect(() => schema.parse("")).toThrow("Required")
121
117
  expect(() => schema.parse(null)).toThrow("Required")
@@ -123,7 +119,7 @@ describe("Taiwan time() validator", () => {
123
119
  })
124
120
 
125
121
  it("should handle required=false", () => {
126
- const schema = time({ format: "HH:mm", required: false })
122
+ const schema = time(false, { format: "HH:mm" })
127
123
 
128
124
  expect(schema.parse("")).toBe(null)
129
125
  expect(schema.parse(null)).toBe(null)
@@ -132,8 +128,8 @@ describe("Taiwan time() validator", () => {
132
128
  })
133
129
 
134
130
  it("should use default values", () => {
135
- const requiredSchema = time({ format: "HH:mm", defaultValue: "09:00" })
136
- const optionalSchema = time({ format: "HH:mm", required: false, defaultValue: "12:00" })
131
+ const requiredSchema = time(true, { format: "HH:mm", defaultValue: "09:00" })
132
+ const optionalSchema = time(false, { format: "HH:mm", defaultValue: "12:00" })
137
133
 
138
134
  expect(requiredSchema.parse("")).toBe("09:00")
139
135
  expect(requiredSchema.parse(null)).toBe("09:00")
@@ -142,12 +138,7 @@ describe("Taiwan time() validator", () => {
142
138
  })
143
139
 
144
140
  it("should handle whitelist with optional fields", () => {
145
- const schema = time({
146
- format: "HH:mm",
147
- required: false,
148
- whitelist: ["flexible", "14:30"],
149
- whitelistOnly: true
150
- })
141
+ const schema = time(false, { format: "HH:mm", whitelist: ["flexible", "14:30"], whitelistOnly: true })
151
142
 
152
143
  expect(schema.parse("")).toBe(null)
153
144
  expect(schema.parse("flexible")).toBe("flexible")
@@ -158,10 +149,10 @@ describe("Taiwan time() validator", () => {
158
149
 
159
150
  describe("time range validation", () => {
160
151
  it("should validate minimum and maximum times", () => {
161
- const schema = time({
152
+ const schema = time(true, {
162
153
  format: "HH:mm",
163
154
  min: "09:00",
164
- max: "17:00"
155
+ max: "17:00",
165
156
  })
166
157
 
167
158
  // Valid times within range
@@ -175,10 +166,10 @@ describe("Taiwan time() validator", () => {
175
166
  })
176
167
 
177
168
  it("should validate hour ranges", () => {
178
- const schema = time({
169
+ const schema = time(true, {
179
170
  format: "HH:mm",
180
171
  minHour: 9,
181
- maxHour: 17
172
+ maxHour: 17,
182
173
  })
183
174
 
184
175
  // Valid hours
@@ -191,9 +182,9 @@ describe("Taiwan time() validator", () => {
191
182
  })
192
183
 
193
184
  it("should validate allowed hours", () => {
194
- const schema = time({
185
+ const schema = time(true, {
195
186
  format: "HH:mm",
196
- allowedHours: [9, 12, 15, 18]
187
+ allowedHours: [9, 12, 15, 18],
197
188
  })
198
189
 
199
190
  // Valid hours
@@ -208,9 +199,9 @@ describe("Taiwan time() validator", () => {
208
199
  })
209
200
 
210
201
  it("should validate minute steps", () => {
211
- const schema = time({
202
+ const schema = time(true, {
212
203
  format: "HH:mm",
213
- minuteStep: 15
204
+ minuteStep: 15,
214
205
  })
215
206
 
216
207
  // Valid minute steps (0, 15, 30, 45)
@@ -227,28 +218,28 @@ describe("Taiwan time() validator", () => {
227
218
 
228
219
  describe("transform function", () => {
229
220
  it("should apply custom transform", () => {
230
- const schema = time({
221
+ const schema = time(true, {
231
222
  format: "HH:mm",
232
- transform: (val) => val.toUpperCase()
223
+ transform: (val) => val.toUpperCase(),
233
224
  })
234
225
 
235
226
  expect(schema.parse("14:30")).toBe("14:30")
236
227
  })
237
228
 
238
229
  it("should apply transform before validation", () => {
239
- const schema = time({
230
+ const schema = time(true, {
240
231
  format: "HH:mm",
241
- transform: (val) => val.replace(/\s+/g, "")
232
+ transform: (val) => val.replace(/\s+/g, ""),
242
233
  })
243
234
 
244
235
  expect(schema.parse("1 4 : 3 0")).toBe("14:30")
245
236
  })
246
237
 
247
238
  it("should work with whitelist after transform", () => {
248
- const schema = time({
239
+ const schema = time(true, {
249
240
  format: "HH:mm",
250
241
  transform: (val) => val.toLowerCase(),
251
- whitelist: ["morning", "14:30"]
242
+ whitelist: ["morning", "14:30"],
252
243
  })
253
244
 
254
245
  expect(schema.parse("MORNING")).toBe("morning")
@@ -258,14 +249,14 @@ describe("Taiwan time() validator", () => {
258
249
 
259
250
  describe("input preprocessing", () => {
260
251
  it("should handle string conversion", () => {
261
- const schema = time({ format: "HH:mm" })
252
+ const schema = time(true, { format: "HH:mm" })
262
253
 
263
254
  // Test string conversion of numbers
264
255
  expect(() => schema.parse(1430)).toThrow("Must be in HH:mm format") // Invalid because not in HH:mm format
265
256
  })
266
257
 
267
258
  it("should trim whitespace", () => {
268
- const schema = time({ format: "HH:mm" })
259
+ const schema = time(true, { format: "HH:mm" })
269
260
 
270
261
  expect(schema.parse(" 14:30 ")).toBe("14:30")
271
262
  expect(schema.parse("\t09:15\n")).toBe("09:15")
@@ -340,7 +331,7 @@ describe("Taiwan time() validator", () => {
340
331
  describe("i18n support", () => {
341
332
  it("should use English messages by default", () => {
342
333
  setLocale("en")
343
- const schema = time({ format: "HH:mm" })
334
+ const schema = time(true, { format: "HH:mm" })
344
335
 
345
336
  expect(() => schema.parse("")).toThrow("Required")
346
337
  expect(() => schema.parse("invalid")).toThrow("Must be in HH:mm format")
@@ -348,7 +339,7 @@ describe("Taiwan time() validator", () => {
348
339
 
349
340
  it("should use Chinese messages when locale is zh-TW", () => {
350
341
  setLocale("zh-TW")
351
- const schema = time({ format: "HH:mm" })
342
+ const schema = time(true, { format: "HH:mm" })
352
343
 
353
344
  expect(() => schema.parse("")).toThrow("必填")
354
345
  expect(() => schema.parse("invalid")).toThrow("必須為 HH:mm 格式")
@@ -356,28 +347,28 @@ describe("Taiwan time() validator", () => {
356
347
 
357
348
  it("should support whitelist error messages", () => {
358
349
  setLocale("en")
359
- const schema = time({
350
+ const schema = time(true, {
360
351
  format: "HH:mm",
361
352
  whitelist: ["morning"],
362
- whitelistOnly: true
353
+ whitelistOnly: true,
363
354
  })
364
355
 
365
356
  expect(() => schema.parse("14:30")).toThrow("Time is not in the allowed list")
366
357
  })
367
358
 
368
359
  it("should support custom i18n messages", () => {
369
- const schema = time({
360
+ const schema = time(true, {
370
361
  format: "HH:mm",
371
362
  i18n: {
372
363
  en: {
373
364
  required: "Time is required",
374
- invalid: "Please enter a valid time"
365
+ invalid: "Please enter a valid time",
375
366
  },
376
367
  "zh-TW": {
377
368
  required: "請輸入時間",
378
- invalid: "請輸入有效的時間格式"
379
- }
380
- }
369
+ invalid: "請輸入有效的時間格式",
370
+ },
371
+ },
381
372
  })
382
373
 
383
374
  setLocale("en")
@@ -388,18 +379,18 @@ describe("Taiwan time() validator", () => {
388
379
  })
389
380
 
390
381
  it("should support custom whitelist messages", () => {
391
- const schema = time({
382
+ const schema = time(true, {
392
383
  format: "HH:mm",
393
384
  whitelist: ["morning"],
394
385
  whitelistOnly: true,
395
386
  i18n: {
396
387
  en: {
397
- notInWhitelist: "This time is not allowed"
388
+ notInWhitelist: "This time is not allowed",
398
389
  },
399
390
  "zh-TW": {
400
- notInWhitelist: "此時間不被允許"
401
- }
402
- }
391
+ notInWhitelist: "此時間不被允許",
392
+ },
393
+ },
403
394
  })
404
395
 
405
396
  setLocale("en")
@@ -412,11 +403,11 @@ describe("Taiwan time() validator", () => {
412
403
 
413
404
  describe("real world time scenarios", () => {
414
405
  it("should validate business hours", () => {
415
- const businessHours = time({
406
+ const businessHours = time(true, {
416
407
  format: "HH:mm",
417
408
  min: "09:00",
418
409
  max: "17:00",
419
- minuteStep: 30
410
+ minuteStep: 30,
420
411
  })
421
412
 
422
413
  expect(businessHours.parse("09:00")).toBe("09:00")
@@ -429,10 +420,10 @@ describe("Taiwan time() validator", () => {
429
420
  })
430
421
 
431
422
  it("should validate appointment slots", () => {
432
- const appointmentSlots = time({
423
+ const appointmentSlots = time(true, {
433
424
  format: "hh:mm A",
434
425
  allowedHours: [9, 10, 11, 14, 15, 16],
435
- minuteStep: 15
426
+ minuteStep: 15,
436
427
  })
437
428
 
438
429
  expect(appointmentSlots.parse("09:00 AM")).toBe("09:00 AM")
@@ -444,11 +435,7 @@ describe("Taiwan time() validator", () => {
444
435
  })
445
436
 
446
437
  it("should handle flexible time input", () => {
447
- const flexibleTime = time({
448
- format: "HH:mm",
449
- whitelist: ["morning", "afternoon", "evening", "anytime"],
450
- required: false
451
- })
438
+ const flexibleTime = time(false, { format: "HH:mm", whitelist: ["morning", "afternoon", "evening", "anytime"] })
452
439
 
453
440
  expect(flexibleTime.parse("morning")).toBe("morning")
454
441
  expect(flexibleTime.parse("14:30")).toBe("14:30")
@@ -459,15 +446,15 @@ describe("Taiwan time() validator", () => {
459
446
 
460
447
  describe("edge cases", () => {
461
448
  it("should handle various input types", () => {
462
- const schema = time({ format: "HH:mm" })
449
+ const schema = time(true, { format: "HH:mm" })
463
450
 
464
451
  // Test different input types that should be converted to string
465
452
  expect(schema.parse("14:30")).toBe("14:30")
466
453
  })
467
454
 
468
455
  it("should handle empty and whitespace inputs", () => {
469
- const requiredSchema = time({ format: "HH:mm", required: true })
470
- const optionalSchema = time({ format: "HH:mm", required: false })
456
+ const requiredSchema = time(true, { format: "HH:mm" })
457
+ const optionalSchema = time(false, { format: "HH:mm" })
471
458
 
472
459
  expect(() => requiredSchema.parse("")).toThrow("Required")
473
460
  expect(() => requiredSchema.parse(" ")).toThrow("Required")
@@ -477,9 +464,9 @@ describe("Taiwan time() validator", () => {
477
464
  })
478
465
 
479
466
  it("should preserve valid format after transformation", () => {
480
- const schema = time({
467
+ const schema = time(true, {
481
468
  format: "HH:mm",
482
- transform: (val) => val.replace(/[^0-9:]/g, "").replace(/^(\d{2})(\d{2})$/, "$1:$2")
469
+ transform: (val) => val.replace(/[^0-9:]/g, "").replace(/^(\d{2})(\d{2})$/, "$1:$2"),
483
470
  })
484
471
 
485
472
  expect(schema.parse("14abc:30def")).toBe("14:30")
@@ -487,12 +474,7 @@ describe("Taiwan time() validator", () => {
487
474
  })
488
475
 
489
476
  it("should work with complex whitelist scenarios", () => {
490
- const schema = time({
491
- format: "HH:mm",
492
- whitelist: ["14:30", "TBD", "flexible", ""],
493
- whitelistOnly: true,
494
- required: false
495
- })
477
+ const schema = time(false, { format: "HH:mm", whitelist: ["14:30", "TBD", "flexible", ""], whitelistOnly: true })
496
478
 
497
479
  // Whitelist scenarios
498
480
  expect(schema.parse("14:30")).toBe("14:30")
@@ -506,8 +488,8 @@ describe("Taiwan time() validator", () => {
506
488
  })
507
489
 
508
490
  it("should handle boundary cases for different formats", () => {
509
- const schema24 = time({ format: "HH:mm" })
510
- const schema12 = time({ format: "hh:mm A" })
491
+ const schema24 = time(true, { format: "HH:mm" })
492
+ const schema12 = time(true, { format: "hh:mm A" })
511
493
 
512
494
  // 24-hour boundary cases
513
495
  expect(schema24.parse("00:00")).toBe("00:00")
@@ -525,4 +507,4 @@ describe("Taiwan time() validator", () => {
525
507
  expect(() => schema12.parse("13:00 PM")).toThrow("Must be in")
526
508
  })
527
509
  })
528
- })
510
+ })