@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.
Files changed (46) hide show
  1. package/.claude/settings.local.json +9 -1
  2. package/README.md +465 -97
  3. package/dist/index.cjs +1690 -179
  4. package/dist/index.d.cts +2791 -28
  5. package/dist/index.d.ts +2791 -28
  6. package/dist/index.js +1672 -178
  7. package/package.json +2 -1
  8. package/src/i18n/locales/en.json +62 -0
  9. package/src/i18n/locales/zh-TW.json +62 -0
  10. package/src/index.ts +4 -0
  11. package/src/validators/common/boolean.ts +101 -4
  12. package/src/validators/common/date.ts +141 -6
  13. package/src/validators/common/datetime.ts +680 -0
  14. package/src/validators/common/email.ts +120 -4
  15. package/src/validators/common/file.ts +391 -0
  16. package/src/validators/common/id.ts +230 -18
  17. package/src/validators/common/number.ts +132 -4
  18. package/src/validators/common/password.ts +187 -8
  19. package/src/validators/common/text.ts +130 -6
  20. package/src/validators/common/time.ts +607 -0
  21. package/src/validators/common/url.ts +153 -6
  22. package/src/validators/taiwan/business-id.ts +138 -9
  23. package/src/validators/taiwan/fax.ts +164 -10
  24. package/src/validators/taiwan/mobile.ts +151 -10
  25. package/src/validators/taiwan/national-id.ts +233 -17
  26. package/src/validators/taiwan/postal-code.ts +1048 -0
  27. package/src/validators/taiwan/tel.ts +167 -10
  28. package/tests/common/boolean.test.ts +38 -38
  29. package/tests/common/date.test.ts +65 -65
  30. package/tests/common/datetime.test.ts +675 -0
  31. package/tests/common/email.test.ts +24 -28
  32. package/tests/common/file.test.ts +475 -0
  33. package/tests/common/id.test.ts +80 -113
  34. package/tests/common/number.test.ts +24 -25
  35. package/tests/common/password.test.ts +28 -35
  36. package/tests/common/text.test.ts +36 -37
  37. package/tests/common/time.test.ts +510 -0
  38. package/tests/common/url.test.ts +67 -67
  39. package/tests/taiwan/business-id.test.ts +22 -22
  40. package/tests/taiwan/fax.test.ts +33 -42
  41. package/tests/taiwan/mobile.test.ts +32 -41
  42. package/tests/taiwan/national-id.test.ts +31 -31
  43. package/tests/taiwan/postal-code.test.ts +751 -0
  44. package/tests/taiwan/tel.test.ts +33 -42
  45. package/debug.js +0 -21
  46. package/debug.ts +0 -16
