agent-relay 6.0.3 → 6.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. package/dist/index.cjs +1395 -674
  2. package/node_modules/@relaycast/sdk/node_modules/zod/README.md +1 -1
  3. package/node_modules/@relaycast/sdk/node_modules/zod/locales/package.json +2 -1
  4. package/node_modules/@relaycast/sdk/node_modules/zod/mini/package.json +2 -1
  5. package/node_modules/@relaycast/sdk/node_modules/zod/package.json +1 -1
  6. package/node_modules/@relaycast/sdk/node_modules/zod/src/v3/tests/all-errors.test.ts +3 -3
  7. package/node_modules/@relaycast/sdk/node_modules/zod/src/v3/tests/object.test.ts +5 -5
  8. package/node_modules/@relaycast/sdk/node_modules/zod/src/v3/tests/partials.test.ts +3 -3
  9. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/errors.ts +2 -2
  10. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/external.ts +1 -0
  11. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/from-json-schema.ts +39 -23
  12. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/parse.ts +6 -6
  13. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/schemas.ts +389 -148
  14. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/catch.test.ts +4 -2
  15. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/codec.test.ts +142 -1
  16. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/continuability.test.ts +1 -1
  17. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/datetime.test.ts +1 -1
  18. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/default.test.ts +44 -0
  19. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/detached-methods.test.ts +197 -0
  20. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/discriminated-unions.test.ts +31 -1
  21. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/error-utils.test.ts +214 -2
  22. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/from-json-schema.test.ts +161 -0
  23. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/function.test.ts +6 -6
  24. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/global-config.test.ts +39 -0
  25. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/index.test.ts +2 -2
  26. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/jitless-allows-eval.test.ts +46 -0
  27. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/locales_ka.test.ts +29 -0
  28. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/locales_ro.test.ts +24 -0
  29. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/number.test.ts +55 -0
  30. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/object.test.ts +83 -6
  31. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/optional.test.ts +114 -4
  32. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/partial.test.ts +28 -2
  33. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/prefault.test.ts +1 -1
  34. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/record.test.ts +85 -0
  35. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/recursive-types.test.ts +49 -0
  36. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/refine.test.ts +63 -0
  37. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/string.test.ts +50 -1
  38. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/template-literal.test.ts +4 -4
  39. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/to-json-schema.test.ts +128 -14
  40. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/transform.test.ts +17 -0
  41. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/tuple.test.ts +315 -2
  42. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/union.test.ts +54 -0
  43. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/core/api.ts +25 -2
  44. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/core/checks.ts +1 -1
  45. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/core/core.ts +17 -2
  46. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/core/errors.ts +31 -24
  47. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/core/json-schema-processors.ts +15 -17
  48. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/core/parse.ts +7 -7
  49. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/core/regexes.ts +8 -1
  50. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/core/schemas.ts +218 -66
  51. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/core/tests/locales/el.test.ts +215 -0
  52. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/core/tests/locales/fr.test.ts +72 -0
  53. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/core/tests/locales/hr.test.ts +163 -0
  54. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/core/tests/locales/uz.test.ts +22 -0
  55. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/core/tests/record-constructor.test.ts +58 -0
  56. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/core/to-json-schema.ts +9 -1
  57. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/core/util.ts +52 -35
  58. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/core/versions.ts +2 -2
  59. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/locales/el.ts +121 -0
  60. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/locales/en.ts +4 -0
  61. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/locales/fr.ts +24 -8
  62. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/locales/hr.ts +131 -0
  63. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/locales/index.ts +3 -0
  64. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/locales/it.ts +1 -1
  65. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/locales/ka.ts +8 -8
  66. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/locales/ro.ts +129 -0
  67. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/locales/uz.ts +1 -0
  68. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/mini/external.ts +1 -0
  69. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/mini/schemas.ts +55 -24
  70. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/mini/tests/codec.test.ts +19 -0
  71. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/mini/tests/index.test.ts +27 -2
  72. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/mini/tests/object.test.ts +9 -9
  73. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/mini/tests/recursive-types.test.ts +51 -1
  74. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/mini/tests/string.test.ts +5 -0
  75. package/node_modules/@relaycast/sdk/node_modules/zod/v3/package.json +2 -1
  76. package/node_modules/@relaycast/sdk/node_modules/zod/v4/classic/errors.js +2 -2
  77. package/node_modules/@relaycast/sdk/node_modules/zod/v4/classic/external.d.cts +1 -0
  78. package/node_modules/@relaycast/sdk/node_modules/zod/v4/classic/external.d.ts +1 -0
  79. package/node_modules/@relaycast/sdk/node_modules/zod/v4/classic/from-json-schema.cjs +31 -16
  80. package/node_modules/@relaycast/sdk/node_modules/zod/v4/classic/from-json-schema.js +31 -16
  81. package/node_modules/@relaycast/sdk/node_modules/zod/v4/classic/package.json +2 -1
  82. package/node_modules/@relaycast/sdk/node_modules/zod/v4/classic/schemas.cjs +346 -117
  83. package/node_modules/@relaycast/sdk/node_modules/zod/v4/classic/schemas.d.cts +34 -12
  84. package/node_modules/@relaycast/sdk/node_modules/zod/v4/classic/schemas.d.ts +34 -12
  85. package/node_modules/@relaycast/sdk/node_modules/zod/v4/classic/schemas.js +345 -117
  86. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/api.cjs +7 -2
  87. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/api.d.cts +20 -1
  88. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/api.d.ts +20 -1
  89. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/api.js +7 -2
  90. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/checks.d.cts +1 -1
  91. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/checks.d.ts +1 -1
  92. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/core.cjs +3 -1
  93. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/core.js +4 -2
  94. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/errors.cjs +26 -23
  95. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/errors.d.cts +1 -0
  96. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/errors.d.ts +1 -0
  97. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/errors.js +26 -23
  98. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/json-schema-processors.cjs +14 -19
  99. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/json-schema-processors.js +14 -19
  100. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/package.json +2 -1
  101. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/parse.cjs +7 -7
  102. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/parse.js +7 -7
  103. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/regexes.cjs +9 -3
  104. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/regexes.d.cts +6 -0
  105. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/regexes.d.ts +6 -0
  106. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/regexes.js +7 -1
  107. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/schemas.cjs +196 -59
  108. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/schemas.d.cts +21 -1
  109. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/schemas.d.ts +21 -1
  110. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/schemas.js +196 -59
  111. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/to-json-schema.cjs +10 -1
  112. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/to-json-schema.js +10 -1
  113. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/util.cjs +54 -30
  114. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/util.d.cts +1 -0
  115. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/util.d.ts +1 -0
  116. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/util.js +55 -32
  117. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/versions.cjs +2 -2
  118. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/versions.d.cts +1 -1
  119. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/versions.d.ts +1 -1
  120. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/versions.js +2 -2
  121. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/el.cjs +136 -0
  122. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/el.d.cts +5 -0
  123. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/el.d.ts +4 -0
  124. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/el.js +109 -0
  125. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/en.cjs +4 -0
  126. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/en.js +4 -0
  127. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/fr.cjs +24 -7
  128. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/fr.js +24 -7
  129. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/hr.cjs +149 -0
  130. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/hr.d.cts +5 -0
  131. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/hr.d.ts +4 -0
  132. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/hr.js +122 -0
  133. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/index.cjs +8 -1
  134. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/index.d.cts +3 -0
  135. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/index.d.ts +3 -0
  136. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/index.js +3 -0
  137. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/it.cjs +1 -1
  138. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/it.js +1 -1
  139. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/ka.cjs +8 -8
  140. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/ka.js +8 -8
  141. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/package.json +2 -1
  142. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/ro.cjs +146 -0
  143. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/ro.d.cts +5 -0
  144. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/ro.d.ts +4 -0
  145. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/ro.js +119 -0
  146. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/uz.cjs +1 -0
  147. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/uz.js +1 -0
  148. package/node_modules/@relaycast/sdk/node_modules/zod/v4/mini/external.d.cts +1 -0
  149. package/node_modules/@relaycast/sdk/node_modules/zod/v4/mini/external.d.ts +1 -0
  150. package/node_modules/@relaycast/sdk/node_modules/zod/v4/mini/package.json +2 -1
  151. package/node_modules/@relaycast/sdk/node_modules/zod/v4/mini/schemas.cjs +41 -4
  152. package/node_modules/@relaycast/sdk/node_modules/zod/v4/mini/schemas.d.cts +27 -9
  153. package/node_modules/@relaycast/sdk/node_modules/zod/v4/mini/schemas.d.ts +27 -9
  154. package/node_modules/@relaycast/sdk/node_modules/zod/v4/mini/schemas.js +40 -4
  155. package/node_modules/@relaycast/sdk/node_modules/zod/v4/package.json +2 -1
  156. package/node_modules/@relaycast/sdk/node_modules/zod/v4-mini/package.json +2 -1
  157. package/package.json +9 -9
