@hy_ong/zod-kit 0.1.1 → 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.
@@ -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>
@@ -253,12 +253,13 @@ export function url<IsRequired extends boolean = false>(required?: IsRequired, o
253
253
 
254
254
  const baseSchema = isRequired ? z.preprocess(preprocessFn, z.string()) : z.preprocess(preprocessFn, z.string().nullable())
255
255
 
256
- const schema = baseSchema.refine((val) => {
257
- if (val === null) return true
256
+ const schema = baseSchema.superRefine((val, ctx) => {
257
+ if (val === null) return
258
258
 
259
259
  // Required check
260
260
  if (isRequired && (val === "" || val === "null" || val === "undefined")) {
261
- throw new z.ZodError([{ code: "custom", message: getMessage("required"), path: [] }])
261
+ ctx.addIssue({ code: "custom", message: getMessage("required") })
262
+ return
262
263
  }
263
264
 
264
265
  // URL format validation
@@ -266,88 +267,104 @@ export function url<IsRequired extends boolean = false>(required?: IsRequired, o
266
267
  try {
267
268
  urlObj = new URL(val)
268
269
  } catch {
269
- throw new z.ZodError([{ code: "custom", message: getMessage("invalid"), path: [] }])
270
+ ctx.addIssue({ code: "custom", message: getMessage("invalid") })
271
+ return
270
272
  }
271
273
 
272
274
  // Length checks
273
275
  if (val !== null && min !== undefined && val.length < min) {
274
- throw new z.ZodError([{ code: "custom", message: getMessage("min", { min }), path: [] }])
276
+ ctx.addIssue({ code: "custom", message: getMessage("min", { min }) })
277
+ return
275
278
  }
276
279
  if (val !== null && max !== undefined && val.length > max) {
277
- throw new z.ZodError([{ code: "custom", message: getMessage("max", { max }), path: [] }])
280
+ ctx.addIssue({ code: "custom", message: getMessage("max", { max }) })
281
+ return
278
282
  }
279
283
 
280
284
  // String content checks
281
285
  if (val !== null && includes !== undefined && !val.includes(includes)) {
282
- throw new z.ZodError([{ code: "custom", message: getMessage("includes", { includes }), path: [] }])
286
+ ctx.addIssue({ code: "custom", message: getMessage("includes", { includes }) })
287
+ return
283
288
  }
284
289
  if (val !== null && excludes !== undefined) {
285
290
  const excludeList = Array.isArray(excludes) ? excludes : [excludes]
286
291
  for (const exclude of excludeList) {
287
292
  if (val.includes(exclude)) {
288
- throw new z.ZodError([{ code: "custom", message: getMessage("excludes", { excludes: exclude }), path: [] }])
293
+ ctx.addIssue({ code: "custom", message: getMessage("excludes", { excludes: exclude }) })
294
+ return
289
295
  }
290
296
  }
291
297
  }
292
298
 
293
299
  // Protocol validation
294
300
  if (protocols && !protocols.includes(urlObj.protocol.slice(0, -1))) {
295
- throw new z.ZodError([{ code: "custom", message: getMessage("protocol", { protocols: protocols.join(", ") }), path: [] }])
301
+ ctx.addIssue({ code: "custom", message: getMessage("protocol", { protocols: protocols.join(", ") }) })
302
+ return
296
303
  }
297
304
 
298
305
  // Domain validation
299
306
  const hostname = urlObj.hostname.toLowerCase()
300
307
  if (allowedDomains && !allowedDomains.some((domain) => hostname === domain || hostname.endsWith(`.${domain}`))) {
301
- throw new z.ZodError([{ code: "custom", message: getMessage("domain", { domains: allowedDomains.join(", ") }), path: [] }])
308
+ ctx.addIssue({ code: "custom", message: getMessage("domain", { domains: allowedDomains.join(", ") }) })
309
+ return
302
310
  }
303
311
  if (blockedDomains && blockedDomains.some((domain) => hostname === domain || hostname.endsWith(`.${domain}`))) {
304
312
  const blockedDomain = blockedDomains.find((domain) => hostname === domain || hostname.endsWith(`.${domain}`))
305
- throw new z.ZodError([{ code: "custom", message: getMessage("domainBlacklist", { domain: blockedDomain }), path: [] }])
313
+ ctx.addIssue({ code: "custom", message: getMessage("domainBlacklist", { domain: blockedDomain }) })
314
+ return
306
315
  }
307
316
 
308
317
  // Port validation
309
318
  const port = urlObj.port ? parseInt(urlObj.port) : urlObj.protocol === "https:" ? 443 : 80
310
319
  if (allowedPorts && !allowedPorts.includes(port)) {
311
- throw new z.ZodError([{ code: "custom", message: getMessage("port", { ports: allowedPorts.join(", ") }), path: [] }])
320
+ ctx.addIssue({ code: "custom", message: getMessage("port", { ports: allowedPorts.join(", ") }) })
321
+ return
312
322
  }
313
323
  if (blockedPorts && blockedPorts.includes(port)) {
314
- throw new z.ZodError([{ code: "custom", message: getMessage("port", { port }), path: [] }])
324
+ ctx.addIssue({ code: "custom", message: getMessage("port", { port }) })
325
+ return
315
326
  }
316
327
 
317
328
  // Path validation
318
329
  if (pathStartsWith && !urlObj.pathname.startsWith(pathStartsWith)) {
319
- throw new z.ZodError([{ code: "custom", message: getMessage("pathStartsWith", { path: pathStartsWith }), path: [] }])
330
+ ctx.addIssue({ code: "custom", message: getMessage("pathStartsWith", { path: pathStartsWith }) })
331
+ return
320
332
  }
321
333
  if (pathEndsWith && !urlObj.pathname.endsWith(pathEndsWith)) {
322
- throw new z.ZodError([{ code: "custom", message: getMessage("pathEndsWith", { path: pathEndsWith }), path: [] }])
334
+ ctx.addIssue({ code: "custom", message: getMessage("pathEndsWith", { path: pathEndsWith }) })
335
+ return
323
336
  }
324
337
 
325
338
  // Query validation
326
339
  if (mustHaveQuery && !urlObj.search) {
327
- throw new z.ZodError([{ code: "custom", message: getMessage("hasQuery"), path: [] }])
340
+ ctx.addIssue({ code: "custom", message: getMessage("hasQuery") })
341
+ return
328
342
  }
329
343
  if (mustNotHaveQuery && urlObj.search) {
330
- throw new z.ZodError([{ code: "custom", message: getMessage("noQuery"), path: [] }])
344
+ ctx.addIssue({ code: "custom", message: getMessage("noQuery") })
345
+ return
331
346
  }
332
347
 
333
348
  // Fragment validation
334
349
  if (mustHaveFragment && !urlObj.hash) {
335
- throw new z.ZodError([{ code: "custom", message: getMessage("hasFragment"), path: [] }])
350
+ ctx.addIssue({ code: "custom", message: getMessage("hasFragment") })
351
+ return
336
352
  }
337
353
  if (mustNotHaveFragment && urlObj.hash) {
338
- throw new z.ZodError([{ code: "custom", message: getMessage("noFragment"), path: [] }])
354
+ ctx.addIssue({ code: "custom", message: getMessage("noFragment") })
355
+ return
339
356
  }
340
357
 
341
358
  // Localhost validation
342
359
  const isLocalhost = hostname === "localhost" || hostname === "127.0.0.1" || hostname.startsWith("192.168.") || hostname.startsWith("10.") || hostname.match(/^172\.(1[6-9]|2[0-9]|3[0-1])\./)
343
360
  if (blockLocalhost && isLocalhost) {
344
- throw new z.ZodError([{ code: "custom", message: getMessage("noLocalhost"), path: [] }])
361
+ ctx.addIssue({ code: "custom", message: getMessage("noLocalhost") })
362
+ return
345
363
  }
346
364
  if (!allowLocalhost && isLocalhost) {
347
- throw new z.ZodError([{ code: "custom", message: getMessage("localhost"), path: [] }])
365
+ ctx.addIssue({ code: "custom", message: getMessage("localhost") })
366
+ return
348
367
  }
349
-
350
- return true
351
368
  })
352
369
 
353
370
  return schema as unknown as UrlSchema<IsRequired>
@@ -15,11 +15,11 @@ import { getLocale, type Locale } from "../../config"
15
15
  /**
16
16
  * Type definition for business ID validation error messages
17
17
  *
18
- * @interface BusinessIdMessages
18
+ * @interface TwBusinessIdMessages
19
19
  * @property {string} [required] - Message when field is required but empty
20
20
  * @property {string} [invalid] - Message when business ID format or checksum is invalid
21
21
  */
22
- export type BusinessIdMessages = {
22
+ export type TwBusinessIdMessages = {
23
23
  required?: string
24
24
  invalid?: string
25
25
  }
@@ -29,26 +29,26 @@ export type BusinessIdMessages = {
29
29
  *
30
30
  * @template IsRequired - Whether the field is required (affects return type)
31
31
  *
32
- * @interface BusinessIdOptions
32
+ * @interface TwBusinessIdOptions
33
33
  * @property {IsRequired} [required=true] - Whether the field is required
34
34
  * @property {Function} [transform] - Custom transformation function for business ID
35
35
  * @property {string | null} [defaultValue] - Default value when input is empty
36
- * @property {Record<Locale, BusinessIdMessages>} [i18n] - Custom error messages for different locales
36
+ * @property {Record<Locale, TwBusinessIdMessages>} [i18n] - Custom error messages for different locales
37
37
  */
38
- export type BusinessIdOptions<IsRequired extends boolean = true> = {
38
+ export type TwBusinessIdOptions<IsRequired extends boolean = true> = {
39
39
  transform?: (value: string) => string
40
40
  defaultValue?: IsRequired extends true ? string : string | null
41
- i18n?: Record<Locale, BusinessIdMessages>
41
+ i18n?: Record<Locale, TwBusinessIdMessages>
42
42
  }
43
43
 
44
44
  /**
45
45
  * Type alias for business ID validation schema based on required flag
46
46
  *
47
47
  * @template IsRequired - Whether the field is required
48
- * @typedef BusinessIdSchema
48
+ * @typedef TwBusinessIdSchema
49
49
  * @description Returns ZodString if required, ZodNullable<ZodString> if optional
50
50
  */
51
- export type BusinessIdSchema<IsRequired extends boolean> = IsRequired extends true ? ZodString : ZodNullable<ZodString>
51
+ export type TwBusinessIdSchema<IsRequired extends boolean> = IsRequired extends true ? ZodString : ZodNullable<ZodString>
52
52
 
53
53
  /**
54
54
  * Validates Taiwan Business Identification Number (統一編號)
@@ -179,10 +179,10 @@ const validateTaiwanBusinessId = (value: string): boolean => {
179
179
  * ```
180
180
  *
181
181
  * @throws {z.ZodError} When validation fails with specific error messages
182
- * @see {@link BusinessIdOptions} for all available configuration options
182
+ * @see {@link TwBusinessIdOptions} for all available configuration options
183
183
  * @see {@link validateTaiwanBusinessId} for validation logic details
184
184
  */
185
- export function businessId<IsRequired extends boolean = false>(required?: IsRequired, options?: Omit<BusinessIdOptions<IsRequired>, 'required'>): BusinessIdSchema<IsRequired> {
185
+ export function twBusinessId<IsRequired extends boolean = false>(required?: IsRequired, options?: Omit<TwBusinessIdOptions<IsRequired>, 'required'>): TwBusinessIdSchema<IsRequired> {
186
186
  const {
187
187
  transform,
188
188
  defaultValue,
@@ -195,7 +195,7 @@ export function businessId<IsRequired extends boolean = false>(required?: IsRequ
195
195
  const actualDefaultValue = defaultValue ?? (isRequired ? "" : null)
196
196
 
197
197
  // Helper function to get custom message or fallback to default i18n
198
- const getMessage = (key: keyof BusinessIdMessages, params?: Record<string, any>) => {
198
+ const getMessage = (key: keyof TwBusinessIdMessages, params?: Record<string, any>) => {
199
199
  if (i18n) {
200
200
  const currentLocale = getLocale()
201
201
  const customMessages = i18n[currentLocale]
@@ -229,23 +229,23 @@ export function businessId<IsRequired extends boolean = false>(required?: IsRequ
229
229
 
230
230
  const baseSchema = isRequired ? z.preprocess(preprocessFn, z.string()) : z.preprocess(preprocessFn, z.string().nullable())
231
231
 
232
- const schema = baseSchema.refine((val) => {
233
- if (val === null) return true
232
+ const schema = baseSchema.superRefine((val, ctx) => {
233
+ if (val === null) return
234
234
 
235
235
  // Required check
236
236
  if (isRequired && (val === "" || val === "null" || val === "undefined")) {
237
- throw new z.ZodError([{ code: "custom", message: getMessage("required"), path: [] }])
237
+ ctx.addIssue({ code: "custom", message: getMessage("required") })
238
+ return
238
239
  }
239
240
 
240
- if (val === null) return true
241
- if (!isRequired && val === "") return true
241
+ if (val === null) return
242
+ if (!isRequired && val === "") return
242
243
 
243
244
  // Taiwan Business ID format validation (8 digits + checksum)
244
245
  if (!validateTaiwanBusinessId(val)) {
245
- throw new z.ZodError([{ code: "custom", message: getMessage("invalid"), path: [] }])
246
+ ctx.addIssue({ code: "custom", message: getMessage("invalid") })
247
+ return
246
248
  }
247
-
248
- return true
249
249
  })
250
250
 
251
251
  return schema as unknown as BusinessIdSchema<IsRequired>