agent-relay 6.0.2 → 6.0.4

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 (173) hide show
  1. package/README.md +10 -3
  2. package/dist/index.cjs +2024 -962
  3. package/dist/src/cli/commands/cloud.d.ts.map +1 -1
  4. package/dist/src/cli/commands/cloud.js +17 -144
  5. package/dist/src/cli/commands/cloud.js.map +1 -1
  6. package/dist/src/cli/commands/setup.d.ts +2 -39
  7. package/dist/src/cli/commands/setup.d.ts.map +1 -1
  8. package/dist/src/cli/commands/setup.js +4 -333
  9. package/dist/src/cli/commands/setup.js.map +1 -1
  10. package/dist/src/cli/lib/auth-ssh.d.ts +2 -33
  11. package/dist/src/cli/lib/auth-ssh.d.ts.map +1 -1
  12. package/dist/src/cli/lib/auth-ssh.js +3 -39
  13. package/dist/src/cli/lib/auth-ssh.js.map +1 -1
  14. package/dist/src/cli/lib/ssh-interactive.d.ts +4 -66
  15. package/dist/src/cli/lib/ssh-interactive.d.ts.map +1 -1
  16. package/dist/src/cli/lib/ssh-interactive.js +4 -436
  17. package/dist/src/cli/lib/ssh-interactive.js.map +1 -1
  18. package/node_modules/@relaycast/sdk/node_modules/zod/README.md +1 -1
  19. package/node_modules/@relaycast/sdk/node_modules/zod/locales/package.json +2 -1
  20. package/node_modules/@relaycast/sdk/node_modules/zod/mini/package.json +2 -1
  21. package/node_modules/@relaycast/sdk/node_modules/zod/package.json +1 -1
  22. package/node_modules/@relaycast/sdk/node_modules/zod/src/v3/tests/all-errors.test.ts +3 -3
  23. package/node_modules/@relaycast/sdk/node_modules/zod/src/v3/tests/object.test.ts +5 -5
  24. package/node_modules/@relaycast/sdk/node_modules/zod/src/v3/tests/partials.test.ts +3 -3
  25. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/errors.ts +2 -2
  26. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/external.ts +1 -0
  27. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/from-json-schema.ts +39 -23
  28. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/parse.ts +6 -6
  29. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/schemas.ts +389 -148
  30. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/catch.test.ts +4 -2
  31. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/codec.test.ts +142 -1
  32. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/continuability.test.ts +1 -1
  33. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/datetime.test.ts +1 -1
  34. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/default.test.ts +44 -0
  35. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/detached-methods.test.ts +197 -0
  36. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/discriminated-unions.test.ts +31 -1
  37. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/error-utils.test.ts +214 -2
  38. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/from-json-schema.test.ts +161 -0
  39. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/function.test.ts +6 -6
  40. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/global-config.test.ts +39 -0
  41. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/index.test.ts +2 -2
  42. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/jitless-allows-eval.test.ts +46 -0
  43. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/locales_ka.test.ts +29 -0
  44. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/locales_ro.test.ts +24 -0
  45. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/number.test.ts +55 -0
  46. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/object.test.ts +83 -6
  47. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/optional.test.ts +114 -4
  48. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/partial.test.ts +28 -2
  49. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/prefault.test.ts +1 -1
  50. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/record.test.ts +85 -0
  51. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/recursive-types.test.ts +49 -0
  52. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/refine.test.ts +63 -0
  53. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/string.test.ts +50 -1
  54. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/template-literal.test.ts +4 -4
  55. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/to-json-schema.test.ts +128 -14
  56. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/transform.test.ts +17 -0
  57. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/tuple.test.ts +315 -2
  58. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/classic/tests/union.test.ts +54 -0
  59. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/core/api.ts +25 -2
  60. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/core/checks.ts +1 -1
  61. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/core/core.ts +17 -2
  62. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/core/errors.ts +31 -24
  63. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/core/json-schema-processors.ts +15 -17
  64. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/core/parse.ts +7 -7
  65. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/core/regexes.ts +8 -1
  66. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/core/schemas.ts +218 -66
  67. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/core/tests/locales/el.test.ts +215 -0
  68. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/core/tests/locales/fr.test.ts +72 -0
  69. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/core/tests/locales/hr.test.ts +163 -0
  70. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/core/tests/locales/uz.test.ts +22 -0
  71. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/core/tests/record-constructor.test.ts +58 -0
  72. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/core/to-json-schema.ts +9 -1
  73. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/core/util.ts +52 -35
  74. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/core/versions.ts +2 -2
  75. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/locales/el.ts +121 -0
  76. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/locales/en.ts +4 -0
  77. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/locales/fr.ts +24 -8
  78. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/locales/hr.ts +131 -0
  79. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/locales/index.ts +3 -0
  80. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/locales/it.ts +1 -1
  81. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/locales/ka.ts +8 -8
  82. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/locales/ro.ts +129 -0
  83. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/locales/uz.ts +1 -0
  84. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/mini/external.ts +1 -0
  85. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/mini/schemas.ts +55 -24
  86. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/mini/tests/codec.test.ts +19 -0
  87. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/mini/tests/index.test.ts +27 -2
  88. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/mini/tests/object.test.ts +9 -9
  89. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/mini/tests/recursive-types.test.ts +51 -1
  90. package/node_modules/@relaycast/sdk/node_modules/zod/src/v4/mini/tests/string.test.ts +5 -0
  91. package/node_modules/@relaycast/sdk/node_modules/zod/v3/package.json +2 -1
  92. package/node_modules/@relaycast/sdk/node_modules/zod/v4/classic/errors.js +2 -2
  93. package/node_modules/@relaycast/sdk/node_modules/zod/v4/classic/external.d.cts +1 -0
  94. package/node_modules/@relaycast/sdk/node_modules/zod/v4/classic/external.d.ts +1 -0
  95. package/node_modules/@relaycast/sdk/node_modules/zod/v4/classic/from-json-schema.cjs +31 -16
  96. package/node_modules/@relaycast/sdk/node_modules/zod/v4/classic/from-json-schema.js +31 -16
  97. package/node_modules/@relaycast/sdk/node_modules/zod/v4/classic/package.json +2 -1
  98. package/node_modules/@relaycast/sdk/node_modules/zod/v4/classic/schemas.cjs +346 -117
  99. package/node_modules/@relaycast/sdk/node_modules/zod/v4/classic/schemas.d.cts +34 -12
  100. package/node_modules/@relaycast/sdk/node_modules/zod/v4/classic/schemas.d.ts +34 -12
  101. package/node_modules/@relaycast/sdk/node_modules/zod/v4/classic/schemas.js +345 -117
  102. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/api.cjs +7 -2
  103. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/api.d.cts +20 -1
  104. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/api.d.ts +20 -1
  105. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/api.js +7 -2
  106. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/checks.d.cts +1 -1
  107. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/checks.d.ts +1 -1
  108. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/core.cjs +3 -1
  109. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/core.js +4 -2
  110. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/errors.cjs +26 -23
  111. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/errors.d.cts +1 -0
  112. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/errors.d.ts +1 -0
  113. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/errors.js +26 -23
  114. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/json-schema-processors.cjs +14 -19
  115. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/json-schema-processors.js +14 -19
  116. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/package.json +2 -1
  117. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/parse.cjs +7 -7
  118. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/parse.js +7 -7
  119. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/regexes.cjs +9 -3
  120. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/regexes.d.cts +6 -0
  121. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/regexes.d.ts +6 -0
  122. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/regexes.js +7 -1
  123. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/schemas.cjs +196 -59
  124. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/schemas.d.cts +21 -1
  125. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/schemas.d.ts +21 -1
  126. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/schemas.js +196 -59
  127. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/to-json-schema.cjs +10 -1
  128. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/to-json-schema.js +10 -1
  129. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/util.cjs +54 -30
  130. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/util.d.cts +1 -0
  131. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/util.d.ts +1 -0
  132. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/util.js +55 -32
  133. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/versions.cjs +2 -2
  134. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/versions.d.cts +1 -1
  135. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/versions.d.ts +1 -1
  136. package/node_modules/@relaycast/sdk/node_modules/zod/v4/core/versions.js +2 -2
  137. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/el.cjs +136 -0
  138. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/el.d.cts +5 -0
  139. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/el.d.ts +4 -0
  140. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/el.js +109 -0
  141. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/en.cjs +4 -0
  142. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/en.js +4 -0
  143. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/fr.cjs +24 -7
  144. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/fr.js +24 -7
  145. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/hr.cjs +149 -0
  146. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/hr.d.cts +5 -0
  147. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/hr.d.ts +4 -0
  148. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/hr.js +122 -0
  149. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/index.cjs +8 -1
  150. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/index.d.cts +3 -0
  151. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/index.d.ts +3 -0
  152. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/index.js +3 -0
  153. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/it.cjs +1 -1
  154. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/it.js +1 -1
  155. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/ka.cjs +8 -8
  156. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/ka.js +8 -8
  157. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/package.json +2 -1
  158. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/ro.cjs +146 -0
  159. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/ro.d.cts +5 -0
  160. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/ro.d.ts +4 -0
  161. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/ro.js +119 -0
  162. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/uz.cjs +1 -0
  163. package/node_modules/@relaycast/sdk/node_modules/zod/v4/locales/uz.js +1 -0
  164. package/node_modules/@relaycast/sdk/node_modules/zod/v4/mini/external.d.cts +1 -0
  165. package/node_modules/@relaycast/sdk/node_modules/zod/v4/mini/external.d.ts +1 -0
  166. package/node_modules/@relaycast/sdk/node_modules/zod/v4/mini/package.json +2 -1
  167. package/node_modules/@relaycast/sdk/node_modules/zod/v4/mini/schemas.cjs +41 -4
  168. package/node_modules/@relaycast/sdk/node_modules/zod/v4/mini/schemas.d.cts +27 -9
  169. package/node_modules/@relaycast/sdk/node_modules/zod/v4/mini/schemas.d.ts +27 -9
  170. package/node_modules/@relaycast/sdk/node_modules/zod/v4/mini/schemas.js +40 -4
  171. package/node_modules/@relaycast/sdk/node_modules/zod/v4/package.json +2 -1
  172. package/node_modules/@relaycast/sdk/node_modules/zod/v4-mini/package.json +2 -1
  173. package/package.json +10 -10