@@ -128,7 +128,8 @@ test("native enum", () => {
128
128
  fruit: z.nativeEnum(Fruits).catch(Fruits.apple),
129
129
  });
130
130
 
131
- expect(schema.parse({})).toEqual({ fruit: Fruits.apple });
131
+ expect(schema.safeParse({}).success).toEqual(false);
132
+ expect(schema.safeParse({}, { jitless: true }).success).toEqual(false);
132
133
  expect(schema.parse({ fruit: 15 })).toEqual({ fruit: Fruits.apple });
133
134
  });
134
135
 
@@ -137,7 +138,8 @@ test("enum", () => {
137
138
  fruit: z.enum(["apple", "orange"]).catch("apple"),
138
139
  });
139
140
 
140
- expect(schema.parse({})).toEqual({ fruit: "apple" });
141
+ expect(schema.safeParse({}).success).toEqual(false);
142
+ expect(schema.safeParse({}, { jitless: true }).success).toEqual(false);
141
143
  expect(schema.parse({ fruit: true })).toEqual({ fruit: "apple" });
142
144
  expect(schema.parse({ fruit: 15 })).toEqual({ fruit: "apple" });
143
145
  });
@@ -1,4 +1,4 @@
1
- import { expect, expectTypeOf, test } from "vitest";
1
+ import { describe, expect, expectTypeOf, test } from "vitest";
2
2
  import * as z from "zod/v4";
