@hy_ong/zod-kit 0.1.4 → 0.1.6
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 +66 -22
- package/dist/index.d.cts +22 -26
- package/dist/index.d.ts +22 -26
- package/dist/index.js +66 -22
- package/package.json +1 -1
- package/src/validators/taiwan/fax.ts +70 -46
- package/src/validators/taiwan/tel.ts +70 -46
- package/tests/taiwan/tel.test.ts +1 -0
package/dist/index.cjs
CHANGED
|
@@ -3326,36 +3326,58 @@ var validateTaiwanTel = (value) => {
|
|
|
3326
3326
|
return false;
|
|
3327
3327
|
}
|
|
3328
3328
|
const areaCode4 = cleanValue.substring(0, 4);
|
|
3329
|
-
if (areaCode4 === "0826") {
|
|
3330
|
-
return cleanValue.length === 9 && /^0826[6]\d{4}$/.test(cleanValue);
|
|
3331
|
-
}
|
|
3332
3329
|
if (areaCode4 === "0836") {
|
|
3333
|
-
return cleanValue.length === 9 && /^0836
|
|
3330
|
+
return cleanValue.length === 9 && /^0836\d{5}$/.test(cleanValue);
|
|
3334
3331
|
}
|
|
3335
3332
|
const areaCode3 = cleanValue.substring(0, 3);
|
|
3336
3333
|
if (areaCode3 === "037") {
|
|
3337
|
-
|
|
3334
|
+
const firstDigit = cleanValue[3];
|
|
3335
|
+
if (firstDigit === "0" || firstDigit === "1") {
|
|
3336
|
+
return false;
|
|
3337
|
+
}
|
|
3338
|
+
return (cleanValue.length === 9 || cleanValue.length === 10) && /^037[2-9]\d{5,6}$/.test(cleanValue);
|
|
3338
3339
|
}
|
|
3339
3340
|
if (areaCode3 === "049") {
|
|
3340
|
-
return cleanValue.length === 10 && /^049
|
|
3341
|
+
return cleanValue.length === 10 && /^049\d{7}$/.test(cleanValue);
|
|
3341
3342
|
}
|
|
3342
3343
|
if (areaCode3 === "082") {
|
|
3343
|
-
return cleanValue.length === 9 && /^082
|
|
3344
|
+
return cleanValue.length === 9 && /^082\d{6}$/.test(cleanValue);
|
|
3344
3345
|
}
|
|
3345
3346
|
if (areaCode3 === "089") {
|
|
3346
|
-
return cleanValue.length === 9 && /^089
|
|
3347
|
+
return cleanValue.length === 9 && /^089\d{6}$/.test(cleanValue);
|
|
3347
3348
|
}
|
|
3348
3349
|
const areaCode2 = cleanValue.substring(0, 2);
|
|
3349
3350
|
if (areaCode2 === "02") {
|
|
3350
|
-
|
|
3351
|
+
const firstDigit = cleanValue[2];
|
|
3352
|
+
if (firstDigit === "0" || firstDigit === "1") {
|
|
3353
|
+
return false;
|
|
3354
|
+
}
|
|
3355
|
+
return cleanValue.length === 10 && /^02[2-9]\d{7}$/.test(cleanValue);
|
|
3356
|
+
}
|
|
3357
|
+
if (areaCode2 === "03") {
|
|
3358
|
+
return (cleanValue.length === 9 || cleanValue.length === 10) && /^03\d{7,8}$/.test(cleanValue);
|
|
3351
3359
|
}
|
|
3352
|
-
if (
|
|
3353
|
-
return cleanValue.length === 9;
|
|
3360
|
+
if (areaCode2 === "04") {
|
|
3361
|
+
return (cleanValue.length === 9 || cleanValue.length === 10) && /^04\d{7,8}$/.test(cleanValue);
|
|
3362
|
+
}
|
|
3363
|
+
if (areaCode2 === "05") {
|
|
3364
|
+
return cleanValue.length === 9 && /^05\d{7}$/.test(cleanValue);
|
|
3365
|
+
}
|
|
3366
|
+
if (areaCode2 === "06") {
|
|
3367
|
+
return cleanValue.length === 9 && /^06\d{7}$/.test(cleanValue);
|
|
3354
3368
|
}
|
|
3355
3369
|
if (areaCode2 === "07") {
|
|
3370
|
+
const firstDigit = cleanValue[2];
|
|
3371
|
+
if (firstDigit === "0" || firstDigit === "1") {
|
|
3372
|
+
return false;
|
|
3373
|
+
}
|
|
3356
3374
|
return cleanValue.length === 9 && /^07[2-9]\d{6}$/.test(cleanValue);
|
|
3357
3375
|
}
|
|
3358
3376
|
if (areaCode2 === "08") {
|
|
3377
|
+
const firstDigit = cleanValue[2];
|
|
3378
|
+
if (firstDigit !== "4" && firstDigit !== "7" && firstDigit !== "8") {
|
|
3379
|
+
return false;
|
|
3380
|
+
}
|
|
3359
3381
|
return cleanValue.length === 9 && /^08[478]\d{6}$/.test(cleanValue);
|
|
3360
3382
|
}
|
|
3361
3383
|
return false;
|
|
@@ -3426,36 +3448,58 @@ var validateTaiwanFax = (value) => {
|
|
|
3426
3448
|
return false;
|
|
3427
3449
|
}
|
|
3428
3450
|
const areaCode4 = cleanValue.substring(0, 4);
|
|
3429
|
-
if (areaCode4 === "0826") {
|
|
3430
|
-
return cleanValue.length === 9 && /^0826[6]\d{4}$/.test(cleanValue);
|
|
3431
|
-
}
|
|
3432
3451
|
if (areaCode4 === "0836") {
|
|
3433
|
-
return cleanValue.length === 9 && /^0836
|
|
3452
|
+
return cleanValue.length === 9 && /^0836\d{5}$/.test(cleanValue);
|
|
3434
3453
|
}
|
|
3435
3454
|
const areaCode3 = cleanValue.substring(0, 3);
|
|
3436
3455
|
if (areaCode3 === "037") {
|
|
3437
|
-
|
|
3456
|
+
const firstDigit = cleanValue[3];
|
|
3457
|
+
if (firstDigit === "0" || firstDigit === "1") {
|
|
3458
|
+
return false;
|
|
3459
|
+
}
|
|
3460
|
+
return (cleanValue.length === 9 || cleanValue.length === 10) && /^037[2-9]\d{5,6}$/.test(cleanValue);
|
|
3438
3461
|
}
|
|
3439
3462
|
if (areaCode3 === "049") {
|
|
3440
|
-
return cleanValue.length === 10 && /^049
|
|
3463
|
+
return cleanValue.length === 10 && /^049\d{7}$/.test(cleanValue);
|
|
3441
3464
|
}
|
|
3442
3465
|
if (areaCode3 === "082") {
|
|
3443
|
-
return cleanValue.length === 9 && /^082
|
|
3466
|
+
return cleanValue.length === 9 && /^082\d{6}$/.test(cleanValue);
|
|
3444
3467
|
}
|
|
3445
3468
|
if (areaCode3 === "089") {
|
|
3446
|
-
return cleanValue.length === 9 && /^089
|
|
3469
|
+
return cleanValue.length === 9 && /^089\d{6}$/.test(cleanValue);
|
|
3447
3470
|
}
|
|
3448
3471
|
const areaCode2 = cleanValue.substring(0, 2);
|
|
3449
3472
|
if (areaCode2 === "02") {
|
|
3450
|
-
|
|
3473
|
+
const firstDigit = cleanValue[2];
|
|
3474
|
+
if (firstDigit === "0" || firstDigit === "1") {
|
|
3475
|
+
return false;
|
|
3476
|
+
}
|
|
3477
|
+
return cleanValue.length === 10 && /^02[2-9]\d{7}$/.test(cleanValue);
|
|
3478
|
+
}
|
|
3479
|
+
if (areaCode2 === "03") {
|
|
3480
|
+
return (cleanValue.length === 9 || cleanValue.length === 10) && /^03\d{7,8}$/.test(cleanValue);
|
|
3451
3481
|
}
|
|
3452
|
-
if (
|
|
3453
|
-
return cleanValue.length === 9;
|
|
3482
|
+
if (areaCode2 === "04") {
|
|
3483
|
+
return (cleanValue.length === 9 || cleanValue.length === 10) && /^04\d{7,8}$/.test(cleanValue);
|
|
3484
|
+
}
|
|
3485
|
+
if (areaCode2 === "05") {
|
|
3486
|
+
return cleanValue.length === 9 && /^05\d{7}$/.test(cleanValue);
|
|
3487
|
+
}
|
|
3488
|
+
if (areaCode2 === "06") {
|
|
3489
|
+
return cleanValue.length === 9 && /^06\d{7}$/.test(cleanValue);
|
|
3454
3490
|
}
|
|
3455
3491
|
if (areaCode2 === "07") {
|
|
3492
|
+
const firstDigit = cleanValue[2];
|
|
3493
|
+
if (firstDigit === "0" || firstDigit === "1") {
|
|
3494
|
+
return false;
|
|
3495
|
+
}
|
|
3456
3496
|
return cleanValue.length === 9 && /^07[2-9]\d{6}$/.test(cleanValue);
|
|
3457
3497
|
}
|
|
3458
3498
|
if (areaCode2 === "08") {
|
|
3499
|
+
const firstDigit = cleanValue[2];
|
|
3500
|
+
if (firstDigit !== "4" && firstDigit !== "7" && firstDigit !== "8") {
|
|
3501
|
+
return false;
|
|
3502
|
+
}
|
|
3459
3503
|
return cleanValue.length === 9 && /^08[478]\d{6}$/.test(cleanValue);
|
|
3460
3504
|
}
|
|
3461
3505
|
return false;
|
package/dist/index.d.cts
CHANGED
|
@@ -2898,28 +2898,26 @@ type TwTelSchema<IsRequired extends boolean> = IsRequired extends true ? ZodStri
|
|
|
2898
2898
|
* number patterns.
|
|
2899
2899
|
*
|
|
2900
2900
|
* Supported area codes and formats:
|
|
2901
|
-
* - 02: Taipei, New Taipei, Keelung - 8 digits
|
|
2902
|
-
* - 03: Taoyuan, Hsinchu, Yilan, Hualien - 7 digits
|
|
2903
|
-
* - 037: Miaoli - 6 digits
|
|
2904
|
-
* - 04: Taichung, Changhua - 7 digits
|
|
2905
|
-
* - 049: Nantou - 7 digits
|
|
2901
|
+
* - 02: Taipei, New Taipei, Keelung - 8 digits
|
|
2902
|
+
* - 03: Taoyuan, Hsinchu, Yilan, Hualien - 7-8 digits
|
|
2903
|
+
* - 037: Miaoli - 6-7 digits
|
|
2904
|
+
* - 04: Taichung, Changhua, Nantou - 7-8 digits
|
|
2905
|
+
* - 049: Nantou - 7 digits
|
|
2906
2906
|
* - 05: Yunlin, Chiayi - 7 digits
|
|
2907
2907
|
* - 06: Tainan - 7 digits
|
|
2908
|
-
* - 07: Kaohsiung - 7 digits
|
|
2909
|
-
* - 08: Pingtung - 7 digits
|
|
2910
|
-
* - 082: Kinmen - 6 digits
|
|
2911
|
-
* -
|
|
2912
|
-
* -
|
|
2913
|
-
* - 089: Taitung - 6 digits (2~9+5D)
|
|
2908
|
+
* - 07: Kaohsiung - 7 digits
|
|
2909
|
+
* - 08: Pingtung - 7 digits
|
|
2910
|
+
* - 082: Kinmen - 6 digits
|
|
2911
|
+
* - 0836: Matsu - 5 digits
|
|
2912
|
+
* - 089: Taitung - 6 digits
|
|
2914
2913
|
*
|
|
2915
2914
|
* @example
|
|
2916
2915
|
* ```typescript
|
|
2917
2916
|
* validateTaiwanTel("0223456789") // true (Taipei area)
|
|
2918
|
-
* validateTaiwanTel("
|
|
2917
|
+
* validateTaiwanTel("0423288882") // true (Taichung area, 8 digits)
|
|
2919
2918
|
* validateTaiwanTel("037234567") // true (Miaoli area)
|
|
2920
2919
|
* validateTaiwanTel("082234567") // true (Kinmen area)
|
|
2921
2920
|
* validateTaiwanTel("02-2345-6789") // true (with separators)
|
|
2922
|
-
* validateTaiwanTel("0812345678") // false (invalid for 08 area)
|
|
2923
2921
|
* ```
|
|
2924
2922
|
*/
|
|
2925
2923
|
declare const validateTaiwanTel: (value: string) => boolean;
|
|
@@ -3055,27 +3053,25 @@ type TwFaxSchema<IsRequired extends boolean> = IsRequired extends true ? ZodStri
|
|
|
3055
3053
|
* Fax numbers follow the same format as landline telephone numbers in Taiwan.
|
|
3056
3054
|
*
|
|
3057
3055
|
* Supported area codes and formats (same as landline):
|
|
3058
|
-
* - 02: Taipei, New Taipei, Keelung - 8 digits
|
|
3059
|
-
* - 03: Taoyuan, Hsinchu, Yilan, Hualien - 7 digits
|
|
3060
|
-
* - 037: Miaoli - 6 digits
|
|
3061
|
-
* - 04: Taichung, Changhua - 7 digits
|
|
3062
|
-
* - 049: Nantou - 7 digits
|
|
3056
|
+
* - 02: Taipei, New Taipei, Keelung - 8 digits
|
|
3057
|
+
* - 03: Taoyuan, Hsinchu, Yilan, Hualien - 7-8 digits
|
|
3058
|
+
* - 037: Miaoli - 6-7 digits
|
|
3059
|
+
* - 04: Taichung, Changhua, Nantou - 7-8 digits
|
|
3060
|
+
* - 049: Nantou - 7 digits
|
|
3063
3061
|
* - 05: Yunlin, Chiayi - 7 digits
|
|
3064
3062
|
* - 06: Tainan - 7 digits
|
|
3065
|
-
* - 07: Kaohsiung - 7 digits
|
|
3066
|
-
* - 08: Pingtung - 7 digits
|
|
3067
|
-
* - 082: Kinmen - 6 digits
|
|
3068
|
-
* -
|
|
3069
|
-
* -
|
|
3070
|
-
* - 089: Taitung - 6 digits (2~9+5D)
|
|
3063
|
+
* - 07: Kaohsiung - 7 digits
|
|
3064
|
+
* - 08: Pingtung - 7 digits
|
|
3065
|
+
* - 082: Kinmen - 6 digits
|
|
3066
|
+
* - 0836: Matsu - 5 digits
|
|
3067
|
+
* - 089: Taitung - 6 digits
|
|
3071
3068
|
*
|
|
3072
3069
|
* @example
|
|
3073
3070
|
* ```typescript
|
|
3074
3071
|
* validateTaiwanFax("0223456789") // true (Taipei area)
|
|
3075
|
-
* validateTaiwanFax("
|
|
3072
|
+
* validateTaiwanFax("0423288882") // true (Taichung area, 8 digits)
|
|
3076
3073
|
* validateTaiwanFax("037234567") // true (Miaoli area)
|
|
3077
3074
|
* validateTaiwanFax("02-2345-6789") // true (with separators)
|
|
3078
|
-
* validateTaiwanFax("0812345678") // false (invalid for 08 area)
|
|
3079
3075
|
* ```
|
|
3080
3076
|
*/
|
|
3081
3077
|
declare const validateTaiwanFax: (value: string) => boolean;
|
package/dist/index.d.ts
CHANGED
|
@@ -2898,28 +2898,26 @@ type TwTelSchema<IsRequired extends boolean> = IsRequired extends true ? ZodStri
|
|
|
2898
2898
|
* number patterns.
|
|
2899
2899
|
*
|
|
2900
2900
|
* Supported area codes and formats:
|
|
2901
|
-
* - 02: Taipei, New Taipei, Keelung - 8 digits
|
|
2902
|
-
* - 03: Taoyuan, Hsinchu, Yilan, Hualien - 7 digits
|
|
2903
|
-
* - 037: Miaoli - 6 digits
|
|
2904
|
-
* - 04: Taichung, Changhua - 7 digits
|
|
2905
|
-
* - 049: Nantou - 7 digits
|
|
2901
|
+
* - 02: Taipei, New Taipei, Keelung - 8 digits
|
|
2902
|
+
* - 03: Taoyuan, Hsinchu, Yilan, Hualien - 7-8 digits
|
|
2903
|
+
* - 037: Miaoli - 6-7 digits
|
|
2904
|
+
* - 04: Taichung, Changhua, Nantou - 7-8 digits
|
|
2905
|
+
* - 049: Nantou - 7 digits
|
|
2906
2906
|
* - 05: Yunlin, Chiayi - 7 digits
|
|
2907
2907
|
* - 06: Tainan - 7 digits
|
|
2908
|
-
* - 07: Kaohsiung - 7 digits
|
|
2909
|
-
* - 08: Pingtung - 7 digits
|
|
2910
|
-
* - 082: Kinmen - 6 digits
|
|
2911
|
-
* -
|
|
2912
|
-
* -
|
|
2913
|
-
* - 089: Taitung - 6 digits (2~9+5D)
|
|
2908
|
+
* - 07: Kaohsiung - 7 digits
|
|
2909
|
+
* - 08: Pingtung - 7 digits
|
|
2910
|
+
* - 082: Kinmen - 6 digits
|
|
2911
|
+
* - 0836: Matsu - 5 digits
|
|
2912
|
+
* - 089: Taitung - 6 digits
|
|
2914
2913
|
*
|
|
2915
2914
|
* @example
|
|
2916
2915
|
* ```typescript
|
|
2917
2916
|
* validateTaiwanTel("0223456789") // true (Taipei area)
|
|
2918
|
-
* validateTaiwanTel("
|
|
2917
|
+
* validateTaiwanTel("0423288882") // true (Taichung area, 8 digits)
|
|
2919
2918
|
* validateTaiwanTel("037234567") // true (Miaoli area)
|
|
2920
2919
|
* validateTaiwanTel("082234567") // true (Kinmen area)
|
|
2921
2920
|
* validateTaiwanTel("02-2345-6789") // true (with separators)
|
|
2922
|
-
* validateTaiwanTel("0812345678") // false (invalid for 08 area)
|
|
2923
2921
|
* ```
|
|
2924
2922
|
*/
|
|
2925
2923
|
declare const validateTaiwanTel: (value: string) => boolean;
|
|
@@ -3055,27 +3053,25 @@ type TwFaxSchema<IsRequired extends boolean> = IsRequired extends true ? ZodStri
|
|
|
3055
3053
|
* Fax numbers follow the same format as landline telephone numbers in Taiwan.
|
|
3056
3054
|
*
|
|
3057
3055
|
* Supported area codes and formats (same as landline):
|
|
3058
|
-
* - 02: Taipei, New Taipei, Keelung - 8 digits
|
|
3059
|
-
* - 03: Taoyuan, Hsinchu, Yilan, Hualien - 7 digits
|
|
3060
|
-
* - 037: Miaoli - 6 digits
|
|
3061
|
-
* - 04: Taichung, Changhua - 7 digits
|
|
3062
|
-
* - 049: Nantou - 7 digits
|
|
3056
|
+
* - 02: Taipei, New Taipei, Keelung - 8 digits
|
|
3057
|
+
* - 03: Taoyuan, Hsinchu, Yilan, Hualien - 7-8 digits
|
|
3058
|
+
* - 037: Miaoli - 6-7 digits
|
|
3059
|
+
* - 04: Taichung, Changhua, Nantou - 7-8 digits
|
|
3060
|
+
* - 049: Nantou - 7 digits
|
|
3063
3061
|
* - 05: Yunlin, Chiayi - 7 digits
|
|
3064
3062
|
* - 06: Tainan - 7 digits
|
|
3065
|
-
* - 07: Kaohsiung - 7 digits
|
|
3066
|
-
* - 08: Pingtung - 7 digits
|
|
3067
|
-
* - 082: Kinmen - 6 digits
|
|
3068
|
-
* -
|
|
3069
|
-
* -
|
|
3070
|
-
* - 089: Taitung - 6 digits (2~9+5D)
|
|
3063
|
+
* - 07: Kaohsiung - 7 digits
|
|
3064
|
+
* - 08: Pingtung - 7 digits
|
|
3065
|
+
* - 082: Kinmen - 6 digits
|
|
3066
|
+
* - 0836: Matsu - 5 digits
|
|
3067
|
+
* - 089: Taitung - 6 digits
|
|
3071
3068
|
*
|
|
3072
3069
|
* @example
|
|
3073
3070
|
* ```typescript
|
|
3074
3071
|
* validateTaiwanFax("0223456789") // true (Taipei area)
|
|
3075
|
-
* validateTaiwanFax("
|
|
3072
|
+
* validateTaiwanFax("0423288882") // true (Taichung area, 8 digits)
|
|
3076
3073
|
* validateTaiwanFax("037234567") // true (Miaoli area)
|
|
3077
3074
|
* validateTaiwanFax("02-2345-6789") // true (with separators)
|
|
3078
|
-
* validateTaiwanFax("0812345678") // false (invalid for 08 area)
|
|
3079
3075
|
* ```
|
|
3080
3076
|
*/
|
|
3081
3077
|
declare const validateTaiwanFax: (value: string) => boolean;
|
package/dist/index.js
CHANGED
|
@@ -3248,36 +3248,58 @@ var validateTaiwanTel = (value) => {
|
|
|
3248
3248
|
return false;
|
|
3249
3249
|
}
|
|
3250
3250
|
const areaCode4 = cleanValue.substring(0, 4);
|
|
3251
|
-
if (areaCode4 === "0826") {
|
|
3252
|
-
return cleanValue.length === 9 && /^0826[6]\d{4}$/.test(cleanValue);
|
|
3253
|
-
}
|
|
3254
3251
|
if (areaCode4 === "0836") {
|
|
3255
|
-
return cleanValue.length === 9 && /^0836
|
|
3252
|
+
return cleanValue.length === 9 && /^0836\d{5}$/.test(cleanValue);
|
|
3256
3253
|
}
|
|
3257
3254
|
const areaCode3 = cleanValue.substring(0, 3);
|
|
3258
3255
|
if (areaCode3 === "037") {
|
|
3259
|
-
|
|
3256
|
+
const firstDigit = cleanValue[3];
|
|
3257
|
+
if (firstDigit === "0" || firstDigit === "1") {
|
|
3258
|
+
return false;
|
|
3259
|
+
}
|
|
3260
|
+
return (cleanValue.length === 9 || cleanValue.length === 10) && /^037[2-9]\d{5,6}$/.test(cleanValue);
|
|
3260
3261
|
}
|
|
3261
3262
|
if (areaCode3 === "049") {
|
|
3262
|
-
return cleanValue.length === 10 && /^049
|
|
3263
|
+
return cleanValue.length === 10 && /^049\d{7}$/.test(cleanValue);
|
|
3263
3264
|
}
|
|
3264
3265
|
if (areaCode3 === "082") {
|
|
3265
|
-
return cleanValue.length === 9 && /^082
|
|
3266
|
+
return cleanValue.length === 9 && /^082\d{6}$/.test(cleanValue);
|
|
3266
3267
|
}
|
|
3267
3268
|
if (areaCode3 === "089") {
|
|
3268
|
-
return cleanValue.length === 9 && /^089
|
|
3269
|
+
return cleanValue.length === 9 && /^089\d{6}$/.test(cleanValue);
|
|
3269
3270
|
}
|
|
3270
3271
|
const areaCode2 = cleanValue.substring(0, 2);
|
|
3271
3272
|
if (areaCode2 === "02") {
|
|
3272
|
-
|
|
3273
|
+
const firstDigit = cleanValue[2];
|
|
3274
|
+
if (firstDigit === "0" || firstDigit === "1") {
|
|
3275
|
+
return false;
|
|
3276
|
+
}
|
|
3277
|
+
return cleanValue.length === 10 && /^02[2-9]\d{7}$/.test(cleanValue);
|
|
3278
|
+
}
|
|
3279
|
+
if (areaCode2 === "03") {
|
|
3280
|
+
return (cleanValue.length === 9 || cleanValue.length === 10) && /^03\d{7,8}$/.test(cleanValue);
|
|
3273
3281
|
}
|
|
3274
|
-
if (
|
|
3275
|
-
return cleanValue.length === 9;
|
|
3282
|
+
if (areaCode2 === "04") {
|
|
3283
|
+
return (cleanValue.length === 9 || cleanValue.length === 10) && /^04\d{7,8}$/.test(cleanValue);
|
|
3284
|
+
}
|
|
3285
|
+
if (areaCode2 === "05") {
|
|
3286
|
+
return cleanValue.length === 9 && /^05\d{7}$/.test(cleanValue);
|
|
3287
|
+
}
|
|
3288
|
+
if (areaCode2 === "06") {
|
|
3289
|
+
return cleanValue.length === 9 && /^06\d{7}$/.test(cleanValue);
|
|
3276
3290
|
}
|
|
3277
3291
|
if (areaCode2 === "07") {
|
|
3292
|
+
const firstDigit = cleanValue[2];
|
|
3293
|
+
if (firstDigit === "0" || firstDigit === "1") {
|
|
3294
|
+
return false;
|
|
3295
|
+
}
|
|
3278
3296
|
return cleanValue.length === 9 && /^07[2-9]\d{6}$/.test(cleanValue);
|
|
3279
3297
|
}
|
|
3280
3298
|
if (areaCode2 === "08") {
|
|
3299
|
+
const firstDigit = cleanValue[2];
|
|
3300
|
+
if (firstDigit !== "4" && firstDigit !== "7" && firstDigit !== "8") {
|
|
3301
|
+
return false;
|
|
3302
|
+
}
|
|
3281
3303
|
return cleanValue.length === 9 && /^08[478]\d{6}$/.test(cleanValue);
|
|
3282
3304
|
}
|
|
3283
3305
|
return false;
|
|
@@ -3348,36 +3370,58 @@ var validateTaiwanFax = (value) => {
|
|
|
3348
3370
|
return false;
|
|
3349
3371
|
}
|
|
3350
3372
|
const areaCode4 = cleanValue.substring(0, 4);
|
|
3351
|
-
if (areaCode4 === "0826") {
|
|
3352
|
-
return cleanValue.length === 9 && /^0826[6]\d{4}$/.test(cleanValue);
|
|
3353
|
-
}
|
|
3354
3373
|
if (areaCode4 === "0836") {
|
|
3355
|
-
return cleanValue.length === 9 && /^0836
|
|
3374
|
+
return cleanValue.length === 9 && /^0836\d{5}$/.test(cleanValue);
|
|
3356
3375
|
}
|
|
3357
3376
|
const areaCode3 = cleanValue.substring(0, 3);
|
|
3358
3377
|
if (areaCode3 === "037") {
|
|
3359
|
-
|
|
3378
|
+
const firstDigit = cleanValue[3];
|
|
3379
|
+
if (firstDigit === "0" || firstDigit === "1") {
|
|
3380
|
+
return false;
|
|
3381
|
+
}
|
|
3382
|
+
return (cleanValue.length === 9 || cleanValue.length === 10) && /^037[2-9]\d{5,6}$/.test(cleanValue);
|
|
3360
3383
|
}
|
|
3361
3384
|
if (areaCode3 === "049") {
|
|
3362
|
-
return cleanValue.length === 10 && /^049
|
|
3385
|
+
return cleanValue.length === 10 && /^049\d{7}$/.test(cleanValue);
|
|
3363
3386
|
}
|
|
3364
3387
|
if (areaCode3 === "082") {
|
|
3365
|
-
return cleanValue.length === 9 && /^082
|
|
3388
|
+
return cleanValue.length === 9 && /^082\d{6}$/.test(cleanValue);
|
|
3366
3389
|
}
|
|
3367
3390
|
if (areaCode3 === "089") {
|
|
3368
|
-
return cleanValue.length === 9 && /^089
|
|
3391
|
+
return cleanValue.length === 9 && /^089\d{6}$/.test(cleanValue);
|
|
3369
3392
|
}
|
|
3370
3393
|
const areaCode2 = cleanValue.substring(0, 2);
|
|
3371
3394
|
if (areaCode2 === "02") {
|
|
3372
|
-
|
|
3395
|
+
const firstDigit = cleanValue[2];
|
|
3396
|
+
if (firstDigit === "0" || firstDigit === "1") {
|
|
3397
|
+
return false;
|
|
3398
|
+
}
|
|
3399
|
+
return cleanValue.length === 10 && /^02[2-9]\d{7}$/.test(cleanValue);
|
|
3400
|
+
}
|
|
3401
|
+
if (areaCode2 === "03") {
|
|
3402
|
+
return (cleanValue.length === 9 || cleanValue.length === 10) && /^03\d{7,8}$/.test(cleanValue);
|
|
3373
3403
|
}
|
|
3374
|
-
if (
|
|
3375
|
-
return cleanValue.length === 9;
|
|
3404
|
+
if (areaCode2 === "04") {
|
|
3405
|
+
return (cleanValue.length === 9 || cleanValue.length === 10) && /^04\d{7,8}$/.test(cleanValue);
|
|
3406
|
+
}
|
|
3407
|
+
if (areaCode2 === "05") {
|
|
3408
|
+
return cleanValue.length === 9 && /^05\d{7}$/.test(cleanValue);
|
|
3409
|
+
}
|
|
3410
|
+
if (areaCode2 === "06") {
|
|
3411
|
+
return cleanValue.length === 9 && /^06\d{7}$/.test(cleanValue);
|
|
3376
3412
|
}
|
|
3377
3413
|
if (areaCode2 === "07") {
|
|
3414
|
+
const firstDigit = cleanValue[2];
|
|
3415
|
+
if (firstDigit === "0" || firstDigit === "1") {
|
|
3416
|
+
return false;
|
|
3417
|
+
}
|
|
3378
3418
|
return cleanValue.length === 9 && /^07[2-9]\d{6}$/.test(cleanValue);
|
|
3379
3419
|
}
|
|
3380
3420
|
if (areaCode2 === "08") {
|
|
3421
|
+
const firstDigit = cleanValue[2];
|
|
3422
|
+
if (firstDigit !== "4" && firstDigit !== "7" && firstDigit !== "8") {
|
|
3423
|
+
return false;
|
|
3424
|
+
}
|
|
3381
3425
|
return cleanValue.length === 9 && /^08[478]\d{6}$/.test(cleanValue);
|
|
3382
3426
|
}
|
|
3383
3427
|
return false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hy_ong/zod-kit",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "A comprehensive TypeScript library providing pre-built Zod validation schemas with full internationalization support for common data types and Taiwan-specific formats",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"zod",
|
|
@@ -65,44 +65,41 @@ export type TwFaxSchema<IsRequired extends boolean> = IsRequired extends true ?
|
|
|
65
65
|
* Fax numbers follow the same format as landline telephone numbers in Taiwan.
|
|
66
66
|
*
|
|
67
67
|
* Supported area codes and formats (same as landline):
|
|
68
|
-
* - 02: Taipei, New Taipei, Keelung - 8 digits
|
|
69
|
-
* - 03: Taoyuan, Hsinchu, Yilan, Hualien - 7 digits
|
|
70
|
-
* - 037: Miaoli - 6 digits
|
|
71
|
-
* - 04: Taichung, Changhua - 7 digits
|
|
72
|
-
* - 049: Nantou - 7 digits
|
|
68
|
+
* - 02: Taipei, New Taipei, Keelung - 8 digits
|
|
69
|
+
* - 03: Taoyuan, Hsinchu, Yilan, Hualien - 7-8 digits
|
|
70
|
+
* - 037: Miaoli - 6-7 digits
|
|
71
|
+
* - 04: Taichung, Changhua, Nantou - 7-8 digits
|
|
72
|
+
* - 049: Nantou - 7 digits
|
|
73
73
|
* - 05: Yunlin, Chiayi - 7 digits
|
|
74
74
|
* - 06: Tainan - 7 digits
|
|
75
|
-
* - 07: Kaohsiung - 7 digits
|
|
76
|
-
* - 08: Pingtung - 7 digits
|
|
77
|
-
* - 082: Kinmen - 6 digits
|
|
78
|
-
* -
|
|
79
|
-
* -
|
|
80
|
-
* - 089: Taitung - 6 digits (2~9+5D)
|
|
75
|
+
* - 07: Kaohsiung - 7 digits
|
|
76
|
+
* - 08: Pingtung - 7 digits
|
|
77
|
+
* - 082: Kinmen - 6 digits
|
|
78
|
+
* - 0836: Matsu - 5 digits
|
|
79
|
+
* - 089: Taitung - 6 digits
|
|
81
80
|
*
|
|
82
81
|
* @example
|
|
83
82
|
* ```typescript
|
|
84
83
|
* validateTaiwanFax("0223456789") // true (Taipei area)
|
|
85
|
-
* validateTaiwanFax("
|
|
84
|
+
* validateTaiwanFax("0423288882") // true (Taichung area, 8 digits)
|
|
86
85
|
* validateTaiwanFax("037234567") // true (Miaoli area)
|
|
87
86
|
* validateTaiwanFax("02-2345-6789") // true (with separators)
|
|
88
|
-
* validateTaiwanFax("0812345678") // false (invalid for 08 area)
|
|
89
87
|
* ```
|
|
90
88
|
*/
|
|
91
89
|
const validateTaiwanFax = (value: string): boolean => {
|
|
92
90
|
// Official Taiwan fax formats according to telecom numbering plan (same as landline):
|
|
93
|
-
// 02: Taipei, New Taipei, Keelung - 8 digits
|
|
94
|
-
// 03: Taoyuan, Hsinchu, Yilan, Hualien - 7 digits
|
|
95
|
-
// 037: Miaoli - 6 digits
|
|
96
|
-
// 04: Taichung, Changhua - 7 digits
|
|
97
|
-
// 049: Nantou - 7 digits
|
|
91
|
+
// 02: Taipei, New Taipei, Keelung - 8 digits
|
|
92
|
+
// 03: Taoyuan, Hsinchu, Yilan, Hualien - 7-8 digits
|
|
93
|
+
// 037: Miaoli - 6-7 digits
|
|
94
|
+
// 04: Taichung, Changhua, Nantou - 7-8 digits
|
|
95
|
+
// 049: Nantou - 7 digits
|
|
98
96
|
// 05: Yunlin, Chiayi - 7 digits
|
|
99
97
|
// 06: Tainan - 7 digits
|
|
100
|
-
// 07: Kaohsiung - 7 digits
|
|
101
|
-
// 08: Pingtung - 7 digits
|
|
102
|
-
// 082: Kinmen - 6 digits
|
|
103
|
-
//
|
|
104
|
-
//
|
|
105
|
-
// 089: Taitung - 6 digits (2~9+5D)
|
|
98
|
+
// 07: Kaohsiung - 7 digits
|
|
99
|
+
// 08: Pingtung - 7 digits
|
|
100
|
+
// 082: Kinmen - 6 digits
|
|
101
|
+
// 0836: Matsu - 5 digits
|
|
102
|
+
// 089: Taitung - 6 digits
|
|
106
103
|
|
|
107
104
|
// Remove common separators for validation
|
|
108
105
|
const cleanValue = value.replace(/[-\s]/g, "")
|
|
@@ -114,52 +111,79 @@ const validateTaiwanFax = (value: string): boolean => {
|
|
|
114
111
|
|
|
115
112
|
// Check 4-digit area codes first
|
|
116
113
|
const areaCode4 = cleanValue.substring(0, 4)
|
|
117
|
-
if (areaCode4 === '0826') {
|
|
118
|
-
// Wuqiu: 0826 + 5 digits (6+4D), total 9 digits
|
|
119
|
-
return cleanValue.length === 9 && /^0826[6]\d{4}$/.test(cleanValue)
|
|
120
|
-
}
|
|
121
114
|
if (areaCode4 === '0836') {
|
|
122
|
-
// Matsu: 0836 + 5 digits
|
|
123
|
-
return cleanValue.length === 9 && /^0836
|
|
115
|
+
// Matsu: 0836 + 5 digits, total 9 digits
|
|
116
|
+
return cleanValue.length === 9 && /^0836\d{5}$/.test(cleanValue)
|
|
124
117
|
}
|
|
125
118
|
|
|
126
119
|
// Check 3-digit area codes
|
|
127
120
|
const areaCode3 = cleanValue.substring(0, 3)
|
|
128
121
|
if (areaCode3 === '037') {
|
|
129
|
-
// Miaoli: 037 + 6 digits
|
|
130
|
-
|
|
122
|
+
// Miaoli: 037 + 6-7 digits, total 9-10 digits
|
|
123
|
+
// User number must start with 2-9 (not 0 or 1)
|
|
124
|
+
const firstDigit = cleanValue[3]
|
|
125
|
+
if (firstDigit === "0" || firstDigit === "1") {
|
|
126
|
+
return false
|
|
127
|
+
}
|
|
128
|
+
return (cleanValue.length === 9 || cleanValue.length === 10) && /^037[2-9]\d{5,6}$/.test(cleanValue)
|
|
131
129
|
}
|
|
132
130
|
if (areaCode3 === '049') {
|
|
133
|
-
// Nantou: 049 + 7 digits
|
|
134
|
-
return cleanValue.length === 10 && /^049
|
|
131
|
+
// Nantou: 049 + 7 digits, total 10 digits
|
|
132
|
+
return cleanValue.length === 10 && /^049\d{7}$/.test(cleanValue)
|
|
135
133
|
}
|
|
136
134
|
if (areaCode3 === '082') {
|
|
137
|
-
// Kinmen: 082 + 6 digits
|
|
138
|
-
return cleanValue.length === 9 && /^082
|
|
135
|
+
// Kinmen: 082 + 6 digits, total 9 digits
|
|
136
|
+
return cleanValue.length === 9 && /^082\d{6}$/.test(cleanValue)
|
|
139
137
|
}
|
|
140
138
|
if (areaCode3 === '089') {
|
|
141
|
-
// Taitung: 089 + 6 digits
|
|
142
|
-
return cleanValue.length === 9 && /^089
|
|
139
|
+
// Taitung: 089 + 6 digits, total 9 digits
|
|
140
|
+
return cleanValue.length === 9 && /^089\d{6}$/.test(cleanValue)
|
|
143
141
|
}
|
|
144
142
|
|
|
145
143
|
// Check 2-digit area codes
|
|
146
144
|
const areaCode2 = cleanValue.substring(0, 2)
|
|
147
145
|
|
|
148
146
|
if (areaCode2 === '02') {
|
|
149
|
-
// Taipei, New Taipei, Keelung: 02 + 8 digits
|
|
150
|
-
|
|
147
|
+
// Taipei, New Taipei, Keelung: 02 + 8 digits, total 10 digits
|
|
148
|
+
// User number must start with 2-9 (not 0 or 1)
|
|
149
|
+
const firstDigit = cleanValue[2]
|
|
150
|
+
if (firstDigit === "0" || firstDigit === "1") {
|
|
151
|
+
return false
|
|
152
|
+
}
|
|
153
|
+
return cleanValue.length === 10 && /^02[2-9]\d{7}$/.test(cleanValue)
|
|
154
|
+
}
|
|
155
|
+
if (areaCode2 === '03') {
|
|
156
|
+
// Taoyuan, Hsinchu, Yilan, Hualien: 03 + 7-8 digits, total 9-10 digits
|
|
157
|
+
return (cleanValue.length === 9 || cleanValue.length === 10) && /^03\d{7,8}$/.test(cleanValue)
|
|
151
158
|
}
|
|
152
|
-
if (
|
|
153
|
-
//
|
|
154
|
-
|
|
155
|
-
|
|
159
|
+
if (areaCode2 === '04') {
|
|
160
|
+
// Taichung, Changhua, Nantou: 04 + 7-8 digits, total 9-10 digits
|
|
161
|
+
return (cleanValue.length === 9 || cleanValue.length === 10) && /^04\d{7,8}$/.test(cleanValue)
|
|
162
|
+
}
|
|
163
|
+
if (areaCode2 === '05') {
|
|
164
|
+
// Yunlin, Chiayi: 05 + 7 digits, total 9 digits
|
|
165
|
+
return cleanValue.length === 9 && /^05\d{7}$/.test(cleanValue)
|
|
166
|
+
}
|
|
167
|
+
if (areaCode2 === '06') {
|
|
168
|
+
// Tainan: 06 + 7 digits, total 9 digits
|
|
169
|
+
return cleanValue.length === 9 && /^06\d{7}$/.test(cleanValue)
|
|
156
170
|
}
|
|
157
171
|
if (areaCode2 === '07') {
|
|
158
|
-
// Kaohsiung: 07 + 7 digits
|
|
172
|
+
// Kaohsiung: 07 + 7 digits, total 9 digits
|
|
173
|
+
// User number must start with 2-9 (not 0 or 1)
|
|
174
|
+
const firstDigit = cleanValue[2]
|
|
175
|
+
if (firstDigit === "0" || firstDigit === "1") {
|
|
176
|
+
return false
|
|
177
|
+
}
|
|
159
178
|
return cleanValue.length === 9 && /^07[2-9]\d{6}$/.test(cleanValue)
|
|
160
179
|
}
|
|
161
180
|
if (areaCode2 === '08') {
|
|
162
|
-
// Pingtung: 08 + 7 digits
|
|
181
|
+
// Pingtung: 08 + 7 digits, total 9 digits
|
|
182
|
+
// User number must start with 4, 7, or 8 (format: 4&7&8+6D)
|
|
183
|
+
const firstDigit = cleanValue[2]
|
|
184
|
+
if (firstDigit !== "4" && firstDigit !== "7" && firstDigit !== "8") {
|
|
185
|
+
return false // Invalid first digit for 08 area code
|
|
186
|
+
}
|
|
163
187
|
return cleanValue.length === 9 && /^08[478]\d{6}$/.test(cleanValue)
|
|
164
188
|
}
|
|
165
189
|
|
|
@@ -66,45 +66,42 @@ export type TwTelSchema<IsRequired extends boolean> = IsRequired extends true ?
|
|
|
66
66
|
* number patterns.
|
|
67
67
|
*
|
|
68
68
|
* Supported area codes and formats:
|
|
69
|
-
* - 02: Taipei, New Taipei, Keelung - 8 digits
|
|
70
|
-
* - 03: Taoyuan, Hsinchu, Yilan, Hualien - 7 digits
|
|
71
|
-
* - 037: Miaoli - 6 digits
|
|
72
|
-
* - 04: Taichung, Changhua - 7 digits
|
|
73
|
-
* - 049: Nantou - 7 digits
|
|
69
|
+
* - 02: Taipei, New Taipei, Keelung - 8 digits
|
|
70
|
+
* - 03: Taoyuan, Hsinchu, Yilan, Hualien - 7-8 digits
|
|
71
|
+
* - 037: Miaoli - 6-7 digits
|
|
72
|
+
* - 04: Taichung, Changhua, Nantou - 7-8 digits
|
|
73
|
+
* - 049: Nantou - 7 digits
|
|
74
74
|
* - 05: Yunlin, Chiayi - 7 digits
|
|
75
75
|
* - 06: Tainan - 7 digits
|
|
76
|
-
* - 07: Kaohsiung - 7 digits
|
|
77
|
-
* - 08: Pingtung - 7 digits
|
|
78
|
-
* - 082: Kinmen - 6 digits
|
|
79
|
-
* -
|
|
80
|
-
* -
|
|
81
|
-
* - 089: Taitung - 6 digits (2~9+5D)
|
|
76
|
+
* - 07: Kaohsiung - 7 digits
|
|
77
|
+
* - 08: Pingtung - 7 digits
|
|
78
|
+
* - 082: Kinmen - 6 digits
|
|
79
|
+
* - 0836: Matsu - 5 digits
|
|
80
|
+
* - 089: Taitung - 6 digits
|
|
82
81
|
*
|
|
83
82
|
* @example
|
|
84
83
|
* ```typescript
|
|
85
84
|
* validateTaiwanTel("0223456789") // true (Taipei area)
|
|
86
|
-
* validateTaiwanTel("
|
|
85
|
+
* validateTaiwanTel("0423288882") // true (Taichung area, 8 digits)
|
|
87
86
|
* validateTaiwanTel("037234567") // true (Miaoli area)
|
|
88
87
|
* validateTaiwanTel("082234567") // true (Kinmen area)
|
|
89
88
|
* validateTaiwanTel("02-2345-6789") // true (with separators)
|
|
90
|
-
* validateTaiwanTel("0812345678") // false (invalid for 08 area)
|
|
91
89
|
* ```
|
|
92
90
|
*/
|
|
93
91
|
const validateTaiwanTel = (value: string): boolean => {
|
|
94
92
|
// Official Taiwan landline formats according to telecom numbering plan:
|
|
95
|
-
// 02: Taipei, New Taipei, Keelung - 8 digits
|
|
96
|
-
// 03: Taoyuan, Hsinchu, Yilan, Hualien - 7 digits
|
|
97
|
-
// 037: Miaoli - 6 digits
|
|
98
|
-
// 04: Taichung, Changhua - 7 digits
|
|
99
|
-
// 049: Nantou - 7 digits
|
|
93
|
+
// 02: Taipei, New Taipei, Keelung - 8 digits
|
|
94
|
+
// 03: Taoyuan, Hsinchu, Yilan, Hualien - 7-8 digits
|
|
95
|
+
// 037: Miaoli - 6-7 digits
|
|
96
|
+
// 04: Taichung, Changhua, Nantou - 7-8 digits
|
|
97
|
+
// 049: Nantou - 7 digits
|
|
100
98
|
// 05: Yunlin, Chiayi - 7 digits
|
|
101
99
|
// 06: Tainan - 7 digits
|
|
102
|
-
// 07: Kaohsiung - 7 digits
|
|
103
|
-
// 08: Pingtung - 7 digits
|
|
104
|
-
// 082: Kinmen - 6 digits
|
|
105
|
-
//
|
|
106
|
-
//
|
|
107
|
-
// 089: Taitung - 6 digits (2~9+5D)
|
|
100
|
+
// 07: Kaohsiung - 7 digits
|
|
101
|
+
// 08: Pingtung - 7 digits
|
|
102
|
+
// 082: Kinmen - 6 digits
|
|
103
|
+
// 0836: Matsu - 5 digits
|
|
104
|
+
// 089: Taitung - 6 digits
|
|
108
105
|
|
|
109
106
|
// Remove common separators for validation
|
|
110
107
|
const cleanValue = value.replace(/[-\s]/g, "")
|
|
@@ -116,52 +113,79 @@ const validateTaiwanTel = (value: string): boolean => {
|
|
|
116
113
|
|
|
117
114
|
// Check 4-digit area codes first
|
|
118
115
|
const areaCode4 = cleanValue.substring(0, 4)
|
|
119
|
-
if (areaCode4 === "0826") {
|
|
120
|
-
// Wuqiu: 0826 + 5 digits (6+4D), total 9 digits
|
|
121
|
-
return cleanValue.length === 9 && /^0826[6]\d{4}$/.test(cleanValue)
|
|
122
|
-
}
|
|
123
116
|
if (areaCode4 === "0836") {
|
|
124
|
-
// Matsu: 0836 + 5 digits
|
|
125
|
-
return cleanValue.length === 9 && /^0836
|
|
117
|
+
// Matsu: 0836 + 5 digits, total 9 digits
|
|
118
|
+
return cleanValue.length === 9 && /^0836\d{5}$/.test(cleanValue)
|
|
126
119
|
}
|
|
127
120
|
|
|
128
121
|
// Check 3-digit area codes
|
|
129
122
|
const areaCode3 = cleanValue.substring(0, 3)
|
|
130
123
|
if (areaCode3 === "037") {
|
|
131
|
-
// Miaoli: 037 + 6 digits
|
|
132
|
-
|
|
124
|
+
// Miaoli: 037 + 6-7 digits, total 9-10 digits
|
|
125
|
+
// User number must start with 2-9 (not 0 or 1)
|
|
126
|
+
const firstDigit = cleanValue[3]
|
|
127
|
+
if (firstDigit === "0" || firstDigit === "1") {
|
|
128
|
+
return false
|
|
129
|
+
}
|
|
130
|
+
return (cleanValue.length === 9 || cleanValue.length === 10) && /^037[2-9]\d{5,6}$/.test(cleanValue)
|
|
133
131
|
}
|
|
134
132
|
if (areaCode3 === "049") {
|
|
135
|
-
// Nantou: 049 + 7 digits
|
|
136
|
-
return cleanValue.length === 10 && /^049
|
|
133
|
+
// Nantou: 049 + 7 digits, total 10 digits
|
|
134
|
+
return cleanValue.length === 10 && /^049\d{7}$/.test(cleanValue)
|
|
137
135
|
}
|
|
138
136
|
if (areaCode3 === "082") {
|
|
139
|
-
// Kinmen: 082 + 6 digits
|
|
140
|
-
return cleanValue.length === 9 && /^082
|
|
137
|
+
// Kinmen: 082 + 6 digits, total 9 digits
|
|
138
|
+
return cleanValue.length === 9 && /^082\d{6}$/.test(cleanValue)
|
|
141
139
|
}
|
|
142
140
|
if (areaCode3 === "089") {
|
|
143
|
-
// Taitung: 089 + 6 digits
|
|
144
|
-
return cleanValue.length === 9 && /^089
|
|
141
|
+
// Taitung: 089 + 6 digits, total 9 digits
|
|
142
|
+
return cleanValue.length === 9 && /^089\d{6}$/.test(cleanValue)
|
|
145
143
|
}
|
|
146
144
|
|
|
147
145
|
// Check 2-digit area codes
|
|
148
146
|
const areaCode2 = cleanValue.substring(0, 2)
|
|
149
147
|
|
|
150
148
|
if (areaCode2 === "02") {
|
|
151
|
-
// Taipei, New Taipei, Keelung: 02 + 8 digits
|
|
152
|
-
|
|
149
|
+
// Taipei, New Taipei, Keelung: 02 + 8 digits, total 10 digits
|
|
150
|
+
// User number must start with 2-9 (not 0 or 1)
|
|
151
|
+
const firstDigit = cleanValue[2]
|
|
152
|
+
if (firstDigit === "0" || firstDigit === "1") {
|
|
153
|
+
return false
|
|
154
|
+
}
|
|
155
|
+
return cleanValue.length === 10 && /^02[2-9]\d{7}$/.test(cleanValue)
|
|
156
|
+
}
|
|
157
|
+
if (areaCode2 === "03") {
|
|
158
|
+
// Taoyuan, Hsinchu, Yilan, Hualien: 03 + 7-8 digits, total 9-10 digits
|
|
159
|
+
return (cleanValue.length === 9 || cleanValue.length === 10) && /^03\d{7,8}$/.test(cleanValue)
|
|
153
160
|
}
|
|
154
|
-
if (
|
|
155
|
-
//
|
|
156
|
-
|
|
157
|
-
|
|
161
|
+
if (areaCode2 === "04") {
|
|
162
|
+
// Taichung, Changhua, Nantou: 04 + 7-8 digits, total 9-10 digits
|
|
163
|
+
return (cleanValue.length === 9 || cleanValue.length === 10) && /^04\d{7,8}$/.test(cleanValue)
|
|
164
|
+
}
|
|
165
|
+
if (areaCode2 === "05") {
|
|
166
|
+
// Yunlin, Chiayi: 05 + 7 digits, total 9 digits
|
|
167
|
+
return cleanValue.length === 9 && /^05\d{7}$/.test(cleanValue)
|
|
168
|
+
}
|
|
169
|
+
if (areaCode2 === "06") {
|
|
170
|
+
// Tainan: 06 + 7 digits, total 9 digits
|
|
171
|
+
return cleanValue.length === 9 && /^06\d{7}$/.test(cleanValue)
|
|
158
172
|
}
|
|
159
173
|
if (areaCode2 === "07") {
|
|
160
|
-
// Kaohsiung: 07 + 7 digits
|
|
174
|
+
// Kaohsiung: 07 + 7 digits, total 9 digits
|
|
175
|
+
// User number must start with 2-9 (not 0 or 1)
|
|
176
|
+
const firstDigit = cleanValue[2]
|
|
177
|
+
if (firstDigit === "0" || firstDigit === "1") {
|
|
178
|
+
return false
|
|
179
|
+
}
|
|
161
180
|
return cleanValue.length === 9 && /^07[2-9]\d{6}$/.test(cleanValue)
|
|
162
181
|
}
|
|
163
182
|
if (areaCode2 === "08") {
|
|
164
|
-
// Pingtung: 08 + 7 digits
|
|
183
|
+
// Pingtung: 08 + 7 digits, total 9 digits
|
|
184
|
+
// User number must start with 4, 7, or 8 (format: 4&7&8+6D)
|
|
185
|
+
const firstDigit = cleanValue[2]
|
|
186
|
+
if (firstDigit !== "4" && firstDigit !== "7" && firstDigit !== "8") {
|
|
187
|
+
return false // Invalid first digit for 08 area code
|
|
188
|
+
}
|
|
165
189
|
return cleanValue.length === 9 && /^08[478]\d{6}$/.test(cleanValue)
|
|
166
190
|
}
|
|
167
191
|
|
package/tests/taiwan/tel.test.ts
CHANGED
|
@@ -20,6 +20,7 @@ describe("Taiwan twTel(true) validator", () => {
|
|
|
20
20
|
// Taichung (04) - requires 9 digits total
|
|
21
21
|
expect(schema.parse("041234567")).toBe("041234567") // 04-123-4567 (9 digits)
|
|
22
22
|
expect(schema.parse("043456789")).toBe("043456789") // 04-345-6789 (9 digits)
|
|
23
|
+
expect(schema.parse("0423288882")).toBe("0423288882") // 04-232-88882 (10 digits)
|
|
23
24
|
|
|
24
25
|
// Tainan (06) - requires 9 digits total
|
|
25
26
|
expect(schema.parse("061234567")).toBe("061234567") // 06-123-4567 (9 digits)
|