@@ -80,7 +80,10 @@ test(".flatten()", () => {
80
80
 
81
81
  test("custom .flatten()", () => {
82
82
  type ErrorType = { message: string; code: number };
83
- const flattened = parsed.error!.flatten((iss) => ({ message: iss.message, code: 1234 }));
83
+ const flattened = parsed.error!.flatten((iss) => ({
84
+ message: iss.message,
85
+ code: 1234,
86
+ }));
84
87
  expectTypeOf(flattened).toMatchTypeOf<{
85
88
  formErrors: ErrorType[];
86
89
  fieldErrors: {
@@ -160,7 +163,10 @@ test(".format()", () => {
160
163
 
161
164
  test("custom .format()", () => {
162
165
  type ErrorType = { message: string; code: number };
163
- const formatted = parsed.error!.format((iss) => ({ message: iss.message, code: 1234 }));
166
+ const formatted = parsed.error!.format((iss) => ({
167
+ message: iss.message,
168
+ code: 1234,
169
+ }));
164
170
  expectTypeOf(formatted).toMatchTypeOf<{
165
171
  _errors: ErrorType[];
166
172
  f2?: { _errors: ErrorType[] };
@@ -593,3 +599,209 @@ test("update message after adding issues", () => {
593
599
  ]"
594
600
  `);
595
601
  });
602
+
603
+ test("z.formatError nested union preserves parent path", () => {
604
+ const syntheticError = new z.ZodError([
605
+ {
606
+ code: "invalid_union",
607
+ path: ["parent"],
608
+ message: "Invalid input",
609
+ errors: [
610
+ [
611
+ {
612
+ code: "invalid_type",
613
+ expected: "string",
614
+ path: [],
615
+ message: "Expected string",
616
+ input: {},
617
+ },
618
+ ],
619
+ [
620
+ {
621
+ code: "invalid_union",
622
+ path: ["child"],
623
+ message: "Invalid input",
624
+ errors: [
625
+ [
626
+ {
627
+ code: "invalid_type",
628
+ expected: "string",
629
+ path: [],
630
+ message: "Expected string",
631
+ input: true,
632
+ },
633
+ ],
634
+ [
635
+ {
636
+ code: "invalid_type",
637
+ expected: "number",
638
+ path: [],
639
+ message: "Expected number",
640
+ input: true,
641
+ },
642
+ ],
643
+ ],
644
+ },
645
+ ],
646
+ ],
647
+ },
648
+ ] as any);
649
+
650
+ const formatted: any = z.formatError(syntheticError);
651
+
652
+ // "child" must be nested under "parent", not at root
653
+ expect(formatted).not.toHaveProperty("child");
654
+ expect(formatted).toHaveProperty("parent");
655
+ expect(formatted.parent).toHaveProperty("child");
656
+ expect(formatted.parent.child._errors).toContain("Expected string");
657
+ expect(formatted.parent.child._errors).toContain("Expected number");
658
+ expect(formatted.parent._errors).toContain("Expected string");
659
+ });
660
+ test("z.treeifyError nested union preserves parent path", () => {
661
+ // When a nested invalid_union appears inside another invalid_union,
662
+ // the inner errors must stay nested under their parent path, not flatten to root.
663
+ const syntheticError = new z.ZodError([
664
+ {
665
+ code: "invalid_union",
666
+ path: ["parent"],
667
+ message: "Invalid input",
668
+ errors: [
669
+ [
670
+ {
671
+ code: "invalid_type",
672
+ expected: "string",
673
+ path: [],
674
+ message: "Expected string",
675
+ input: {},
676
+ },
677
+ ],
678
+ [
679
+ {
680
+ code: "invalid_union",
681
+ path: ["child"],
682
+ message: "Invalid input",
683
+ errors: [
684
+ [
685
+ {
686
+ code: "invalid_type",
687
+ expected: "string",
688
+ path: [],
689
+ message: "Expected string",
690
+ input: true,
691
+ },
692
+ ],
693
+ [
694
+ {
695
+ code: "invalid_type",
696
+ expected: "number",
697
+ path: [],
698
+ message: "Expected number",
699
+ input: true,
700
+ },
701
+ ],
702
+ ],
703
+ },
704
+ ],
705
+ ],
706
+ },
707
+ ] as any);
708
+
709
+ const tree: any = z.treeifyError(syntheticError);
710
+
711
+ // "child" must be nested under "parent", not at root
712
+ expect(tree.properties).not.toHaveProperty("child");
713
+ expect(tree.properties).toHaveProperty("parent");
714
+ expect(tree.properties.parent.properties).toHaveProperty("child");
715
+ expect(tree.properties.parent.properties.child.errors).toContain("Expected string");
716
+ expect(tree.properties.parent.properties.child.errors).toContain("Expected number");
717
+ expect(tree.properties.parent.errors).toContain("Expected string");
718
+ });
719
+
720
+ test("z.treeifyError deeply nested union (4 levels) preserves full path", () => {
721
+ // a > b > c > d — each level wrapped in an invalid_union
722
+ const syntheticError = new z.ZodError([
723
+ {
724
+ code: "invalid_union",
725
+ path: ["a"],
726
+ message: "Invalid input",
727
+ errors: [
728
+ [
729
+ {
730
+ code: "invalid_union",
731
+ path: ["b"],
732
+ message: "Invalid input",
733
+ errors: [
734
+ [
735
+ {
736
+ code: "invalid_union",
737
+ path: ["c"],
738
+ message: "Invalid input",
739
+ errors: [
740
+ [
741
+ {
742
+ code: "invalid_type",
743
+ expected: "string",
744
+ path: ["d"],
745
+ message: "Expected string",
746
+ input: 123,
747
+ },
748
+ ],
749
+ ],
750
+ },
751
+ ],
752
+ ],
753
+ },
754
+ ],
755
+ ],
756
+ },
757
+ ] as any);
758
+
759
+ const tree: any = z.treeifyError(syntheticError);
760
+
761
+ // The full path must be preserved: a.b.c.d
762
+ expect(tree.properties).toHaveProperty("a");
763
+ expect(tree.properties).not.toHaveProperty("b");
764
+ expect(tree.properties).not.toHaveProperty("c");
765
+
766
+ const lvlA = tree.properties.a;
767
+ expect(lvlA.properties).toHaveProperty("b");
768
+
769
+ const lvlB = lvlA.properties.b;
770
+ expect(lvlB.properties).toHaveProperty("c");
771
+
772
+ const lvlC = lvlB.properties.c;
773
+ expect(lvlC.properties).toHaveProperty("d");
774
+ expect(lvlC.properties.d.errors).toContain("Expected string");
775
+ });
776
+
777
+ test("z.treeifyError nested union with real schema", () => {
778
+ const innerUnion = z.union([
779
+ z.object({ type: z.literal("a"), value: z.string() }),
780
+ z.object({ type: z.literal("b"), value: z.number() }),
781
+ ]);
782
+
783
+ const schema = z.string().or(
784
+ z.object({
785
+ settings: z.object({ name: z.string() }).and(innerUnion),
786
+ })
787
+ );
788
+
789
+ const result = schema.safeParse({
790
+ settings: { name: 123, type: "x", value: true },
791
+ });
792
+
793
+ expect(result.success).toBe(false);
794
+ if (!result.success) {
795
+ const tree: any = z.treeifyError(result.error);
796
+
797
+ // All settings-related errors should be under "settings", not at root
798
+ expect(tree.properties).toHaveProperty("settings");
799
+ const settingsProperties = tree.properties.settings.properties ?? {};
800
+ for (const key of Object.keys(settingsProperties)) {
801
+ // Every sub-property under settings should NOT also appear at root
802
+ if (key !== "settings") {
803
+ expect(tree.properties).not.toHaveProperty(key);
804
+ }
805
+ }
806
+ }
807
+ });
@@ -732,3 +732,164 @@ test("contentEncoding and contentMediaType are stored as metadata", () => {
732
732
  expect(meta?.contentEncoding).toBe("base64");
733
733
  expect(meta?.contentMediaType).toBe("image/png");
734
734
  });
735
+
736
+ test("description on enum schema is applied", () => {
737
+ const schema = fromJSONSchema({
738
+ enum: ["red", "green", "blue"],
739
+ description: "A color value",
740
+ });
741
+ expect(schema.description).toBe("A color value");
742
+ expect(schema.parse("red")).toBe("red");
743
+ });
744
+
745
+ test("description on const schema is applied", () => {
746
+ const schema = fromJSONSchema({
747
+ const: "hello",
748
+ description: "A greeting",
749
+ });
750
+ expect(schema.description).toBe("A greeting");
751
+ expect(schema.parse("hello")).toBe("hello");
752
+ });
753
+
754
+ test("description on not: {} (never) schema is applied", () => {
755
+ const schema = fromJSONSchema({
756
+ not: {},
757
+ description: "A never schema",
758
+ });
759
+ expect(schema.description).toBe("A never schema");
760
+ expect(() => schema.parse("anything")).toThrow();
761
+ });
762
+
763
+ test("default on enum schema is applied", () => {
764
+ const schema = fromJSONSchema({
765
+ enum: ["red", "green", "blue"],
766
+ default: "red",
767
+ });
768
+ expect(schema.parse(undefined)).toBe("red");
769
+ });
770
+
771
+ test("default on const schema is applied", () => {
772
+ const schema = fromJSONSchema({
773
+ const: "hello",
774
+ default: "hello",
775
+ });
776
+ expect(schema.parse(undefined)).toBe("hello");
777
+ });
778
+
779
+ test("description and default on enum schema are both applied", () => {
780
+ const schema = fromJSONSchema({
781
+ enum: ["red", "green", "blue"],
782
+ description: "A color value",
783
+ default: "red",
784
+ });
785
+ expect(schema.description).toBe("A color value");
786
+ expect(schema.parse(undefined)).toBe("red");
787
+ expect(schema.parse("green")).toBe("green");
788
+ });
789
+
790
+ test("description on type-array schema is applied", () => {
791
+ const schema = fromJSONSchema({
792
+ type: ["string", "number"],
793
+ description: "A string or number",
794
+ } as any);
795
+ expect(schema.description).toBe("A string or number");
796
+ expect(schema.parse("hello")).toBe("hello");
797
+ expect(schema.parse(42)).toBe(42);
798
+ });
799
+
800
+ test("default on type-array schema is applied", () => {
801
+ const schema = fromJSONSchema({
802
+ type: ["string", "number"],
803
+ default: "fallback",
804
+ } as any);
805
+ expect(schema.parse(undefined)).toBe("fallback");
806
+ expect(schema.parse("hello")).toBe("hello");
807
+ expect(schema.parse(42)).toBe(42);
808
+ });
809
+
810
+ test("description on schema with anyOf is applied to the outer schema", () => {
811
+ const schema = fromJSONSchema({
812
+ description: "Either a string or a number",
813
+ anyOf: [{ type: "string" }, { type: "number" }],
814
+ });
815
+ expect(schema.description).toBe("Either a string or a number");
816
+ expect(schema.parse("hello")).toBe("hello");
817
+ expect(schema.parse(42)).toBe(42);
818
+ });
819
+
820
+ test("default on schema with anyOf is applied to the outer schema", () => {
821
+ const schema = fromJSONSchema({
822
+ default: "fallback",
823
+ anyOf: [{ type: "string" }, { type: "number" }],
824
+ });
825
+ expect(schema.parse(undefined)).toBe("fallback");
826
+ expect(schema.parse(42)).toBe(42);
827
+ });
828
+
829
+ test("description and unrecognized metadata coexist on the same schema", () => {
830
+ const customRegistry = z.registry<{ "x-custom"?: string; description?: string }>();
831
+ const schema = fromJSONSchema(
832
+ {
833
+ type: "string",
834
+ description: "A custom string",
835
+ "x-custom": "value",
836
+ },
837
+ { registry: customRegistry }
838
+ );
839
+ expect(schema.description).toBe("A custom string");
840
+ expect(customRegistry.get(schema)?.["x-custom"]).toBe("value");
841
+ });
842
+
843
+ test("circular input throws a clear error", () => {
844
+ const person: any = {
845
+ type: "object",
846
+ properties: { name: { type: "string" } },
847
+ required: ["name"],
848
+ };
849
+ person.properties.bestFriend = person;
850
+ expect(() => fromJSONSchema(person)).toThrow(/not valid JSON/);
851
+ });
852
+
853
+ test("getter-based input that synthesizes a cycle throws", () => {
854
+ const root: any = { type: "object", properties: { name: { type: "string" } } };
855
+ Object.defineProperty(root.properties, "self", {
856
+ enumerable: true,
857
+ get() {
858
+ return root;
859
+ },
860
+ });
861
+ expect(() => fromJSONSchema(root)).toThrow(/not valid JSON/);
862
+ });
863
+
864
+ test("BigInt in input throws", () => {
865
+ const input: any = { type: "integer", minimum: 1n };
866
+ expect(() => fromJSONSchema(input)).toThrow(/not valid JSON/);
867
+ });
868
+
869
+ test("class-instance input is normalized to a plain object", () => {
870
+ class StringSchema {
871
+ type = "string" as const;
872
+ minLength = 2;
873
+ }
874
+ const schema = fromJSONSchema(new StringSchema() as any);
875
+ expect(schema.parse("hi")).toBe("hi");
876
+ expect(() => schema.parse("h")).toThrow();
877
+ });
878
+
879
+ test("getter-based properties are materialized", () => {
880
+ const input: any = { type: "object", properties: {}, required: [] };
881
+ Object.defineProperty(input.properties, "name", {
882
+ enumerable: true,
883
+ get() {
884
+ return { type: "string" };
885
+ },
886
+ });
887
+ const schema = fromJSONSchema(input);
888
+ expect(schema.parse({ name: "Alice" })).toEqual({ name: "Alice" });
889
+ });
890
+
891
+ test("Date default is coerced to its JSON string form", () => {
892
+ const date = new Date("2026-01-02T03:04:05.000Z");
893
+ const schema = fromJSONSchema({ type: "string", default: date as any });
894
+ expect(schema.parse(undefined)).toBe(date.toISOString());
895
+ });
@@ -186,12 +186,12 @@ test("input validation error", () => {
186
186
  expect(e.issues).toMatchInlineSnapshot(`
187
187
  [
188
188
  {
189
- "code": "invalid_type",
190
- "expected": "string",
191
- "message": "Invalid input: expected string, received undefined",
192
- "path": [
193
- 0,
194
- ],
189
+ "code": "too_small",
190
+ "inclusive": true,
191
+ "message": "Too small: expected array to have >=1 items",
192
+ "minimum": 1,
193
+ "origin": "array",
194
+ "path": [],
195
195
  },
196
196
  ]
197
197
  `);
@@ -0,0 +1,39 @@
1
+ import { afterEach, expect, test } from "vitest";
2
+ import * as z from "zod/v4";
3
+ import * as core from "zod/v4/core";
4
+
5
+ // `globalConfig` is attached to `globalThis.__zod_globalConfig` so that a
6
+ // single config object is shared across CJS/ESM builds and across multiple
7
+ // bundled copies of Zod in a monorepo. This mirrors the existing
8
+ // `globalRegistry` -> `globalThis.__zod_globalRegistry` treatment.
9
+ //
10
+ // See #5789 for the footgun this fixes: users with both CJS and ESM
11
+ // instances of Zod loaded had to call `z.config({ jitless: true })`
12
+ // twice — once per instance — because each module-scope `globalConfig`
13
+ // was a different object. With this change, one call updates state seen
14
+ // by every loaded copy.
15
+
16
+ afterEach(() => {
17
+ // Don't leak config mutations into other test files.
18
+ delete core.globalConfig.jitless;
19
+ });
20
+
21
+ test("globalConfig is singleton and attached to globalThis", () => {
22
+ expect(core.globalConfig).toBe((globalThis as any).__zod_globalConfig);
23
+ });
24
+
25
+ test("z.config writes are observed via globalThis.__zod_globalConfig", () => {
26
+ z.config({ jitless: true });
27
+ expect((globalThis as any).__zod_globalConfig.jitless).toBe(true);
28
+ });
29
+
30
+ test("pre-set globalThis.__zod_globalConfig is preserved on import", () => {
31
+ // Object identity is preserved across reloads of the module: anyone who
32
+ // pre-populates `globalThis.__zod_globalConfig` before Zod loads (e.g.
33
+ // an inline script before the bundle) keeps that exact object as the
34
+ // source of truth. Mutating it directly is equivalent to z.config().
35
+ const direct = (globalThis as any).__zod_globalConfig;
36
+ direct.jitless = true;
37
+ expect(core.globalConfig.jitless).toBe(true);
38
+ expect(z.config()).toBe(core.globalConfig);
39
+ });
@@ -247,7 +247,7 @@ test("z.tuple", () => {
247
247
  const b = z.tuple([z.string(), z.number(), z.optional(z.string())], z.boolean());
248
248
  type b = z.output<typeof b>;
249
249
 
250
- expectTypeOf<b>().toEqualTypeOf<[string, number, string?, ...boolean[]]>();
250
+ expectTypeOf<b>().toEqualTypeOf<[string, number, (string | undefined)?, ...boolean[]]>();
251
251
  const datas = [
252
252
  ["hello", 123],
253
253
  ["hello", 123, "world"],
@@ -265,7 +265,7 @@ test("z.tuple", () => {
265
265
  const cArgs = [z.string(), z.number(), z.optional(z.string())] as const;
266
266
  const c = z.tuple(cArgs, z.boolean());
267
267
  type c = z.output<typeof c>;
268
- expectTypeOf<c>().toEqualTypeOf<[string, number, string?, ...boolean[]]>();
268
+ expectTypeOf<c>().toEqualTypeOf<[string, number, (string | undefined)?, ...boolean[]]>();
269
269
  // type c = z.output<typeof c>;
270
270
  });
271
271
 
@@ -0,0 +1,46 @@
1
+ import { expect, test } from "vitest";
2
+ import * as z from "zod/v4";
3
+ import * as core from "zod/v4/core";
4
+
5
+ const { allowsEval } = core.util;
6
+
7
+ // Regression test for the CSP feature-probe issue (#4461, #5414):
8
+ // `allowsEval` used to always invoke `new Function("")` even when the
9
+ // user had opted into `z.config({ jitless: true })`, producing a
10
+ // `securitypolicyviolation` report on strict-CSP pages (no 'unsafe-eval')
11
+ // that Chrome DevTools surfaces as an Issue.
12
+ //
13
+ // The fix: when `globalConfig.jitless` is true, `allowsEval.value`
14
+ // returns `false` without triggering the probe. This test lives in its
15
+ // own file because vitest isolates ESM graphs per file, so the cached
16
+ // `allowsEval.value` is fresh and is never accessed before the config
17
+ // mutation below.
18
+
19
+ test("globalConfig.jitless=true short-circuits the allowsEval probe", () => {
20
+ // Set BEFORE first access to allowsEval.value — the getter is memoised
21
+ // via `cached()`, so the contract is "configure at app entry".
22
+ z.config({ jitless: true });
23
+
24
+ // Sanity: config is wired
25
+ expect(core.globalConfig.jitless).toBe(true);
26
+
27
+ // Spy: if the probe were still attempted, `new Function("")` would be
28
+ // called. Swap the global `Function` constructor with a throwing stub
29
+ // and verify the stub is NEVER invoked.
30
+ const origFunction = globalThis.Function;
31
+ let probeAttempted = false;
32
+ // @ts-expect-error assigning a stub to the Function global for the test
33
+ globalThis.Function = function StubFunction(..._args: unknown[]): never {
34
+ probeAttempted = true;
35
+ throw new Error("allowsEval probe should have been skipped under jitless=true");
36
+ };
37
+
38
+ try {
39
+ expect(allowsEval.value).toBe(false);
40
+ expect(probeAttempted).toBe(false);
41
+ } finally {
42
+ globalThis.Function = origFunction;
43
+ // Restore config so other test files in the same worker see default
44
+ delete core.globalConfig.jitless;
45
+ }
46
+ });
@@ -0,0 +1,29 @@
1
+ import { expect, test } from "vitest";
2
+ import * as z from "zod/v4";
3
+
4
+ test("Georgian locale uses 'ველი' instead of 'სტრინგი'", () => {
5
+ // Save original error map to restore later if needed, though tests are usually isolated or we can reset
6
+ // const originalErrorMap = z.getErrorMap(); // z.getErrorMap might not exist, but let's assume isolation or just set it
7
+
8
+ z.setErrorMap(z.locales.ka().localeError);
9
+
10
+ // Test 1: Invalid type (Expected string, received number)
11
+ const stringSchema = z.string();
12
+ const numberResult = stringSchema.safeParse(123);
13
+ expect(numberResult.success).toBe(false);
14
+ if (!numberResult.success) {
15
+ // Expected: "არასწორი შეყვანა: მოსალოდნელი ველი, მიღებული რიცხვი"
16
+ expect(numberResult.error.issues[0].message).toBe("არასწორი შეყვანა: მოსალოდნელი ველი, მიღებული რიცხვი");
17
+ }
18
+
19
+ // Test 2: Invalid base64
20
+ const base64Schema = z.string().base64();
21
+ const base64Result = base64Schema.safeParse("not base64!");
22
+ expect(base64Result.success).toBe(false);
23
+ if (!base64Result.success) {
24
+ // Expected: "არასწორი base64-კოდირებული ველი"
25
+ // "არასწორი ${FormatDictionary[_issue.format] ?? issue.format}"
26
+ // FormatDictionary['base64'] is "base64-კოდირებული ველი"
27
+ expect(base64Result.error.issues[0].message).toBe("არასწორი base64-კოდირებული ველი");
28
+ }
29
+ });
@@ -0,0 +1,24 @@
1
+ import { expect, test } from "vitest";
2
+ import * as z from "zod/v4";
3
+
4
+ test("Romanian locale uses 'șir' instead of 'string'", () => {
5
+ z.setErrorMap(z.locales.ro().localeError);
6
+
7
+ // Test 1: Invalid type (Expected string, received number)
8
+ const stringSchema = z.string();
9
+ const numberResult = stringSchema.safeParse(123);
10
+ expect(numberResult.success).toBe(false);
11
+ if (!numberResult.success) {
12
+ // Expected: "Intrare invalidă: așteptat șir, primit număr"
13
+ expect(numberResult.error.issues[0].message).toBe("Intrare invalidă: așteptat șir, primit număr");
14
+ }
15
+
16
+ // Test 2: Invalid base64
17
+ const base64Schema = z.string().base64();
18
+ const base64Result = base64Schema.safeParse("not base64!");
19
+ expect(base64Result.success).toBe(false);
20
+ if (!base64Result.success) {
21
+ // Expected: "Format invalid: șir codat base64"
22
+ expect(base64Result.error.issues[0].message).toBe("Format invalid: șir codat base64");
23
+ }
24
+ });
@@ -153,6 +153,36 @@ test(".multipleOf() with negative divisor", () => {
153
153
  expect(() => schema.parse(7.5)).toThrow();
154
154
  });
155
155
 
156
+ test(".multipleOf() with scientific notation (multi-digit exponents)", () => {
157
+ // Regression test for https://github.com/colinhacks/zod/pull/5687
158
+ // The regex was using \d? which only matches single-digit exponents
159
+ const schema = z.number().multipleOf(1e-10);
160
+
161
+ // These should all pass - they are valid multiples of 1e-10
162
+ expect(schema.parse(1e-10)).toEqual(1e-10);
163
+ expect(schema.parse(5e-10)).toEqual(5e-10);
164
+ expect(schema.parse(1e-9)).toEqual(1e-9); // 10 * 1e-10
165
+
166
+ // Test with 1e-15 (exponent = 15, two digits)
167
+ const schema15 = z.number().multipleOf(1e-15);
168
+ expect(schema15.parse(1e-15)).toEqual(1e-15);
169
+ expect(schema15.parse(3e-15)).toEqual(3e-15);
170
+ });
171
+
172
+ test(".multipleOf() with small floats / scientific notation (#5792)", () => {
173
+ const schema = z.number().multipleOf(1e-7);
174
+
175
+ // Valid multiples (integer * 1e-7)
176
+ expect(schema.safeParse(0).success).toBe(true);
177
+ expect(schema.safeParse(1e-7).success).toBe(true);
178
+ expect(schema.safeParse(2e-7).success).toBe(true);
179
+ expect(schema.safeParse(3e-7).success).toBe(true);
180
+
181
+ // Invalid — 2.5 and 1.5 are not integers
182
+ expect(schema.safeParse(2.5e-7).success).toBe(false);
183
+ expect(schema.safeParse(1.5e-7).success).toBe(false);
184
+ });
185
+
156
186
  test(".step() validation", () => {
157
187
  const schemaPointOne = z.number().step(0.1);
158
188
  const schemaPointZeroZeroZeroOne = z.number().step(0.0001);
@@ -264,6 +294,31 @@ test("string format methods", () => {
264
294
  expect(() => a.parse(1)).toThrow();
265
295
  });
266
296
 
297
+ test("negative zero edge case", () => {
298
+ const schema = z.number();
299
+ const negativeZero = -0;
300
+ const positiveZero = 0;
301
+
302
+ // Both -0 and 0 should be valid (parse succeeds)
303
+ expect(schema.safeParse(negativeZero).success).toBe(true);
304
+ expect(schema.safeParse(positiveZero).success).toBe(true);
305
+ // Note: -0 is normalized to 0 after parsing
306
+ expect(schema.parse(negativeZero) === 0).toBe(true);
307
+ expect(schema.parse(positiveZero)).toEqual(0);
308
+
309
+ // With positive() constraint, both should be invalid (0 is not positive)
310
+ const positiveSchema = z.number().positive();
311
+ expect(() => positiveSchema.parse(negativeZero)).toThrow();
312
+ expect(() => positiveSchema.parse(positiveZero)).toThrow();
313
+
314
+ // With nonnegative(), both should be valid (0 is non-negative)
315
+ const nonnegativeSchema = z.number().nonnegative();
316
+ expect(nonnegativeSchema.safeParse(negativeZero).success).toBe(true);
317
+ expect(nonnegativeSchema.safeParse(positiveZero).success).toBe(true);
318
+ expect(nonnegativeSchema.parse(negativeZero) === 0).toBe(true);
319
+ expect(nonnegativeSchema.parse(positiveZero)).toEqual(0);
320
+ });
321
+
267
322
  test("error customization", () => {
268
323
  z.number().gte(5, { error: (iss) => "Min: " + iss.minimum.valueOf() });
269
324
  z.number().lte(5, { error: (iss) => "Max: " + iss.maximum.valueOf() });