3
3
 
4
4
  const isoDateCodec = z.codec(
@@ -560,3 +560,144 @@ test("async codec functionality", async () => {
560
560
  const mixedResult = await z.decodeAsync(mixedCodec, "123");
561
561
  expect(mixedResult).toBe(123);
562
562
  });
563
+
564
+ test("invertCodec basic", () => {
565
+ const inverted = z.invertCodec(isoDateCodec);
566
+
567
+ const testDate = new Date("2024-01-15T10:30:00.000Z");
568
+ const decoded = z.decode(inverted, testDate);
569
+ expect(typeof decoded).toBe("string");
570
+ expect(decoded).toBe("2024-01-15T10:30:00.000Z");
571
+
572
+ const encoded = z.encode(inverted, "2024-01-15T10:30:00.000Z");
573
+ expect(encoded).toBeInstanceOf(Date);
574
+ expect(encoded.toISOString()).toBe("2024-01-15T10:30:00.000Z");
575
+ });
576
+
577
+ test("invertCodec round trip", () => {
578
+ const inverted = z.invertCodec(isoDateCodec);
579
+ const testDate = new Date("2024-06-01T12:00:00.000Z");
580
+
581
+ const toStr = z.decode(inverted, testDate);
582
+ const backToDate = z.encode(inverted, toStr);
583
+ expect(backToDate.toISOString()).toBe(testDate.toISOString());
584
+ });
585
+
586
+ test("invertCodec types", () => {
587
+ const inverted = z.invertCodec(isoDateCodec);
588
+
589
+ type InvIn = z.input<typeof inverted>;
590
+ type InvOut = z.output<typeof inverted>;
591
+ expectTypeOf<InvIn>().toEqualTypeOf<Date>();
592
+ expectTypeOf<InvOut>().toEqualTypeOf<string>();
593
+ });
594
+
595
+ test("invertCodec is its own inverse", () => {
596
+ const doubleInverted = z.invertCodec(z.invertCodec(isoDateCodec));
597
+ const testIsoString = "2024-03-10T08:00:00.000Z";
598
+
599
+ const decoded = z.decode(doubleInverted, testIsoString);
600
+ expect(decoded).toBeInstanceOf(Date);
601
+ expect(decoded.toISOString()).toBe(testIsoString);
602
+
603
+ const encoded = z.encode(doubleInverted, decoded);
604
+ expect(encoded).toBe(testIsoString);
605
+ });
606
+
607
+ test("invertCodec with custom codec", () => {
608
+ const intToString = z.codec(z.int(), z.string().regex(/^\d+$/), {
609
+ decode: (num) => num.toString(),
610
+ encode: (str) => Number.parseInt(str, 10),
611
+ });
612
+
613
+ const stringToInt = z.invertCodec(intToString);
614
+ const result = z.decode(stringToInt, "42");
615
+ expect(result).toBe(42);
616
+
617
+ const back = z.encode(stringToInt, 42);
618
+ expect(back).toBe("42");
619
+ });
620
+
621
+ describe("context immutability", () => {
622
+ test("decode/encode", () => {
623
+ const stringToDateCodec = z.codec(z.iso.datetime(), z.date(), {
624
+ decode: (isoString) => new Date(isoString),
625
+ encode: (date) => date.toISOString(),
626
+ });
627
+
628
+ const ctx = { reportInput: true } as const;
629
+
630
+ const result1 = z.decode(stringToDateCodec, "2024-01-15T10:30:00.000Z", ctx);
631
+ expect(result1).toBeInstanceOf(Date);
632
+
633
+ expect(ctx).toEqual({ reportInput: true });
634
+ expect("async" in ctx).toBe(false);
635
+ expect("direction" in ctx).toBe(false);
636
+
637
+ const result2 = z.decode(stringToDateCodec, "2024-12-25T15:45:30.123Z", ctx);
638
+ expect(result2).toBeInstanceOf(Date);
639
+
640
+ expect(ctx).toEqual({ reportInput: true });
641
+ expect("async" in ctx).toBe(false);
642
+ expect("direction" in ctx).toBe(false);
643
+
644
+ z.encode(stringToDateCodec, new Date("2024-01-01T00:00:00.000Z"), ctx);
645
+ expect(ctx).toEqual({ reportInput: true });
646
+ expect("direction" in ctx).toBe(false);
647
+
648
+ z.safeEncode(stringToDateCodec, new Date("2024-01-01T00:00:00.000Z"), ctx);
649
+ expect(ctx).toEqual({ reportInput: true });
650
+ expect("direction" in ctx).toBe(false);
651
+ });
652
+
653
+ test("parse functions", () => {
654
+ const schema = z.string().min(1);
655
+ const ctx = { reportInput: true } as const;
656
+
657
+ z.parse(schema, "asdf", ctx);
658
+ expect(ctx).toEqual({ reportInput: true });
659
+ expect("async" in ctx).toBe(false);
660
+
661
+ z.safeParse(schema, "asdf", ctx);
662
+ expect(ctx).toEqual({ reportInput: true });
663
+ expect("async" in ctx).toBe(false);
664
+ });
665
+
666
+ test("async functions", async () => {
667
+ const stringToDateCodec = z.codec(z.iso.datetime(), z.date(), {
668
+ decode: (isoString) => new Date(isoString),
669
+ encode: (date) => date.toISOString(),
670
+ });
671
+
672
+ const ctx = { reportInput: true } as const;
673
+
674
+ const schema = z.string();
675
+ await z.parseAsync(schema, "asdf", ctx);
676
+ expect(ctx).toEqual({ reportInput: true });
677
+ expect("async" in ctx).toBe(false);
678
+
679
+ await z.safeParseAsync(schema, "asdf", ctx);
680
+ expect(ctx).toEqual({ reportInput: true });
681
+ expect("async" in ctx).toBe(false);
682
+
683
+ await z.decodeAsync(stringToDateCodec, "2024-01-15T10:30:00.000Z", ctx);
684
+ expect(ctx).toEqual({ reportInput: true });
685
+ expect("async" in ctx).toBe(false);
686
+ expect("direction" in ctx).toBe(false);
687
+
688
+ await z.encodeAsync(stringToDateCodec, new Date("2024-01-01T00:00:00.000Z"), ctx);
689
+ expect(ctx).toEqual({ reportInput: true });
690
+ expect("async" in ctx).toBe(false);
691
+ expect("direction" in ctx).toBe(false);
692
+
693
+ await z.safeDecodeAsync(stringToDateCodec, "2024-01-15T10:30:00.000Z", ctx);
694
+ expect(ctx).toEqual({ reportInput: true });
695
+ expect("async" in ctx).toBe(false);
696
+ expect("direction" in ctx).toBe(false);
697
+
698
+ await z.safeEncodeAsync(stringToDateCodec, new Date("2024-01-01T00:00:00.000Z"), ctx);
699
+ expect(ctx).toEqual({ reportInput: true });
700
+ expect("async" in ctx).toBe(false);
701
+ expect("direction" in ctx).toBe(false);
702
+ });
703
+ });
@@ -274,7 +274,7 @@ test("continuability", () => {
274
274
  "message": "Invalid cuid",
275
275
  "origin": "string",
276
276
  "path": [],
277
- "pattern": "/^[cC][^\\s-]{8,}$/",
277
+ "pattern": "/^[cC][0-9a-z]{6,}$/",
278
278
  },
279
279
  {
280
280
  "code": "custom",
@@ -299,4 +299,4 @@ test("redos checker", () => {
299
299
  const result = checkSync(schema._zod.pattern.source, "");
300
300
  if (result.status !== "safe") throw Error("ReDoS issue");
301
301
  }
302
- });
302
+ }, 10000);
@@ -332,6 +332,50 @@ test("defaulted array schema returns shallow clone", () => {
332
332
  expect(result1).toEqual(result2);
333
333
  });