@@ -4,123 +4,123 @@ import { setLocale, url } from "../../src"
4
4
  describe("url", () => {
5
5
  describe("basic validation", () => {
6
6
  it("should validate valid URL", () => {
7
- const schema = url()
7
+ const schema = url(true)
8
8
  expect(schema.parse("https://example.com")).toBe("https://example.com")
9
9
  })
10
10
 
11
11
  it("should validate http URL", () => {
12
- const schema = url()
12
+ const schema = url(true)
13
13
  expect(schema.parse("http://example.com")).toBe("http://example.com")
14
14
  })
15
15
 
16
16
  it("should validate URL with path", () => {
17
- const schema = url()
17
+ const schema = url(true)
18
18
  expect(schema.parse("https://example.com/path")).toBe("https://example.com/path")
19
19
  })
20
20
 
21
21
  it("should validate URL with query parameters", () => {
22
- const schema = url()
22
+ const schema = url(true)
23
23
  expect(schema.parse("https://example.com?param=value")).toBe("https://example.com?param=value")
24
24
  })
25
25
 
26
26
  it("should validate URL with fragment", () => {
27
- const schema = url()
27
+ const schema = url(true)
28
28
  expect(schema.parse("https://example.com#section")).toBe("https://example.com#section")
29
29
  })
30
30
 
31
31
  it("should reject invalid URL format", () => {
32
- const schema = url()
32
+ const schema = url(true)
33
33
  expect(() => schema.parse("invalid-url")).toThrow()
34
34
  })
35
35
 
36
36
  it("should reject empty string", () => {
37
- const schema = url()
37
+ const schema = url(true)
38
38
  expect(() => schema.parse("")).toThrow()
39
39
  })
40
40
 
41
41
  it("should reject null", () => {
42
- const schema = url()
42
+ const schema = url(true)
43
43
  expect(() => schema.parse(null)).toThrow()
44
44
  })
45
45
 
46
46
  it("should reject undefined", () => {
47
- const schema = url()
47
+ const schema = url(true)
48
48
  expect(() => schema.parse(undefined)).toThrow()
49
49
  })
50
50
  })
51
51
 
52
52
  describe("optional", () => {
53
53
  it("should allow null when not required", () => {
54
- const schema = url({ required: false })
54
+ const schema = url(false)
55
55
  expect(schema.parse(null)).toBe(null)
56
56
  })
57
57
 
58
58
  it("should allow empty string when not required", () => {
59
- const schema = url({ required: false })
59
+ const schema = url(false)
60
60
  expect(schema.parse("")).toBe(null)
61
61
  })
62
62
 
63
63
  it("should allow undefined when not required", () => {
64
- const schema = url({ required: false })
64
+ const schema = url(false)
65
65
  expect(schema.parse(undefined)).toBe(null)
66
66
  })
67
67
 
68
68
  it("should validate valid URL when not required", () => {
69
- const schema = url({ required: false })
69
+ const schema = url(false)
70
70
  expect(schema.parse("https://example.com")).toBe("https://example.com")
71
71
  })
72
72
  })
73
73
 
74
74
  describe("length validation", () => {
75
75
  it("should accept URL with valid min length", () => {
76
- const schema = url({ min: 10 })
76
+ const schema = url(true, { min: 10 })
77
77
  expect(schema.parse("https://example.com")).toBe("https://example.com")
78
78
  })
79
79
 
80
80
  it("should reject URL below min length", () => {
81
- const schema = url({ min: 30 })
81
+ const schema = url(true, { min: 30 })
82
82
  expect(() => schema.parse("https://short.co")).toThrow()
83
83
  })
84
84
 
85
85
  it("should accept URL with valid max length", () => {
86
- const schema = url({ max: 30 })
86
+ const schema = url(true, { max: 30 })
87
87
  expect(schema.parse("https://example.com")).toBe("https://example.com")
88
88
  })
89
89
 
90
90
  it("should reject URL above max length", () => {
91
- const schema = url({ max: 10 })
91
+ const schema = url(true, { max: 10 })
92
92
  expect(() => schema.parse("https://verylongurl.com")).toThrow()
93
93
  })
94
94
 
95
95
  it("should accept URL within range", () => {
96
- const schema = url({ min: 10, max: 30 })
96
+ const schema = url(true, { min: 10, max: 30 })
97
97
  expect(schema.parse("https://example.com")).toBe("https://example.com")
98
98
  })
99
99
  })
100
100
 
101
101
  describe("includes/excludes validation", () => {
102
102
  it("should accept URL containing required substring", () => {
103
- const schema = url({ includes: "company" })
103
+ const schema = url(true, { includes: "company" })
104
104
  expect(schema.parse("https://company.example.com")).toBe("https://company.example.com")
105
105
  })
106
106
 
107
107
  it("should reject URL not containing required substring", () => {
108
- const schema = url({ includes: "company" })
108
+ const schema = url(true, { includes: "company" })
109
109
  expect(() => schema.parse("https://other.com")).toThrow()
110
110
  })
111
111
 
112
112
  it("should accept URL not containing excluded substring", () => {
113
- const schema = url({ excludes: "banned" })
113
+ const schema = url(true, { excludes: "banned" })
114
114
  expect(schema.parse("https://example.com")).toBe("https://example.com")
115
115
  })
116
116
 
117
117
  it("should reject URL containing excluded substring", () => {
118
- const schema = url({ excludes: "banned" })
118
+ const schema = url(true, { excludes: "banned" })
119
119
  expect(() => schema.parse("https://banned.com")).toThrow()
120
120
  })
121
121
 
122
122
  it("should handle multiple excluded substrings as array", () => {
123
- const schema = url({ excludes: ["banned", "blocked"] })
123
+ const schema = url(true, { excludes: ["banned", "blocked"] })
124
124
  expect(schema.parse("https://example.com")).toBe("https://example.com")
125
125
  expect(() => schema.parse("https://banned.com")).toThrow()
126
126
  expect(() => schema.parse("https://blocked.com")).toThrow()
@@ -129,36 +129,36 @@ describe("url", () => {
129
129
 
130
130
  describe("protocol validation", () => {
131
131
  it("should accept allowed protocols", () => {
132
- const schema = url({ protocols: ["https", "http"] })
132
+ const schema = url(true, { protocols: ["https", "http"] })
133
133
  expect(schema.parse("https://example.com")).toBe("https://example.com")
134
134
  expect(schema.parse("http://example.com")).toBe("http://example.com")
135
135
  })
136
136
 
137
137
  it("should reject disallowed protocols", () => {
138
- const schema = url({ protocols: ["https"] })
138
+ const schema = url(true, { protocols: ["https"] })
139
139
  expect(() => schema.parse("http://example.com")).toThrow()
140
140
  })
141
141
 
142
142
  it("should accept ftp protocol when allowed", () => {
143
- const schema = url({ protocols: ["ftp"] })
143
+ const schema = url(true, { protocols: ["ftp"] })
144
144
  expect(schema.parse("ftp://files.example.com")).toBe("ftp://files.example.com")
145
145
  })
146
146
  })
147
147
 
148
148
  describe("domain validation", () => {
149
149
  it("should accept allowed domains", () => {
150
- const schema = url({ allowedDomains: ["example.com", "test.org"] })
150
+ const schema = url(true, { allowedDomains: ["example.com", "test.org"] })
151
151
  expect(schema.parse("https://example.com")).toBe("https://example.com")
152
152
  expect(schema.parse("https://sub.example.com")).toBe("https://sub.example.com")
153
153
  })
154
154
 
155
155
  it("should reject disallowed domains", () => {
156
- const schema = url({ allowedDomains: ["example.com"] })
156
+ const schema = url(true, { allowedDomains: ["example.com"] })
157
157
  expect(() => schema.parse("https://other.com")).toThrow()
158
158
  })
159
159
 
160
160
  it("should reject blocked domains", () => {
161
- const schema = url({ blockedDomains: ["blocked.com", "spam.org"] })
161
+ const schema = url(true, { blockedDomains: ["blocked.com", "spam.org"] })
162
162
  expect(schema.parse("https://example.com")).toBe("https://example.com")
163
163
  expect(() => schema.parse("https://blocked.com")).toThrow()
164
164
  expect(() => schema.parse("https://sub.blocked.com")).toThrow()
@@ -167,19 +167,19 @@ describe("url", () => {
167
167
 
168
168
  describe("port validation", () => {
169
169
  it("should accept allowed ports", () => {
170
- const schema = url({ allowedPorts: [80, 443, 8080] })
170
+ const schema = url(true, { allowedPorts: [80, 443, 8080] })
171
171
  expect(schema.parse("https://example.com")).toBe("https://example.com") // 443
172
172
  expect(schema.parse("http://example.com")).toBe("http://example.com") // 80
173
173
  expect(schema.parse("https://example.com:8080")).toBe("https://example.com:8080")
174
174
  })
175
175
 
176
176
  it("should reject disallowed ports", () => {
177
- const schema = url({ allowedPorts: [443] })
177
+ const schema = url(true, { allowedPorts: [443] })
178
178
  expect(() => schema.parse("http://example.com")).toThrow() // Port 80
179
179
  })
180
180
 
181
181
  it("should reject blocked ports", () => {
182
- const schema = url({ blockedPorts: [80] })
182
+ const schema = url(true, { blockedPorts: [80] })
183
183
  expect(schema.parse("https://example.com")).toBe("https://example.com") // 443
184
184
  expect(() => schema.parse("http://example.com")).toThrow() // Port 80
185
185
  })
@@ -187,80 +187,80 @@ describe("url", () => {
187
187
 
188
188
  describe("path validation", () => {
189
189
  it("should accept path starting with required prefix", () => {
190
- const schema = url({ pathStartsWith: "/api" })
190
+ const schema = url(true, { pathStartsWith: "/api" })
191
191
  expect(schema.parse("https://example.com/api/users")).toBe("https://example.com/api/users")
192
192
  })
193
193
 
194
194
  it("should reject path not starting with required prefix", () => {
195
- const schema = url({ pathStartsWith: "/api" })
195
+ const schema = url(true, { pathStartsWith: "/api" })
196
196
  expect(() => schema.parse("https://example.com/web/users")).toThrow()
197
197
  })
198
198
 
199
199
  it("should accept path ending with required suffix", () => {
200
- const schema = url({ pathEndsWith: ".json" })
200
+ const schema = url(true, { pathEndsWith: ".json" })
201
201
  expect(schema.parse("https://example.com/api/data.json")).toBe("https://example.com/api/data.json")
202
202
  })
203
203
 
204
204
  it("should reject path not ending with required suffix", () => {
205
- const schema = url({ pathEndsWith: ".json" })
205
+ const schema = url(true, { pathEndsWith: ".json" })
206
206
  expect(() => schema.parse("https://example.com/api/data.xml")).toThrow()
207
207
  })
208
208
  })
209
209
 
210
210
  describe("query validation", () => {
211
211
  it("should accept URL with query when required", () => {
212
- const schema = url({ mustHaveQuery: true })
212
+ const schema = url(true, { mustHaveQuery: true })
213
213
  expect(schema.parse("https://example.com?param=value")).toBe("https://example.com?param=value")
214
214
  })
215
215
 
216
216
  it("should reject URL without query when required", () => {
217
- const schema = url({ mustHaveQuery: true })
217
+ const schema = url(true, { mustHaveQuery: true })
218
218
  expect(() => schema.parse("https://example.com")).toThrow()
219
219
  })
220
220
 
221
221
  it("should accept URL without query when forbidden", () => {
222
- const schema = url({ mustNotHaveQuery: true })
222
+ const schema = url(true, { mustNotHaveQuery: true })
223
223
  expect(schema.parse("https://example.com")).toBe("https://example.com")
224
224
  })
225
225
 
226
226
  it("should reject URL with query when forbidden", () => {
227
- const schema = url({ mustNotHaveQuery: true })
227
+ const schema = url(true, { mustNotHaveQuery: true })
228
228
  expect(() => schema.parse("https://example.com?param=value")).toThrow()
229
229
  })
230
230
  })
231
231
 
232
232
  describe("fragment validation", () => {
233
233
  it("should accept URL with fragment when required", () => {
234
- const schema = url({ mustHaveFragment: true })
234
+ const schema = url(true, { mustHaveFragment: true })
235
235
  expect(schema.parse("https://example.com#section")).toBe("https://example.com#section")
236
236
  })
237
237
 
238
238
  it("should reject URL without fragment when required", () => {
239
- const schema = url({ mustHaveFragment: true })
239
+ const schema = url(true, { mustHaveFragment: true })
240
240
  expect(() => schema.parse("https://example.com")).toThrow()
241
241
  })
242
242
 
243
243
  it("should accept URL without fragment when forbidden", () => {
244
- const schema = url({ mustNotHaveFragment: true })
244
+ const schema = url(true, { mustNotHaveFragment: true })
245
245
  expect(schema.parse("https://example.com")).toBe("https://example.com")
246
246
  })
247
247
 
248
248
  it("should reject URL with fragment when forbidden", () => {
249
- const schema = url({ mustNotHaveFragment: true })
249
+ const schema = url(true, { mustNotHaveFragment: true })
250
250
  expect(() => schema.parse("https://example.com#section")).toThrow()
251
251
  })
252
252
  })
253
253
 
254
254
  describe("localhost validation", () => {
255
255
  it("should allow localhost by default", () => {
256
- const schema = url()
256
+ const schema = url(true)
257
257
  expect(schema.parse("http://localhost:3000")).toBe("http://localhost:3000")
258
258
  expect(schema.parse("http://127.0.0.1")).toBe("http://127.0.0.1")
259
259
  expect(schema.parse("http://192.168.1.1")).toBe("http://192.168.1.1")
260
260
  })
261
261
 
262
262
  it("should block localhost when blockLocalhost is true", () => {
263
- const schema = url({ blockLocalhost: true })
263
+ const schema = url(true, { blockLocalhost: true })
264
264
  expect(schema.parse("https://example.com")).toBe("https://example.com")
265
265
  expect(() => schema.parse("http://localhost:3000")).toThrow()
266
266
  expect(() => schema.parse("http://127.0.0.1")).toThrow()
@@ -268,19 +268,19 @@ describe("url", () => {
268
268
  })
269
269
 
270
270
  it("should block localhost when allowLocalhost is false", () => {
271
- const schema = url({ allowLocalhost: false })
271
+ const schema = url(true, { allowLocalhost: false })
272
272
  expect(() => schema.parse("http://localhost:3000")).toThrow()
273
273
  })
274
274
  })
275
275
 
276
276
  describe("transform function", () => {
277
277
  it("should apply custom transform function", () => {
278
- const schema = url({ transform: (val) => val.replace("http://", "https://") })
278
+ const schema = url(true, { transform: (val) => val.replace("http://", "https://") })
279
279
  expect(schema.parse("http://example.com")).toBe("https://example.com")
280
280
  })
281
281
 
282
282
  it("should apply transform before validation", () => {
283
- const schema = url({
283
+ const schema = url(true, {
284
284
  protocols: ["https"],
285
285
  transform: (val) => val.replace("http://", "https://"),
286
286
  })
@@ -288,7 +288,7 @@ describe("url", () => {
288
288
  })
289
289
 
290
290
  it("should work with other validations after transform", () => {
291
- const schema = url({
291
+ const schema = url(true, {
292
292
  includes: "https",
293
293
  transform: (val) => val.replace("http://", "https://"),
294
294
  })
@@ -298,14 +298,14 @@ describe("url", () => {
298
298
 
299
299
  describe("default value", () => {
300
300
  it("should use default value when input is empty", () => {
301
- const schema = url({ defaultValue: "https://example.com" })
301
+ const schema = url(true, { defaultValue: "https://example.com" })
302
302
  expect(schema.parse("")).toBe("https://example.com")
303
303
  expect(schema.parse(null)).toBe("https://example.com")
304
304
  expect(schema.parse(undefined)).toBe("https://example.com")
305
305
  })
306
306
 
307
307
  it("should use default value when optional and input is empty", () => {
308
- const schema = url({ required: false, defaultValue: "https://example.com" })
308
+ const schema = url(false, { defaultValue: "https://example.com" })
309
309
  expect(schema.parse("")).toBe("https://example.com")
310
310
  expect(schema.parse(null)).toBe("https://example.com")
311
311
  expect(schema.parse(undefined)).toBe("https://example.com")
@@ -314,7 +314,7 @@ describe("url", () => {
314
314
 
315
315
  describe("i18n custom messages", () => {
316
316
  it("should use custom English messages", () => {
317
- const schema = url({
317
+ const schema = url(true, {
318
318
  i18n: {
319
319
  en: { invalid: "Custom URL format error" },
320
320
  "zh-TW": { invalid: "自定義 URL 格式錯誤" },
@@ -330,7 +330,7 @@ describe("url", () => {
330
330
  })
331
331
 
332
332
  it("should use custom Chinese messages", () => {
333
- const schema = url({
333
+ const schema = url(true, {
334
334
  i18n: {
335
335
  en: { invalid: "Custom URL format error" },
336
336
  "zh-TW": { invalid: "自定義 URL 格式錯誤" },
@@ -346,7 +346,7 @@ describe("url", () => {
346
346
  })
347
347
 
348
348
  it("should fallback to default messages when custom not provided", () => {
349
- const schema = url({
349
+ const schema = url(true, {
350
350
  i18n: {
351
351
  en: { invalid: "Custom invalid error" },
352
352
  "zh-TW": { invalid: "自定義無效錯誤" },
@@ -362,7 +362,7 @@ describe("url", () => {
362
362
  })
363
363
 
364
364
  it("should handle protocol validation with custom message", () => {
365
- const schema = url({
365
+ const schema = url(true, {
366
366
  protocols: ["https"],
367
367
  i18n: {
368
368
  en: { protocol: "Only HTTPS allowed!" },
@@ -379,7 +379,7 @@ describe("url", () => {
379
379
  })
380
380
 
381
381
  it("should handle domain validation with custom message", () => {
382
- const schema = url({
382
+ const schema = url(true, {
383
383
  allowedDomains: ["example.com"],
384
384
  i18n: {
385
385
  en: { domain: "Only example.com allowed!" },
@@ -399,7 +399,7 @@ describe("url", () => {
399
399
  describe("localization", () => {
400
400
  it("should use English error messages", () => {
401
401
  setLocale("en")
402
- const schema = url()
402
+ const schema = url(true)
403
403
 
404
404
  try {
405
405
  schema.parse("invalid")
@@ -410,7 +410,7 @@ describe("url", () => {
410
410
 
411
411
  it("should use Chinese error messages", () => {
412
412
  setLocale("zh-TW")
413
- const schema = url()
413
+ const schema = url(true)
414
414
 
415
415
  try {
416
416
  schema.parse("invalid")
@@ -421,7 +421,7 @@ describe("url", () => {
421
421
 
422
422
  it("should use Chinese domain validation messages", () => {
423
423
  setLocale("zh-TW")
424
- const schema = url({ allowedDomains: ["example.com"] })
424
+ const schema = url(true, { allowedDomains: ["example.com"] })
425
425
 
426
426
  try {
427
427
  schema.parse("https://other.com")
@@ -433,7 +433,7 @@ describe("url", () => {
433
433
 
434
434
  describe("complex scenarios", () => {
435
435
  it("should handle multiple validations combined", () => {
436
- const schema = url({
436
+ const schema = url(true, {
437
437
  protocols: ["https"],
438
438
  allowedDomains: ["example.com"],
439
439
  min: 20,
@@ -451,7 +451,7 @@ describe("url", () => {
451
451
  })
452
452
 
453
453
  it("should handle localhost detection in private networks", () => {
454
- const schema = url({ blockLocalhost: true })
454
+ const schema = url(true, { blockLocalhost: true })
455
455
 
456
456
  expect(() => schema.parse("http://10.0.0.1")).toThrow()
457
457
  expect(() => schema.parse("http://172.16.0.1")).toThrow()
@@ -460,7 +460,7 @@ describe("url", () => {
460
460
  })
461
461
 
462
462
  it("should handle edge cases with ports", () => {
463
- const schema = url({ allowedPorts: [443, 8080] })
463
+ const schema = url(true, { allowedPorts: [443, 8080] })
464
464
 
465
465
  expect(schema.parse("https://example.com")).toBe("https://example.com") // Default 443
466
466
  expect(schema.parse("https://example.com:8080")).toBe("https://example.com:8080")
@@ -470,24 +470,24 @@ describe("url", () => {
470
470
 
471
471
  describe("edge cases", () => {
472
472
  it("should handle URLs with special characters", () => {
473
- const schema = url()
473
+ const schema = url(true)
474
474
  expect(schema.parse("https://example.com/path%20with%20spaces")).toBe("https://example.com/path%20with%20spaces")
475
475
  })
476
476
 
477
477
  it("should handle international domain names", () => {
478
- const schema = url()
478
+ const schema = url(true)
479
479
  expect(schema.parse("https://xn--fsq.com")).toBe("https://xn--fsq.com") // Internationalized domain
480
480
  })
481
481
 
482
482
  it("should handle URLs with authentication", () => {
483
- const schema = url()
483
+ const schema = url(true)
484
484
  expect(schema.parse("https://user:pass@example.com")).toBe("https://user:pass@example.com")
485
485
  })
486
486
 
487
487
  it("should handle very long URLs", () => {
488
488
  const longPath = "/very/long/path/" + "segment/".repeat(100)
489
489
  const longUrl = `https://example.com${longPath}`
490
- const schema = url()
490
+ const schema = url(true)
491
491
  expect(schema.parse(longUrl)).toBe(longUrl)
492
492
  })
493
493
  })
@@ -1,12 +1,12 @@
1
1
  import { describe, it, expect, beforeEach } from "vitest"
2
2
  import { businessId, setLocale, validateTaiwanBusinessId } from "../../src"
3
3
 
4
- describe("Taiwan businessId() validator", () => {
4
+ describe("Taiwan businessId(true) validator", () => {
5
5
  beforeEach(() => setLocale("en"))
6
6
 
7
7
  describe("basic functionality", () => {
8
8
  it("should validate correct Taiwan business IDs", () => {
9
- const schema = businessId()
9
+ const schema = businessId(true)
10
10
 
11
11
  // Valid Taiwan business IDs (統一編號) - using calculation based on new/old rules
12
12
  expect(schema.parse("22550077")).toBe("22550077") // Sum = 50, 50 % 5 = 0 (new rule)
@@ -15,7 +15,7 @@ describe("Taiwan businessId() validator", () => {
15
15
  })
16
16
 
17
17
  it("should reject invalid Taiwan business IDs", () => {
18
- const schema = businessId()
18
+ const schema = businessId(true)
19
19
 
20
20
  // Invalid checksums
21
21
  expect(() => schema.parse("12345672")).toThrow("Invalid Taiwan Business ID")
@@ -24,7 +24,7 @@ describe("Taiwan businessId() validator", () => {
24
24
  })
25
25
 
26
26
  it("should reject non-numeric inputs", () => {
27
- const schema = businessId()
27
+ const schema = businessId(true)
28
28
 
29
29
  expect(() => schema.parse("1234567A")).toThrow("Invalid Taiwan Business ID")
30
30
  expect(() => schema.parse("abcdefgh")).toThrow("Invalid Taiwan Business ID")
@@ -32,7 +32,7 @@ describe("Taiwan businessId() validator", () => {
32
32
  })
33
33
 
34
34
  it("should reject wrong length inputs", () => {
35
- const schema = businessId()
35
+ const schema = businessId(true)
36
36
 
37
37
  expect(() => schema.parse("1234567")).toThrow("Invalid Taiwan Business ID")
38
38
  expect(() => schema.parse("123456789")).toThrow("Invalid Taiwan Business ID")
@@ -43,7 +43,7 @@ describe("Taiwan businessId() validator", () => {
43
43
 
44
44
  describe("special case validation (7th digit = 7)", () => {
45
45
  it("should handle special case where 7th digit is 7", () => {
46
- const schema = businessId()
46
+ const schema = businessId(true)
47
47
 
48
48
  // Valid number with 7th digit = 7 for testing special case
49
49
  expect(schema.parse("12345670")).toBe("12345670") // Should be valid with special case
@@ -75,7 +75,7 @@ describe("Taiwan businessId() validator", () => {
75
75
 
76
76
  describe("required/optional behavior", () => {
77
77
  it("should handle required=true (default)", () => {
78
- const schema = businessId()
78
+ const schema = businessId(true)
79
79
 
80
80
  expect(() => schema.parse("")).toThrow("Required")
81
81
  expect(() => schema.parse(null)).toThrow()
@@ -83,7 +83,7 @@ describe("Taiwan businessId() validator", () => {
83
83
  })
84
84
 
85
85
  it("should handle required=false", () => {
86
- const schema = businessId({ required: false })
86
+ const schema = businessId(false)
87
87
 
88
88
  expect(schema.parse("")).toBe(null)
89
89
  expect(schema.parse(null)).toBe(null)
@@ -92,8 +92,8 @@ describe("Taiwan businessId() validator", () => {
92
92
  })
93
93
 
94
94
  it("should use default values", () => {
95
- const requiredSchema = businessId({ defaultValue: "12345675" })
96
- const optionalSchema = businessId({ required: false, defaultValue: "12345675" })
95
+ const requiredSchema = businessId(true, { defaultValue: "12345675" })
96
+ const optionalSchema = businessId(false, { defaultValue: "12345675" })
97
97
 
98
98
  expect(requiredSchema.parse("")).toBe("12345675")
99
99
  expect(optionalSchema.parse("")).toBe("12345675")
@@ -102,7 +102,7 @@ describe("Taiwan businessId() validator", () => {
102
102
 
103
103
  describe("transform function", () => {
104
104
  it("should apply custom transform", () => {
105
- const schema = businessId({
105
+ const schema = businessId(true, {
106
106
  transform: (val) => val.replace(/[-\s]/g, ""),
107
107
  })
108
108
 
@@ -112,7 +112,7 @@ describe("Taiwan businessId() validator", () => {
112
112
  })
113
113
 
114
114
  it("should apply transform before validation", () => {
115
- const schema = businessId({
115
+ const schema = businessId(true, {
116
116
  transform: (val) => val.replace(/\s+/g, ""),
117
117
  })
118
118
 
@@ -123,14 +123,14 @@ describe("Taiwan businessId() validator", () => {
123
123
 
124
124
  describe("input preprocessing", () => {
125
125
  it("should handle string conversion", () => {
126
- const schema = businessId()
126
+ const schema = businessId(true)
127
127
 
128
128
  expect(schema.parse(12345675)).toBe("12345675")
129
129
  expect(() => schema.parse(12345672)).toThrow("Invalid Taiwan Business ID")
130
130
  })
131
131
 
132
132
  it("should trim whitespace", () => {
133
- const schema = businessId()
133
+ const schema = businessId(true)
134
134
 
135
135
  expect(schema.parse(" 12345675 ")).toBe("12345675")
136
136
  expect(schema.parse("\t12345675\n")).toBe("12345675")
@@ -140,7 +140,7 @@ describe("Taiwan businessId() validator", () => {
140
140
  describe("i18n support", () => {
141
141
  it("should use English messages by default", () => {
142
142
  setLocale("en")
143
- const schema = businessId()
143
+ const schema = businessId(true)
144
144
 
145
145
  expect(() => schema.parse("")).toThrow("Required")
146
146
  expect(() => schema.parse("1234567")).toThrow("Invalid Taiwan Business ID")
@@ -149,7 +149,7 @@ describe("Taiwan businessId() validator", () => {
149
149
 
150
150
  it("should use Chinese messages when locale is zh-TW", () => {
151
151
  setLocale("zh-TW")
152
- const schema = businessId()
152
+ const schema = businessId(true)
153
153
 
154
154
  expect(() => schema.parse("")).toThrow("必填")
155
155
  expect(() => schema.parse("1234567")).toThrow("無效的統一編號")
@@ -157,7 +157,7 @@ describe("Taiwan businessId() validator", () => {
157
157
  })
158
158
 
159
159
  it("should support custom i18n messages", () => {
160
- const schema = businessId({
160
+ const schema = businessId(true, {
161
161
  i18n: {
162
162
  en: {
163
163
  required: "Business ID is required",
@@ -182,7 +182,7 @@ describe("Taiwan businessId() validator", () => {
182
182
 
183
183
  describe("real world Taiwan business IDs", () => {
184
184
  it("should validate known real business IDs", () => {
185
- const schema = businessId()
185
+ const schema = businessId(true)
186
186
 
187
187
  // These are example valid Taiwan business IDs for testing
188
188
  const validIds = [
@@ -198,7 +198,7 @@ describe("Taiwan businessId() validator", () => {
198
198
  })
199
199
 
200
200
  it("should reject common invalid patterns", () => {
201
- const schema = businessId()
201
+ const schema = businessId(true)
202
202
 
203
203
  const invalidIds = [
204
204
  "00000001", // All zeros with bad checksum
@@ -218,15 +218,15 @@ describe("Taiwan businessId() validator", () => {
218
218
 
219
219
  describe("edge cases", () => {
220
220
  it("should handle leading zeros", () => {
221
- const schema = businessId()
221
+ const schema = businessId(true)
222
222
 
223
223
  expect(schema.parse("04595257")).toBe("04595257")
224
224
  expect(() => schema.parse("00123456")).toThrow("Invalid Taiwan Business ID")
225
225
  })
226
226
 
227
227
  it("should handle empty and whitespace inputs", () => {
228
- const schema = businessId()
229
- const optionalSchema = businessId({ required: false })
228
+ const schema = businessId(true)
229
+ const optionalSchema = businessId(false)
230
230
 
231
231
  expect(() => schema.parse("")).toThrow("Required")
232
232
  expect(() => schema.parse(" ")).toThrow("Required")