@hy_ong/zod-kit 0.0.5 → 0.0.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/.claude/settings.local.json +6 -1
- package/README.md +465 -97
- package/dist/index.cjs +1628 -121
- package/dist/index.d.cts +2699 -2
- package/dist/index.d.ts +2699 -2
- package/dist/index.js +1610 -120
- package/package.json +1 -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 +94 -0
- package/src/validators/common/date.ts +128 -0
- package/src/validators/common/datetime.ts +673 -0
- package/src/validators/common/email.ts +113 -0
- package/src/validators/common/file.ts +384 -0
- package/src/validators/common/id.ts +224 -12
- package/src/validators/common/number.ts +125 -0
- package/src/validators/common/password.ts +174 -2
- package/src/validators/common/text.ts +120 -0
- package/src/validators/common/time.ts +600 -0
- package/src/validators/common/url.ts +140 -0
- package/src/validators/taiwan/business-id.ts +124 -2
- package/src/validators/taiwan/fax.ts +147 -2
- package/src/validators/taiwan/mobile.ts +134 -2
- package/src/validators/taiwan/national-id.ts +227 -10
- package/src/validators/taiwan/postal-code.ts +1049 -0
- package/src/validators/taiwan/tel.ts +150 -2
- package/tests/common/datetime.test.ts +693 -0
- package/tests/common/file.test.ts +479 -0
- package/tests/common/time.test.ts +528 -0
- package/tests/taiwan/postal-code.test.ts +705 -0
package/package.json
CHANGED
package/src/i18n/locales/en.json
CHANGED
|
@@ -112,6 +112,56 @@
|
|
|
112
112
|
"notToday": "Date must not be today",
|
|
113
113
|
"weekday": "Date must be a weekday (Monday-Friday)",
|
|
114
114
|
"weekend": "Date must be a weekend (Saturday-Sunday)"
|
|
115
|
+
},
|
|
116
|
+
"time": {
|
|
117
|
+
"required": "Required",
|
|
118
|
+
"invalid": "Invalid time format",
|
|
119
|
+
"format": "Must be in ${format} format",
|
|
120
|
+
"min": "Time must be after ${min}",
|
|
121
|
+
"max": "Time must be before ${max}",
|
|
122
|
+
"hour": "Hour must be between ${minHour} and ${maxHour}",
|
|
123
|
+
"minute": "Minutes must be in ${minuteStep}-minute intervals",
|
|
124
|
+
"second": "Seconds must be in ${secondStep}-second intervals",
|
|
125
|
+
"includes": "Must include ${includes}",
|
|
126
|
+
"excludes": "Must not contain ${excludes}",
|
|
127
|
+
"customRegex": "Invalid time format",
|
|
128
|
+
"notInWhitelist": "Time is not in the allowed list"
|
|
129
|
+
},
|
|
130
|
+
"datetime": {
|
|
131
|
+
"required": "Required",
|
|
132
|
+
"invalid": "Invalid datetime format",
|
|
133
|
+
"format": "Must be in ${format} format",
|
|
134
|
+
"min": "DateTime must be after ${min}",
|
|
135
|
+
"max": "DateTime must be before ${max}",
|
|
136
|
+
"hour": "Hour must be between ${minHour} and ${maxHour}",
|
|
137
|
+
"minute": "Minutes must be in ${minuteStep}-minute intervals",
|
|
138
|
+
"includes": "Must include ${includes}",
|
|
139
|
+
"excludes": "Must not contain ${excludes}",
|
|
140
|
+
"past": "DateTime must be in the past",
|
|
141
|
+
"future": "DateTime must be in the future",
|
|
142
|
+
"today": "DateTime must be today",
|
|
143
|
+
"notToday": "DateTime must not be today",
|
|
144
|
+
"weekday": "DateTime must be a weekday (Monday-Friday)",
|
|
145
|
+
"weekend": "DateTime must be a weekend (Saturday-Sunday)",
|
|
146
|
+
"customRegex": "Invalid datetime format",
|
|
147
|
+
"notInWhitelist": "DateTime is not in the allowed list"
|
|
148
|
+
},
|
|
149
|
+
"file": {
|
|
150
|
+
"required": "Required",
|
|
151
|
+
"invalid": "Invalid file format",
|
|
152
|
+
"size": "File size must not exceed ${size}",
|
|
153
|
+
"minSize": "File size must be at least ${minSize}",
|
|
154
|
+
"maxSize": "File size must not exceed ${maxSize}",
|
|
155
|
+
"type": "File type must be one of: ${type}",
|
|
156
|
+
"extension": "File extension must be one of: ${extension}",
|
|
157
|
+
"extensionBlacklist": "File extension ${extension} is not allowed",
|
|
158
|
+
"name": "File name must match pattern ${pattern}",
|
|
159
|
+
"nameBlacklist": "File name must not match pattern ${pattern}",
|
|
160
|
+
"imageOnly": "Only image files are allowed",
|
|
161
|
+
"documentOnly": "Only document files are allowed",
|
|
162
|
+
"videoOnly": "Only video files are allowed",
|
|
163
|
+
"audioOnly": "Only audio files are allowed",
|
|
164
|
+
"archiveOnly": "Only archive files are allowed"
|
|
115
165
|
}
|
|
116
166
|
},
|
|
117
167
|
"taiwan": {
|
|
@@ -137,6 +187,18 @@
|
|
|
137
187
|
"required": "Required",
|
|
138
188
|
"invalid": "Invalid Taiwan fax format",
|
|
139
189
|
"notInWhitelist": "Not in allowed fax list"
|
|
190
|
+
},
|
|
191
|
+
"postalCode": {
|
|
192
|
+
"required": "Required",
|
|
193
|
+
"invalid": "Invalid Taiwan postal code",
|
|
194
|
+
"invalidFormat": "Invalid postal code format",
|
|
195
|
+
"invalidRange": "Postal code is outside valid range",
|
|
196
|
+
"legacy5DigitWarning": "5-digit postal codes are legacy format, consider using 6-digit format",
|
|
197
|
+
"format3Only": "Only 3-digit postal codes are allowed",
|
|
198
|
+
"format5Only": "Only 5-digit postal codes are allowed",
|
|
199
|
+
"format6Only": "Only 6-digit postal codes are allowed",
|
|
200
|
+
"invalidSuffix": "Invalid postal code suffix - must be 01-99 for 5-digit or 001-999 for 6-digit codes",
|
|
201
|
+
"deprecated5Digit": "5-digit postal codes are deprecated and no longer supported"
|
|
140
202
|
}
|
|
141
203
|
}
|
|
142
204
|
}
|
|
@@ -112,6 +112,56 @@
|
|
|
112
112
|
"notToday": "不得為今天",
|
|
113
113
|
"weekday": "必須為工作日(週一至週五)",
|
|
114
114
|
"weekend": "必須為週末(週六至週日)"
|
|
115
|
+
},
|
|
116
|
+
"time": {
|
|
117
|
+
"required": "必填",
|
|
118
|
+
"invalid": "無效的時間格式",
|
|
119
|
+
"format": "必須為 ${format} 格式",
|
|
120
|
+
"min": "時間不得早於 ${min}",
|
|
121
|
+
"max": "時間不得晚於 ${max}",
|
|
122
|
+
"hour": "小時必須介於 ${minHour} 與 ${maxHour} 之間",
|
|
123
|
+
"minute": "分鐘必須為 ${minuteStep} 分鐘間隔",
|
|
124
|
+
"second": "秒數必須為 ${secondStep} 秒間隔",
|
|
125
|
+
"includes": "必須包含「${includes}」",
|
|
126
|
+
"excludes": "不得包含「${excludes}」",
|
|
127
|
+
"customRegex": "無效的時間格式",
|
|
128
|
+
"notInWhitelist": "時間不在允許清單中"
|
|
129
|
+
},
|
|
130
|
+
"datetime": {
|
|
131
|
+
"required": "必填",
|
|
132
|
+
"invalid": "無效的日期時間格式",
|
|
133
|
+
"format": "必須為 ${format} 格式",
|
|
134
|
+
"min": "日期時間不得早於 ${min}",
|
|
135
|
+
"max": "日期時間不得晚於 ${max}",
|
|
136
|
+
"hour": "小時必須介於 ${minHour} 與 ${maxHour} 之間",
|
|
137
|
+
"minute": "分鐘必須為 ${minuteStep} 分鐘間隔",
|
|
138
|
+
"includes": "必須包含「${includes}」",
|
|
139
|
+
"excludes": "不得包含「${excludes}」",
|
|
140
|
+
"past": "必須為過去的日期時間",
|
|
141
|
+
"future": "必須為未來的日期時間",
|
|
142
|
+
"today": "必須為今天",
|
|
143
|
+
"notToday": "不得為今天",
|
|
144
|
+
"weekday": "必須為工作日(週一至週五)",
|
|
145
|
+
"weekend": "必須為週末(週六至週日)",
|
|
146
|
+
"customRegex": "無效的日期時間格式",
|
|
147
|
+
"notInWhitelist": "日期時間不在允許清單中"
|
|
148
|
+
},
|
|
149
|
+
"file": {
|
|
150
|
+
"required": "必填",
|
|
151
|
+
"invalid": "無效的檔案格式",
|
|
152
|
+
"size": "檔案大小不得超過 ${size}",
|
|
153
|
+
"minSize": "檔案大小至少 ${minSize}",
|
|
154
|
+
"maxSize": "檔案大小不得超過 ${maxSize}",
|
|
155
|
+
"type": "檔案類型必須為:${type}",
|
|
156
|
+
"extension": "副檔名必須為:${extension}",
|
|
157
|
+
"extensionBlacklist": "不允許使用副檔名 ${extension}",
|
|
158
|
+
"name": "檔案名稱必須符合格式 ${pattern}",
|
|
159
|
+
"nameBlacklist": "檔案名稱不得符合格式 ${pattern}",
|
|
160
|
+
"imageOnly": "僅允許圖片檔案",
|
|
161
|
+
"documentOnly": "僅允許文件檔案",
|
|
162
|
+
"videoOnly": "僅允許影片檔案",
|
|
163
|
+
"audioOnly": "僅允許音訊檔案",
|
|
164
|
+
"archiveOnly": "僅允許壓縮檔案"
|
|
115
165
|
}
|
|
116
166
|
},
|
|
117
167
|
"taiwan": {
|
|
@@ -137,6 +187,18 @@
|
|
|
137
187
|
"required": "必填",
|
|
138
188
|
"invalid": "無效的傳真號碼格式",
|
|
139
189
|
"notInWhitelist": "不在允許的傳真號碼清單中"
|
|
190
|
+
},
|
|
191
|
+
"postalCode": {
|
|
192
|
+
"required": "必填",
|
|
193
|
+
"invalid": "無效的郵遞區號",
|
|
194
|
+
"invalidFormat": "郵遞區號格式錯誤",
|
|
195
|
+
"invalidRange": "郵遞區號超出有效範圍",
|
|
196
|
+
"legacy5DigitWarning": "5 碼郵遞區號為舊式格式,建議使用 6 碼格式",
|
|
197
|
+
"format3Only": "僅允許 3 碼郵遞區號",
|
|
198
|
+
"format5Only": "僅允許 5 碼郵遞區號",
|
|
199
|
+
"format6Only": "僅允許 6 碼郵遞區號",
|
|
200
|
+
"invalidSuffix": "無效的郵遞區號後碼 - 5 碼格式須為 01-99,6 碼格式須為 001-999",
|
|
201
|
+
"deprecated5Digit": "5 碼郵遞區號已棄用且不再支援"
|
|
140
202
|
}
|
|
141
203
|
}
|
|
142
204
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
export * from "./validators/common/boolean"
|
|
2
2
|
export * from "./validators/common/date"
|
|
3
|
+
export * from "./validators/common/datetime"
|
|
3
4
|
export * from "./validators/common/email"
|
|
5
|
+
export * from "./validators/common/file"
|
|
4
6
|
export * from "./validators/common/id"
|
|
5
7
|
export * from "./validators/common/number"
|
|
6
8
|
export * from "./validators/common/password"
|
|
7
9
|
export * from "./validators/common/text"
|
|
10
|
+
export * from "./validators/common/time"
|
|
8
11
|
export * from "./validators/common/url"
|
|
9
12
|
export * from "./validators/taiwan/business-id"
|
|
10
13
|
export * from "./validators/taiwan/national-id"
|
|
11
14
|
export * from "./validators/taiwan/mobile"
|
|
15
|
+
export * from "./validators/taiwan/postal-code"
|
|
12
16
|
export * from "./validators/taiwan/tel"
|
|
13
17
|
export * from "./validators/taiwan/fax"
|
|
14
18
|
export * from "./config"
|
|
@@ -1,7 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Boolean validator for Zod Kit
|
|
3
|
+
*
|
|
4
|
+
* Provides flexible boolean validation with support for various truthy/falsy values,
|
|
5
|
+
* strict mode validation, and comprehensive transformation options.
|
|
6
|
+
*
|
|
7
|
+
* @author Ong Hoe Yuan
|
|
8
|
+
* @version 0.0.5
|
|
9
|
+
*/
|
|
10
|
+
|
|
1
11
|
import { z, ZodBoolean, ZodNullable, ZodType } from "zod"
|
|
2
12
|
import { t } from "../../i18n"
|
|
3
13
|
import { getLocale, type Locale } from "../../config"
|
|
4
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Type definition for boolean validation error messages
|
|
17
|
+
*
|
|
18
|
+
* @interface BooleanMessages
|
|
19
|
+
* @property {string} [required] - Message when field is required but empty
|
|
20
|
+
* @property {string} [shouldBeTrue] - Message when value should be true but isn't
|
|
21
|
+
* @property {string} [shouldBeFalse] - Message when value should be false but isn't
|
|
22
|
+
* @property {string} [invalid] - Message when value is not a valid boolean
|
|
23
|
+
*/
|
|
5
24
|
export type BooleanMessages = {
|
|
6
25
|
required?: string
|
|
7
26
|
shouldBeTrue?: string
|
|
@@ -9,6 +28,21 @@ export type BooleanMessages = {
|
|
|
9
28
|
invalid?: string
|
|
10
29
|
}
|
|
11
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Configuration options for boolean validation
|
|
33
|
+
*
|
|
34
|
+
* @template IsRequired - Whether the field is required (affects return type)
|
|
35
|
+
*
|
|
36
|
+
* @interface BooleanOptions
|
|
37
|
+
* @property {IsRequired} [required=true] - Whether the field is required
|
|
38
|
+
* @property {boolean | null} [defaultValue] - Default value when input is empty
|
|
39
|
+
* @property {boolean} [shouldBe] - Specific boolean value that must be matched
|
|
40
|
+
* @property {unknown[]} [truthyValues] - Array of values that should be treated as true
|
|
41
|
+
* @property {unknown[]} [falsyValues] - Array of values that should be treated as false
|
|
42
|
+
* @property {boolean} [strict=false] - If true, only accepts actual boolean values
|
|
43
|
+
* @property {Function} [transform] - Custom transformation function for boolean values
|
|
44
|
+
* @property {Record<Locale, BooleanMessages>} [i18n] - Custom error messages for different locales
|
|
45
|
+
*/
|
|
12
46
|
export type BooleanOptions<IsRequired extends boolean = true> = {
|
|
13
47
|
required?: IsRequired
|
|
14
48
|
defaultValue?: IsRequired extends true ? boolean : boolean | null
|
|
@@ -20,8 +54,68 @@ export type BooleanOptions<IsRequired extends boolean = true> = {
|
|
|
20
54
|
i18n?: Record<Locale, BooleanMessages>
|
|
21
55
|
}
|
|
22
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Type alias for boolean validation schema based on required flag
|
|
59
|
+
*
|
|
60
|
+
* @template IsRequired - Whether the field is required
|
|
61
|
+
* @typedef BooleanSchema
|
|
62
|
+
* @description Returns ZodBoolean if required, ZodNullable<ZodBoolean> if optional
|
|
63
|
+
*/
|
|
23
64
|
export type BooleanSchema<IsRequired extends boolean> = IsRequired extends true ? ZodBoolean : ZodNullable<ZodBoolean>
|
|
24
65
|
|
|
66
|
+
/**
|
|
67
|
+
* Creates a Zod schema for boolean validation with flexible value interpretation
|
|
68
|
+
*
|
|
69
|
+
* @template IsRequired - Whether the field is required (affects return type)
|
|
70
|
+
* @param {BooleanOptions<IsRequired>} [options] - Configuration options for boolean validation
|
|
71
|
+
* @returns {BooleanSchema<IsRequired>} Zod schema for boolean validation
|
|
72
|
+
*
|
|
73
|
+
* @description
|
|
74
|
+
* Creates a flexible boolean validator that can interpret various values as true/false,
|
|
75
|
+
* supports strict mode for type safety, and provides comprehensive transformation options.
|
|
76
|
+
*
|
|
77
|
+
* Features:
|
|
78
|
+
* - Flexible truthy/falsy value interpretation
|
|
79
|
+
* - Strict mode for type safety
|
|
80
|
+
* - Custom transformation functions
|
|
81
|
+
* - Specific boolean value requirements
|
|
82
|
+
* - Comprehensive internationalization
|
|
83
|
+
* - Default value support
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```typescript
|
|
87
|
+
* // Basic boolean validation
|
|
88
|
+
* const basicSchema = boolean()
|
|
89
|
+
* basicSchema.parse(true) // ✓ Valid
|
|
90
|
+
* basicSchema.parse("true") // ✓ Valid (converted to true)
|
|
91
|
+
*
|
|
92
|
+
* // Strict mode (only actual booleans)
|
|
93
|
+
* const strictSchema = boolean({ strict: true })
|
|
94
|
+
* strictSchema.parse(true) // ✓ Valid
|
|
95
|
+
* strictSchema.parse("true") // ✗ Invalid
|
|
96
|
+
*
|
|
97
|
+
* // Must be true
|
|
98
|
+
* const mustBeTrueSchema = boolean({ shouldBe: true })
|
|
99
|
+
* mustBeTrueSchema.parse(true) // ✓ Valid
|
|
100
|
+
* mustBeTrueSchema.parse(false) // ✗ Invalid
|
|
101
|
+
*
|
|
102
|
+
* // Custom truthy/falsy values
|
|
103
|
+
* const customSchema = boolean({
|
|
104
|
+
* truthyValues: ["yes", "on", 1],
|
|
105
|
+
* falsyValues: ["no", "off", 0]
|
|
106
|
+
* })
|
|
107
|
+
* customSchema.parse("yes") // ✓ Valid (converted to true)
|
|
108
|
+
*
|
|
109
|
+
* // Optional with default
|
|
110
|
+
* const optionalSchema = boolean({
|
|
111
|
+
* required: false,
|
|
112
|
+
* defaultValue: false
|
|
113
|
+
* })
|
|
114
|
+
* ```
|
|
115
|
+
*
|
|
116
|
+
* @throws {z.ZodError} When validation fails with specific error messages
|
|
117
|
+
* @see {@link BooleanOptions} for all available configuration options
|
|
118
|
+
*/
|
|
25
119
|
export function boolean<IsRequired extends boolean = true>(options?: BooleanOptions<IsRequired>): BooleanSchema<IsRequired> {
|
|
26
120
|
const {
|
|
27
121
|
required = true,
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Date validator for Zod Kit
|
|
3
|
+
*
|
|
4
|
+
* Provides comprehensive date validation with format support, range validation,
|
|
5
|
+
* temporal constraints, and weekday/weekend filtering using dayjs library.
|
|
6
|
+
*
|
|
7
|
+
* @author Ong Hoe Yuan
|
|
8
|
+
* @version 0.0.5
|
|
9
|
+
*/
|
|
10
|
+
|
|
1
11
|
import { z, ZodNullable, ZodString } from "zod"
|
|
2
12
|
import { t } from "../../i18n"
|
|
3
13
|
import { getLocale, type Locale } from "../../config"
|
|
@@ -8,12 +18,33 @@ import isSameOrBefore from "dayjs/plugin/isSameOrBefore"
|
|
|
8
18
|
import isToday from "dayjs/plugin/isToday"
|
|
9
19
|
import weekday from "dayjs/plugin/weekday"
|
|
10
20
|
|
|
21
|
+
// Initialize dayjs plugins for extended date functionality
|
|
11
22
|
dayjs.extend(isSameOrAfter)
|
|
12
23
|
dayjs.extend(isSameOrBefore)
|
|
13
24
|
dayjs.extend(customParseFormat)
|
|
14
25
|
dayjs.extend(isToday)
|
|
15
26
|
dayjs.extend(weekday)
|
|
16
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Type definition for date validation error messages
|
|
30
|
+
*
|
|
31
|
+
* @interface DateMessages
|
|
32
|
+
* @property {string} [required] - Message when field is required but empty
|
|
33
|
+
* @property {string} [invalid] - Message when date is invalid
|
|
34
|
+
* @property {string} [format] - Message when date doesn't match expected format
|
|
35
|
+
* @property {string} [min] - Message when date is before minimum allowed
|
|
36
|
+
* @property {string} [max] - Message when date is after maximum allowed
|
|
37
|
+
* @property {string} [includes] - Message when date string doesn't contain required text
|
|
38
|
+
* @property {string} [excludes] - Message when date string contains forbidden text
|
|
39
|
+
* @property {string} [past] - Message when date must be in the past
|
|
40
|
+
* @property {string} [future] - Message when date must be in the future
|
|
41
|
+
* @property {string} [today] - Message when date must be today
|
|
42
|
+
* @property {string} [notToday] - Message when date must not be today
|
|
43
|
+
* @property {string} [weekday] - Message when date must be a weekday
|
|
44
|
+
* @property {string} [notWeekday] - Message when date must not be a weekday
|
|
45
|
+
* @property {string} [weekend] - Message when date must be a weekend
|
|
46
|
+
* @property {string} [notWeekend] - Message when date must not be a weekend
|
|
47
|
+
*/
|
|
17
48
|
export type DateMessages = {
|
|
18
49
|
required?: string
|
|
19
50
|
invalid?: string
|
|
@@ -32,6 +63,28 @@ export type DateMessages = {
|
|
|
32
63
|
notWeekend?: string
|
|
33
64
|
}
|
|
34
65
|
|
|
66
|
+
/**
|
|
67
|
+
* Configuration options for date validation
|
|
68
|
+
*
|
|
69
|
+
* @template IsRequired - Whether the field is required (affects return type)
|
|
70
|
+
*
|
|
71
|
+
* @interface DateOptions
|
|
72
|
+
* @property {IsRequired} [required=true] - Whether the field is required
|
|
73
|
+
* @property {string} [min] - Minimum allowed date (in same format as specified)
|
|
74
|
+
* @property {string} [max] - Maximum allowed date (in same format as specified)
|
|
75
|
+
* @property {string} [format="YYYY-MM-DD"] - Date format for parsing and validation
|
|
76
|
+
* @property {string} [includes] - String that must be included in the date
|
|
77
|
+
* @property {string | string[]} [excludes] - String(s) that must not be included
|
|
78
|
+
* @property {boolean} [mustBePast] - Whether date must be in the past
|
|
79
|
+
* @property {boolean} [mustBeFuture] - Whether date must be in the future
|
|
80
|
+
* @property {boolean} [mustBeToday] - Whether date must be today
|
|
81
|
+
* @property {boolean} [mustNotBeToday] - Whether date must not be today
|
|
82
|
+
* @property {boolean} [weekdaysOnly] - Whether date must be a weekday (Monday-Friday)
|
|
83
|
+
* @property {boolean} [weekendsOnly] - Whether date must be a weekend (Saturday-Sunday)
|
|
84
|
+
* @property {Function} [transform] - Custom transformation function for date strings
|
|
85
|
+
* @property {string | null} [defaultValue] - Default value when input is empty
|
|
86
|
+
* @property {Record<Locale, DateMessages>} [i18n] - Custom error messages for different locales
|
|
87
|
+
*/
|
|
35
88
|
export type DateOptions<IsRequired extends boolean = true> = {
|
|
36
89
|
required?: IsRequired
|
|
37
90
|
min?: string
|
|
@@ -50,8 +103,83 @@ export type DateOptions<IsRequired extends boolean = true> = {
|
|
|
50
103
|
i18n?: Record<Locale, DateMessages>
|
|
51
104
|
}
|
|
52
105
|
|
|
106
|
+
/**
|
|
107
|
+
* Type alias for date validation schema based on required flag
|
|
108
|
+
*
|
|
109
|
+
* @template IsRequired - Whether the field is required
|
|
110
|
+
* @typedef DateSchema
|
|
111
|
+
* @description Returns ZodString if required, ZodNullable<ZodString> if optional
|
|
112
|
+
*/
|
|
53
113
|
export type DateSchema<IsRequired extends boolean> = IsRequired extends true ? ZodString : ZodNullable<ZodString>
|
|
54
114
|
|
|
115
|
+
/**
|
|
116
|
+
* Creates a Zod schema for date validation with temporal constraints
|
|
117
|
+
*
|
|
118
|
+
* @template IsRequired - Whether the field is required (affects return type)
|
|
119
|
+
* @param {DateOptions<IsRequired>} [options] - Configuration options for date validation
|
|
120
|
+
* @returns {DateSchema<IsRequired>} Zod schema for date validation
|
|
121
|
+
*
|
|
122
|
+
* @description
|
|
123
|
+
* Creates a comprehensive date validator with format support, range validation,
|
|
124
|
+
* temporal constraints, and weekday/weekend filtering using dayjs library.
|
|
125
|
+
*
|
|
126
|
+
* Features:
|
|
127
|
+
* - Flexible date format parsing (default: YYYY-MM-DD)
|
|
128
|
+
* - Range validation (min/max dates)
|
|
129
|
+
* - Temporal validation (past/future/today)
|
|
130
|
+
* - Weekday/weekend filtering
|
|
131
|
+
* - Content inclusion/exclusion
|
|
132
|
+
* - Custom transformation functions
|
|
133
|
+
* - Comprehensive internationalization
|
|
134
|
+
* - Strict date parsing with format validation
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* ```typescript
|
|
138
|
+
* // Basic date validation (YYYY-MM-DD)
|
|
139
|
+
* const basicSchema = date()
|
|
140
|
+
* basicSchema.parse("2024-03-15") // ✓ Valid
|
|
141
|
+
* basicSchema.parse("2024-13-01") // ✗ Invalid (month 13)
|
|
142
|
+
*
|
|
143
|
+
* // Custom format
|
|
144
|
+
* const customFormatSchema = date({ format: "DD/MM/YYYY" })
|
|
145
|
+
* customFormatSchema.parse("15/03/2024") // ✓ Valid
|
|
146
|
+
* customFormatSchema.parse("2024-03-15") // ✗ Invalid (wrong format)
|
|
147
|
+
*
|
|
148
|
+
* // Date range validation
|
|
149
|
+
* const rangeSchema = date({
|
|
150
|
+
* min: "2024-01-01",
|
|
151
|
+
* max: "2024-12-31"
|
|
152
|
+
* })
|
|
153
|
+
* rangeSchema.parse("2024-06-15") // ✓ Valid
|
|
154
|
+
* rangeSchema.parse("2023-12-31") // ✗ Invalid (before min)
|
|
155
|
+
*
|
|
156
|
+
* // Future dates only
|
|
157
|
+
* const futureSchema = date({ mustBeFuture: true })
|
|
158
|
+
* futureSchema.parse("2030-01-01") // ✓ Valid (assuming current date < 2030)
|
|
159
|
+
* futureSchema.parse("2020-01-01") // ✗ Invalid (past date)
|
|
160
|
+
*
|
|
161
|
+
* // Weekdays only (Monday-Friday)
|
|
162
|
+
* const weekdaySchema = date({ weekdaysOnly: true })
|
|
163
|
+
* weekdaySchema.parse("2024-03-15") // ✓ Valid (if Friday)
|
|
164
|
+
* weekdaySchema.parse("2024-03-16") // ✗ Invalid (if Saturday)
|
|
165
|
+
*
|
|
166
|
+
* // Business date validation
|
|
167
|
+
* const businessSchema = date({
|
|
168
|
+
* format: "YYYY-MM-DD",
|
|
169
|
+
* mustBeFuture: true,
|
|
170
|
+
* weekdaysOnly: true
|
|
171
|
+
* })
|
|
172
|
+
*
|
|
173
|
+
* // Optional with default
|
|
174
|
+
* const optionalSchema = date({
|
|
175
|
+
* required: false,
|
|
176
|
+
* defaultValue: "2024-01-01"
|
|
177
|
+
* })
|
|
178
|
+
* ```
|
|
179
|
+
*
|
|
180
|
+
* @throws {z.ZodError} When validation fails with specific error messages
|
|
181
|
+
* @see {@link DateOptions} for all available configuration options
|
|
182
|
+
*/
|
|
55
183
|
export function date<IsRequired extends boolean = true>(options?: DateOptions<IsRequired>): DateSchema<IsRequired> {
|
|
56
184
|
const {
|
|
57
185
|
required = true,
|