334
334
 
335
+ test("defaulted Map schema returns shallow clone", () => {
336
+ const schema = z.map(z.string(), z.number()).default(new Map([["a", 1]]));
337
+ const result1 = schema.parse(undefined);
338
+ const result2 = schema.parse(undefined);
339
+ expect(result1).not.toBe(result2);
340
+ expect(result1).toEqual(result2);
341
+ });
342
+
343
+ test("defaulted Set schema returns shallow clone", () => {
344
+ const schema = z.set(z.string()).default(new Set(["x"]));
345
+ const result1 = schema.parse(undefined);
346
+ const result2 = schema.parse(undefined);
347
+ expect(result1).not.toBe(result2);
348
+ expect(result1).toEqual(result2);
349
+ });
350
+
351
+ test("mutations on defaulted Map do not affect subsequent parses", () => {
352
+ const schema = z.map(z.string(), z.number()).default(new Map());
353
+ const result1 = schema.parse(undefined);
354
+ const result2 = schema.parse(undefined);
355
+ result1.set("key1", 1);
356
+ result2.set("key2", 2);
357
+ expect(result1.size).toBe(1);
358
+ expect(result1.get("key1")).toBe(1);
359
+ expect(result1.has("key2")).toBe(false);
360
+ expect(result2.size).toBe(1);
361
+ expect(result2.get("key2")).toBe(2);
362
+ expect(result2.has("key1")).toBe(false);
363
+ });
364
+
365
+ test("mutations on defaulted Set do not affect subsequent parses", () => {
366
+ const schema = z.set(z.string()).default(new Set());
367
+ const result1 = schema.parse(undefined);
368
+ const result2 = schema.parse(undefined);
369
+ result1.add("item1");
370
+ result2.add("item2");
371
+ expect(result1.size).toBe(1);
372
+ expect(result1.has("item1")).toBe(true);
373
+ expect(result1.has("item2")).toBe(false);
374
+ expect(result2.size).toBe(1);
375
+ expect(result2.has("item2")).toBe(true);
376
+ expect(result2.has("item1")).toBe(false);
377
+ });
378
+
335
379
  test("direction-aware defaults", () => {
336
380
  const schema = z.string().default("hello");
337
381
 
@@ -0,0 +1,197 @@
1
+ import { expect, test } from "vitest";
2
+ import * as z from "zod/v4";
3
+
4
+ /**
5
+ * Schema methods are exposed in a way that works when detached from the
6
+ * schema instance — `const opt = schema.optional; opt()` must produce a
7
+ * working `ZodOptional`, not a corrupt one. This pattern is used in real
8
+ * code (e.g. `arr.map(schema.parse)`, `arr.map(schema.optional)`,
9
+ * destructuring inside utility functions).
10
+ *
11
+ * This test caught a regression in colinhacks/zod#5870 where a memory
12
+ * optimization moved methods to the prototype and made `this`-binding
13
+ * required, silently breaking any detached usage.
14
+ */
15
+
16
+ const probeArgs: Record<string, unknown[]> = {
17
+ // ZodType
18
+ optional: [],
19
+ exactOptional: [],
20
+ nullable: [],
21
+ nullish: [],
22
+ array: [],
23
+ describe: ["x"],
24
+ brand: [],
25
+ readonly: [],
26
+ default: ["fallback"],
27
+ catch: ["fallback"],
28
+ // _ZodString
29
+ min: [1],
30
+ max: [10],
31
+ length: [5],
32
+ nonempty: [],
33
+ trim: [],
34
+ toLowerCase: [],
35
+ toUpperCase: [],
36
+ // ZodString format methods
37
+ email: [],
38
+ url: [],
39
+ uuid: [],
40
+ cuid: [],
41
+ cuid2: [],
42
+ ulid: [],
43
+ base64: [],
44
+ base64url: [],
45
+ ipv4: [],
46
+ ipv6: [],
47
+ // ZodNumber
48
+ int: [],
49
+ positive: [],
50
+ negative: [],
51
+ finite: [],
52
+ };
53
+
54
+ test("detached parse-family methods work without `this` binding", () => {
55
+ const schema = z.string();
56
+ const { parse, safeParse } = schema;
57
+
58
+ expect(parse("hello")).toBe("hello");
59
+ expect(safeParse("hello").success).toBe(true);
60
+ });
61
+
62
+ test("detached schema.optional() returns a working ZodOptional", () => {
63
+ const schema = z.string();
64
+ const opt = schema.optional;
65
+
66
+ const detached = opt();
67
+
68
+ expect(detached).toBeInstanceOf(z.ZodOptional);
69
+ expect(detached.safeParse("hello").success).toBe(true);
70
+ expect(detached.safeParse(undefined).success).toBe(true);
71
+ expect(detached.safeParse(123).success).toBe(false);
72
+ });
73
+
74
+ test("detached schema.nullable() returns a working ZodNullable", () => {
75
+ const schema = z.string();
76
+ const nul = schema.nullable;
77
+
78
+ const detached = nul();
79
+
80
+ expect(detached).toBeInstanceOf(z.ZodNullable);
81
+ expect(detached.safeParse("hello").success).toBe(true);
82
+ expect(detached.safeParse(null).success).toBe(true);
83
+ expect(detached.safeParse(123).success).toBe(false);
84
+ });
85
+
86
+ test("detached schema.array() returns a working ZodArray", () => {
87
+ const schema = z.string();
88
+ const arr = schema.array;
89
+
90
+ const detached = arr();
91
+
92
+ expect(detached).toBeInstanceOf(z.ZodArray);
93
+ expect(detached.safeParse(["a", "b"]).success).toBe(true);
94
+ expect(detached.safeParse([1, 2]).success).toBe(false);
95
+ });
96
+
97
+ test("detached schema.describe() returns a described schema", () => {
98
+ const schema = z.string();
99
+ const describe = schema.describe;
100
+
101
+ const described = describe("hello world");
102
+
103
+ expect(described.description).toBe("hello world");
104
+ });
105
+
106
+ test("detached refinement still validates", () => {
107
+ const schema = z.string();
108
+ const refine = schema.refine;
109
+
110
+ const refined = refine((s: string) => s.startsWith("x"), "must start with x");
111
+
112
+ expect(refined.safeParse("xhello").success).toBe(true);
113
+ expect(refined.safeParse("hello").success).toBe(false);
114
+ });
115
+
116
+ test("detached chained calls work — schema.optional then parse", () => {
117
+ const schema = z.string();
118
+ const opt = schema.optional;
119
+ const optionalSchema = opt();
120
+ const { parse } = optionalSchema;
121
+
122
+ expect(parse("hi")).toBe("hi");
123
+ expect(parse(undefined)).toBe(undefined);
124
+ });
125
+
126
+ test("detached parse can be called as a free function", () => {
127
+ const schema = z.string();
128
+ const parse = schema.parse;
129
+ const inputs = ["a", "b", "c"];
130
+
131
+ const results = inputs.map((v) => parse(v));
132
+
133
+ expect(results).toEqual(["a", "b", "c"]);
134
+ });
135
+
136
+ test("detached methods on z.number() work", () => {
137
+ const schema = z.number();
138
+
139
+ const min = schema.min;
140
+ const max = schema.max;
141
+ const positive = schema.positive;
142
+
143
+ expect(min(5).safeParse(3).success).toBe(false);
144
+ expect(max(5).safeParse(7).success).toBe(false);
145
+ expect(positive().safeParse(-1).success).toBe(false);
146
+ });
147
+
148
+ test("detached object methods work", () => {
149
+ const schema = z.object({ a: z.string(), b: z.number() });
150
+
151
+ const pick = schema.pick;
152
+ const omit = schema.omit;
153
+ const partial = schema.partial;
154
+ const extend = schema.extend;
155
+
156
+ expect(Object.keys(pick({ a: true })._zod.def.shape)).toEqual(["a"]);
157
+ expect(Object.keys(omit({ a: true })._zod.def.shape)).toEqual(["b"]);
158
+ expect(partial().safeParse({}).success).toBe(true);
159
+ const extended = extend({ c: z.boolean() });
160
+ expect(Object.keys(extended._zod.def.shape).sort()).toEqual(["a", "b", "c"]);
161
+ });
162
+
163
+ // Sweep across many builder methods at once. If any of them break with the
164
+ // `const m = schema.foo; m(...)` pattern, this test will report which.
165
+ test("broad sweep: detaching builder methods does not throw or produce a corrupt schema", () => {
166
+ const stringSchema = z.string();
167
+ const numberSchema = z.number();
168
+
169
+ const broken: Array<{ method: string; reason: string }> = [];
170
+
171
+ for (const [methodName, args] of Object.entries(probeArgs)) {
172
+ const target: any = methodName in stringSchema ? stringSchema : methodName in numberSchema ? numberSchema : null;
173
+ if (!target) continue;
174
+
175
+ const detached = target[methodName] as Function | undefined;
176
+ if (typeof detached !== "function") continue;
177
+
178
+ try {
179
+ const result = detached(...args);
180
+ // If the detached call returned a schema, sanity-check it parses
181
+ // its base type. (e.g. `optional()` should accept its inner type.)
182
+ if (result && typeof result === "object" && "_zod" in result && typeof (result as any).safeParse === "function") {
183
+ const probeValue = target === stringSchema ? "x" : 1;
184
+ const r = (result as any).safeParse(probeValue);
185
+ // success or a clean failure are both fine — we only fail on throw or
186
+ // on a schema with corrupt internal state (innerType undefined etc).
187
+ if (r === undefined || (typeof r === "object" && !("success" in r))) {
188
+ broken.push({ method: methodName, reason: "safeParse returned malformed result" });
189
+ }
190
+ }
191
+ } catch (err: any) {
192
+ broken.push({ method: methodName, reason: err?.message ?? String(err) });
193
+ }
194
+ }
195
+
196
+ expect(broken).toEqual([]);
197
+ });
@@ -158,10 +158,14 @@ test("invalid discriminator value", () => {
158
158
  "errors": [],
159
159
  "note": "No matching discriminator",
160
160
  "discriminator": "type",
161
+ "options": [
162
+ "a",
163
+ "b"
164
+ ],
161
165
  "path": [
162
166
  "type"
163
167
  ],
164
- "message": "Invalid input"
168
+ "message": "Invalid discriminator value. Expected 'a' | 'b'"
165
169
  }
166
170
  ]],
167
171
  "success": false,
@@ -659,3 +663,29 @@ test("def", () => {
659
663
  expect(schema.def.discriminator).toEqual("type");
660
664
  expect(schema.def.unionFallback).toEqual(true);
661
665
  });
666
+
667
+ test("encode with codec discriminator", () => {
668
+ const codec1 = z.codec(z.literal(1), z.literal("one"), {
669
+ decode: () => "one" as const,
670
+ encode: () => 1 as const,
671
+ });
672
+
673
+ const codec2 = z.codec(z.literal(2), z.literal("two"), {
674
+ decode: () => "two" as const,
675
+ encode: () => 2 as const,
676
+ });
677
+
678
+ const schema = z.discriminatedUnion("type", [
679
+ z.object({ type: codec1, value: z.string() }),
680
+ z.object({ type: codec2, value: z.number() }),
681
+ ]);
682
+
683
+ // decode (forward) should work
684
+ const decoded = schema.decode({ type: 1, value: "hello" });
685
+ expect(decoded).toEqual({ type: "one", value: "hello" });
686
+
687
+ // encode (backward) should also work — the discriminator values differ
688
+ // between forward (1, 2) and backward ("one", "two") directions
689
+ const encoded = z.encode(schema, { type: "one", value: "hello" });
690
+ expect(encoded).toEqual({ type: 1, value: "hello" });
691
+ });