@hy_ong/zod-kit 0.1.2 → 0.1.3

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.
@@ -98,6 +98,7 @@ export type NumberSchema<IsRequired extends boolean> = IsRequired extends true ?
98
98
  * Creates a Zod schema for number validation with comprehensive constraints
99
99
  *
100
100
  * @template IsRequired - Whether the field is required (affects return type)
101
+ * @param required
101
102
  * @param {NumberOptions<IsRequired>} [options] - Configuration options for number validation
102
103
  * @returns {NumberSchema<IsRequired>} Zod schema for number validation
103
104
  *
@@ -165,25 +166,10 @@ export type NumberSchema<IsRequired extends boolean> = IsRequired extends true ?
165
166
  * @throws {z.ZodError} When validation fails with specific error messages
166
167
  * @see {@link NumberOptions} for all available configuration options
167
168
  */
168
- export function number<IsRequired extends boolean = false>(required?: IsRequired, options?: Omit<NumberOptions<IsRequired>, 'required'>): NumberSchema<IsRequired> {
169
- const {
170
- min,
171
- max,
172
- defaultValue,
173
- type = "both",
174
- positive,
175
- negative,
176
- nonNegative,
177
- nonPositive,
178
- multipleOf,
179
- precision,
180
- finite = true,
181
- transform,
182
- parseCommas = false,
183
- i18n,
184
- } = options ?? {}
169
+ export function number<IsRequired extends boolean = false>(required?: IsRequired, options?: Omit<NumberOptions<IsRequired>, "required">): NumberSchema<IsRequired> {
170
+ const { min, max, defaultValue, type = "both", positive, negative, nonNegative, nonPositive, multipleOf, precision, finite = true, transform, parseCommas = false, i18n } = options ?? {}
185
171
 
186
- const isRequired = required ?? false as IsRequired
172
+ const isRequired = required ?? (false as IsRequired)
187
173
 
188
174
  // Helper function to get custom message or fallback to default i18n
189
175
  const getMessage = (key: keyof NumberMessages, params?: Record<string, any>) => {
@@ -243,79 +229,130 @@ export function number<IsRequired extends boolean = false>(required?: IsRequired
243
229
  },
244
230
  z.union([z.number(), z.null(), z.nan(), z.custom<number>((val) => val === Infinity || val === -Infinity)])
245
231
  )
246
- .refine((val) => {
232
+ .superRefine((val, ctx) => {
247
233
  // Required check first
248
234
  if (isRequired && val === null) {
249
- throw new z.ZodError([{ code: "custom", message: getMessage("required"), path: [] }])
235
+ ctx.addIssue({
236
+ code: "custom",
237
+ message: getMessage("required"),
238
+ })
239
+ return
250
240
  }
251
241
 
252
- if (val === null) return true
242
+ if (val === null) return
253
243
 
254
244
  // Type validation for invalid inputs (NaN)
255
- if (typeof val === "number" && isNaN(val)) {
245
+ if (isNaN(val)) {
256
246
  if (type === "integer") {
257
- throw new z.ZodError([{ code: "custom", message: getMessage("integer"), path: [] }])
247
+ ctx.addIssue({
248
+ code: "custom",
249
+ message: getMessage("integer"),
250
+ })
258
251
  } else if (type === "float") {
259
- throw new z.ZodError([{ code: "custom", message: getMessage("float"), path: [] }])
252
+ ctx.addIssue({
253
+ code: "custom",
254
+ message: getMessage("float"),
255
+ })
260
256
  } else {
261
- throw new z.ZodError([{ code: "custom", message: getMessage("invalid"), path: [] }])
257
+ ctx.addIssue({
258
+ code: "custom",
259
+ message: getMessage("invalid"),
260
+ })
262
261
  }
263
- }
264
-
265
- // Invalid number check for non-numbers
266
- if (typeof val !== "number") {
267
- throw new z.ZodError([{ code: "custom", message: getMessage("invalid"), path: [] }])
262
+ return
268
263
  }
269
264
 
270
265
  // Finite check
271
266
  if (finite && !Number.isFinite(val)) {
272
- throw new z.ZodError([{ code: "custom", message: getMessage("finite"), path: [] }])
267
+ ctx.addIssue({
268
+ code: "custom",
269
+ message: getMessage("finite"),
270
+ })
271
+ return
273
272
  }
274
273
 
275
274
  // Type validation for valid numbers
276
275
  if (type === "integer" && !Number.isInteger(val)) {
277
- throw new z.ZodError([{ code: "custom", message: getMessage("integer"), path: [] }])
276
+ ctx.addIssue({
277
+ code: "custom",
278
+ message: getMessage("integer"),
279
+ })
280
+ return
278
281
  }
279
282
  if (type === "float" && Number.isInteger(val)) {
280
- throw new z.ZodError([{ code: "custom", message: getMessage("float"), path: [] }])
283
+ ctx.addIssue({
284
+ code: "custom",
285
+ message: getMessage("float"),
286
+ })
287
+ return
281
288
  }
282
289
 
283
290
  // Sign checks (more specific, should come first)
284
291
  if (positive && val <= 0) {
285
- throw new z.ZodError([{ code: "custom", message: getMessage("positive"), path: [] }])
292
+ ctx.addIssue({
293
+ code: "custom",
294
+ message: getMessage("positive"),
295
+ })
296
+ return
286
297
  }
287
298
  if (negative && val >= 0) {
288
- throw new z.ZodError([{ code: "custom", message: getMessage("negative"), path: [] }])
299
+ ctx.addIssue({
300
+ code: "custom",
301
+ message: getMessage("negative"),
302
+ })
303
+ return
289
304
  }
290
305
  if (nonNegative && val < 0) {
291
- throw new z.ZodError([{ code: "custom", message: getMessage("nonNegative"), path: [] }])
306
+ ctx.addIssue({
307
+ code: "custom",
308
+ message: getMessage("nonNegative"),
309
+ })
310
+ return
292
311
  }
293
312
  if (nonPositive && val > 0) {
294
- throw new z.ZodError([{ code: "custom", message: getMessage("nonPositive"), path: [] }])
313
+ ctx.addIssue({
314
+ code: "custom",
315
+ message: getMessage("nonPositive"),
316
+ })
317
+ return
295
318
  }
296
319
 
297
320
  // Range checks
298
321
  if (min !== undefined && val < min) {
299
- throw new z.ZodError([{ code: "custom", message: getMessage("min", { min }), path: [] }])
322
+ ctx.addIssue({
323
+ code: "custom",
324
+ message: getMessage("min", { min }),
325
+ })
326
+ return
300
327
  }
301
328
  if (max !== undefined && val > max) {
302
- throw new z.ZodError([{ code: "custom", message: getMessage("max", { max }), path: [] }])
329
+ ctx.addIssue({
330
+ code: "custom",
331
+ message: getMessage("max", { max }),
332
+ })
333
+ return
303
334
  }
304
335
 
305
336
  // Multiple of check
306
337
  if (multipleOf !== undefined && val % multipleOf !== 0) {
307
- throw new z.ZodError([{ code: "custom", message: getMessage("multipleOf", { multipleOf }), path: [] }])
338
+ ctx.addIssue({
339
+ code: "custom",
340
+ message: getMessage("multipleOf", { multipleOf }),
341
+ })
342
+ return
308
343
  }
309
344
 
310
345
  // Precision check
311
346
  if (precision !== undefined) {
312
347
  const decimalPlaces = (val.toString().split(".")[1] || "").length
313
348
  if (decimalPlaces > precision) {
314
- throw new z.ZodError([{ code: "custom", message: getMessage("precision", { precision }), path: [] }])
349
+ ctx.addIssue({
350
+ code: "custom",
351
+ message: getMessage("precision", { precision }),
352
+ })
353
+ return
315
354
  }
316
355
  }
317
-
318
- return true
319
356
  })
320
357
 
321
358
  return schema as unknown as NumberSchema<IsRequired>
@@ -320,45 +320,55 @@ export function password<IsRequired extends boolean = false>(required?: IsRequir
320
320
 
321
321
  const baseSchema = isRequired ? z.preprocess(preprocessFn, z.string()) : z.preprocess(preprocessFn, z.string().nullable())
322
322
 
323
- const schema = baseSchema.refine((val) => {
324
- if (val === null) return true
323
+ const schema = baseSchema.superRefine((val, ctx) => {
324
+ if (val === null) return
325
325
 
326
326
  // Required check
327
327
  if (isRequired && (val === "" || val === "null" || val === "undefined")) {
328
- throw new z.ZodError([{ code: "custom", message: getMessage("required"), path: [] }])
328
+ ctx.addIssue({ code: "custom", message: getMessage("required") })
329
+ return
329
330
  }
330
331
 
331
332
  // Length checks
332
333
  if (val !== null && min !== undefined && val.length < min) {
333
- throw new z.ZodError([{ code: "custom", message: getMessage("min", { min }), path: [] }])
334
+ ctx.addIssue({ code: "custom", message: getMessage("min", { min }) })
335
+ return
334
336
  }
335
337
  if (val !== null && max !== undefined && val.length > max) {
336
- throw new z.ZodError([{ code: "custom", message: getMessage("max", { max }), path: [] }])
338
+ ctx.addIssue({ code: "custom", message: getMessage("max", { max }) })
339
+ return
337
340
  }
338
341
 
339
342
  // Character requirements
340
343
  if (val !== null && uppercase && !/[A-Z]/.test(val)) {
341
- throw new z.ZodError([{ code: "custom", message: getMessage("uppercase"), path: [] }])
344
+ ctx.addIssue({ code: "custom", message: getMessage("uppercase") })
345
+ return
342
346
  }
343
347
  if (val !== null && lowercase && !/[a-z]/.test(val)) {
344
- throw new z.ZodError([{ code: "custom", message: getMessage("lowercase"), path: [] }])
348
+ ctx.addIssue({ code: "custom", message: getMessage("lowercase") })
349
+ return
345
350
  }
346
351
  if (val !== null && digits && !/[0-9]/.test(val)) {
347
- throw new z.ZodError([{ code: "custom", message: getMessage("digits"), path: [] }])
352
+ ctx.addIssue({ code: "custom", message: getMessage("digits") })
353
+ return
348
354
  }
349
355
  if (val !== null && special && !/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/.test(val)) {
350
- throw new z.ZodError([{ code: "custom", message: getMessage("special"), path: [] }])
356
+ ctx.addIssue({ code: "custom", message: getMessage("special") })
357
+ return
351
358
  }
352
359
 
353
360
  // Advanced security checks
354
361
  if (val !== null && noRepeating && /(.)\1{2,}/.test(val)) {
355
- throw new z.ZodError([{ code: "custom", message: getMessage("noRepeating"), path: [] }])
362
+ ctx.addIssue({ code: "custom", message: getMessage("noRepeating") })
363
+ return
356
364
  }
357
365
  if (val !== null && noSequential && /(?:abc|bcd|cde|def|efg|fgh|ghi|hij|ijk|jkl|klm|lmn|mno|nop|opq|pqr|qrs|rst|stu|tuv|uvw|vwx|wxy|xyz|012|123|234|345|456|567|678|789)/i.test(val)) {
358
- throw new z.ZodError([{ code: "custom", message: getMessage("noSequential"), path: [] }])
366
+ ctx.addIssue({ code: "custom", message: getMessage("noSequential") })
367
+ return
359
368
  }
360
369
  if (val !== null && noCommonWords && COMMON_PASSWORDS.some((common) => val.toLowerCase().includes(common.toLowerCase()))) {
361
- throw new z.ZodError([{ code: "custom", message: getMessage("noCommonWords"), path: [] }])
370
+ ctx.addIssue({ code: "custom", message: getMessage("noCommonWords") })
371
+ return
362
372
  }
363
373
  if (val !== null && minStrength) {
364
374
  const strength = calculatePasswordStrength(val)
@@ -366,27 +376,29 @@ export function password<IsRequired extends boolean = false>(required?: IsRequir
366
376
  const currentLevel = strengthLevels.indexOf(strength)
367
377
  const requiredLevel = strengthLevels.indexOf(minStrength)
368
378
  if (currentLevel < requiredLevel) {
369
- throw new z.ZodError([{ code: "custom", message: getMessage("minStrength", { minStrength }), path: [] }])
379
+ ctx.addIssue({ code: "custom", message: getMessage("minStrength", { minStrength }) })
380
+ return
370
381
  }
371
382
  }
372
383
 
373
384
  // Content checks
374
385
  if (val !== null && includes !== undefined && !val.includes(includes)) {
375
- throw new z.ZodError([{ code: "custom", message: getMessage("includes", { includes }), path: [] }])
386
+ ctx.addIssue({ code: "custom", message: getMessage("includes", { includes }) })
387
+ return
376
388
  }
377
389
  if (val !== null && excludes !== undefined) {
378
390
  const excludeList = Array.isArray(excludes) ? excludes : [excludes]
379
391
  for (const exclude of excludeList) {
380
392
  if (val.includes(exclude)) {
381
- throw new z.ZodError([{ code: "custom", message: getMessage("excludes", { excludes: exclude }), path: [] }])
393
+ ctx.addIssue({ code: "custom", message: getMessage("excludes", { excludes: exclude }) })
394
+ return
382
395
  }
383
396
  }
384
397
  }
385
398
  if (val !== null && regex !== undefined && !regex.test(val)) {
386
- throw new z.ZodError([{ code: "custom", message: getMessage("invalid", { regex }), path: [] }])
399
+ ctx.addIssue({ code: "custom", message: getMessage("invalid", { regex }) })
400
+ return
387
401
  }
388
-
389
- return true
390
402
  })
391
403
 
392
404
  return schema as unknown as PasswordSchema<IsRequired>
@@ -223,52 +223,86 @@ export function text<IsRequired extends boolean = false>(required?: IsRequired,
223
223
 
224
224
  const baseSchema = isRequired ? z.preprocess(preprocessFn, z.string()) : z.preprocess(preprocessFn, z.string().nullable())
225
225
 
226
- // Single refine with all validations for better performance
227
- const schema = baseSchema.refine((val) => {
228
- if (val === null) return true
226
+ // Single superRefine with all validations for better performance
227
+ const schema = baseSchema.superRefine((val, ctx) => {
228
+ if (val === null) return
229
229
 
230
230
  // Required check
231
231
  if (isRequired && (val === "" || val === "null" || val === "undefined")) {
232
- throw new z.ZodError([{ code: "custom", message: getMessage("required"), path: [] }])
232
+ ctx.addIssue({
233
+ code: "custom",
234
+ message: getMessage("required")
235
+ })
236
+ return
233
237
  }
234
238
 
235
239
  // Not empty check (different from required - checks whitespace)
236
240
  // For notEmpty, we need to check if the original string (before processing) was only whitespace
237
241
  if (notEmpty && val !== null && val.trim() === "") {
238
- throw new z.ZodError([{ code: "custom", message: getMessage("notEmpty"), path: [] }])
242
+ ctx.addIssue({
243
+ code: "custom",
244
+ message: getMessage("notEmpty")
245
+ })
246
+ return
239
247
  }
240
248
 
241
249
  // Length checks
242
250
  if (val !== null && minLength !== undefined && val.length < minLength) {
243
- throw new z.ZodError([{ code: "custom", message: getMessage("minLength", { minLength }), path: [] }])
251
+ ctx.addIssue({
252
+ code: "custom",
253
+ message: getMessage("minLength", { minLength })
254
+ })
255
+ return
244
256
  }
245
257
  if (val !== null && maxLength !== undefined && val.length > maxLength) {
246
- throw new z.ZodError([{ code: "custom", message: getMessage("maxLength", { maxLength }), path: [] }])
258
+ ctx.addIssue({
259
+ code: "custom",
260
+ message: getMessage("maxLength", { maxLength })
261
+ })
262
+ return
247
263
  }
248
264
 
249
265
  // String content checks
250
266
  if (val !== null && startsWith !== undefined && !val.startsWith(startsWith)) {
251
- throw new z.ZodError([{ code: "custom", message: getMessage("startsWith", { startsWith }), path: [] }])
267
+ ctx.addIssue({
268
+ code: "custom",
269
+ message: getMessage("startsWith", { startsWith })
270
+ })
271
+ return
252
272
  }
253
273
  if (val !== null && endsWith !== undefined && !val.endsWith(endsWith)) {
254
- throw new z.ZodError([{ code: "custom", message: getMessage("endsWith", { endsWith }), path: [] }])
274
+ ctx.addIssue({
275
+ code: "custom",
276
+ message: getMessage("endsWith", { endsWith })
277
+ })
278
+ return
255
279
  }
256
280
  if (val !== null && includes !== undefined && !val.includes(includes)) {
257
- throw new z.ZodError([{ code: "custom", message: getMessage("includes", { includes }), path: [] }])
281
+ ctx.addIssue({
282
+ code: "custom",
283
+ message: getMessage("includes", { includes })
284
+ })
285
+ return
258
286
  }
259
287
  if (val !== null && excludes !== undefined) {
260
288
  const excludeList = Array.isArray(excludes) ? excludes : [excludes]
261
289
  for (const exclude of excludeList) {
262
290
  if (val.includes(exclude)) {
263
- throw new z.ZodError([{ code: "custom", message: getMessage("excludes", { excludes: exclude }), path: [] }])
291
+ ctx.addIssue({
292
+ code: "custom",
293
+ message: getMessage("excludes", { excludes: exclude })
294
+ })
295
+ return
264
296
  }
265
297
  }
266
298
  }
267
299
  if (val !== null && regex !== undefined && !regex.test(val)) {
268
- throw new z.ZodError([{ code: "custom", message: getMessage("invalid", { regex }), path: [] }])
300
+ ctx.addIssue({
301
+ code: "custom",
302
+ message: getMessage("invalid", { regex })
303
+ })
304
+ return
269
305
  }
270
-
271
- return true
272
306
  })
273
307
 
274
308
  return schema as unknown as TextSchema<IsRequired>
@@ -465,25 +465,27 @@ export function time<IsRequired extends boolean = false>(required?: IsRequired,
465
465
 
466
466
  const baseSchema = isRequired ? z.preprocess(preprocessFn, z.string()) : z.preprocess(preprocessFn, z.string().nullable())
467
467
 
468
- const schema = baseSchema.refine((val) => {
469
- if (val === null) return true
468
+ const schema = baseSchema.superRefine((val, ctx) => {
469
+ if (val === null) return
470
470
 
471
471
  // Required check
472
472
  if (isRequired && (val === "" || val === "null" || val === "undefined")) {
473
- throw new z.ZodError([{ code: "custom", message: getMessage("required"), path: [] }])
473
+ ctx.addIssue({ code: "custom", message: getMessage("required") })
474
+ return
474
475
  }
475
476
 
476
- if (val === null) return true
477
- if (!isRequired && val === "") return true
477
+ if (val === null) return
478
+ if (!isRequired && val === "") return
478
479
 
479
480
  // Whitelist check
480
481
  if (whitelist && whitelist.length > 0) {
481
482
  if (whitelist.includes(val)) {
482
- return true
483
+ return
483
484
  }
484
485
  // If whitelistOnly is true, reject values not in whitelist
485
486
  if (whitelistOnly) {
486
- throw new z.ZodError([{ code: "custom", message: getMessage("notInWhitelist"), path: [] }])
487
+ ctx.addIssue({ code: "custom", message: getMessage("notInWhitelist") })
488
+ return
487
489
  }
488
490
  // Otherwise, continue with normal validation
489
491
  }
@@ -491,60 +493,69 @@ export function time<IsRequired extends boolean = false>(required?: IsRequired,
491
493
  // Custom regex validation (overrides format validation)
492
494
  if (regex) {
493
495
  if (!regex.test(val)) {
494
- throw new z.ZodError([{ code: "custom", message: getMessage("customRegex"), path: [] }])
496
+ ctx.addIssue({ code: "custom", message: getMessage("customRegex") })
497
+ return
495
498
  }
496
499
  } else {
497
500
  // Time format validation (only if no regex is provided)
498
501
  if (!validateTimeFormat(val, format)) {
499
- throw new z.ZodError([{ code: "custom", message: getMessage("format", { format }), path: [] }])
502
+ ctx.addIssue({ code: "custom", message: getMessage("format", { format }) })
503
+ return
500
504
  }
501
505
  }
502
506
 
503
507
  // String content checks
504
508
  if (includes && !val.includes(includes)) {
505
- throw new z.ZodError([{ code: "custom", message: getMessage("includes", { includes }), path: [] }])
509
+ ctx.addIssue({ code: "custom", message: getMessage("includes", { includes }) })
510
+ return
506
511
  }
507
512
 
508
513
  if (excludes) {
509
514
  const excludeList = Array.isArray(excludes) ? excludes : [excludes]
510
515
  for (const exclude of excludeList) {
511
516
  if (val.includes(exclude)) {
512
- throw new z.ZodError([{ code: "custom", message: getMessage("excludes", { excludes: exclude }), path: [] }])
517
+ ctx.addIssue({ code: "custom", message: getMessage("excludes", { excludes: exclude }) })
518
+ return
513
519
  }
514
520
  }
515
521
  }
516
522
 
517
523
  // Skip time parsing and range validation if using custom regex
518
524
  if (regex) {
519
- return true
525
+ return
520
526
  }
521
527
 
522
528
  // Parse time for range validation
523
529
  const timeMinutes = parseTimeToMinutes(val, format)
524
530
  if (timeMinutes === null) {
525
- throw new z.ZodError([{ code: "custom", message: getMessage("invalid"), path: [] }])
531
+ ctx.addIssue({ code: "custom", message: getMessage("invalid") })
532
+ return
526
533
  }
527
534
 
528
535
  // Hour validation
529
536
  const hour = Math.floor(timeMinutes / 60)
530
537
  if (minHour !== undefined && hour < minHour) {
531
- throw new z.ZodError([{ code: "custom", message: getMessage("hour", { minHour, maxHour: maxHour ?? 23 }), path: [] }])
538
+ ctx.addIssue({ code: "custom", message: getMessage("hour", { minHour, maxHour: maxHour ?? 23 }) })
539
+ return
532
540
  }
533
541
  if (maxHour !== undefined && hour > maxHour) {
534
- throw new z.ZodError([{ code: "custom", message: getMessage("hour", { minHour: minHour ?? 0, maxHour }), path: [] }])
542
+ ctx.addIssue({ code: "custom", message: getMessage("hour", { minHour: minHour ?? 0, maxHour }) })
543
+ return
535
544
  }
536
545
 
537
546
  // Allowed hours check
538
547
  if (allowedHours && allowedHours.length > 0) {
539
548
  if (!allowedHours.includes(hour)) {
540
- throw new z.ZodError([{ code: "custom", message: getMessage("hour", { allowedHours: allowedHours.join(", ") }), path: [] }])
549
+ ctx.addIssue({ code: "custom", message: getMessage("hour", { allowedHours: allowedHours.join(", ") }) })
550
+ return
541
551
  }
542
552
  }
543
553
 
544
554
  // Minute step validation
545
555
  const minute = timeMinutes % 60
546
556
  if (minuteStep !== undefined && minute % minuteStep !== 0) {
547
- throw new z.ZodError([{ code: "custom", message: getMessage("minute", { minuteStep }), path: [] }])
557
+ ctx.addIssue({ code: "custom", message: getMessage("minute", { minuteStep }) })
558
+ return
548
559
  }
549
560
 
550
561
  // Second step validation (only for formats with seconds)
@@ -554,7 +565,8 @@ export function time<IsRequired extends boolean = false>(required?: IsRequired,
554
565
  if (secondMatch) {
555
566
  const seconds = parseInt(secondMatch[1], 10)
556
567
  if (seconds % secondStep !== 0) {
557
- throw new z.ZodError([{ code: "custom", message: getMessage("second", { secondStep }), path: [] }])
568
+ ctx.addIssue({ code: "custom", message: getMessage("second", { secondStep }) })
569
+ return
558
570
  }
559
571
  }
560
572
  }
@@ -563,18 +575,18 @@ export function time<IsRequired extends boolean = false>(required?: IsRequired,
563
575
  if (min) {
564
576
  const minMinutes = parseTimeToMinutes(min, format)
565
577
  if (minMinutes !== null && timeMinutes < minMinutes) {
566
- throw new z.ZodError([{ code: "custom", message: getMessage("min", { min }), path: [] }])
578
+ ctx.addIssue({ code: "custom", message: getMessage("min", { min }) })
579
+ return
567
580
  }
568
581
  }
569
582
 
570
583
  if (max) {
571
584
  const maxMinutes = parseTimeToMinutes(max, format)
572
585
  if (maxMinutes !== null && timeMinutes > maxMinutes) {
573
- throw new z.ZodError([{ code: "custom", message: getMessage("max", { max }), path: [] }])
586
+ ctx.addIssue({ code: "custom", message: getMessage("max", { max }) })
587
+ return
574
588
  }
575
589
  }
576
-
577
- return true
578
590
  })
579
591
 
580
592
  return schema as unknown as TimeSchema<IsRequired>