@loomhelm/multi-task-flow 0.2.6 → 0.2.8

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 (1090) hide show
  1. package/README.md +12 -8
  2. package/package.json +2 -12
  3. package/src/build-info.ts +4 -2
  4. package/src/cli/release.ts +4 -40
  5. package/src/release-tarball.ts +1 -1
  6. package/src/release.ts +7 -1
  7. package/src/runtime-identity.ts +4 -2
  8. package/src/toolkit.ts +71 -15
  9. package/toolkit/artifact-manifest.json +609 -4208
  10. package/toolkit/package.json +1 -1
  11. package/toolkit/skills/docs/vendor/dot-codex/design/multi-task-flow/data-and-scripts.md +77 -23
  12. package/toolkit/skills/docs-migrate/scripts/_runtime/compatibility_cli.ts +12 -0
  13. package/toolkit/skills/docs-migrate/scripts/_runtime/compatibility_docs.ts +115 -0
  14. package/toolkit/skills/docs-migrate/scripts/_runtime/compatibility_shared.ts +230 -0
  15. package/toolkit/skills/docs-migrate/scripts/_runtime/modules/checks/replay.ts +336 -0
  16. package/toolkit/skills/docs-migrate/scripts/_runtime/modules/docs/git.ts +54 -0
  17. package/toolkit/skills/docs-migrate/scripts/_runtime/modules/docs/hardware_ingest.ts +377 -0
  18. package/toolkit/skills/docs-migrate/scripts/_runtime/modules/docs/hardware_locks.ts +181 -0
  19. package/toolkit/skills/docs-migrate/scripts/_runtime/modules/docs/legacy_spec_id.ts +131 -0
  20. package/toolkit/skills/docs-migrate/scripts/_runtime/modules/docs/migration_common.ts +291 -0
  21. package/toolkit/skills/docs-migrate/scripts/_runtime/modules/docs/next_plan.ts +199 -0
  22. package/toolkit/skills/docs-migrate/scripts/_runtime/modules/docs/next_plan_support.ts +245 -0
  23. package/toolkit/skills/docs-migrate/scripts/_runtime/modules/docs/spec_contract.ts +299 -0
  24. package/toolkit/skills/docs-migrate/scripts/_runtime/modules/docs/spec_drift.ts +387 -0
  25. package/toolkit/skills/docs-migrate/scripts/_runtime/modules/docs/spec_drift_helpers.ts +381 -0
  26. package/toolkit/skills/docs-migrate/scripts/_runtime/modules/docs/spec_drift_legacy.ts +376 -0
  27. package/toolkit/skills/docs-migrate/scripts/_runtime/modules/docs/spec_drift_paths.ts +3 -0
  28. package/toolkit/skills/docs-migrate/scripts/_runtime/modules/docs/spec_drift_types.ts +27 -0
  29. package/toolkit/skills/docs-migrate/scripts/_runtime/modules/docs/spec_drift_validation.ts +251 -0
  30. package/toolkit/skills/docs-migrate/scripts/_runtime/modules/docs/spec_migration.ts +191 -0
  31. package/toolkit/skills/docs-migrate/scripts/gen_legacy_spec_id.ts +1 -1
  32. package/toolkit/skills/docs-migrate/scripts/specs_migrate_guard.ts +1 -1
  33. package/toolkit/skills/find-next-plan/scripts/_runtime/compatibility_cli.ts +12 -0
  34. package/toolkit/skills/find-next-plan/scripts/_runtime/compatibility_docs.ts +115 -0
  35. package/toolkit/skills/find-next-plan/scripts/_runtime/compatibility_shared.ts +230 -0
  36. package/toolkit/skills/find-next-plan/scripts/_runtime/modules/checks/replay.ts +336 -0
  37. package/toolkit/skills/find-next-plan/scripts/_runtime/modules/docs/git.ts +54 -0
  38. package/toolkit/skills/find-next-plan/scripts/_runtime/modules/docs/hardware_ingest.ts +377 -0
  39. package/toolkit/skills/find-next-plan/scripts/_runtime/modules/docs/hardware_locks.ts +181 -0
  40. package/toolkit/skills/find-next-plan/scripts/_runtime/modules/docs/legacy_spec_id.ts +131 -0
  41. package/toolkit/skills/find-next-plan/scripts/_runtime/modules/docs/migration_common.ts +291 -0
  42. package/toolkit/skills/find-next-plan/scripts/_runtime/modules/docs/next_plan.ts +199 -0
  43. package/toolkit/skills/find-next-plan/scripts/_runtime/modules/docs/next_plan_support.ts +245 -0
  44. package/toolkit/skills/find-next-plan/scripts/_runtime/modules/docs/spec_contract.ts +299 -0
  45. package/toolkit/skills/find-next-plan/scripts/_runtime/modules/docs/spec_drift.ts +387 -0
  46. package/toolkit/skills/find-next-plan/scripts/_runtime/modules/docs/spec_drift_helpers.ts +381 -0
  47. package/toolkit/skills/find-next-plan/scripts/_runtime/modules/docs/spec_drift_legacy.ts +376 -0
  48. package/toolkit/skills/find-next-plan/scripts/_runtime/modules/docs/spec_drift_paths.ts +3 -0
  49. package/toolkit/skills/find-next-plan/scripts/_runtime/modules/docs/spec_drift_types.ts +27 -0
  50. package/toolkit/skills/find-next-plan/scripts/_runtime/modules/docs/spec_drift_validation.ts +251 -0
  51. package/toolkit/skills/find-next-plan/scripts/_runtime/modules/docs/spec_migration.ts +191 -0
  52. package/toolkit/skills/find-next-plan/scripts/find_next_plan.ts +1 -1
  53. package/toolkit/skills/hardware-doc-ingest/scripts/_runtime/compatibility_cli.ts +12 -0
  54. package/toolkit/skills/hardware-doc-ingest/scripts/_runtime/compatibility_docs.ts +115 -0
  55. package/toolkit/skills/hardware-doc-ingest/scripts/_runtime/compatibility_shared.ts +230 -0
  56. package/toolkit/skills/hardware-doc-ingest/scripts/_runtime/modules/checks/replay.ts +336 -0
  57. package/toolkit/skills/hardware-doc-ingest/scripts/_runtime/modules/docs/git.ts +54 -0
  58. package/toolkit/skills/hardware-doc-ingest/scripts/_runtime/modules/docs/hardware_ingest.ts +377 -0
  59. package/toolkit/skills/hardware-doc-ingest/scripts/_runtime/modules/docs/hardware_locks.ts +181 -0
  60. package/toolkit/skills/hardware-doc-ingest/scripts/_runtime/modules/docs/legacy_spec_id.ts +131 -0
  61. package/toolkit/skills/hardware-doc-ingest/scripts/_runtime/modules/docs/migration_common.ts +291 -0
  62. package/toolkit/skills/hardware-doc-ingest/scripts/_runtime/modules/docs/next_plan.ts +199 -0
  63. package/toolkit/skills/hardware-doc-ingest/scripts/_runtime/modules/docs/next_plan_support.ts +245 -0
  64. package/toolkit/skills/hardware-doc-ingest/scripts/_runtime/modules/docs/spec_contract.ts +299 -0
  65. package/toolkit/skills/hardware-doc-ingest/scripts/_runtime/modules/docs/spec_drift.ts +387 -0
  66. package/toolkit/skills/hardware-doc-ingest/scripts/_runtime/modules/docs/spec_drift_helpers.ts +381 -0
  67. package/toolkit/skills/hardware-doc-ingest/scripts/_runtime/modules/docs/spec_drift_legacy.ts +376 -0
  68. package/toolkit/skills/hardware-doc-ingest/scripts/_runtime/modules/docs/spec_drift_paths.ts +3 -0
  69. package/toolkit/skills/hardware-doc-ingest/scripts/_runtime/modules/docs/spec_drift_types.ts +27 -0
  70. package/toolkit/skills/hardware-doc-ingest/scripts/_runtime/modules/docs/spec_drift_validation.ts +251 -0
  71. package/toolkit/skills/hardware-doc-ingest/scripts/_runtime/modules/docs/spec_migration.ts +191 -0
  72. package/toolkit/skills/hardware-doc-ingest/scripts/ingest_mineru_extract.ts +1 -1
  73. package/toolkit/skills/hardware-doc-ingest/scripts/verify_doc_locks.ts +1 -1
  74. package/toolkit/skills/multi-task-flow/dist/app.css +1 -1
  75. package/toolkit/skills/multi-task-flow/dist/app.js +45 -45
  76. package/toolkit/skills/multi-task-flow/lib/atomic-orchestration.ts +25 -3
  77. package/toolkit/skills/multi-task-flow/lib/engine.ts +71 -10
  78. package/toolkit/skills/multi-task-flow/lib/view.ts +115 -13
  79. package/toolkit/skills/multi-task-flow/scripts/package-client-skills.ts +24 -153
  80. package/toolkit/skills/multi-task-flow/scripts/preview-source.ts +3 -0
  81. package/toolkit/skills/multi-task-flow/tests/atomic-orchestration-schema.test.ts +35 -0
  82. package/toolkit/skills/multi-task-flow/tests/engine.test.ts +339 -0
  83. package/toolkit/skills/multi-task-flow/tests/source-preview.test.ts +29 -0
  84. package/toolkit/skills/multi-task-flow/tests/ui/details-content.test.ts +22 -0
  85. package/toolkit/skills/multi-task-flow/tests/view.test.ts +149 -0
  86. package/toolkit/skills/multi-task-flow/web/app.css +4 -0
  87. package/toolkit/skills/multi-task-flow/web/app.ts +11 -3
  88. package/toolkit/skills/multi-task-flow/web/atomic-graph-view.tsx +1 -1
  89. package/toolkit/skills/multi-task-flow/web/details-content.ts +7 -2
  90. package/toolkit/skills/multi-task-flow/web/graph-layout.ts +3 -3
  91. package/toolkit/skills/source-manifest.json +330 -26
  92. package/toolkit/skills/spec-sync/SKILL.md +1 -1
  93. package/toolkit/skills/spec-sync/scripts/_runtime/compatibility_cli.ts +12 -0
  94. package/toolkit/skills/spec-sync/scripts/_runtime/compatibility_docs.ts +115 -0
  95. package/toolkit/skills/spec-sync/scripts/_runtime/compatibility_shared.ts +230 -0
  96. package/toolkit/skills/spec-sync/scripts/_runtime/modules/checks/replay.ts +336 -0
  97. package/toolkit/skills/spec-sync/scripts/_runtime/modules/docs/git.ts +54 -0
  98. package/toolkit/skills/spec-sync/scripts/_runtime/modules/docs/hardware_ingest.ts +377 -0
  99. package/toolkit/skills/spec-sync/scripts/_runtime/modules/docs/hardware_locks.ts +181 -0
  100. package/toolkit/skills/spec-sync/scripts/_runtime/modules/docs/legacy_spec_id.ts +131 -0
  101. package/toolkit/skills/spec-sync/scripts/_runtime/modules/docs/migration_common.ts +291 -0
  102. package/toolkit/skills/spec-sync/scripts/_runtime/modules/docs/next_plan.ts +199 -0
  103. package/toolkit/skills/spec-sync/scripts/_runtime/modules/docs/next_plan_support.ts +245 -0
  104. package/toolkit/skills/spec-sync/scripts/_runtime/modules/docs/spec_contract.ts +299 -0
  105. package/toolkit/skills/spec-sync/scripts/_runtime/modules/docs/spec_drift.ts +387 -0
  106. package/toolkit/skills/spec-sync/scripts/_runtime/modules/docs/spec_drift_helpers.ts +381 -0
  107. package/toolkit/skills/spec-sync/scripts/_runtime/modules/docs/spec_drift_legacy.ts +376 -0
  108. package/toolkit/skills/spec-sync/scripts/_runtime/modules/docs/spec_drift_paths.ts +3 -0
  109. package/toolkit/skills/spec-sync/scripts/_runtime/modules/docs/spec_drift_types.ts +27 -0
  110. package/toolkit/skills/spec-sync/scripts/_runtime/modules/docs/spec_drift_validation.ts +251 -0
  111. package/toolkit/skills/spec-sync/scripts/_runtime/modules/docs/spec_migration.ts +191 -0
  112. package/toolkit/skills/spec-sync/scripts/spec_drift_check.ts +1 -1
  113. package/toolkit/skills/support-manifest.json +77 -1
  114. package/toolkit/skills/multi-task-flow/node_modules/zod/LICENSE +0 -21
  115. package/toolkit/skills/multi-task-flow/node_modules/zod/README.md +0 -218
  116. package/toolkit/skills/multi-task-flow/node_modules/zod/compile.cjs +0 -96
  117. package/toolkit/skills/multi-task-flow/node_modules/zod/compile.d.cts +0 -1
  118. package/toolkit/skills/multi-task-flow/node_modules/zod/compile.d.ts +0 -1
  119. package/toolkit/skills/multi-task-flow/node_modules/zod/compile.js +0 -52
  120. package/toolkit/skills/multi-task-flow/node_modules/zod/index.cjs +0 -52
  121. package/toolkit/skills/multi-task-flow/node_modules/zod/index.d.cts +0 -3
  122. package/toolkit/skills/multi-task-flow/node_modules/zod/index.d.ts +0 -3
  123. package/toolkit/skills/multi-task-flow/node_modules/zod/index.js +0 -7
  124. package/toolkit/skills/multi-task-flow/node_modules/zod/locales/index.cjs +0 -36
  125. package/toolkit/skills/multi-task-flow/node_modules/zod/locales/index.d.cts +0 -1
  126. package/toolkit/skills/multi-task-flow/node_modules/zod/locales/index.d.ts +0 -1
  127. package/toolkit/skills/multi-task-flow/node_modules/zod/locales/index.js +0 -1
  128. package/toolkit/skills/multi-task-flow/node_modules/zod/locales/package.json +0 -7
  129. package/toolkit/skills/multi-task-flow/node_modules/zod/mini/index.cjs +0 -51
  130. package/toolkit/skills/multi-task-flow/node_modules/zod/mini/index.d.cts +0 -3
  131. package/toolkit/skills/multi-task-flow/node_modules/zod/mini/index.d.ts +0 -3
  132. package/toolkit/skills/multi-task-flow/node_modules/zod/mini/index.js +0 -3
  133. package/toolkit/skills/multi-task-flow/node_modules/zod/mini/package.json +0 -7
  134. package/toolkit/skills/multi-task-flow/node_modules/zod/package.json +0 -147
  135. package/toolkit/skills/multi-task-flow/node_modules/zod/src/compile.ts +0 -56
  136. package/toolkit/skills/multi-task-flow/node_modules/zod/src/index.ts +0 -7
  137. package/toolkit/skills/multi-task-flow/node_modules/zod/src/locales/index.ts +0 -1
  138. package/toolkit/skills/multi-task-flow/node_modules/zod/src/mini/index.ts +0 -3
  139. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/ZodError.ts +0 -340
  140. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/benchmarks/datetime.ts +0 -58
  141. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/benchmarks/discriminatedUnion.ts +0 -80
  142. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/benchmarks/index.ts +0 -59
  143. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/benchmarks/ipv4.ts +0 -57
  144. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/benchmarks/object.ts +0 -69
  145. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/benchmarks/primitives.ts +0 -162
  146. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/benchmarks/realworld.ts +0 -63
  147. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/benchmarks/string.ts +0 -55
  148. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/benchmarks/union.ts +0 -80
  149. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/errors.ts +0 -13
  150. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/external.ts +0 -6
  151. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/helpers/enumUtil.ts +0 -17
  152. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/helpers/errorUtil.ts +0 -8
  153. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/helpers/parseUtil.ts +0 -176
  154. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/helpers/partialUtil.ts +0 -34
  155. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/helpers/typeAliases.ts +0 -2
  156. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/helpers/util.ts +0 -224
  157. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/index.ts +0 -4
  158. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/locales/en.ts +0 -124
  159. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/standard-schema.ts +0 -113
  160. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/Mocker.ts +0 -54
  161. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/all-errors.test.ts +0 -157
  162. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/anyunknown.test.ts +0 -28
  163. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/array.test.ts +0 -71
  164. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/async-parsing.test.ts +0 -388
  165. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/async-refinements.test.ts +0 -46
  166. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/base.test.ts +0 -29
  167. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/bigint.test.ts +0 -55
  168. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/branded.test.ts +0 -53
  169. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/catch.test.ts +0 -220
  170. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/coerce.test.ts +0 -133
  171. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/complex.test.ts +0 -70
  172. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/custom.test.ts +0 -31
  173. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/date.test.ts +0 -32
  174. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/deepmasking.test.ts +0 -186
  175. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/default.test.ts +0 -112
  176. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/description.test.ts +0 -33
  177. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/discriminated-unions.test.ts +0 -315
  178. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/enum.test.ts +0 -80
  179. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/error.test.ts +0 -586
  180. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/firstparty.test.ts +0 -87
  181. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/firstpartyschematypes.test.ts +0 -21
  182. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/function.test.ts +0 -261
  183. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/generics.test.ts +0 -48
  184. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/instanceof.test.ts +0 -37
  185. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/intersection.test.ts +0 -128
  186. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/language-server.source.ts +0 -76
  187. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/language-server.test.ts +0 -206
  188. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/literal.test.ts +0 -36
  189. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/map.test.ts +0 -110
  190. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/masking.test.ts +0 -4
  191. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/mocker.test.ts +0 -19
  192. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/nan.test.ts +0 -24
  193. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/nativeEnum.test.ts +0 -87
  194. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/nullable.test.ts +0 -42
  195. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/number.test.ts +0 -176
  196. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/object-augmentation.test.ts +0 -29
  197. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/object-in-es5-env.test.ts +0 -29
  198. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/object.test.ts +0 -431
  199. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/optional.test.ts +0 -42
  200. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/parseUtil.test.ts +0 -23
  201. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/parser.test.ts +0 -41
  202. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/partials.test.ts +0 -243
  203. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/pickomit.test.ts +0 -111
  204. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/pipeline.test.ts +0 -29
  205. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/preprocess.test.ts +0 -186
  206. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/primitive.test.ts +0 -440
  207. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/promise.test.ts +0 -90
  208. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/readonly.test.ts +0 -114
  209. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/record.test.ts +0 -171
  210. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/recursive.test.ts +0 -197
  211. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/refine.test.ts +0 -313
  212. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/safeparse.test.ts +0 -27
  213. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/set.test.ts +0 -142
  214. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/standard-schema.test.ts +0 -83
  215. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/string.test.ts +0 -922
  216. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/transformer.test.ts +0 -233
  217. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/tuple.test.ts +0 -90
  218. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/unions.test.ts +0 -57
  219. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/validations.test.ts +0 -133
  220. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/tests/void.test.ts +0 -15
  221. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v3/types.ts +0 -5138
  222. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/checks.ts +0 -33
  223. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/coerce.ts +0 -27
  224. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/compat.ts +0 -78
  225. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/deep-partial.ts +0 -76
  226. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/errors.ts +0 -97
  227. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/external.ts +0 -57
  228. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/from-json-schema.ts +0 -944
  229. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/in-out.ts +0 -45
  230. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/index.ts +0 -5
  231. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/iso.ts +0 -20
  232. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/parse.ts +0 -88
  233. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/schemas.ts +0 -2937
  234. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/anyunknown.test.ts +0 -26
  235. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/apply.test.ts +0 -86
  236. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/array.test.ts +0 -291
  237. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/assignability.test.ts +0 -402
  238. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/async-parsing.test.ts +0 -381
  239. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/async-refinements.test.ts +0 -68
  240. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/base.test.ts +0 -7
  241. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/bigint.test.ts +0 -89
  242. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/brand.test.ts +0 -106
  243. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/catch.test.ts +0 -604
  244. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/coalesce.test.ts +0 -20
  245. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/codec-examples.test.ts +0 -572
  246. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/codec.test.ts +0 -704
  247. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/coerce.test.ts +0 -160
  248. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/continuability.test.ts +0 -374
  249. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/credit-card.test.ts +0 -76
  250. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/custom.test.ts +0 -40
  251. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/cyclic-data.test.ts +0 -985
  252. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/date.test.ts +0 -92
  253. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/datetime.test.ts +0 -316
  254. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/deep-partial.test.ts +0 -380
  255. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/default-locale.test.ts +0 -32
  256. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/default.test.ts +0 -455
  257. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/describe-meta-checks.test.ts +0 -27
  258. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/description.test.ts +0 -32
  259. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/detached-methods.test.ts +0 -221
  260. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/discriminated-unions.test.ts +0 -942
  261. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/enum.test.ts +0 -305
  262. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/error-utils.test.ts +0 -917
  263. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/error.test.ts +0 -1108
  264. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/file.test.ts +0 -96
  265. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/firstparty.test.ts +0 -179
  266. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/fix-json-issue.test.ts +0 -26
  267. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/from-json-schema.test.ts +0 -1467
  268. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/function.test.ts +0 -391
  269. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/generics.test.ts +0 -72
  270. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/global-config.test.ts +0 -32
  271. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/hash.test.ts +0 -67
  272. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/iban.test.ts +0 -81
  273. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/in-out.test.ts +0 -159
  274. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/index.test.ts +0 -958
  275. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/instance-footprint.test.ts +0 -319
  276. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/instanceof.test.ts +0 -127
  277. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/intersection.test.ts +0 -334
  278. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/issue-schema.test.ts +0 -215
  279. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/jitless-allows-eval.test.ts +0 -39
  280. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/json.test.ts +0 -109
  281. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/lazy.test.ts +0 -262
  282. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/literal.test.ts +0 -128
  283. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/locales_ka.test.ts +0 -29
  284. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/locales_ro.test.ts +0 -24
  285. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/map.test.ts +0 -349
  286. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/nan.test.ts +0 -21
  287. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/nested-refine.test.ts +0 -168
  288. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/nonoptional.test.ts +0 -101
  289. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/nullable.test.ts +0 -22
  290. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/number.test.ts +0 -401
  291. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/object.test.ts +0 -1006
  292. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/optin-ladder.test.ts +0 -235
  293. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/optional.test.ts +0 -366
  294. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/partial.test.ts +0 -497
  295. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/pickomit.test.ts +0 -211
  296. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/pipe.test.ts +0 -101
  297. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/prefault.test.ts +0 -144
  298. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/preprocess-types.test.ts +0 -44
  299. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/preprocess.test.ts +0 -351
  300. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/primitive.test.ts +0 -175
  301. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/promise.test.ts +0 -81
  302. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/properties.test.ts +0 -141
  303. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/prototypes.test.ts +0 -23
  304. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/readonly.test.ts +0 -184
  305. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/record.test.ts +0 -885
  306. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/recursive-types.test.ts +0 -707
  307. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/redos.test.ts +0 -68
  308. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/refine.test.ts +0 -693
  309. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/registries.test.ts +0 -243
  310. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/set.test.ts +0 -196
  311. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/standard-schema.test.ts +0 -153
  312. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/string-formats.test.ts +0 -125
  313. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/string.test.ts +0 -1440
  314. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/stringbool.test.ts +0 -124
  315. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/template-literal.test.ts +0 -812
  316. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/to-json-schema-methods.test.ts +0 -438
  317. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/to-json-schema.test.ts +0 -4733
  318. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/transform.test.ts +0 -378
  319. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/tuple.test.ts +0 -511
  320. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/union.test.ts +0 -310
  321. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/url.test.ts +0 -13
  322. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/validate.test.ts +0 -645
  323. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/validations.test.ts +0 -283
  324. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/classic/tests/void.test.ts +0 -12
  325. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/api.ts +0 -1875
  326. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/checks.ts +0 -1266
  327. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/compile.ts +0 -2322
  328. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/core.ts +0 -230
  329. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/doc.ts +0 -52
  330. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/errors.ts +0 -543
  331. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/index.ts +0 -19
  332. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/json-schema-generator.ts +0 -131
  333. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/json-schema-processors.ts +0 -934
  334. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/json-schema.ts +0 -148
  335. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/memoizer.ts +0 -331
  336. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/parse.ts +0 -309
  337. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/regexes.ts +0 -217
  338. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/registries.ts +0 -105
  339. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/schemas.ts +0 -5226
  340. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/standard-schema.ts +0 -159
  341. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/tests/cached.test.ts +0 -54
  342. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/tests/compile-differential.test.ts +0 -1004
  343. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/tests/compile-generative.test.ts +0 -445
  344. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/tests/compile-global.test.ts +0 -89
  345. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/tests/compile-off-by-default.test.ts +0 -26
  346. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/tests/compile-stats.test.ts +0 -34
  347. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/tests/compile.test.ts +0 -2036
  348. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/tests/email-regex.test.ts +0 -140
  349. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/tests/extend.test.ts +0 -59
  350. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/tests/index.test.ts +0 -46
  351. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/tests/locales/be.test.ts +0 -124
  352. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/tests/locales/el.test.ts +0 -214
  353. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/tests/locales/en.test.ts +0 -22
  354. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/tests/locales/es.test.ts +0 -180
  355. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/tests/locales/fr.test.ts +0 -72
  356. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/tests/locales/he.test.ts +0 -379
  357. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/tests/locales/hr.test.ts +0 -163
  358. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/tests/locales/nl.test.ts +0 -46
  359. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/tests/locales/parity.test.ts +0 -42
  360. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/tests/locales/ru.test.ts +0 -128
  361. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/tests/locales/tg.test.ts +0 -85
  362. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/tests/locales/tk.test.ts +0 -69
  363. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/tests/locales/tr.test.ts +0 -69
  364. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/tests/locales/uz.test.ts +0 -105
  365. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/tests/polyfill-collision.test.ts +0 -46
  366. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/tests/record-constructor.test.ts +0 -125
  367. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/tests/recursive-tuples.test.ts +0 -45
  368. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/tests/treeshake.test.ts +0 -51
  369. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/tests/url-no-canparse.test.ts +0 -133
  370. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/to-json-schema.ts +0 -857
  371. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/util.ts +0 -1293
  372. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/versions.ts +0 -5
  373. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/visit.ts +0 -193
  374. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/core/zsf.ts +0 -323
  375. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/index.ts +0 -4
  376. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/ar.ts +0 -120
  377. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/az.ts +0 -116
  378. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/be.ts +0 -188
  379. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/bg.ts +0 -133
  380. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/bn.ts +0 -123
  381. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/ca.ts +0 -121
  382. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/ckb.ts +0 -140
  383. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/cs.ts +0 -123
  384. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/da.ts +0 -128
  385. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/de.ts +0 -121
  386. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/el.ts +0 -124
  387. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/en.ts +0 -136
  388. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/eo.ts +0 -123
  389. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/es.ts +0 -145
  390. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/fa.ts +0 -131
  391. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/fi.ts +0 -126
  392. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/fr-CA.ts +0 -121
  393. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/fr.ts +0 -139
  394. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/gu.ts +0 -123
  395. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/he.ts +0 -253
  396. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/hi.ts +0 -126
  397. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/hr.ts +0 -135
  398. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/hu.ts +0 -122
  399. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/hy.ts +0 -175
  400. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/id.ts +0 -120
  401. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/index.ts +0 -63
  402. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/is.ts +0 -124
  403. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/it.ts +0 -121
  404. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/ja.ts +0 -119
  405. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/ka.ts +0 -128
  406. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/kh.ts +0 -7
  407. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/km.ts +0 -124
  408. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/kn.ts +0 -126
  409. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/ko.ts +0 -126
  410. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/lt.ts +0 -243
  411. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/mk.ts +0 -123
  412. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/ms.ts +0 -120
  413. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/ne.ts +0 -128
  414. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/nl.ts +0 -126
  415. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/nn.ts +0 -121
  416. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/no.ts +0 -121
  417. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/ota.ts +0 -122
  418. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/pl.ts +0 -123
  419. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/ps.ts +0 -131
  420. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/pt-BR.ts +0 -161
  421. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/pt.ts +0 -159
  422. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/ro.ts +0 -132
  423. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/ru.ts +0 -188
  424. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/sk.ts +0 -123
  425. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/sl.ts +0 -123
  426. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/sv.ts +0 -124
  427. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/ta.ts +0 -123
  428. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/tg.ts +0 -135
  429. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/th.ts +0 -124
  430. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/tk.ts +0 -113
  431. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/tr.ts +0 -116
  432. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/ua.ts +0 -7
  433. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/uk.ts +0 -122
  434. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/ur.ts +0 -124
  435. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/uz.ts +0 -120
  436. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/vi.ts +0 -122
  437. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/yo.ts +0 -129
  438. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/zh-CN.ts +0 -121
  439. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/locales/zh-TW.ts +0 -120
  440. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/mini/checks.ts +0 -33
  441. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/mini/coerce.ts +0 -27
  442. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/mini/deep-partial.ts +0 -73
  443. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/mini/external.ts +0 -52
  444. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/mini/in-out.ts +0 -45
  445. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/mini/index.ts +0 -3
  446. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/mini/iso.ts +0 -66
  447. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/mini/parse.ts +0 -16
  448. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/mini/schemas.ts +0 -2051
  449. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/mini/tests/apply.test.ts +0 -57
  450. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/mini/tests/assignability.test.ts +0 -190
  451. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/mini/tests/brand.test.ts +0 -94
  452. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/mini/tests/checks.test.ts +0 -158
  453. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/mini/tests/codec.test.ts +0 -582
  454. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/mini/tests/computed.test.ts +0 -30
  455. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/mini/tests/cyclic-data.test.ts +0 -84
  456. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/mini/tests/deep-partial.test.ts +0 -54
  457. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/mini/tests/error.test.ts +0 -41
  458. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/mini/tests/functions.test.ts +0 -14
  459. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/mini/tests/index.test.ts +0 -1146
  460. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/mini/tests/number.test.ts +0 -109
  461. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/mini/tests/object.test.ts +0 -292
  462. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/mini/tests/prototypes.test.ts +0 -43
  463. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/mini/tests/recursive-types.test.ts +0 -341
  464. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/mini/tests/standard-schema.test.ts +0 -50
  465. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4/mini/tests/string.test.ts +0 -396
  466. package/toolkit/skills/multi-task-flow/node_modules/zod/src/v4-mini/index.ts +0 -3
  467. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/ZodError.cjs +0 -167
  468. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/ZodError.d.cts +0 -164
  469. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/ZodError.d.ts +0 -164
  470. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/ZodError.js +0 -143
  471. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/errors.cjs +0 -36
  472. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/errors.d.cts +0 -5
  473. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/errors.d.ts +0 -5
  474. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/errors.js +0 -9
  475. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/external.cjs +0 -41
  476. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/external.d.cts +0 -6
  477. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/external.d.ts +0 -6
  478. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/external.js +0 -6
  479. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/helpers/enumUtil.cjs +0 -21
  480. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/helpers/enumUtil.d.cts +0 -8
  481. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/helpers/enumUtil.d.ts +0 -8
  482. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/helpers/enumUtil.js +0 -1
  483. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/helpers/errorUtil.cjs +0 -28
  484. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/helpers/errorUtil.d.cts +0 -9
  485. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/helpers/errorUtil.d.ts +0 -9
  486. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/helpers/errorUtil.js +0 -6
  487. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/helpers/parseUtil.cjs +0 -143
  488. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/helpers/parseUtil.d.cts +0 -78
  489. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/helpers/parseUtil.d.ts +0 -78
  490. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/helpers/parseUtil.js +0 -109
  491. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/helpers/partialUtil.cjs +0 -21
  492. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/helpers/partialUtil.d.cts +0 -8
  493. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/helpers/partialUtil.d.ts +0 -8
  494. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/helpers/partialUtil.js +0 -1
  495. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/helpers/typeAliases.cjs +0 -21
  496. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/helpers/typeAliases.d.cts +0 -2
  497. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/helpers/typeAliases.d.ts +0 -2
  498. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/helpers/typeAliases.js +0 -1
  499. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/helpers/util.cjs +0 -156
  500. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/helpers/util.d.cts +0 -85
  501. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/helpers/util.d.ts +0 -85
  502. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/helpers/util.js +0 -133
  503. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/index.cjs +0 -52
  504. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/index.d.cts +0 -4
  505. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/index.d.ts +0 -4
  506. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/index.js +0 -4
  507. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/locales/en.cjs +0 -112
  508. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/locales/en.d.cts +0 -3
  509. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/locales/en.d.ts +0 -3
  510. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/locales/en.js +0 -109
  511. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/package.json +0 -7
  512. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/standard-schema.cjs +0 -21
  513. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/standard-schema.d.cts +0 -102
  514. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/standard-schema.d.ts +0 -102
  515. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/standard-schema.js +0 -1
  516. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/types.cjs +0 -3798
  517. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/types.d.cts +0 -1034
  518. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/types.d.ts +0 -1034
  519. package/toolkit/skills/multi-task-flow/node_modules/zod/v3/types.js +0 -3697
  520. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/checks.cjs +0 -53
  521. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/checks.d.cts +0 -1
  522. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/checks.d.ts +0 -1
  523. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/checks.js +0 -1
  524. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/coerce.cjs +0 -66
  525. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/coerce.d.cts +0 -17
  526. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/coerce.d.ts +0 -17
  527. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/coerce.js +0 -17
  528. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/compat.cjs +0 -80
  529. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/compat.d.cts +0 -48
  530. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/compat.d.ts +0 -48
  531. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/compat.js +0 -31
  532. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/deep-partial.cjs +0 -58
  533. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/deep-partial.d.cts +0 -14
  534. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/deep-partial.d.ts +0 -14
  535. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/deep-partial.js +0 -13
  536. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/errors.cjs +0 -102
  537. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/errors.d.cts +0 -29
  538. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/errors.d.ts +0 -29
  539. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/errors.js +0 -57
  540. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/external.cjs +0 -97
  541. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/external.d.cts +0 -19
  542. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/external.d.ts +0 -19
  543. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/external.js +0 -17
  544. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/from-json-schema.cjs +0 -926
  545. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/from-json-schema.d.cts +0 -12
  546. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/from-json-schema.d.ts +0 -12
  547. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/from-json-schema.js +0 -881
  548. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/in-out.cjs +0 -82
  549. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/in-out.d.cts +0 -8
  550. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/in-out.d.ts +0 -8
  551. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/in-out.js +0 -36
  552. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/index.cjs +0 -52
  553. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/index.d.cts +0 -3
  554. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/index.d.ts +0 -3
  555. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/index.js +0 -4
  556. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/iso.cjs +0 -68
  557. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/iso.d.cts +0 -7
  558. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/iso.d.ts +0 -7
  559. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/iso.js +0 -15
  560. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/package.json +0 -7
  561. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/parse.cjs +0 -63
  562. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/parse.d.cts +0 -44
  563. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/parse.d.ts +0 -44
  564. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/parse.js +0 -16
  565. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/schemas.cjs +0 -1676
  566. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/schemas.d.cts +0 -816
  567. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/schemas.d.ts +0 -816
  568. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/classic/schemas.js +0 -1535
  569. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/api.cjs +0 -1269
  570. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/api.d.cts +0 -335
  571. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/api.d.ts +0 -335
  572. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/api.js +0 -1107
  573. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/checks.cjs +0 -561
  574. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/checks.d.cts +0 -294
  575. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/checks.d.ts +0 -294
  576. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/checks.js +0 -516
  577. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/compile.cjs +0 -1916
  578. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/compile.d.cts +0 -65
  579. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/compile.d.ts +0 -65
  580. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/compile.js +0 -1866
  581. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/core.cjs +0 -167
  582. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/core.d.cts +0 -82
  583. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/core.d.ts +0 -82
  584. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/core.js +0 -141
  585. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/doc.cjs +0 -61
  586. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/doc.d.cts +0 -16
  587. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/doc.d.ts +0 -16
  588. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/doc.js +0 -38
  589. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/errors.cjs +0 -317
  590. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/errors.d.cts +0 -225
  591. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/errors.d.ts +0 -225
  592. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/errors.js +0 -267
  593. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/index.cjs +0 -70
  594. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/index.d.cts +0 -19
  595. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/index.d.ts +0 -19
  596. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/index.js +0 -19
  597. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/json-schema-generator.cjs +0 -122
  598. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/json-schema-generator.d.cts +0 -65
  599. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/json-schema-generator.d.ts +0 -65
  600. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/json-schema-generator.js +0 -99
  601. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/json-schema-processors.cjs +0 -929
  602. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/json-schema-processors.d.cts +0 -65
  603. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/json-schema-processors.d.ts +0 -65
  604. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/json-schema-processors.js +0 -843
  605. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/json-schema.cjs +0 -21
  606. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/json-schema.d.cts +0 -89
  607. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/json-schema.d.ts +0 -89
  608. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/json-schema.js +0 -1
  609. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/memoizer.cjs +0 -360
  610. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/memoizer.d.cts +0 -15
  611. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/memoizer.d.ts +0 -15
  612. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/memoizer.js +0 -311
  613. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/package.json +0 -7
  614. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/parse.cjs +0 -233
  615. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/parse.d.cts +0 -52
  616. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/parse.d.ts +0 -52
  617. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/parse.js +0 -175
  618. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/regexes.cjs +0 -209
  619. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/regexes.d.cts +0 -90
  620. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/regexes.d.ts +0 -90
  621. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/regexes.js +0 -156
  622. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/registries.cjs +0 -75
  623. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/registries.d.cts +0 -35
  624. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/registries.d.ts +0 -35
  625. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/registries.js +0 -51
  626. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/schemas.cjs +0 -2699
  627. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/schemas.d.cts +0 -1275
  628. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/schemas.d.ts +0 -1275
  629. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/schemas.js +0 -2636
  630. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/standard-schema.cjs +0 -21
  631. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/standard-schema.d.cts +0 -126
  632. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/standard-schema.d.ts +0 -126
  633. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/standard-schema.js +0 -1
  634. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/to-json-schema.cjs +0 -681
  635. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/to-json-schema.d.cts +0 -154
  636. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/to-json-schema.d.ts +0 -154
  637. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/to-json-schema.js +0 -651
  638. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/util.cjs +0 -964
  639. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/util.d.cts +0 -280
  640. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/util.d.ts +0 -280
  641. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/util.js +0 -873
  642. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/versions.cjs +0 -27
  643. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/versions.d.cts +0 -5
  644. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/versions.d.ts +0 -5
  645. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/versions.js +0 -5
  646. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/visit.cjs +0 -214
  647. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/visit.d.cts +0 -30
  648. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/visit.d.ts +0 -30
  649. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/core/visit.js +0 -169
  650. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/index.cjs +0 -51
  651. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/index.d.cts +0 -3
  652. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/index.d.ts +0 -3
  653. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/index.js +0 -4
  654. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ar.cjs +0 -138
  655. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ar.d.cts +0 -5
  656. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ar.d.ts +0 -4
  657. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ar.js +0 -111
  658. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/az.cjs +0 -137
  659. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/az.d.cts +0 -5
  660. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/az.d.ts +0 -4
  661. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/az.js +0 -110
  662. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/be.cjs +0 -195
  663. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/be.d.cts +0 -5
  664. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/be.d.ts +0 -4
  665. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/be.js +0 -168
  666. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/bg.cjs +0 -152
  667. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/bg.d.cts +0 -5
  668. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/bg.d.ts +0 -4
  669. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/bg.js +0 -125
  670. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/bn.cjs +0 -140
  671. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/bn.d.cts +0 -5
  672. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/bn.d.ts +0 -4
  673. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/bn.js +0 -113
  674. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ca.cjs +0 -139
  675. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ca.d.cts +0 -5
  676. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ca.d.ts +0 -4
  677. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ca.js +0 -112
  678. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ckb.cjs +0 -160
  679. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ckb.d.cts +0 -5
  680. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ckb.d.ts +0 -4
  681. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ckb.js +0 -133
  682. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/cs.cjs +0 -143
  683. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/cs.d.cts +0 -5
  684. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/cs.d.ts +0 -4
  685. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/cs.js +0 -116
  686. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/da.cjs +0 -147
  687. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/da.d.cts +0 -5
  688. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/da.d.ts +0 -4
  689. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/da.js +0 -120
  690. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/de.cjs +0 -140
  691. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/de.d.cts +0 -5
  692. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/de.d.ts +0 -4
  693. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/de.js +0 -113
  694. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/el.cjs +0 -139
  695. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/el.d.cts +0 -5
  696. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/el.d.ts +0 -4
  697. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/el.js +0 -112
  698. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/en.cjs +0 -152
  699. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/en.d.cts +0 -5
  700. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/en.d.ts +0 -4
  701. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/en.js +0 -125
  702. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/eo.cjs +0 -141
  703. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/eo.d.cts +0 -5
  704. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/eo.d.ts +0 -4
  705. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/eo.js +0 -114
  706. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/es.cjs +0 -163
  707. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/es.d.cts +0 -5
  708. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/es.d.ts +0 -4
  709. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/es.js +0 -136
  710. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/fa.cjs +0 -146
  711. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/fa.d.cts +0 -5
  712. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/fa.d.ts +0 -4
  713. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/fa.js +0 -119
  714. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/fi.cjs +0 -144
  715. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/fi.d.cts +0 -5
  716. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/fi.d.ts +0 -4
  717. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/fi.js +0 -117
  718. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/fr-CA.cjs +0 -139
  719. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/fr-CA.d.cts +0 -5
  720. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/fr-CA.d.ts +0 -4
  721. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/fr-CA.js +0 -112
  722. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/fr.cjs +0 -156
  723. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/fr.d.cts +0 -5
  724. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/fr.d.ts +0 -4
  725. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/fr.js +0 -129
  726. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/gu.cjs +0 -140
  727. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/gu.d.cts +0 -5
  728. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/gu.d.ts +0 -4
  729. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/gu.js +0 -113
  730. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/he.cjs +0 -248
  731. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/he.d.cts +0 -5
  732. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/he.d.ts +0 -4
  733. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/he.js +0 -221
  734. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/hi.cjs +0 -138
  735. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/hi.d.cts +0 -5
  736. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/hi.d.ts +0 -4
  737. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/hi.js +0 -111
  738. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/hr.cjs +0 -153
  739. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/hr.d.cts +0 -5
  740. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/hr.d.ts +0 -4
  741. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/hr.js +0 -126
  742. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/hu.cjs +0 -140
  743. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/hu.d.cts +0 -5
  744. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/hu.d.ts +0 -4
  745. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/hu.js +0 -113
  746. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/hy.cjs +0 -185
  747. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/hy.d.cts +0 -5
  748. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/hy.d.ts +0 -4
  749. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/hy.js +0 -158
  750. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/id.cjs +0 -138
  751. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/id.d.cts +0 -5
  752. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/id.d.ts +0 -4
  753. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/id.js +0 -111
  754. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/index.cjs +0 -152
  755. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/index.d.cts +0 -63
  756. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/index.d.ts +0 -63
  757. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/index.js +0 -63
  758. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/is.cjs +0 -141
  759. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/is.d.cts +0 -5
  760. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/is.d.ts +0 -4
  761. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/is.js +0 -114
  762. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/it.cjs +0 -140
  763. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/it.d.cts +0 -5
  764. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/it.d.ts +0 -4
  765. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/it.js +0 -113
  766. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ja.cjs +0 -139
  767. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ja.d.cts +0 -5
  768. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ja.d.ts +0 -4
  769. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ja.js +0 -112
  770. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ka.cjs +0 -144
  771. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ka.d.cts +0 -5
  772. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ka.d.ts +0 -4
  773. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ka.js +0 -117
  774. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/kh.cjs +0 -12
  775. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/kh.d.cts +0 -5
  776. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/kh.d.ts +0 -5
  777. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/kh.js +0 -5
  778. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/km.cjs +0 -142
  779. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/km.d.cts +0 -5
  780. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/km.d.ts +0 -4
  781. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/km.js +0 -115
  782. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/kn.cjs +0 -143
  783. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/kn.d.cts +0 -5
  784. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/kn.d.ts +0 -4
  785. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/kn.js +0 -116
  786. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ko.cjs +0 -143
  787. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ko.d.cts +0 -5
  788. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ko.d.ts +0 -4
  789. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ko.js +0 -116
  790. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/lt.cjs +0 -234
  791. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/lt.d.cts +0 -5
  792. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/lt.d.ts +0 -4
  793. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/lt.js +0 -207
  794. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/mk.cjs +0 -141
  795. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/mk.d.cts +0 -5
  796. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/mk.d.ts +0 -4
  797. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/mk.js +0 -114
  798. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ms.cjs +0 -139
  799. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ms.d.cts +0 -5
  800. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ms.d.ts +0 -4
  801. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ms.js +0 -112
  802. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ne.cjs +0 -138
  803. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ne.d.cts +0 -5
  804. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ne.d.ts +0 -4
  805. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ne.js +0 -111
  806. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/nl.cjs +0 -142
  807. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/nl.d.cts +0 -5
  808. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/nl.d.ts +0 -4
  809. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/nl.js +0 -115
  810. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/nn.cjs +0 -140
  811. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/nn.d.cts +0 -5
  812. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/nn.d.ts +0 -4
  813. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/nn.js +0 -113
  814. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/no.cjs +0 -140
  815. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/no.d.cts +0 -5
  816. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/no.d.ts +0 -4
  817. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/no.js +0 -113
  818. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ota.cjs +0 -141
  819. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ota.d.cts +0 -5
  820. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ota.d.ts +0 -4
  821. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ota.js +0 -114
  822. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/package.json +0 -7
  823. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/pl.cjs +0 -141
  824. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/pl.d.cts +0 -5
  825. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/pl.d.ts +0 -4
  826. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/pl.js +0 -114
  827. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ps.cjs +0 -146
  828. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ps.d.cts +0 -5
  829. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ps.d.ts +0 -4
  830. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ps.js +0 -119
  831. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/pt-BR.cjs +0 -170
  832. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/pt-BR.d.cts +0 -5
  833. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/pt-BR.d.ts +0 -4
  834. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/pt-BR.js +0 -143
  835. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/pt.cjs +0 -169
  836. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/pt.d.cts +0 -5
  837. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/pt.d.ts +0 -4
  838. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/pt.js +0 -142
  839. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ro.cjs +0 -149
  840. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ro.d.cts +0 -5
  841. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ro.d.ts +0 -4
  842. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ro.js +0 -122
  843. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ru.cjs +0 -195
  844. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ru.d.cts +0 -5
  845. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ru.d.ts +0 -4
  846. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ru.js +0 -168
  847. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/sk.cjs +0 -143
  848. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/sk.d.cts +0 -5
  849. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/sk.d.ts +0 -4
  850. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/sk.js +0 -116
  851. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/sl.cjs +0 -141
  852. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/sl.d.cts +0 -5
  853. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/sl.d.ts +0 -4
  854. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/sl.js +0 -114
  855. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/sv.cjs +0 -142
  856. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/sv.d.cts +0 -5
  857. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/sv.d.ts +0 -4
  858. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/sv.js +0 -115
  859. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ta.cjs +0 -142
  860. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ta.d.cts +0 -5
  861. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ta.d.ts +0 -4
  862. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ta.js +0 -115
  863. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/tg.cjs +0 -144
  864. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/tg.d.cts +0 -5
  865. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/tg.d.ts +0 -4
  866. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/tg.js +0 -117
  867. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/th.cjs +0 -142
  868. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/th.d.cts +0 -5
  869. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/th.d.ts +0 -4
  870. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/th.js +0 -115
  871. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/tk.cjs +0 -134
  872. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/tk.d.cts +0 -5
  873. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/tk.d.ts +0 -4
  874. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/tk.js +0 -107
  875. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/tr.cjs +0 -137
  876. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/tr.d.cts +0 -5
  877. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/tr.d.ts +0 -4
  878. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/tr.js +0 -110
  879. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ua.cjs +0 -12
  880. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ua.d.cts +0 -5
  881. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ua.d.ts +0 -5
  882. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ua.js +0 -5
  883. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/uk.cjs +0 -140
  884. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/uk.d.cts +0 -5
  885. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/uk.d.ts +0 -4
  886. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/uk.js +0 -113
  887. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ur.cjs +0 -142
  888. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ur.d.cts +0 -5
  889. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ur.d.ts +0 -4
  890. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/ur.js +0 -115
  891. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/uz.cjs +0 -140
  892. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/uz.d.cts +0 -5
  893. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/uz.d.ts +0 -4
  894. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/uz.js +0 -113
  895. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/vi.cjs +0 -140
  896. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/vi.d.cts +0 -5
  897. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/vi.d.ts +0 -4
  898. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/vi.js +0 -113
  899. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/yo.cjs +0 -139
  900. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/yo.d.cts +0 -5
  901. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/yo.d.ts +0 -4
  902. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/yo.js +0 -112
  903. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/zh-CN.cjs +0 -141
  904. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/zh-CN.d.cts +0 -5
  905. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/zh-CN.d.ts +0 -4
  906. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/zh-CN.js +0 -114
  907. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/zh-TW.cjs +0 -139
  908. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/zh-TW.d.cts +0 -5
  909. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/zh-TW.d.ts +0 -4
  910. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/locales/zh-TW.js +0 -112
  911. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/checks.cjs +0 -54
  912. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/checks.d.cts +0 -1
  913. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/checks.d.ts +0 -1
  914. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/checks.js +0 -1
  915. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/coerce.cjs +0 -71
  916. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/coerce.d.cts +0 -7
  917. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/coerce.d.ts +0 -7
  918. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/coerce.js +0 -22
  919. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/deep-partial.cjs +0 -58
  920. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/deep-partial.d.cts +0 -14
  921. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/deep-partial.d.ts +0 -14
  922. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/deep-partial.js +0 -13
  923. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/external.cjs +0 -95
  924. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/external.d.cts +0 -16
  925. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/external.d.ts +0 -16
  926. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/external.js +0 -16
  927. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/in-out.cjs +0 -82
  928. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/in-out.d.cts +0 -8
  929. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/in-out.d.ts +0 -8
  930. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/in-out.js +0 -36
  931. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/index.cjs +0 -51
  932. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/index.d.cts +0 -3
  933. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/index.d.ts +0 -3
  934. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/index.js +0 -3
  935. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/iso.cjs +0 -83
  936. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/iso.d.cts +0 -22
  937. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/iso.d.ts +0 -22
  938. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/iso.js +0 -34
  939. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/package.json +0 -7
  940. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/parse.cjs +0 -37
  941. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/parse.d.cts +0 -1
  942. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/parse.d.ts +0 -1
  943. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/parse.js +0 -1
  944. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/schemas.cjs +0 -1147
  945. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/schemas.d.cts +0 -480
  946. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/schemas.d.ts +0 -480
  947. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/mini/schemas.js +0 -1002
  948. package/toolkit/skills/multi-task-flow/node_modules/zod/v4/package.json +0 -7
  949. package/toolkit/skills/multi-task-flow/node_modules/zod/v4-mini/index.cjs +0 -51
  950. package/toolkit/skills/multi-task-flow/node_modules/zod/v4-mini/index.d.cts +0 -3
  951. package/toolkit/skills/multi-task-flow/node_modules/zod/v4-mini/index.d.ts +0 -3
  952. package/toolkit/skills/multi-task-flow/node_modules/zod/v4-mini/index.js +0 -3
  953. package/toolkit/skills/multi-task-flow/node_modules/zod/v4-mini/package.json +0 -7
  954. package/toolkit/skills/node_modules/@img/colour/LICENSE.md +0 -82
  955. package/toolkit/skills/node_modules/@img/colour/README.md +0 -15
  956. package/toolkit/skills/node_modules/@img/colour/color.cjs +0 -1596
  957. package/toolkit/skills/node_modules/@img/colour/index.cjs +0 -1
  958. package/toolkit/skills/node_modules/@img/colour/index.d.ts +0 -929
  959. package/toolkit/skills/node_modules/@img/colour/package.json +0 -58
  960. package/toolkit/skills/node_modules/@img/sharp-libvips-linux-x64/README.md +0 -46
  961. package/toolkit/skills/node_modules/@img/sharp-libvips-linux-x64/lib/glib-2.0/include/glibconfig.h +0 -219
  962. package/toolkit/skills/node_modules/@img/sharp-libvips-linux-x64/lib/index.js +0 -1
  963. package/toolkit/skills/node_modules/@img/sharp-libvips-linux-x64/lib/libvips-cpp.so.8.18.7 +0 -0
  964. package/toolkit/skills/node_modules/@img/sharp-libvips-linux-x64/package.json +0 -43
  965. package/toolkit/skills/node_modules/@img/sharp-libvips-linux-x64/versions.json +0 -30
  966. package/toolkit/skills/node_modules/@img/sharp-libvips-linuxmusl-x64/README.md +0 -46
  967. package/toolkit/skills/node_modules/@img/sharp-libvips-linuxmusl-x64/lib/glib-2.0/include/glibconfig.h +0 -219
  968. package/toolkit/skills/node_modules/@img/sharp-libvips-linuxmusl-x64/lib/index.js +0 -1
  969. package/toolkit/skills/node_modules/@img/sharp-libvips-linuxmusl-x64/lib/libvips-cpp.so.8.18.7 +0 -0
  970. package/toolkit/skills/node_modules/@img/sharp-libvips-linuxmusl-x64/package.json +0 -43
  971. package/toolkit/skills/node_modules/@img/sharp-libvips-linuxmusl-x64/versions.json +0 -30
  972. package/toolkit/skills/node_modules/@img/sharp-linux-x64/LICENSE +0 -191
  973. package/toolkit/skills/node_modules/@img/sharp-linux-x64/README.md +0 -18
  974. package/toolkit/skills/node_modules/@img/sharp-linux-x64/index.cjs +0 -2
  975. package/toolkit/skills/node_modules/@img/sharp-linux-x64/lib/sharp-linux-x64-0.35.5.node +0 -0
  976. package/toolkit/skills/node_modules/@img/sharp-linux-x64/package.json +0 -47
  977. package/toolkit/skills/node_modules/@img/sharp-linuxmusl-x64/LICENSE +0 -191
  978. package/toolkit/skills/node_modules/@img/sharp-linuxmusl-x64/README.md +0 -18
  979. package/toolkit/skills/node_modules/@img/sharp-linuxmusl-x64/index.cjs +0 -2
  980. package/toolkit/skills/node_modules/@img/sharp-linuxmusl-x64/lib/sharp-linuxmusl-x64-0.35.5.node +0 -0
  981. package/toolkit/skills/node_modules/@img/sharp-linuxmusl-x64/package.json +0 -47
  982. package/toolkit/skills/node_modules/detect-libc/LICENSE +0 -201
  983. package/toolkit/skills/node_modules/detect-libc/README.md +0 -163
  984. package/toolkit/skills/node_modules/detect-libc/index.d.ts +0 -14
  985. package/toolkit/skills/node_modules/detect-libc/lib/detect-libc.js +0 -313
  986. package/toolkit/skills/node_modules/detect-libc/lib/elf.js +0 -39
  987. package/toolkit/skills/node_modules/detect-libc/lib/filesystem.js +0 -51
  988. package/toolkit/skills/node_modules/detect-libc/lib/process.js +0 -24
  989. package/toolkit/skills/node_modules/detect-libc/package.json +0 -44
  990. package/toolkit/skills/node_modules/semver/LICENSE +0 -15
  991. package/toolkit/skills/node_modules/semver/README.md +0 -680
  992. package/toolkit/skills/node_modules/semver/bin/semver.js +0 -195
  993. package/toolkit/skills/node_modules/semver/classes/comparator.js +0 -143
  994. package/toolkit/skills/node_modules/semver/classes/index.js +0 -7
  995. package/toolkit/skills/node_modules/semver/classes/range.js +0 -577
  996. package/toolkit/skills/node_modules/semver/classes/semver.js +0 -350
  997. package/toolkit/skills/node_modules/semver/functions/clean.js +0 -8
  998. package/toolkit/skills/node_modules/semver/functions/cmp.js +0 -54
  999. package/toolkit/skills/node_modules/semver/functions/coerce.js +0 -62
  1000. package/toolkit/skills/node_modules/semver/functions/compare-build.js +0 -9
  1001. package/toolkit/skills/node_modules/semver/functions/compare-loose.js +0 -5
  1002. package/toolkit/skills/node_modules/semver/functions/compare.js +0 -7
  1003. package/toolkit/skills/node_modules/semver/functions/diff.js +0 -60
  1004. package/toolkit/skills/node_modules/semver/functions/eq.js +0 -5
  1005. package/toolkit/skills/node_modules/semver/functions/gt.js +0 -5
  1006. package/toolkit/skills/node_modules/semver/functions/gte.js +0 -5
  1007. package/toolkit/skills/node_modules/semver/functions/inc.js +0 -21
  1008. package/toolkit/skills/node_modules/semver/functions/lt.js +0 -5
  1009. package/toolkit/skills/node_modules/semver/functions/lte.js +0 -5
  1010. package/toolkit/skills/node_modules/semver/functions/major.js +0 -5
  1011. package/toolkit/skills/node_modules/semver/functions/minor.js +0 -5
  1012. package/toolkit/skills/node_modules/semver/functions/neq.js +0 -5
  1013. package/toolkit/skills/node_modules/semver/functions/parse.js +0 -18
  1014. package/toolkit/skills/node_modules/semver/functions/patch.js +0 -5
  1015. package/toolkit/skills/node_modules/semver/functions/prerelease.js +0 -8
  1016. package/toolkit/skills/node_modules/semver/functions/rcompare.js +0 -5
  1017. package/toolkit/skills/node_modules/semver/functions/rsort.js +0 -5
  1018. package/toolkit/skills/node_modules/semver/functions/satisfies.js +0 -12
  1019. package/toolkit/skills/node_modules/semver/functions/sort.js +0 -5
  1020. package/toolkit/skills/node_modules/semver/functions/truncate.js +0 -48
  1021. package/toolkit/skills/node_modules/semver/functions/valid.js +0 -8
  1022. package/toolkit/skills/node_modules/semver/index.js +0 -93
  1023. package/toolkit/skills/node_modules/semver/internal/constants.js +0 -67
  1024. package/toolkit/skills/node_modules/semver/internal/debug.js +0 -11
  1025. package/toolkit/skills/node_modules/semver/internal/identifiers.js +0 -29
  1026. package/toolkit/skills/node_modules/semver/internal/lrucache.js +0 -42
  1027. package/toolkit/skills/node_modules/semver/internal/parse-options.js +0 -17
  1028. package/toolkit/skills/node_modules/semver/internal/re.js +0 -223
  1029. package/toolkit/skills/node_modules/semver/internal/trim-comparator-whitespace.js +0 -438
  1030. package/toolkit/skills/node_modules/semver/package.json +0 -78
  1031. package/toolkit/skills/node_modules/semver/preload.js +0 -4
  1032. package/toolkit/skills/node_modules/semver/range.bnf +0 -17
  1033. package/toolkit/skills/node_modules/semver/ranges/gtr.js +0 -6
  1034. package/toolkit/skills/node_modules/semver/ranges/intersects.js +0 -9
  1035. package/toolkit/skills/node_modules/semver/ranges/ltr.js +0 -6
  1036. package/toolkit/skills/node_modules/semver/ranges/max-satisfying.js +0 -27
  1037. package/toolkit/skills/node_modules/semver/ranges/min-satisfying.js +0 -26
  1038. package/toolkit/skills/node_modules/semver/ranges/min-version.js +0 -63
  1039. package/toolkit/skills/node_modules/semver/ranges/outside.js +0 -82
  1040. package/toolkit/skills/node_modules/semver/ranges/simplify.js +0 -49
  1041. package/toolkit/skills/node_modules/semver/ranges/subset.js +0 -249
  1042. package/toolkit/skills/node_modules/semver/ranges/to-comparators.js +0 -10
  1043. package/toolkit/skills/node_modules/semver/ranges/valid.js +0 -13
  1044. package/toolkit/skills/node_modules/sharp/LICENSE +0 -191
  1045. package/toolkit/skills/node_modules/sharp/README.md +0 -112
  1046. package/toolkit/skills/node_modules/sharp/dist/channel.cjs +0 -177
  1047. package/toolkit/skills/node_modules/sharp/dist/channel.mjs +0 -177
  1048. package/toolkit/skills/node_modules/sharp/dist/colour.cjs +0 -199
  1049. package/toolkit/skills/node_modules/sharp/dist/colour.mjs +0 -199
  1050. package/toolkit/skills/node_modules/sharp/dist/composite.cjs +0 -213
  1051. package/toolkit/skills/node_modules/sharp/dist/composite.mjs +0 -213
  1052. package/toolkit/skills/node_modules/sharp/dist/constructor.cjs +0 -511
  1053. package/toolkit/skills/node_modules/sharp/dist/constructor.mjs +0 -511
  1054. package/toolkit/skills/node_modules/sharp/dist/index.cjs +0 -25
  1055. package/toolkit/skills/node_modules/sharp/dist/index.d.cts +0 -1999
  1056. package/toolkit/skills/node_modules/sharp/dist/index.d.mts +0 -2046
  1057. package/toolkit/skills/node_modules/sharp/dist/index.mjs +0 -25
  1058. package/toolkit/skills/node_modules/sharp/dist/input.cjs +0 -819
  1059. package/toolkit/skills/node_modules/sharp/dist/input.mjs +0 -819
  1060. package/toolkit/skills/node_modules/sharp/dist/is.cjs +0 -149
  1061. package/toolkit/skills/node_modules/sharp/dist/is.mjs +0 -149
  1062. package/toolkit/skills/node_modules/sharp/dist/libvips.cjs +0 -212
  1063. package/toolkit/skills/node_modules/sharp/dist/libvips.mjs +0 -212
  1064. package/toolkit/skills/node_modules/sharp/dist/operation.cjs +0 -1002
  1065. package/toolkit/skills/node_modules/sharp/dist/operation.mjs +0 -1002
  1066. package/toolkit/skills/node_modules/sharp/dist/output.cjs +0 -1786
  1067. package/toolkit/skills/node_modules/sharp/dist/output.mjs +0 -1786
  1068. package/toolkit/skills/node_modules/sharp/dist/resize.cjs +0 -617
  1069. package/toolkit/skills/node_modules/sharp/dist/resize.mjs +0 -617
  1070. package/toolkit/skills/node_modules/sharp/dist/sharp.cjs +0 -174
  1071. package/toolkit/skills/node_modules/sharp/dist/sharp.mjs +0 -174
  1072. package/toolkit/skills/node_modules/sharp/dist/utility.cjs +0 -301
  1073. package/toolkit/skills/node_modules/sharp/dist/utility.mjs +0 -301
  1074. package/toolkit/skills/node_modules/sharp/install/build.js +0 -38
  1075. package/toolkit/skills/node_modules/sharp/lib/index.d.ts +0 -1999
  1076. package/toolkit/skills/node_modules/sharp/package.json +0 -227
  1077. package/toolkit/skills/node_modules/sharp/src/binding.gyp +0 -303
  1078. package/toolkit/skills/node_modules/sharp/src/common.cc +0 -1186
  1079. package/toolkit/skills/node_modules/sharp/src/common.h +0 -421
  1080. package/toolkit/skills/node_modules/sharp/src/metadata.cc +0 -404
  1081. package/toolkit/skills/node_modules/sharp/src/metadata.h +0 -95
  1082. package/toolkit/skills/node_modules/sharp/src/operations.cc +0 -516
  1083. package/toolkit/skills/node_modules/sharp/src/operations.h +0 -137
  1084. package/toolkit/skills/node_modules/sharp/src/pipeline.cc +0 -1973
  1085. package/toolkit/skills/node_modules/sharp/src/pipeline.h +0 -422
  1086. package/toolkit/skills/node_modules/sharp/src/sharp.cc +0 -43
  1087. package/toolkit/skills/node_modules/sharp/src/stats.cc +0 -186
  1088. package/toolkit/skills/node_modules/sharp/src/stats.h +0 -62
  1089. package/toolkit/skills/node_modules/sharp/src/utilities.cc +0 -289
  1090. package/toolkit/skills/node_modules/sharp/src/utilities.h +0 -22
@@ -1,4733 +0,0 @@
1
- import { Validator } from "@seriousme/openapi-schema-validator";
2
- import { describe, expect, test, vi } from "vitest";
3
- import * as z from "zod";
4
- // import * as zCore from "zod/v4/core";
5
-
6
- const openAPI30Validator = new Validator();
7
- /** @see https://github.com/colinhacks/zod/issues/5147 */
8
- const validateOpenAPI30Schema = async (zodJSONSchema: Record<string, unknown>): Promise<true> => {
9
- const res = await openAPI30Validator.validate({
10
- openapi: "3.0.0",
11
- info: {
12
- title: "SampleApi",
13
- description: "Sample backend service",
14
- version: "1.0.0",
15
- },
16
- components: { schemas: { test: zodJSONSchema } },
17
- paths: {},
18
- });
19
-
20
- if (!res.valid) {
21
- // `console.error` should make `vitest` trow an unhandled error printing the validation messages in consoles
22
- console.error(
23
- `OpenAPI schema is not valid against ${openAPI30Validator.version}`,
24
- JSON.stringify(res.errors, null, 2)
25
- );
26
- }
27
-
28
- return true;
29
- };
30
-
31
- describe("toJSONSchema", () => {
32
- test("primitive types", () => {
33
- expect(z.toJSONSchema(z.string())).toMatchInlineSnapshot(`
34
- {
35
- "$schema": "https://json-schema.org/draft/2020-12/schema",
36
- "type": "string",
37
- }
38
- `);
39
- expect(z.toJSONSchema(z.number())).toMatchInlineSnapshot(`
40
- {
41
- "$schema": "https://json-schema.org/draft/2020-12/schema",
42
- "type": "number",
43
- }
44
- `);
45
- expect(z.toJSONSchema(z.boolean())).toMatchInlineSnapshot(`
46
- {
47
- "$schema": "https://json-schema.org/draft/2020-12/schema",
48
- "type": "boolean",
49
- }
50
- `);
51
- expect(z.toJSONSchema(z.null())).toMatchInlineSnapshot(`
52
- {
53
- "$schema": "https://json-schema.org/draft/2020-12/schema",
54
- "type": "null",
55
- }
56
- `);
57
- expect(z.toJSONSchema(z.undefined(), { unrepresentable: "any" })).toMatchInlineSnapshot(`
58
- {
59
- "$schema": "https://json-schema.org/draft/2020-12/schema",
60
- }
61
- `);
62
- expect(z.toJSONSchema(z.any())).toMatchInlineSnapshot(`
63
- {
64
- "$schema": "https://json-schema.org/draft/2020-12/schema",
65
- }
66
- `);
67
- expect(z.toJSONSchema(z.unknown())).toMatchInlineSnapshot(`
68
- {
69
- "$schema": "https://json-schema.org/draft/2020-12/schema",
70
- }
71
- `);
72
- expect(z.toJSONSchema(z.never())).toMatchInlineSnapshot(`
73
- {
74
- "$schema": "https://json-schema.org/draft/2020-12/schema",
75
- "not": {},
76
- }
77
- `);
78
- expect(z.toJSONSchema(z.email())).toMatchInlineSnapshot(`
79
- {
80
- "$schema": "https://json-schema.org/draft/2020-12/schema",
81
- "format": "email",
82
- "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
83
- "type": "string",
84
- }
85
- `);
86
- expect(z.toJSONSchema(z.iso.datetime())).toMatchInlineSnapshot(`
87
- {
88
- "$schema": "https://json-schema.org/draft/2020-12/schema",
89
- "format": "date-time",
90
- "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
91
- "type": "string",
92
- }
93
- `);
94
- expect(z.toJSONSchema(z.iso.date())).toMatchInlineSnapshot(`
95
- {
96
- "$schema": "https://json-schema.org/draft/2020-12/schema",
97
- "format": "date",
98
- "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
99
- "type": "string",
100
- }
101
- `);
102
- // only shapes keeping both an offset and seconds may advertise `date-time`, composed onto a string as well as constructed
103
- expect(z.toJSONSchema(z.iso.datetime()).format).toEqual("date-time");
104
- expect(z.toJSONSchema(z.iso.datetime({ offset: true })).format).toEqual("date-time");
105
- expect(z.toJSONSchema(z.iso.datetime({ precision: 0 })).format).toEqual("date-time");
106
- expect(z.toJSONSchema(z.iso.datetime({ local: true })).format).toEqual(undefined);
107
- expect(z.toJSONSchema(z.iso.datetime({ precision: -1 })).format).toEqual(undefined);
108
- expect(z.toJSONSchema(z.string().check(z.iso.datetime({ local: true }))).format).toEqual(undefined);
109
- expect(z.toJSONSchema(z.string().check(z.iso.datetime())).format).toEqual("date-time");
110
- // the pattern still describes what the schema accepts
111
- expect(z.toJSONSchema(z.iso.datetime({ local: true })).pattern).toBeDefined();
112
-
113
- expect(z.toJSONSchema(z.iso.time())).toMatchInlineSnapshot(`
114
- {
115
- "$schema": "https://json-schema.org/draft/2020-12/schema",
116
- "pattern": "^(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?$",
117
- "type": "string",
118
- }
119
- `);
120
- expect(z.toJSONSchema(z.iso.time({ precision: -1 }))).toMatchInlineSnapshot(`
121
- {
122
- "$schema": "https://json-schema.org/draft/2020-12/schema",
123
- "pattern": "^(?:[01]\\d|2[0-3]):[0-5]\\d$",
124
- "type": "string",
125
- }
126
- `);
127
- expect(z.toJSONSchema(z.iso.time({ precision: 0 }))).toMatchInlineSnapshot(`
128
- {
129
- "$schema": "https://json-schema.org/draft/2020-12/schema",
130
- "pattern": "^(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d$",
131
- "type": "string",
132
- }
133
- `);
134
- expect(z.toJSONSchema(z.iso.time({ precision: 3 }))).toMatchInlineSnapshot(`
135
- {
136
- "$schema": "https://json-schema.org/draft/2020-12/schema",
137
- "pattern": "^(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}$",
138
- "type": "string",
139
- }
140
- `);
141
- expect(z.toJSONSchema(z.iso.duration())).toMatchInlineSnapshot(`
142
- {
143
- "$schema": "https://json-schema.org/draft/2020-12/schema",
144
- "format": "duration",
145
- "pattern": "^P(?:(\\d+W)|(?!.*W)(?=\\d|T\\d)(\\d+Y)?(\\d+M)?(\\d+D)?(T(?=\\d)(\\d+H)?(\\d+M)?(\\d+([.,]\\d+)?S)?)?)$",
146
- "type": "string",
147
- }
148
- `);
149
- expect(z.toJSONSchema(z.ipv4())).toMatchInlineSnapshot(`
150
- {
151
- "$schema": "https://json-schema.org/draft/2020-12/schema",
152
- "format": "ipv4",
153
- "pattern": "^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$",
154
- "type": "string",
155
- }
156
- `);
157
- expect(z.toJSONSchema(z.ipv6())).toMatchInlineSnapshot(`
158
- {
159
- "$schema": "https://json-schema.org/draft/2020-12/schema",
160
- "format": "ipv6",
161
- "pattern": "^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$",
162
- "type": "string",
163
- }
164
- `);
165
- expect(z.toJSONSchema(z.mac())).toMatchInlineSnapshot(`
166
- {
167
- "$schema": "https://json-schema.org/draft/2020-12/schema",
168
- "format": "mac",
169
- "pattern": "^(?:[0-9A-F]{2}:){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}:){5}[0-9a-f]{2}$",
170
- "type": "string",
171
- }
172
- `);
173
- expect(z.toJSONSchema(z.mac({ delimiter: ":" }))).toMatchInlineSnapshot(`
174
- {
175
- "$schema": "https://json-schema.org/draft/2020-12/schema",
176
- "format": "mac",
177
- "pattern": "^(?:[0-9A-F]{2}:){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}:){5}[0-9a-f]{2}$",
178
- "type": "string",
179
- }
180
- `);
181
- expect(z.toJSONSchema(z.mac({ delimiter: "-" }))).toMatchInlineSnapshot(`
182
- {
183
- "$schema": "https://json-schema.org/draft/2020-12/schema",
184
- "format": "mac",
185
- "pattern": "^(?:[0-9A-F]{2}-){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}-){5}[0-9a-f]{2}$",
186
- "type": "string",
187
- }
188
- `);
189
- expect(z.toJSONSchema(z.uuid())).toMatchInlineSnapshot(`
190
- {
191
- "$schema": "https://json-schema.org/draft/2020-12/schema",
192
- "format": "uuid",
193
- "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
194
- "type": "string",
195
- }
196
- `);
197
- expect(z.toJSONSchema(z.guid())).toMatchInlineSnapshot(`
198
- {
199
- "$schema": "https://json-schema.org/draft/2020-12/schema",
200
- "format": "uuid",
201
- "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
202
- "type": "string",
203
- }
204
- `);
205
- expect(z.toJSONSchema(z.url())).toMatchInlineSnapshot(`
206
- {
207
- "$schema": "https://json-schema.org/draft/2020-12/schema",
208
- "format": "uri",
209
- "type": "string",
210
- }
211
- `);
212
- expect(z.toJSONSchema(z.base64())).toMatchInlineSnapshot(`
213
- {
214
- "$schema": "https://json-schema.org/draft/2020-12/schema",
215
- "contentEncoding": "base64",
216
- "format": "base64",
217
- "pattern": "^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$",
218
- "type": "string",
219
- }
220
- `);
221
- expect(z.toJSONSchema(z.base64url())).toMatchInlineSnapshot(`
222
- {
223
- "$schema": "https://json-schema.org/draft/2020-12/schema",
224
- "contentEncoding": "base64url",
225
- "format": "base64url",
226
- "pattern": "^(?:[A-Za-z0-9_-]{4})*(?:[A-Za-z0-9_-]{2,3})?$",
227
- "type": "string",
228
- }
229
- `);
230
- expect(z.toJSONSchema(z.cuid())).toMatchInlineSnapshot(`
231
- {
232
- "$schema": "https://json-schema.org/draft/2020-12/schema",
233
- "format": "cuid",
234
- "pattern": "^[cC][0-9a-z]{6,}$",
235
- "type": "string",
236
- }
237
- `);
238
- // expect(z.toJSONSchema(z.regex(/asdf/))).toMatchInlineSnapshot();
239
- expect(z.toJSONSchema(z.emoji())).toMatchInlineSnapshot(`
240
- {
241
- "$schema": "https://json-schema.org/draft/2020-12/schema",
242
- "format": "emoji",
243
- "pattern": "^(?=[\\s\\S]*[\\p{Extended_Pictographic}\\p{Regional_Indicator}\\u20E3])[\\p{Extended_Pictographic}\\p{Emoji_Component}]+$",
244
- "type": "string",
245
- }
246
- `);
247
- expect(z.toJSONSchema(z.nanoid())).toMatchInlineSnapshot(`
248
- {
249
- "$schema": "https://json-schema.org/draft/2020-12/schema",
250
- "format": "nanoid",
251
- "pattern": "^[a-zA-Z0-9_-]{21}$",
252
- "type": "string",
253
- }
254
- `);
255
- expect(z.toJSONSchema(z.nanoid({ length: 64 }))).toMatchInlineSnapshot(`
256
- {
257
- "$schema": "https://json-schema.org/draft/2020-12/schema",
258
- "format": "nanoid",
259
- "pattern": "^[a-zA-Z0-9_-]{64}$",
260
- "type": "string",
261
- }
262
- `);
263
- expect(z.toJSONSchema(z.cuid2())).toMatchInlineSnapshot(`
264
- {
265
- "$schema": "https://json-schema.org/draft/2020-12/schema",
266
- "format": "cuid2",
267
- "pattern": "^[0-9a-z]+$",
268
- "type": "string",
269
- }
270
- `);
271
- expect(z.toJSONSchema(z.ulid())).toMatchInlineSnapshot(`
272
- {
273
- "$schema": "https://json-schema.org/draft/2020-12/schema",
274
- "format": "ulid",
275
- "pattern": "^[0-7][0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{25}$",
276
- "type": "string",
277
- }
278
- `);
279
- // expect(z.toJSONSchema(z.cidr())).toMatchInlineSnapshot();
280
- expect(z.toJSONSchema(z.number())).toMatchInlineSnapshot(`
281
- {
282
- "$schema": "https://json-schema.org/draft/2020-12/schema",
283
- "type": "number",
284
- }
285
- `);
286
- expect(z.toJSONSchema(z.int())).toMatchInlineSnapshot(`
287
- {
288
- "$schema": "https://json-schema.org/draft/2020-12/schema",
289
- "maximum": 9007199254740991,
290
- "minimum": -9007199254740991,
291
- "type": "integer",
292
- }
293
- `);
294
- expect(z.toJSONSchema(z.int32())).toMatchInlineSnapshot(`
295
- {
296
- "$schema": "https://json-schema.org/draft/2020-12/schema",
297
- "maximum": 2147483647,
298
- "minimum": -2147483648,
299
- "type": "integer",
300
- }
301
- `);
302
- expect(z.toJSONSchema(z.float32())).toMatchInlineSnapshot(`
303
- {
304
- "$schema": "https://json-schema.org/draft/2020-12/schema",
305
- "maximum": 3.4028234663852886e+38,
306
- "minimum": -3.4028234663852886e+38,
307
- "type": "number",
308
- }
309
- `);
310
- expect(z.toJSONSchema(z.float64())).toMatchInlineSnapshot(`
311
- {
312
- "$schema": "https://json-schema.org/draft/2020-12/schema",
313
- "maximum": 1.7976931348623157e+308,
314
- "minimum": -1.7976931348623157e+308,
315
- "type": "number",
316
- }
317
- `);
318
- expect(z.toJSONSchema(z.jwt())).toMatchInlineSnapshot(`
319
- {
320
- "$schema": "https://json-schema.org/draft/2020-12/schema",
321
- "format": "jwt",
322
- "type": "string",
323
- }
324
- `);
325
- });
326
-
327
- test("unsupported schema types", () => {
328
- expect(() => z.toJSONSchema(z.bigint())).toThrow("BigInt cannot be represented in JSON Schema");
329
- expect(() => z.toJSONSchema(z.int64())).toThrow("BigInt cannot be represented in JSON Schema");
330
- expect(() => z.toJSONSchema(z.symbol())).toThrow("Symbols cannot be represented in JSON Schema");
331
- expect(() => z.toJSONSchema(z.void())).toThrow("Void cannot be represented in JSON Schema");
332
- expect(() => z.toJSONSchema(z.undefined())).toThrow("Undefined cannot be represented in JSON Schema");
333
- expect(() => z.toJSONSchema(z.date())).toThrow("Date cannot be represented in JSON Schema");
334
- expect(() => z.toJSONSchema(z.map(z.string(), z.number()))).toThrow("Map cannot be represented in JSON Schema");
335
- expect(() => z.toJSONSchema(z.set(z.string()))).toThrow("Set cannot be represented in JSON Schema");
336
- expect(() => z.toJSONSchema(z.custom(() => true))).toThrow("Custom types cannot be represented in JSON Schema");
337
-
338
- // Transform
339
- const transformSchema = z.string().transform((val) => Number.parseInt(val));
340
- expect(() => z.toJSONSchema(transformSchema)).toThrow("Transforms cannot be represented in JSON Schema");
341
-
342
- // Static catch values
343
- const staticCatchSchema = z.string().catch(() => "sup");
344
- expect(z.toJSONSchema(staticCatchSchema)).toMatchInlineSnapshot(`
345
- {
346
- "$schema": "https://json-schema.org/draft/2020-12/schema",
347
- "default": "sup",
348
- "type": "string",
349
- }
350
- `);
351
-
352
- // Dynamic catch values
353
- const dynamicCatchSchema = z.string().catch((ctx) => `${ctx.issues.length}`);
354
- expect(() => z.toJSONSchema(dynamicCatchSchema)).toThrow("Dynamic catch values are not supported in JSON Schema");
355
- expect(z.toJSONSchema(dynamicCatchSchema, { unrepresentable: "any" })).toMatchInlineSnapshot(`
356
- {
357
- "$schema": "https://json-schema.org/draft/2020-12/schema",
358
- "type": "string",
359
- }
360
- `);
361
- });
362
-
363
- test("string formats", () => {
364
- expect(z.toJSONSchema(z.string().email())).toMatchInlineSnapshot(`
365
- {
366
- "$schema": "https://json-schema.org/draft/2020-12/schema",
367
- "format": "email",
368
- "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
369
- "type": "string",
370
- }
371
- `);
372
- expect(z.toJSONSchema(z.string().uuid())).toMatchInlineSnapshot(`
373
- {
374
- "$schema": "https://json-schema.org/draft/2020-12/schema",
375
- "format": "uuid",
376
- "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
377
- "type": "string",
378
- }
379
- `);
380
- expect(z.toJSONSchema(z.iso.datetime())).toMatchInlineSnapshot(`
381
- {
382
- "$schema": "https://json-schema.org/draft/2020-12/schema",
383
- "format": "date-time",
384
- "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
385
- "type": "string",
386
- }
387
- `);
388
-
389
- expect(z.toJSONSchema(z.iso.date())).toMatchInlineSnapshot(`
390
- {
391
- "$schema": "https://json-schema.org/draft/2020-12/schema",
392
- "format": "date",
393
- "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
394
- "type": "string",
395
- }
396
- `);
397
- expect(z.toJSONSchema(z.iso.time())).toMatchInlineSnapshot(`
398
- {
399
- "$schema": "https://json-schema.org/draft/2020-12/schema",
400
- "pattern": "^(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?$",
401
- "type": "string",
402
- }
403
- `);
404
- expect(z.toJSONSchema(z.iso.duration())).toMatchInlineSnapshot(`
405
- {
406
- "$schema": "https://json-schema.org/draft/2020-12/schema",
407
- "format": "duration",
408
- "pattern": "^P(?:(\\d+W)|(?!.*W)(?=\\d|T\\d)(\\d+Y)?(\\d+M)?(\\d+D)?(T(?=\\d)(\\d+H)?(\\d+M)?(\\d+([.,]\\d+)?S)?)?)$",
409
- "type": "string",
410
- }
411
- `);
412
- // expect(z.toJSONSchema(z.string().ip())).toMatchInlineSnapshot(`
413
- // {
414
- // "pattern": /\\(\\^\\(\\?:\\(\\?:25\\[0-5\\]\\|2\\[0-4\\]\\[0-9\\]\\|1\\[0-9\\]\\[0-9\\]\\|\\[1-9\\]\\[0-9\\]\\|\\[0-9\\]\\)\\\\\\.\\)\\{3\\}\\(\\?:25\\[0-5\\]\\|2\\[0-4\\]\\[0-9\\]\\|1\\[0-9\\]\\[0-9\\]\\|\\[1-9\\]\\[0-9\\]\\|\\[0-9\\]\\)\\$\\)\\|\\(\\^\\(\\(\\[a-fA-F0-9\\]\\{1,4\\}:\\)\\{7\\}\\|::\\(\\[a-fA-F0-9\\]\\{1,4\\}:\\)\\{0,6\\}\\|\\(\\[a-fA-F0-9\\]\\{1,4\\}:\\)\\{1\\}:\\(\\[a-fA-F0-9\\]\\{1,4\\}:\\)\\{0,5\\}\\|\\(\\[a-fA-F0-9\\]\\{1,4\\}:\\)\\{2\\}:\\(\\[a-fA-F0-9\\]\\{1,4\\}:\\)\\{0,4\\}\\|\\(\\[a-fA-F0-9\\]\\{1,4\\}:\\)\\{3\\}:\\(\\[a-fA-F0-9\\]\\{1,4\\}:\\)\\{0,3\\}\\|\\(\\[a-fA-F0-9\\]\\{1,4\\}:\\)\\{4\\}:\\(\\[a-fA-F0-9\\]\\{1,4\\}:\\)\\{0,2\\}\\|\\(\\[a-fA-F0-9\\]\\{1,4\\}:\\)\\{5\\}:\\(\\[a-fA-F0-9\\]\\{1,4\\}:\\)\\{0,1\\}\\)\\(\\[a-fA-F0-9\\]\\{1,4\\}\\|\\(\\(\\(25\\[0-5\\]\\)\\|\\(2\\[0-4\\]\\[0-9\\]\\)\\|\\(1\\[0-9\\]\\{2\\}\\)\\|\\(\\[0-9\\]\\{1,2\\}\\)\\)\\\\\\.\\)\\{3\\}\\(\\(25\\[0-5\\]\\)\\|\\(2\\[0-4\\]\\[0-9\\]\\)\\|\\(1\\[0-9\\]\\{2\\}\\)\\|\\(\\[0-9\\]\\{1,2\\}\\)\\)\\)\\$\\)/,
415
- // "type": "string",
416
- // }
417
- // `);
418
- expect(z.toJSONSchema(z.ipv4())).toMatchInlineSnapshot(`
419
- {
420
- "$schema": "https://json-schema.org/draft/2020-12/schema",
421
- "format": "ipv4",
422
- "pattern": "^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$",
423
- "type": "string",
424
- }
425
- `);
426
-
427
- expect(z.toJSONSchema(z.ipv6())).toMatchInlineSnapshot(`
428
- {
429
- "$schema": "https://json-schema.org/draft/2020-12/schema",
430
- "format": "ipv6",
431
- "pattern": "^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$",
432
- "type": "string",
433
- }
434
- `);
435
-
436
- expect(z.toJSONSchema(z.mac())).toMatchInlineSnapshot(`
437
- {
438
- "$schema": "https://json-schema.org/draft/2020-12/schema",
439
- "format": "mac",
440
- "pattern": "^(?:[0-9A-F]{2}:){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}:){5}[0-9a-f]{2}$",
441
- "type": "string",
442
- }
443
- `);
444
- expect(z.toJSONSchema(z.mac({ delimiter: ":" }))).toMatchInlineSnapshot(`
445
- {
446
- "$schema": "https://json-schema.org/draft/2020-12/schema",
447
- "format": "mac",
448
- "pattern": "^(?:[0-9A-F]{2}:){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}:){5}[0-9a-f]{2}$",
449
- "type": "string",
450
- }
451
- `);
452
- expect(z.toJSONSchema(z.mac({ delimiter: "-" }))).toMatchInlineSnapshot(`
453
- {
454
- "$schema": "https://json-schema.org/draft/2020-12/schema",
455
- "format": "mac",
456
- "pattern": "^(?:[0-9A-F]{2}-){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}-){5}[0-9a-f]{2}$",
457
- "type": "string",
458
- }
459
- `);
460
-
461
- expect(z.toJSONSchema(z.base64())).toMatchInlineSnapshot(`
462
- {
463
- "$schema": "https://json-schema.org/draft/2020-12/schema",
464
- "contentEncoding": "base64",
465
- "format": "base64",
466
- "pattern": "^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$",
467
- "type": "string",
468
- }
469
- `);
470
- expect(z.toJSONSchema(z.url())).toMatchInlineSnapshot(`
471
- {
472
- "$schema": "https://json-schema.org/draft/2020-12/schema",
473
- "format": "uri",
474
- "type": "string",
475
- }
476
- `);
477
- expect(z.toJSONSchema(z.guid())).toMatchInlineSnapshot(`
478
- {
479
- "$schema": "https://json-schema.org/draft/2020-12/schema",
480
- "format": "uuid",
481
- "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
482
- "type": "string",
483
- }
484
- `);
485
- expect(z.toJSONSchema(z.string().regex(/asdf/))).toMatchInlineSnapshot(`
486
- {
487
- "$schema": "https://json-schema.org/draft/2020-12/schema",
488
- "pattern": "asdf",
489
- "type": "string",
490
- }
491
- `);
492
- });
493
-
494
- test("base64url pattern agrees with parse", () => {
495
- const schema = z.base64url();
496
- const pattern = new RegExp(z.toJSONSchema(schema).pattern!);
497
- // lengths 1 (mod 4) carry no whole byte; the emitted pattern must reject them like parse does
498
- for (const s of ["", "A", "AA", "AAA", "AAAA", "AAAAA"]) {
499
- expect(pattern.test(s)).toBe(schema.safeParse(s).success);
500
- }
501
- });
502
-
503
- test("base64 pattern agrees with parse", () => {
504
- const schema = z.base64();
505
- const pattern = new RegExp(z.toJSONSchema(schema).pattern!);
506
- // the runtime def.pattern is lax; the emitted pattern must still carry the block structure parse enforces
507
- for (const s of ["", "A", "AA", "AAA", "AAAA", "AAAAA", "AA==", "AAA=", "A===", "=", "AAAA=="]) {
508
- expect(pattern.test(s)).toBe(schema.safeParse(s).success);
509
- }
510
- });
511
-
512
- test("looseRecord with a format key emits the exact pattern", () => {
513
- // recordProcessor reads bag.patterns directly; it must apply the same lax-to-exact swap as stringProcessor
514
- const json = z.toJSONSchema(z.looseRecord(z.base64url(), z.number()));
515
- expect(Object.keys(json.patternProperties!)).toEqual([z.regexes.base64url.source]);
516
- });
517
-
518
- test("string patterns", () => {
519
- expect(
520
- z.toJSONSchema(
521
- z
522
- .string()
523
- .startsWith("hello")
524
- .includes("cruel")
525
- .includes("dark", { position: 10 })
526
- .endsWith("world")
527
- .regex(/stuff/)
528
- )
529
- ).toMatchInlineSnapshot(`
530
- {
531
- "$schema": "https://json-schema.org/draft/2020-12/schema",
532
- "allOf": [
533
- {
534
- "pattern": "^hello.*",
535
- },
536
- {
537
- "pattern": "cruel",
538
- },
539
- {
540
- "pattern": "^.{10,}dark",
541
- },
542
- {
543
- "pattern": ".*world$",
544
- },
545
- {
546
- "pattern": "stuff",
547
- },
548
- ],
549
- "type": "string",
550
- }
551
- `);
552
-
553
- expect(
554
- z.toJSONSchema(
555
- z
556
- .string()
557
- .startsWith("hello")
558
- .includes("cruel")
559
- .includes("dark", { position: 10 })
560
- .endsWith("world")
561
- .regex(/stuff/),
562
- {
563
- target: "draft-7",
564
- }
565
- )
566
- ).toMatchInlineSnapshot(`
567
- {
568
- "$schema": "http://json-schema.org/draft-07/schema#",
569
- "allOf": [
570
- {
571
- "pattern": "^hello.*",
572
- "type": "string",
573
- },
574
- {
575
- "pattern": "cruel",
576
- "type": "string",
577
- },
578
- {
579
- "pattern": "^.{10,}dark",
580
- "type": "string",
581
- },
582
- {
583
- "pattern": ".*world$",
584
- "type": "string",
585
- },
586
- {
587
- "pattern": "stuff",
588
- "type": "string",
589
- },
590
- ],
591
- "type": "string",
592
- }
593
- `);
594
- });
595
-
596
- test("includes with position emits a pattern matching runtime semantics", () => {
597
- // String.prototype.includes(sub, position) matches `sub` at `position` OR
598
- // LATER, so the JSON Schema pattern must allow >= position leading chars.
599
- const schema = z.string().includes("foo", { position: 2 });
600
- const json = z.toJSONSchema(schema) as { pattern?: string };
601
- expect(json.pattern).toBe("^.{2,}foo");
602
-
603
- const re = new RegExp(json.pattern!);
604
- for (const input of ["xxfoo", "xxxfoo", "xfoo", "ab"]) {
605
- expect(re.test(input)).toBe(schema.safeParse(input).success);
606
- }
607
- });
608
-
609
- test("number constraints", () => {
610
- expect(z.toJSONSchema(z.number().min(5).max(10))).toMatchInlineSnapshot(
611
- `
612
- {
613
- "$schema": "https://json-schema.org/draft/2020-12/schema",
614
- "maximum": 10,
615
- "minimum": 5,
616
- "type": "number",
617
- }
618
- `
619
- );
620
-
621
- expect(z.toJSONSchema(z.number().gt(5).gt(10))).toMatchInlineSnapshot(`
622
- {
623
- "$schema": "https://json-schema.org/draft/2020-12/schema",
624
- "exclusiveMinimum": 10,
625
- "type": "number",
626
- }
627
- `);
628
-
629
- expect(z.toJSONSchema(z.number().gt(5).gte(10))).toMatchInlineSnapshot(`
630
- {
631
- "$schema": "https://json-schema.org/draft/2020-12/schema",
632
- "minimum": 10,
633
- "type": "number",
634
- }
635
- `);
636
-
637
- expect(z.toJSONSchema(z.number().lt(5).lt(3))).toMatchInlineSnapshot(`
638
- {
639
- "$schema": "https://json-schema.org/draft/2020-12/schema",
640
- "exclusiveMaximum": 3,
641
- "type": "number",
642
- }
643
- `);
644
-
645
- expect(z.toJSONSchema(z.number().lt(5).lt(3).lte(2))).toMatchInlineSnapshot(`
646
- {
647
- "$schema": "https://json-schema.org/draft/2020-12/schema",
648
- "maximum": 2,
649
- "type": "number",
650
- }
651
- `);
652
-
653
- expect(z.toJSONSchema(z.number().lt(5).lte(3))).toMatchInlineSnapshot(`
654
- {
655
- "$schema": "https://json-schema.org/draft/2020-12/schema",
656
- "maximum": 3,
657
- "type": "number",
658
- }
659
- `);
660
-
661
- expect(z.toJSONSchema(z.number().gt(5).lt(10))).toMatchInlineSnapshot(`
662
- {
663
- "$schema": "https://json-schema.org/draft/2020-12/schema",
664
- "exclusiveMaximum": 10,
665
- "exclusiveMinimum": 5,
666
- "type": "number",
667
- }
668
- `);
669
- expect(z.toJSONSchema(z.number().gte(5).lte(10))).toMatchInlineSnapshot(`
670
- {
671
- "$schema": "https://json-schema.org/draft/2020-12/schema",
672
- "maximum": 10,
673
- "minimum": 5,
674
- "type": "number",
675
- }
676
- `);
677
- expect(z.toJSONSchema(z.number().positive())).toMatchInlineSnapshot(`
678
- {
679
- "$schema": "https://json-schema.org/draft/2020-12/schema",
680
- "exclusiveMinimum": 0,
681
- "type": "number",
682
- }
683
- `);
684
- expect(z.toJSONSchema(z.number().negative())).toMatchInlineSnapshot(`
685
- {
686
- "$schema": "https://json-schema.org/draft/2020-12/schema",
687
- "exclusiveMaximum": 0,
688
- "type": "number",
689
- }
690
- `);
691
- expect(z.toJSONSchema(z.number().nonpositive())).toMatchInlineSnapshot(`
692
- {
693
- "$schema": "https://json-schema.org/draft/2020-12/schema",
694
- "maximum": 0,
695
- "type": "number",
696
- }
697
- `);
698
- expect(z.toJSONSchema(z.number().nonnegative())).toMatchInlineSnapshot(`
699
- {
700
- "$schema": "https://json-schema.org/draft/2020-12/schema",
701
- "minimum": 0,
702
- "type": "number",
703
- }
704
- `);
705
- });
706
-
707
- test("number constraints draft-4", () => {
708
- expect(z.toJSONSchema(z.number().gt(5).lt(10), { target: "draft-4" })).toMatchInlineSnapshot(`
709
- {
710
- "$schema": "http://json-schema.org/draft-04/schema#",
711
- "exclusiveMaximum": true,
712
- "exclusiveMinimum": true,
713
- "maximum": 10,
714
- "minimum": 5,
715
- "type": "number",
716
- }
717
- `);
718
- });
719
-
720
- test("number constraints intersection draft-04", () => {
721
- // When both minimum (from .int()) and exclusiveMinimum (from .positive()) exist, the more restrictive constraint should be used
722
- expect(z.toJSONSchema(z.number().int().positive().lte(65535), { target: "draft-04" })).toMatchInlineSnapshot(`
723
- {
724
- "$schema": "http://json-schema.org/draft-04/schema#",
725
- "exclusiveMinimum": true,
726
- "maximum": 65535,
727
- "minimum": 0,
728
- "type": "integer",
729
- }
730
- `);
731
- // Same for openapi-3.0
732
- expect(z.toJSONSchema(z.number().int().positive().lte(65535), { target: "openapi-3.0" })).toMatchInlineSnapshot(`
733
- {
734
- "exclusiveMinimum": true,
735
- "maximum": 65535,
736
- "minimum": 0,
737
- "type": "integer",
738
- }
739
- `);
740
- // When inclusive minimum is more restrictive than exclusive minimum
741
- expect(z.toJSONSchema(z.number().gt(3).gte(10), { target: "draft-04" })).toMatchInlineSnapshot(`
742
- {
743
- "$schema": "http://json-schema.org/draft-04/schema#",
744
- "minimum": 10,
745
- "type": "number",
746
- }
747
- `);
748
- // Same logic for maximum constraints
749
- expect(z.toJSONSchema(z.number().int().negative(), { target: "draft-04" })).toMatchInlineSnapshot(`
750
- {
751
- "$schema": "http://json-schema.org/draft-04/schema#",
752
- "exclusiveMaximum": true,
753
- "maximum": 0,
754
- "minimum": -9007199254740991,
755
- "type": "integer",
756
- }
757
- `);
758
- });
759
-
760
- test("number constraints order independence with int()", () => {
761
- // .int() applied last should not overwrite the tighter bounds .min()/.max() already stored
762
- expect(z.toJSONSchema(z.number().int().min(0).max(23))).toMatchInlineSnapshot(`
763
- {
764
- "$schema": "https://json-schema.org/draft/2020-12/schema",
765
- "maximum": 23,
766
- "minimum": 0,
767
- "type": "integer",
768
- }
769
- `);
770
- expect(z.toJSONSchema(z.number().min(0).max(23).int())).toMatchInlineSnapshot(`
771
- {
772
- "$schema": "https://json-schema.org/draft/2020-12/schema",
773
- "maximum": 23,
774
- "minimum": 0,
775
- "type": "integer",
776
- }
777
- `);
778
- });
779
-
780
- test("chained multipleOf divisors emit the whole conjunction", () => {
781
- // runtime rejects 4 (not a multiple of 3), so the emitted schema must too
782
- expect(z.toJSONSchema(z.number().multipleOf(2).multipleOf(3))).toMatchInlineSnapshot(`
783
- {
784
- "$schema": "https://json-schema.org/draft/2020-12/schema",
785
- "allOf": [
786
- {
787
- "multipleOf": 3,
788
- },
789
- ],
790
- "multipleOf": 2,
791
- "type": "number",
792
- }
793
- `);
794
- });
795
-
796
- test("length() does not overwrite a tighter earlier bound", () => {
797
- // min(8) + length(5) matches nothing at runtime; the emitted bounds stay honest about that
798
- expect(z.toJSONSchema(z.string().min(8).length(5))).toMatchInlineSnapshot(`
799
- {
800
- "$schema": "https://json-schema.org/draft/2020-12/schema",
801
- "maxLength": 5,
802
- "minLength": 8,
803
- "type": "string",
804
- }
805
- `);
806
- });
807
-
808
- test("an integer format keeps the emitted type integer whatever format lands last", () => {
809
- // runtime rejects 1.5 in both orders, so both must emit type integer
810
- const after = z.number().int().check(z.float32());
811
- expect(after.safeParse(1.5).success).toBe(false);
812
- expect(z.toJSONSchema(after).type).toBe("integer");
813
- expect(z.toJSONSchema(z.number().check(z.float32()).int()).type).toBe("integer");
814
- });
815
-
816
- test("disjoint mime checks emit a false schema, not an unconstrained file", () => {
817
- const file = z.file().mime("image/png").mime("text/plain");
818
- expect(z.toJSONSchema(file)).toMatchInlineSnapshot(`
819
- {
820
- "$schema": "https://json-schema.org/draft/2020-12/schema",
821
- "contentEncoding": "binary",
822
- "format": "binary",
823
- "not": {},
824
- "type": "string",
825
- }
826
- `);
827
- });
828
-
829
- test("a custom mime narrowing via onattach intersects with built-in mime checks", () => {
830
- const check = {
831
- _zod: {
832
- def: { check: "custom_mime" },
833
- onattach: [
834
- (inst: any) => {
835
- inst._zod.bag.mime = ["text/plain"];
836
- },
837
- ],
838
- check: () => {},
839
- },
840
- };
841
- const file = z
842
- .file()
843
- .mime(["image/png", "text/plain"])
844
- .check(check as any);
845
- expect(z.toJSONSchema(file).contentMediaType).toBe("text/plain");
846
- });
847
-
848
- test("a custom check contributing via onattach still lands", () => {
849
- // third-party checks have no converter handler; their bag writes are merged in as a fallback
850
- const check = {
851
- _zod: {
852
- def: { check: "custom_range" },
853
- onattach: [
854
- (inst: any) => {
855
- const bag = inst._zod.bag;
856
- if (bag.minimum === undefined || 5 > bag.minimum) bag.minimum = 5;
857
- },
858
- ],
859
- check: () => {},
860
- },
861
- };
862
- expect(z.toJSONSchema(z.number().check(check as any))).toMatchInlineSnapshot(`
863
- {
864
- "$schema": "https://json-schema.org/draft/2020-12/schema",
865
- "minimum": 5,
866
- "type": "number",
867
- }
868
- `);
869
- });
870
-
871
- test("target normalization draft-04 and draft-07", () => {
872
- // Test that both old (draft-4, draft-7) and new (draft-04, draft-07) target formats work
873
-
874
- // Test draft-04 / draft-4
875
- expect(z.toJSONSchema(z.number().gt(5), { target: "draft-04" })).toMatchInlineSnapshot(`
876
- {
877
- "$schema": "http://json-schema.org/draft-04/schema#",
878
- "exclusiveMinimum": true,
879
- "minimum": 5,
880
- "type": "number",
881
- }
882
- `);
883
- expect(z.toJSONSchema(z.number().gt(5), { target: "draft-4" })).toMatchInlineSnapshot(`
884
- {
885
- "$schema": "http://json-schema.org/draft-04/schema#",
886
- "exclusiveMinimum": true,
887
- "minimum": 5,
888
- "type": "number",
889
- }
890
- `);
891
- // Test draft-07 / draft-7
892
- expect(z.toJSONSchema(z.number().gt(5), { target: "draft-07" })).toMatchInlineSnapshot(`
893
- {
894
- "$schema": "http://json-schema.org/draft-07/schema#",
895
- "exclusiveMinimum": 5,
896
- "type": "number",
897
- }
898
- `);
899
- expect(z.toJSONSchema(z.number().gt(5), { target: "draft-7" })).toMatchInlineSnapshot(`
900
- {
901
- "$schema": "http://json-schema.org/draft-07/schema#",
902
- "exclusiveMinimum": 5,
903
- "type": "number",
904
- }
905
- `);
906
- });
907
-
908
- test("nullable openapi-3.0", () => {
909
- const schema = z.string().nullable();
910
- const jsonSchema = z.toJSONSchema(schema, { target: "openapi-3.0" });
911
- validateOpenAPI30Schema(jsonSchema);
912
- expect(jsonSchema).toMatchInlineSnapshot(`
913
- {
914
- "nullable": true,
915
- "type": "string",
916
- }
917
- `);
918
- });
919
-
920
- test("union with null openapi-3.0", () => {
921
- const schema = z.union([z.string(), z.null()]);
922
- const jsonSchema = z.toJSONSchema(schema, { target: "openapi-3.0" });
923
- validateOpenAPI30Schema(jsonSchema);
924
- expect(jsonSchema).toMatchInlineSnapshot(`
925
- {
926
- "anyOf": [
927
- {
928
- "type": "string",
929
- },
930
- {
931
- "enum": [
932
- null,
933
- ],
934
- "nullable": true,
935
- "type": "string",
936
- },
937
- ],
938
- }
939
- `);
940
- });
941
-
942
- test("number with exclusive min-max openapi-3.0", () => {
943
- const schema = z.number().lt(100).gt(1);
944
- const jsonSchema = z.toJSONSchema(schema, { target: "openapi-3.0" });
945
- validateOpenAPI30Schema(jsonSchema);
946
- expect(jsonSchema).toMatchInlineSnapshot(`
947
- {
948
- "exclusiveMaximum": true,
949
- "exclusiveMinimum": true,
950
- "maximum": 100,
951
- "minimum": 1,
952
- "type": "number",
953
- }
954
- `);
955
- });
956
-
957
- test("arrays", () => {
958
- expect(z.toJSONSchema(z.array(z.string()))).toMatchInlineSnapshot(`
959
- {
960
- "$schema": "https://json-schema.org/draft/2020-12/schema",
961
- "items": {
962
- "type": "string",
963
- },
964
- "type": "array",
965
- }
966
- `);
967
- });
968
-
969
- test("unions", () => {
970
- const schema = z.union([z.string(), z.number()]);
971
- expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
972
- {
973
- "$schema": "https://json-schema.org/draft/2020-12/schema",
974
- "type": [
975
- "string",
976
- "number",
977
- ],
978
- }
979
- `);
980
- });
981
-
982
- test("nullable compacts to a type array", () => {
983
- expect(z.toJSONSchema(z.string().nullable())).toMatchInlineSnapshot(`
984
- {
985
- "$schema": "https://json-schema.org/draft/2020-12/schema",
986
- "type": [
987
- "string",
988
- "null",
989
- ],
990
- }
991
- `);
992
-
993
- // a nested union folds into the outer type array rather than leaving a mixed shape
994
- expect(z.toJSONSchema(z.union([z.string(), z.number()]).nullable())).toMatchInlineSnapshot(`
995
- {
996
- "$schema": "https://json-schema.org/draft/2020-12/schema",
997
- "type": [
998
- "string",
999
- "number",
1000
- "null",
1001
- ],
1002
- }
1003
- `);
1004
-
1005
- // the null branch is bare but the object branch is not, so this stays an anyOf
1006
- expect(z.toJSONSchema(z.object({ a: z.string() }).nullable())).toMatchInlineSnapshot(`
1007
- {
1008
- "$schema": "https://json-schema.org/draft/2020-12/schema",
1009
- "anyOf": [
1010
- {
1011
- "additionalProperties": false,
1012
- "properties": {
1013
- "a": {
1014
- "type": "string",
1015
- },
1016
- },
1017
- "required": [
1018
- "a",
1019
- ],
1020
- "type": "object",
1021
- },
1022
- {
1023
- "type": "null",
1024
- },
1025
- ],
1026
- }
1027
- `);
1028
- });
1029
-
1030
- test("duplicate branches dedupe, single branch stays a bare type", () => {
1031
- // a `type` array must have unique members, so two branches that erase to the same bare type collapse
1032
- const refined = z.union([z.string().refine((s) => s.length > 2), z.string().refine((s) => s.length < 9)]);
1033
- expect(z.toJSONSchema(refined)).toMatchInlineSnapshot(`
1034
- {
1035
- "$schema": "https://json-schema.org/draft/2020-12/schema",
1036
- "type": "string",
1037
- }
1038
- `);
1039
- expect(z.toJSONSchema(z.union([z.string()]))).toMatchInlineSnapshot(`
1040
- {
1041
- "$schema": "https://json-schema.org/draft/2020-12/schema",
1042
- "type": "string",
1043
- }
1044
- `);
1045
- });
1046
-
1047
- test("compaction runs after overrides and ref extraction", () => {
1048
- // an override decorates the string branch, so it is no longer a bare type and must survive in anyOf
1049
- const decorated = z.toJSONSchema(z.union([z.string(), z.number()]), {
1050
- override(ctx) {
1051
- if (ctx.zodSchema._zod.def.type === "string") ctx.jsonSchema.whatever = "sup";
1052
- },
1053
- });
1054
- expect(decorated).toMatchInlineSnapshot(`
1055
- {
1056
- "$schema": "https://json-schema.org/draft/2020-12/schema",
1057
- "anyOf": [
1058
- {
1059
- "type": "string",
1060
- "whatever": "sup",
1061
- },
1062
- {
1063
- "type": "number",
1064
- },
1065
- ],
1066
- }
1067
- `);
1068
-
1069
- // a branch extracted into $defs is a $ref, not a bare type, so `reused` is not silently bypassed
1070
- const shared = z.string();
1071
- expect(
1072
- z.toJSONSchema(z.object({ a: shared, b: z.union([shared, z.null()]) }), { reused: "ref" })
1073
- ).toMatchInlineSnapshot(`
1074
- {
1075
- "$defs": {
1076
- "__schema0": {
1077
- "type": "string",
1078
- },
1079
- },
1080
- "$schema": "https://json-schema.org/draft/2020-12/schema",
1081
- "additionalProperties": false,
1082
- "properties": {
1083
- "a": {
1084
- "$ref": "#/$defs/__schema0",
1085
- },
1086
- "b": {
1087
- "anyOf": [
1088
- {
1089
- "$ref": "#/$defs/__schema0",
1090
- },
1091
- {
1092
- "type": "null",
1093
- },
1094
- ],
1095
- },
1096
- },
1097
- "required": [
1098
- "a",
1099
- "b",
1100
- ],
1101
- "type": "object",
1102
- }
1103
- `);
1104
- });
1105
-
1106
- test("openapi-3.0 keeps a single-string type", () => {
1107
- // OpenAPI 3.0 has no type arrays; nullability is spelled with `nullable`
1108
- expect(z.toJSONSchema(z.string().nullable(), { target: "openapi-3.0" })).toMatchInlineSnapshot(`
1109
- {
1110
- "nullable": true,
1111
- "type": "string",
1112
- }
1113
- `);
1114
- });
1115
-
1116
- test("union with constrained branch is not compacted", () => {
1117
- const schema = z.union([z.string().min(1), z.number()]);
1118
- expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
1119
- {
1120
- "$schema": "https://json-schema.org/draft/2020-12/schema",
1121
- "anyOf": [
1122
- {
1123
- "minLength": 1,
1124
- "type": "string",
1125
- },
1126
- {
1127
- "type": "number",
1128
- },
1129
- ],
1130
- }
1131
- `);
1132
- });
1133
-
1134
- test("union of literals is not compacted", () => {
1135
- const schema = z.union([z.literal("a"), z.literal("b")]);
1136
- expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
1137
- {
1138
- "$schema": "https://json-schema.org/draft/2020-12/schema",
1139
- "anyOf": [
1140
- {
1141
- "const": "a",
1142
- "type": "string",
1143
- },
1144
- {
1145
- "const": "b",
1146
- "type": "string",
1147
- },
1148
- ],
1149
- }
1150
- `);
1151
- });
1152
-
1153
- test("discriminated unions", () => {
1154
- const schema = z.discriminatedUnion("type", [
1155
- z.object({ type: z.literal("success"), data: z.string() }),
1156
- z.object({ type: z.literal("error"), message: z.string() }),
1157
- ]);
1158
- expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
1159
- {
1160
- "$schema": "https://json-schema.org/draft/2020-12/schema",
1161
- "oneOf": [
1162
- {
1163
- "additionalProperties": false,
1164
- "properties": {
1165
- "data": {
1166
- "type": "string",
1167
- },
1168
- "type": {
1169
- "const": "success",
1170
- "type": "string",
1171
- },
1172
- },
1173
- "required": [
1174
- "type",
1175
- "data",
1176
- ],
1177
- "type": "object",
1178
- },
1179
- {
1180
- "additionalProperties": false,
1181
- "properties": {
1182
- "message": {
1183
- "type": "string",
1184
- },
1185
- "type": {
1186
- "const": "error",
1187
- "type": "string",
1188
- },
1189
- },
1190
- "required": [
1191
- "type",
1192
- "message",
1193
- ],
1194
- "type": "object",
1195
- },
1196
- ],
1197
- }
1198
- `);
1199
- });
1200
-
1201
- test("intersections", () => {
1202
- const schema = z.intersection(z.object({ name: z.string() }), z.object({ age: z.number() }));
1203
-
1204
- expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
1205
- {
1206
- "$schema": "https://json-schema.org/draft/2020-12/schema",
1207
- "additionalProperties": false,
1208
- "properties": {
1209
- "age": {
1210
- "type": "number",
1211
- },
1212
- "name": {
1213
- "type": "string",
1214
- },
1215
- },
1216
- "required": [
1217
- "name",
1218
- "age",
1219
- ],
1220
- "type": "object",
1221
- }
1222
- `);
1223
- });
1224
-
1225
- test("record", () => {
1226
- const schema = z.record(z.string(), z.boolean());
1227
- expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
1228
- {
1229
- "$schema": "https://json-schema.org/draft/2020-12/schema",
1230
- "additionalProperties": {
1231
- "type": "boolean",
1232
- },
1233
- "propertyNames": {
1234
- "type": "string",
1235
- },
1236
- "type": "object",
1237
- }
1238
- `);
1239
- });
1240
-
1241
- test("record openapi-3.0", () => {
1242
- const schema = z.record(z.string(), z.boolean());
1243
- const jsonSchema = z.toJSONSchema(schema, { target: "openapi-3.0" });
1244
- validateOpenAPI30Schema(jsonSchema);
1245
- expect(jsonSchema).toMatchInlineSnapshot(`
1246
- {
1247
- "additionalProperties": {
1248
- "type": "boolean",
1249
- },
1250
- "type": "object",
1251
- }
1252
- `);
1253
- });
1254
-
1255
- test("record with enum keys adds required", () => {
1256
- const schema = z.record(z.enum(["key1", "key2"]), z.number());
1257
-
1258
- expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
1259
- {
1260
- "$schema": "https://json-schema.org/draft/2020-12/schema",
1261
- "additionalProperties": {
1262
- "type": "number",
1263
- },
1264
- "propertyNames": {
1265
- "enum": [
1266
- "key1",
1267
- "key2",
1268
- ],
1269
- "type": "string",
1270
- },
1271
- "required": [
1272
- "key1",
1273
- "key2",
1274
- ],
1275
- "type": "object",
1276
- }
1277
- `);
1278
- });
1279
-
1280
- test("record with enum keys drops required for an optional-in value under io: input", () => {
1281
- const schema = z.record(z.enum(["key1", "key2"]), z.number().default(0));
1282
-
1283
- expect(z.toJSONSchema(schema, { io: "input" }).required).toBeUndefined();
1284
- expect(z.toJSONSchema(schema).required).toEqual(["key1", "key2"]);
1285
- expect(z.toJSONSchema(z.record(z.enum(["key1", "key2"]), z.number()), { io: "input" }).required).toEqual([
1286
- "key1",
1287
- "key2",
1288
- ]);
1289
- // A caught value keeps required, matching the input type and z.object().
1290
- expect(z.toJSONSchema(z.record(z.enum(["key1", "key2"]), z.number().catch(0)), { io: "input" }).required).toEqual([
1291
- "key1",
1292
- "key2",
1293
- ]);
1294
- });
1295
-
1296
- test("record stringifies numeric enum keys for propertyNames and required", () => {
1297
- enum NumberEnum {
1298
- Zero = 0,
1299
- One = 1,
1300
- }
1301
- const schema = z.record(z.enum(NumberEnum), z.string());
1302
-
1303
- expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
1304
- {
1305
- "$schema": "https://json-schema.org/draft/2020-12/schema",
1306
- "additionalProperties": {
1307
- "type": "string",
1308
- },
1309
- "propertyNames": {
1310
- "enum": [
1311
- "0",
1312
- "1",
1313
- ],
1314
- "type": "string",
1315
- },
1316
- "required": [
1317
- "0",
1318
- "1",
1319
- ],
1320
- "type": "object",
1321
- }
1322
- `);
1323
- });
1324
-
1325
- test("record with a numeric key emits propertyNames over the numeric-string form", () => {
1326
- expect(z.toJSONSchema(z.record(z.number(), z.boolean())).propertyNames).toEqual({
1327
- type: "string",
1328
- pattern: "^-?\\d+(?:\\.\\d+)?$",
1329
- });
1330
- // range checks can't apply to a key, so only the integer shape survives
1331
- expect(z.toJSONSchema(z.record(z.int32(), z.boolean())).propertyNames).toEqual({
1332
- type: "string",
1333
- pattern: "^-?\\d+$",
1334
- });
1335
- expect(z.toJSONSchema(z.record(z.literal([1, 2]), z.boolean()))).toMatchObject({
1336
- propertyNames: { type: "string", enum: ["1", "2"] },
1337
- required: ["1", "2"],
1338
- });
1339
- expect(z.toJSONSchema(z.record(z.literal(1), z.boolean())).propertyNames).toEqual({
1340
- type: "string",
1341
- const: "1",
1342
- });
1343
- });
1344
-
1345
- test("record key rewrite reaches through wrappers and union branches", () => {
1346
- const numericString = { type: "string", pattern: "^-?\\d+(?:\\.\\d+)?$" };
1347
- // a wrapper only carries its inner type once the refs are flattened, so this is decided after the record itself is emitted
1348
- expect(
1349
- z.toJSONSchema(
1350
- z.record(
1351
- z.lazy(() => z.number()),
1352
- z.boolean()
1353
- )
1354
- ).propertyNames
1355
- ).toEqual(numericString);
1356
- expect(z.toJSONSchema(z.record(z.number().pipe(z.number()), z.boolean())).propertyNames).toEqual(numericString);
1357
- expect(z.toJSONSchema(z.record(z.number().readonly(), z.boolean())).propertyNames).toMatchObject(numericString);
1358
- expect(z.toJSONSchema(z.record(z.union([z.literal("Tuna"), z.literal(21)]), z.string()))).toMatchObject({
1359
- propertyNames: {
1360
- anyOf: [
1361
- { type: "string", const: "Tuna" },
1362
- { type: "string", const: "21" },
1363
- ],
1364
- },
1365
- required: ["Tuna", "21"],
1366
- });
1367
- });
1368
-
1369
- test("record with a numeric key inlines an extracted key, and leaves a string one referenced", () => {
1370
- expect(z.toJSONSchema(z.record(z.number().meta({ id: "Num" }), z.boolean())).propertyNames).toEqual({
1371
- type: "string",
1372
- pattern: "^-?\\d+(?:\\.\\d+)?$",
1373
- });
1374
- expect(z.toJSONSchema(z.record(z.string().meta({ id: "Str" }), z.boolean())).propertyNames).toEqual({
1375
- $ref: "#/$defs/Str",
1376
- });
1377
- // the value position still wants the number form, so the two cannot share one def
1378
- const key = z.number().meta({ id: "Shared" });
1379
- expect(z.toJSONSchema(z.object({ a: key, b: z.record(key, z.string()) }))).toMatchObject({
1380
- properties: { a: { $ref: "#/$defs/Shared" }, b: { propertyNames: { type: "string" } } },
1381
- $defs: { Shared: { type: "number" } },
1382
- });
1383
- });
1384
-
1385
- test("record key rewrite reaches a wrapped record", () => {
1386
- // the flatten copies a record's properties onto its wrapper by reference, so the rewrite has to find every copy
1387
- expect(z.toJSONSchema(z.record(z.number(), z.boolean()).optional()).propertyNames).toEqual({
1388
- type: "string",
1389
- pattern: "^-?\\d+(?:\\.\\d+)?$",
1390
- });
1391
- expect(z.toJSONSchema(z.object({ a: z.record(z.literal([1, 2]), z.boolean()).optional() }))).toMatchObject({
1392
- properties: { a: { propertyNames: { type: "string", enum: ["1", "2"] }, required: ["1", "2"] } },
1393
- });
1394
- });
1395
-
1396
- test("record with a recursive key converts without looping", () => {
1397
- const numeric: any = z.lazy(() => z.union([z.number(), numeric]));
1398
- expect(z.toJSONSchema(z.record(numeric, z.boolean())).propertyNames).toMatchObject({
1399
- anyOf: [{ type: "string", pattern: "^-?\\d+(?:\\.\\d+)?$" }, { $ref: "#/$defs/__schema0" }],
1400
- });
1401
- // a key with nothing to re-express keeps the reference it had
1402
- const stringy: any = z.lazy(() => z.union([z.string(), stringy]));
1403
- expect(z.toJSONSchema(z.record(stringy, z.boolean())).propertyNames).toEqual({ $ref: "#/$defs/__schema0" });
1404
- expect(
1405
- z.toJSONSchema(z.record(z.union([z.literal("a"), z.literal("b")]).meta({ id: "Keys" }), z.boolean()))
1406
- .propertyNames
1407
- ).toEqual({ $ref: "#/$defs/Keys" });
1408
- });
1409
-
1410
- test("record with a heterogeneous key stringifies only its numeric members", () => {
1411
- // a mixed key carries no `type`, so the numeric members are caught by value rather than by type
1412
- expect(z.toJSONSchema(z.record(z.literal(["a", 1]), z.boolean()))).toMatchObject({
1413
- propertyNames: { enum: ["a", "1"] },
1414
- required: ["a", "1"],
1415
- });
1416
- // a member no key can spell is left as it was, since the parser only ever retries a key as a number
1417
- expect(z.toJSONSchema(z.record(z.literal(["a", true]) as any, z.boolean())).propertyNames).toEqual({
1418
- enum: ["a", true],
1419
- });
1420
- });
1421
-
1422
- test("record stringifies required for every target", () => {
1423
- const schema = z.record(z.literal([1, 2]), z.boolean());
1424
- for (const target of ["draft-2020-12", "draft-7", "draft-4", "openapi-3.0"] as const) {
1425
- expect(z.toJSONSchema(schema, { target }).required).toEqual(["1", "2"]);
1426
- }
1427
- });
1428
-
1429
- test("strict record with regex key uses propertyNames", () => {
1430
- const schema = z.record(z.string().regex(/^label:[a-z]{2}$/), z.string());
1431
-
1432
- expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
1433
- {
1434
- "$schema": "https://json-schema.org/draft/2020-12/schema",
1435
- "additionalProperties": {
1436
- "type": "string",
1437
- },
1438
- "propertyNames": {
1439
- "pattern": "^label:[a-z]{2}$",
1440
- "type": "string",
1441
- },
1442
- "type": "object",
1443
- }
1444
- `);
1445
- });
1446
-
1447
- test("looseRecord with regex key uses patternProperties", () => {
1448
- const schema = z.looseRecord(z.string().regex(/^label:[a-z]{2}$/), z.string());
1449
-
1450
- expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
1451
- {
1452
- "$schema": "https://json-schema.org/draft/2020-12/schema",
1453
- "patternProperties": {
1454
- "^label:[a-z]{2}$": {
1455
- "type": "string",
1456
- },
1457
- },
1458
- "type": "object",
1459
- }
1460
- `);
1461
- });
1462
-
1463
- test("looseRecord with multiple regex patterns uses patternProperties", () => {
1464
- const schema = z.looseRecord(
1465
- z
1466
- .string()
1467
- .regex(/^prefix_/)
1468
- .regex(/_suffix$/),
1469
- z.number()
1470
- );
1471
-
1472
- expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
1473
- {
1474
- "$schema": "https://json-schema.org/draft/2020-12/schema",
1475
- "patternProperties": {
1476
- "^prefix_": {
1477
- "type": "number",
1478
- },
1479
- "_suffix$": {
1480
- "type": "number",
1481
- },
1482
- },
1483
- "type": "object",
1484
- }
1485
- `);
1486
- });
1487
-
1488
- test("looseRecord without regex key uses propertyNames", () => {
1489
- // looseRecord with plain string key should still use propertyNames
1490
- const schema = z.looseRecord(z.string(), z.boolean());
1491
-
1492
- expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
1493
- {
1494
- "$schema": "https://json-schema.org/draft/2020-12/schema",
1495
- "additionalProperties": {
1496
- "type": "boolean",
1497
- },
1498
- "propertyNames": {
1499
- "type": "string",
1500
- },
1501
- "type": "object",
1502
- }
1503
- `);
1504
- });
1505
-
1506
- test("intersection of object with looseRecord uses patternProperties", () => {
1507
- const zLabeled = z.object({ label: z.string() });
1508
- const zLocalizedLabeled = z.looseRecord(z.string().regex(/^label:[a-z]{2}$/), z.string());
1509
- const schema = zLabeled.and(zLocalizedLabeled);
1510
-
1511
- expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
1512
- {
1513
- "$schema": "https://json-schema.org/draft/2020-12/schema",
1514
- "allOf": [
1515
- {
1516
- "additionalProperties": false,
1517
- "properties": {
1518
- "label": {
1519
- "type": "string",
1520
- },
1521
- },
1522
- "required": [
1523
- "label",
1524
- ],
1525
- "type": "object",
1526
- },
1527
- {
1528
- "patternProperties": {
1529
- "^label:[a-z]{2}$": {
1530
- "type": "string",
1531
- },
1532
- },
1533
- "type": "object",
1534
- },
1535
- ],
1536
- }
1537
- `);
1538
- });
1539
-
1540
- test("tuple", () => {
1541
- const schema = z.tuple([z.string(), z.number()]);
1542
- expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
1543
- {
1544
- "$schema": "https://json-schema.org/draft/2020-12/schema",
1545
- "items": false,
1546
- "maxItems": 2,
1547
- "minItems": 2,
1548
- "prefixItems": [
1549
- {
1550
- "type": "string",
1551
- },
1552
- {
1553
- "type": "number",
1554
- },
1555
- ],
1556
- "type": "array",
1557
- }
1558
- `);
1559
- });
1560
-
1561
- test("tuple with rest", () => {
1562
- const schema = z.tuple([z.string(), z.number()]).rest(z.boolean());
1563
- expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
1564
- {
1565
- "$schema": "https://json-schema.org/draft/2020-12/schema",
1566
- "items": {
1567
- "type": "boolean",
1568
- },
1569
- "minItems": 2,
1570
- "prefixItems": [
1571
- {
1572
- "type": "string",
1573
- },
1574
- {
1575
- "type": "number",
1576
- },
1577
- ],
1578
- "type": "array",
1579
- }
1580
- `);
1581
- });
1582
-
1583
- test("tuple openapi-3.0", () => {
1584
- const schema = z.tuple([z.string(), z.number()]);
1585
- const jsonSchema = z.toJSONSchema(schema, { target: "openapi-3.0" });
1586
- validateOpenAPI30Schema(jsonSchema);
1587
- expect(jsonSchema).toMatchInlineSnapshot(`
1588
- {
1589
- "items": {
1590
- "anyOf": [
1591
- {
1592
- "type": "string",
1593
- },
1594
- {
1595
- "type": "number",
1596
- },
1597
- ],
1598
- },
1599
- "maxItems": 2,
1600
- "minItems": 2,
1601
- "type": "array",
1602
- }
1603
- `);
1604
- });
1605
-
1606
- test("tuple with rest openapi-3.0", () => {
1607
- const schema = z.tuple([z.string(), z.number()]).rest(z.boolean());
1608
- const jsonSchema = z.toJSONSchema(schema, { target: "openapi-3.0" });
1609
- validateOpenAPI30Schema(jsonSchema);
1610
- expect(jsonSchema).toMatchInlineSnapshot(`
1611
- {
1612
- "items": {
1613
- "anyOf": [
1614
- {
1615
- "type": "string",
1616
- },
1617
- {
1618
- "type": "number",
1619
- },
1620
- {
1621
- "type": "boolean",
1622
- },
1623
- ],
1624
- },
1625
- "minItems": 2,
1626
- "type": "array",
1627
- }
1628
- `);
1629
- });
1630
-
1631
- test("tuple with null openapi-3.0", () => {
1632
- const schema = z.tuple([z.string(), z.number(), z.null()]);
1633
- const jsonSchema = z.toJSONSchema(schema, { target: "openapi-3.0" });
1634
- validateOpenAPI30Schema(jsonSchema);
1635
- expect(jsonSchema).toMatchInlineSnapshot(`
1636
- {
1637
- "items": {
1638
- "anyOf": [
1639
- {
1640
- "type": "string",
1641
- },
1642
- {
1643
- "type": "number",
1644
- },
1645
- {
1646
- "enum": [
1647
- null,
1648
- ],
1649
- "nullable": true,
1650
- "type": "string",
1651
- },
1652
- ],
1653
- },
1654
- "maxItems": 3,
1655
- "minItems": 3,
1656
- "type": "array",
1657
- }
1658
- `);
1659
- });
1660
-
1661
- test("tuple draft-7", () => {
1662
- const schema = z.tuple([z.string(), z.number()]);
1663
- expect(z.toJSONSchema(schema, { target: "draft-7", io: "input" })).toMatchInlineSnapshot(`
1664
- {
1665
- "$schema": "http://json-schema.org/draft-07/schema#",
1666
- "additionalItems": false,
1667
- "items": [
1668
- {
1669
- "type": "string",
1670
- },
1671
- {
1672
- "type": "number",
1673
- },
1674
- ],
1675
- "maxItems": 2,
1676
- "minItems": 2,
1677
- "type": "array",
1678
- }
1679
- `);
1680
- });
1681
-
1682
- test("tuple with rest draft-7", () => {
1683
- const schema = z.tuple([z.string(), z.number()]).rest(z.boolean());
1684
- expect(z.toJSONSchema(schema, { target: "draft-7", io: "input" })).toMatchInlineSnapshot(`
1685
- {
1686
- "$schema": "http://json-schema.org/draft-07/schema#",
1687
- "additionalItems": {
1688
- "type": "boolean",
1689
- },
1690
- "items": [
1691
- {
1692
- "type": "string",
1693
- },
1694
- {
1695
- "type": "number",
1696
- },
1697
- ],
1698
- "minItems": 2,
1699
- "type": "array",
1700
- }
1701
- `);
1702
- });
1703
-
1704
- test("tuple with rest draft-7 - issue #5151 regression test", () => {
1705
- // This test addresses issue #5151: tuple with rest elements and ids in draft-7 had incorrect internal path handling affecting complex scenarios
1706
- const primarySchema = z.string().meta({ id: "primary" });
1707
- const restSchema = z.number().meta({ id: "rest" });
1708
- const testSchema = z.tuple([primarySchema], restSchema);
1709
-
1710
- // Test both final output structure AND internal path handling
1711
- const capturedPaths: string[] = [];
1712
- const result = z.toJSONSchema(testSchema, {
1713
- target: "draft-7",
1714
- override: (ctx) => capturedPaths.push(ctx.path.join("/")),
1715
- });
1716
-
1717
- // Verify correct draft-7 structure with metadata extraction
1718
- expect(result).toMatchInlineSnapshot(`
1719
- {
1720
- "$schema": "http://json-schema.org/draft-07/schema#",
1721
- "additionalItems": {
1722
- "$ref": "#/definitions/rest",
1723
- },
1724
- "definitions": {
1725
- "primary": {
1726
- "type": "string",
1727
- },
1728
- "rest": {
1729
- "type": "number",
1730
- },
1731
- },
1732
- "items": [
1733
- {
1734
- "$ref": "#/definitions/primary",
1735
- },
1736
- ],
1737
- "minItems": 1,
1738
- "type": "array",
1739
- }
1740
- `);
1741
-
1742
- // Verify internal paths are correct (this was the actual bug)
1743
- expect(capturedPaths).toContain("items/0"); // prefix items should use "items" path
1744
- expect(capturedPaths).toContain("additionalItems"); // rest should use "additionalItems" path
1745
- expect(capturedPaths).not.toContain("prefixItems/0"); // should not use draft-2020-12 paths
1746
-
1747
- // Structural validations
1748
- expect(Array.isArray(result.items)).toBe(true);
1749
- expect(result.additionalItems).toBeDefined();
1750
- });
1751
-
1752
- test("closed tuple length constraints - issue #6193", () => {
1753
- const schema = z.tuple([z.string(), z.string(), z.object({ lang: z.string() })]);
1754
-
1755
- expect(schema.safeParse(["a", "b", { lang: "en" }, "extra"]).success).toBe(false);
1756
-
1757
- const draft2020 = z.toJSONSchema(schema, { target: "draft-2020-12" });
1758
- expect(draft2020.items).toBe(false);
1759
- expect(draft2020.minItems).toBe(3);
1760
- expect(draft2020.maxItems).toBe(3);
1761
-
1762
- const draft7 = z.toJSONSchema(schema, { target: "draft-7", io: "input" });
1763
- expect(draft7.additionalItems).toBe(false);
1764
- expect(draft7.minItems).toBe(3);
1765
- expect(draft7.maxItems).toBe(3);
1766
-
1767
- const openapi = z.toJSONSchema(schema, { target: "openapi-3.0" });
1768
- validateOpenAPI30Schema(openapi);
1769
- expect(openapi.minItems).toBe(3);
1770
- expect(openapi.maxItems).toBe(3);
1771
- });
1772
-
1773
- test("closed tuple with optional trailing items", () => {
1774
- const schema = z.tuple([z.string(), z.number().optional()]);
1775
-
1776
- const draft2020 = z.toJSONSchema(schema, { target: "draft-2020-12" });
1777
- expect(draft2020.items).toBe(false);
1778
- expect(draft2020.minItems).toBe(1);
1779
- expect(draft2020.maxItems).toBe(2);
1780
-
1781
- const draft7 = z.toJSONSchema(schema, { target: "draft-7", io: "input" });
1782
- expect(draft7.additionalItems).toBe(false);
1783
- expect(draft7.minItems).toBe(1);
1784
- expect(draft7.maxItems).toBe(2);
1785
- });
1786
-
1787
- test("empty closed tuple rejects extra elements", () => {
1788
- const schema = z.tuple([]);
1789
-
1790
- const draft2020 = z.toJSONSchema(schema, { target: "draft-2020-12" });
1791
- expect(draft2020.items).toBe(false);
1792
- expect(draft2020.maxItems).toBe(0);
1793
-
1794
- const draft7 = z.toJSONSchema(schema, { target: "draft-7", io: "input" });
1795
- expect(draft7.additionalItems).toBe(false);
1796
- expect(draft7.maxItems).toBe(0);
1797
-
1798
- const openapi = z.toJSONSchema(schema, { target: "openapi-3.0" });
1799
- validateOpenAPI30Schema(openapi);
1800
- expect(openapi.maxItems).toBe(0);
1801
- });
1802
-
1803
- test("closed tuple length respects io direction with defaults", () => {
1804
- const schema = z.tuple([z.string(), z.string().default("x")]);
1805
-
1806
- const input = z.toJSONSchema(schema, { target: "draft-2020-12", io: "input" });
1807
- expect(input.items).toBe(false);
1808
- expect(input.minItems).toBe(1);
1809
- expect(input.maxItems).toBe(2);
1810
-
1811
- const output = z.toJSONSchema(schema, { target: "draft-2020-12", io: "output" });
1812
- expect(output.items).toBe(false);
1813
- expect(output.minItems).toBe(2);
1814
- expect(output.maxItems).toBe(2);
1815
- });
1816
-
1817
- test("closed tuple length resolves input optionality past transform and catch", () => {
1818
- const minItems = (schema: z.core.$ZodType, io: "input" | "output") =>
1819
- z.toJSONSchema(schema, { target: "draft-2020-12", io }).minItems;
1820
-
1821
- // Both let the parser observe an absent slot, but declare a required input.
1822
- const pre = z.tuple([z.string(), z.preprocess((v) => v, z.string())]);
1823
- expect(minItems(pre, "input")).toBe(2);
1824
- expect(minItems(pre, "output")).toBe(2);
1825
-
1826
- const caught = z.tuple([z.string(), z.string().catch("x")]);
1827
- expect(minItems(caught, "input")).toBe(2);
1828
- expect(minItems(caught, "output")).toBe(2);
1829
-
1830
- // Resolution passes through the wrapper rather than stopping at it.
1831
- expect(minItems(z.tuple([z.string(), z.string().optional().catch("x")]), "input")).toBe(1);
1832
- });
1833
-
1834
- test("promise", () => {
1835
- const schema = z.promise(z.string());
1836
- expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
1837
- {
1838
- "$schema": "https://json-schema.org/draft/2020-12/schema",
1839
- "type": "string",
1840
- }
1841
- `);
1842
- });
1843
-
1844
- test("lazy", () => {
1845
- const schema = z.lazy(() => z.string());
1846
- expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
1847
- {
1848
- "$schema": "https://json-schema.org/draft/2020-12/schema",
1849
- "type": "string",
1850
- }
1851
- `);
1852
- });
1853
-
1854
- // enum
1855
- test("enum", () => {
1856
- const a = z.enum(["a", "b", "c"]);
1857
- expect(z.toJSONSchema(a)).toMatchInlineSnapshot(`
1858
- {
1859
- "$schema": "https://json-schema.org/draft/2020-12/schema",
1860
- "enum": [
1861
- "a",
1862
- "b",
1863
- "c",
1864
- ],
1865
- "type": "string",
1866
- }
1867
- `);
1868
-
1869
- enum B {
1870
- A = 0,
1871
- B = 1,
1872
- C = 2,
1873
- }
1874
-
1875
- const b = z.enum(B);
1876
- expect(z.toJSONSchema(b)).toMatchInlineSnapshot(`
1877
- {
1878
- "$schema": "https://json-schema.org/draft/2020-12/schema",
1879
- "enum": [
1880
- 0,
1881
- 1,
1882
- 2,
1883
- ],
1884
- "type": "number",
1885
- }
1886
- `);
1887
- });
1888
-
1889
- // literal
1890
- test("literal", () => {
1891
- const a = z.literal("hello");
1892
- expect(z.toJSONSchema(a)).toMatchInlineSnapshot(`
1893
- {
1894
- "$schema": "https://json-schema.org/draft/2020-12/schema",
1895
- "const": "hello",
1896
- "type": "string",
1897
- }
1898
- `);
1899
-
1900
- const b = z.literal(7);
1901
- expect(z.toJSONSchema(b)).toMatchInlineSnapshot(`
1902
- {
1903
- "$schema": "https://json-schema.org/draft/2020-12/schema",
1904
- "const": 7,
1905
- "type": "number",
1906
- }
1907
- `);
1908
-
1909
- const c = z.literal(["hello", undefined, null, 5, BigInt(1324)]);
1910
- expect(() => z.toJSONSchema(c)).toThrow();
1911
-
1912
- const d = z.literal(["hello", null, 5]);
1913
- expect(z.toJSONSchema(d)).toMatchInlineSnapshot(`
1914
- {
1915
- "$schema": "https://json-schema.org/draft/2020-12/schema",
1916
- "enum": [
1917
- "hello",
1918
- null,
1919
- 5,
1920
- ],
1921
- }
1922
- `);
1923
-
1924
- const e = z.literal(["hello", "zod", "v4"]);
1925
- expect(z.toJSONSchema(e)).toMatchInlineSnapshot(`
1926
- {
1927
- "$schema": "https://json-schema.org/draft/2020-12/schema",
1928
- "enum": [
1929
- "hello",
1930
- "zod",
1931
- "v4",
1932
- ],
1933
- "type": "string",
1934
- }
1935
- `);
1936
- });
1937
-
1938
- test("literal draft-4", () => {
1939
- const a = z.literal("hello");
1940
- expect(z.toJSONSchema(a, { target: "draft-4" })).toMatchInlineSnapshot(`
1941
- {
1942
- "$schema": "http://json-schema.org/draft-04/schema#",
1943
- "enum": [
1944
- "hello",
1945
- ],
1946
- "type": "string",
1947
- }
1948
- `);
1949
- });
1950
-
1951
- // pipe
1952
- test("pipe", () => {
1953
- const schema = z
1954
- .string()
1955
- .transform((val) => Number.parseInt(val))
1956
- .pipe(z.number());
1957
- expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
1958
- {
1959
- "$schema": "https://json-schema.org/draft/2020-12/schema",
1960
- "type": "number",
1961
- }
1962
- `);
1963
- });
1964
-
1965
- test("simple objects", () => {
1966
- const schema = z.object({
1967
- name: z.string(),
1968
- age: z.number(),
1969
- });
1970
-
1971
- expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(
1972
- `
1973
- {
1974
- "$schema": "https://json-schema.org/draft/2020-12/schema",
1975
- "additionalProperties": false,
1976
- "properties": {
1977
- "age": {
1978
- "type": "number",
1979
- },
1980
- "name": {
1981
- "type": "string",
1982
- },
1983
- },
1984
- "required": [
1985
- "name",
1986
- "age",
1987
- ],
1988
- "type": "object",
1989
- }
1990
- `
1991
- );
1992
- });
1993
-
1994
- test("additionalproperties in z.object", () => {
1995
- const a = z.object({
1996
- name: z.string(),
1997
- });
1998
- expect(z.toJSONSchema(a)).toMatchInlineSnapshot(`
1999
- {
2000
- "$schema": "https://json-schema.org/draft/2020-12/schema",
2001
- "additionalProperties": false,
2002
- "properties": {
2003
- "name": {
2004
- "type": "string",
2005
- },
2006
- },
2007
- "required": [
2008
- "name",
2009
- ],
2010
- "type": "object",
2011
- }
2012
- `);
2013
- expect(z.toJSONSchema(a, { io: "input" })).toMatchInlineSnapshot(`
2014
- {
2015
- "$schema": "https://json-schema.org/draft/2020-12/schema",
2016
- "properties": {
2017
- "name": {
2018
- "type": "string",
2019
- },
2020
- },
2021
- "required": [
2022
- "name",
2023
- ],
2024
- "type": "object",
2025
- }
2026
- `);
2027
- expect(
2028
- z.toJSONSchema(a, {
2029
- io: "input",
2030
- override(ctx) {
2031
- const def = ctx.zodSchema._zod.def;
2032
- if (def.type === "object" && !def.catchall) {
2033
- (ctx.jsonSchema as z.core.JSONSchema.ObjectSchema).additionalProperties = false;
2034
- }
2035
- },
2036
- })
2037
- ).toMatchInlineSnapshot(`
2038
- {
2039
- "$schema": "https://json-schema.org/draft/2020-12/schema",
2040
- "additionalProperties": false,
2041
- "properties": {
2042
- "name": {
2043
- "type": "string",
2044
- },
2045
- },
2046
- "required": [
2047
- "name",
2048
- ],
2049
- "type": "object",
2050
- }
2051
- `);
2052
- });
2053
-
2054
- test("catchall objects", () => {
2055
- const a = z.strictObject({
2056
- name: z.string(),
2057
- age: z.number(),
2058
- });
2059
-
2060
- expect(z.toJSONSchema(a)).toMatchInlineSnapshot(`
2061
- {
2062
- "$schema": "https://json-schema.org/draft/2020-12/schema",
2063
- "additionalProperties": false,
2064
- "properties": {
2065
- "age": {
2066
- "type": "number",
2067
- },
2068
- "name": {
2069
- "type": "string",
2070
- },
2071
- },
2072
- "required": [
2073
- "name",
2074
- "age",
2075
- ],
2076
- "type": "object",
2077
- }
2078
- `);
2079
-
2080
- const b = z
2081
- .object({
2082
- name: z.string(),
2083
- })
2084
- .catchall(z.string());
2085
-
2086
- expect(z.toJSONSchema(b)).toMatchInlineSnapshot(`
2087
- {
2088
- "$schema": "https://json-schema.org/draft/2020-12/schema",
2089
- "additionalProperties": {
2090
- "type": "string",
2091
- },
2092
- "properties": {
2093
- "name": {
2094
- "type": "string",
2095
- },
2096
- },
2097
- "required": [
2098
- "name",
2099
- ],
2100
- "type": "object",
2101
- }
2102
- `);
2103
-
2104
- const c = z.looseObject({
2105
- name: z.string(),
2106
- });
2107
-
2108
- expect(z.toJSONSchema(c)).toMatchInlineSnapshot(`
2109
- {
2110
- "$schema": "https://json-schema.org/draft/2020-12/schema",
2111
- "additionalProperties": {},
2112
- "properties": {
2113
- "name": {
2114
- "type": "string",
2115
- },
2116
- },
2117
- "required": [
2118
- "name",
2119
- ],
2120
- "type": "object",
2121
- }
2122
- `);
2123
- });
2124
-
2125
- test("optional fields - object", () => {
2126
- const schema = z.object({
2127
- required: z.string(),
2128
- optional: z.string().optional(),
2129
- nonoptional: z.string().optional().nonoptional(),
2130
- });
2131
-
2132
- const result = z.toJSONSchema(schema);
2133
-
2134
- expect(result).toMatchInlineSnapshot(`
2135
- {
2136
- "$schema": "https://json-schema.org/draft/2020-12/schema",
2137
- "additionalProperties": false,
2138
- "properties": {
2139
- "nonoptional": {
2140
- "type": "string",
2141
- },
2142
- "optional": {
2143
- "type": "string",
2144
- },
2145
- "required": {
2146
- "type": "string",
2147
- },
2148
- },
2149
- "required": [
2150
- "required",
2151
- "nonoptional",
2152
- ],
2153
- "type": "object",
2154
- }
2155
- `);
2156
- });
2157
-
2158
- test("recursive object", () => {
2159
- interface Category {
2160
- name: string;
2161
- subcategories: Category[];
2162
- }
2163
-
2164
- const categorySchema: z.ZodType<Category> = z.object({
2165
- name: z.string(),
2166
- subcategories: z.array(z.lazy(() => categorySchema)),
2167
- });
2168
-
2169
- const result = z.toJSONSchema(categorySchema);
2170
- expect(result).toMatchInlineSnapshot(`
2171
- {
2172
- "$schema": "https://json-schema.org/draft/2020-12/schema",
2173
- "additionalProperties": false,
2174
- "properties": {
2175
- "name": {
2176
- "type": "string",
2177
- },
2178
- "subcategories": {
2179
- "items": {
2180
- "$ref": "#",
2181
- },
2182
- "type": "array",
2183
- },
2184
- },
2185
- "required": [
2186
- "name",
2187
- "subcategories",
2188
- ],
2189
- "type": "object",
2190
- }
2191
- `);
2192
- });
2193
-
2194
- test("simple interface", () => {
2195
- const userSchema = z.object({
2196
- name: z.string(),
2197
- age: z.number().optional(),
2198
- });
2199
-
2200
- const result = z.toJSONSchema(userSchema);
2201
- expect(result).toMatchInlineSnapshot(`
2202
- {
2203
- "$schema": "https://json-schema.org/draft/2020-12/schema",
2204
- "additionalProperties": false,
2205
- "properties": {
2206
- "age": {
2207
- "type": "number",
2208
- },
2209
- "name": {
2210
- "type": "string",
2211
- },
2212
- },
2213
- "required": [
2214
- "name",
2215
- ],
2216
- "type": "object",
2217
- }
2218
- `);
2219
- });
2220
-
2221
- test("catchall interface", () => {
2222
- const a = z.strictObject({
2223
- name: z.string(),
2224
- age: z.number(),
2225
- });
2226
-
2227
- expect(z.toJSONSchema(a)).toMatchInlineSnapshot(`
2228
- {
2229
- "$schema": "https://json-schema.org/draft/2020-12/schema",
2230
- "additionalProperties": false,
2231
- "properties": {
2232
- "age": {
2233
- "type": "number",
2234
- },
2235
- "name": {
2236
- "type": "string",
2237
- },
2238
- },
2239
- "required": [
2240
- "name",
2241
- "age",
2242
- ],
2243
- "type": "object",
2244
- }
2245
- `);
2246
-
2247
- const b = z
2248
- .object({
2249
- name: z.string(),
2250
- })
2251
- .catchall(z.string());
2252
-
2253
- expect(z.toJSONSchema(b)).toMatchInlineSnapshot(`
2254
- {
2255
- "$schema": "https://json-schema.org/draft/2020-12/schema",
2256
- "additionalProperties": {
2257
- "type": "string",
2258
- },
2259
- "properties": {
2260
- "name": {
2261
- "type": "string",
2262
- },
2263
- },
2264
- "required": [
2265
- "name",
2266
- ],
2267
- "type": "object",
2268
- }
2269
- `);
2270
-
2271
- const c = z.looseObject({
2272
- name: z.string(),
2273
- });
2274
-
2275
- expect(z.toJSONSchema(c)).toMatchInlineSnapshot(`
2276
- {
2277
- "$schema": "https://json-schema.org/draft/2020-12/schema",
2278
- "additionalProperties": {},
2279
- "properties": {
2280
- "name": {
2281
- "type": "string",
2282
- },
2283
- },
2284
- "required": [
2285
- "name",
2286
- ],
2287
- "type": "object",
2288
- }
2289
- `);
2290
- });
2291
-
2292
- test("recursive interface schemas", () => {
2293
- const TreeNodeSchema = z.object({
2294
- id: z.string(),
2295
- get children() {
2296
- return TreeNodeSchema;
2297
- },
2298
- });
2299
-
2300
- const result = z.toJSONSchema(TreeNodeSchema);
2301
-
2302
- // Should have definitions for recursive schema
2303
- expect(JSON.stringify(result, null, 2)).toMatchInlineSnapshot(
2304
- `
2305
- "{
2306
- "$schema": "https://json-schema.org/draft/2020-12/schema",
2307
- "type": "object",
2308
- "properties": {
2309
- "id": {
2310
- "type": "string"
2311
- },
2312
- "children": {
2313
- "$ref": "#"
2314
- }
2315
- },
2316
- "required": [
2317
- "id",
2318
- "children"
2319
- ],
2320
- "additionalProperties": false
2321
- }"
2322
- `
2323
- );
2324
- });
2325
-
2326
- test("mutually recursive interface schemas", () => {
2327
- const FolderSchema = z.object({
2328
- name: z.string(),
2329
- get files() {
2330
- return z.array(FileSchema);
2331
- },
2332
- });
2333
-
2334
- const FileSchema = z.object({
2335
- name: z.string(),
2336
- get parent() {
2337
- return FolderSchema;
2338
- },
2339
- });
2340
-
2341
- const result = z.toJSONSchema(FolderSchema);
2342
-
2343
- // Should have definitions for both schemas
2344
- expect(JSON.stringify(result, null, 2)).toMatchInlineSnapshot(
2345
- `
2346
- "{
2347
- "$schema": "https://json-schema.org/draft/2020-12/schema",
2348
- "type": "object",
2349
- "properties": {
2350
- "name": {
2351
- "type": "string"
2352
- },
2353
- "files": {
2354
- "type": "array",
2355
- "items": {
2356
- "type": "object",
2357
- "properties": {
2358
- "name": {
2359
- "type": "string"
2360
- },
2361
- "parent": {
2362
- "$ref": "#"
2363
- }
2364
- },
2365
- "required": [
2366
- "name",
2367
- "parent"
2368
- ],
2369
- "additionalProperties": false
2370
- }
2371
- }
2372
- },
2373
- "required": [
2374
- "name",
2375
- "files"
2376
- ],
2377
- "additionalProperties": false
2378
- }"
2379
- `
2380
- );
2381
- });
2382
- });
2383
-
2384
- test("override", () => {
2385
- const schema = z.toJSONSchema(z.string(), {
2386
- override: (ctx) => {
2387
- ctx.zodSchema;
2388
- ctx.jsonSchema;
2389
- ctx.jsonSchema.whatever = "sup";
2390
- },
2391
- });
2392
- expect(schema).toMatchInlineSnapshot(`
2393
- {
2394
- "$schema": "https://json-schema.org/draft/2020-12/schema",
2395
- "type": "string",
2396
- "whatever": "sup",
2397
- }
2398
- `);
2399
- });
2400
-
2401
- test("override: do not run on references", () => {
2402
- let overrideCount = 0;
2403
- const schema = z
2404
- .union([z.string().date(), z.string().datetime(), z.string().datetime({ local: true })])
2405
- .meta({ a: true })
2406
- .transform((str) => new Date(str))
2407
- .meta({ b: true })
2408
- .pipe(z.date())
2409
- .meta({ c: true })
2410
- .brand("dateIn");
2411
- z.toJSONSchema(schema, {
2412
- unrepresentable: "any",
2413
- io: "input",
2414
- override(_) {
2415
- overrideCount++;
2416
- },
2417
- });
2418
-
2419
- expect(overrideCount).toBe(12);
2420
- });
2421
-
2422
- test("override with refs", () => {
2423
- const a = z.string().optional();
2424
- const result = z.toJSONSchema(a, {
2425
- override(ctx) {
2426
- if (ctx.zodSchema._zod.def.type === "string") {
2427
- ctx.jsonSchema.type = "STRING" as "string";
2428
- }
2429
- },
2430
- });
2431
-
2432
- expect(result).toMatchInlineSnapshot(`
2433
- {
2434
- "$schema": "https://json-schema.org/draft/2020-12/schema",
2435
- "type": "STRING",
2436
- }
2437
- `);
2438
- });
2439
-
2440
- test("override execution order", () => {
2441
- const schema = z.union([z.string(), z.number()]);
2442
- let unionSchema!: any;
2443
- z.toJSONSchema(schema, {
2444
- override(ctx) {
2445
- if (ctx.zodSchema._zod.def.type === "union") {
2446
- unionSchema = ctx.jsonSchema;
2447
- }
2448
- },
2449
- });
2450
-
2451
- expect(unionSchema).toMatchInlineSnapshot(`
2452
- {
2453
- "type": [
2454
- "string",
2455
- "number",
2456
- ],
2457
- }
2458
- `);
2459
- });
2460
-
2461
- test("override with path", () => {
2462
- const userSchema = z.object({
2463
- name: z.string(),
2464
- age: z.number(),
2465
- });
2466
-
2467
- const capturedPaths: (string | number)[][] = [];
2468
-
2469
- z.toJSONSchema(userSchema, {
2470
- override(ctx) {
2471
- capturedPaths.push(ctx.path);
2472
- },
2473
- });
2474
-
2475
- expect(capturedPaths).toMatchInlineSnapshot(`
2476
- [
2477
- [
2478
- "properties",
2479
- "age",
2480
- ],
2481
- [
2482
- "properties",
2483
- "name",
2484
- ],
2485
- [],
2486
- ]
2487
- `);
2488
- });
2489
-
2490
- test("pipe", () => {
2491
- const mySchema = z
2492
- .string()
2493
- .transform((val) => val.length)
2494
- .pipe(z.number());
2495
- // ZodPipe
2496
-
2497
- const a = z.toJSONSchema(mySchema);
2498
- expect(a).toMatchInlineSnapshot(`
2499
- {
2500
- "$schema": "https://json-schema.org/draft/2020-12/schema",
2501
- "type": "number",
2502
- }
2503
- `);
2504
- // => { type: "number" }
2505
-
2506
- const b = z.toJSONSchema(mySchema, { io: "input" });
2507
- expect(b).toMatchInlineSnapshot(`
2508
- {
2509
- "$schema": "https://json-schema.org/draft/2020-12/schema",
2510
- "type": "string",
2511
- }
2512
- `);
2513
- // => { type: "string" }
2514
- });
2515
-
2516
- test("passthrough schemas", () => {
2517
- const Internal = z.object({
2518
- num: z.number(),
2519
- str: z.string(),
2520
- });
2521
- //.meta({ id: "Internal" });
2522
-
2523
- const External = z.object({
2524
- a: Internal,
2525
- b: Internal.optional(),
2526
- c: z.lazy(() => Internal),
2527
- d: z.promise(Internal),
2528
- e: z.pipe(Internal, Internal),
2529
- });
2530
-
2531
- const result = z.toJSONSchema(External, {
2532
- reused: "ref",
2533
- });
2534
- expect(result).toMatchInlineSnapshot(`
2535
- {
2536
- "$defs": {
2537
- "__schema0": {
2538
- "additionalProperties": false,
2539
- "properties": {
2540
- "num": {
2541
- "type": "number",
2542
- },
2543
- "str": {
2544
- "type": "string",
2545
- },
2546
- },
2547
- "required": [
2548
- "num",
2549
- "str",
2550
- ],
2551
- "type": "object",
2552
- },
2553
- },
2554
- "$schema": "https://json-schema.org/draft/2020-12/schema",
2555
- "additionalProperties": false,
2556
- "properties": {
2557
- "a": {
2558
- "$ref": "#/$defs/__schema0",
2559
- },
2560
- "b": {
2561
- "$ref": "#/$defs/__schema0",
2562
- },
2563
- "c": {
2564
- "$ref": "#/$defs/__schema0",
2565
- },
2566
- "d": {
2567
- "$ref": "#/$defs/__schema0",
2568
- },
2569
- "e": {
2570
- "$ref": "#/$defs/__schema0",
2571
- },
2572
- },
2573
- "required": [
2574
- "a",
2575
- "c",
2576
- "d",
2577
- "e",
2578
- ],
2579
- "type": "object",
2580
- }
2581
- `);
2582
- });
2583
-
2584
- test("extract schemas with id", () => {
2585
- const name = z.string().meta({ id: "name" });
2586
- const result = z.toJSONSchema(
2587
- z.object({
2588
- first_name: name,
2589
- last_name: name.nullable(),
2590
- middle_name: name.optional(),
2591
- age: z.number().meta({ id: "age" }),
2592
- })
2593
- );
2594
- expect(result).toMatchInlineSnapshot(`
2595
- {
2596
- "$defs": {
2597
- "age": {
2598
- "type": "number",
2599
- },
2600
- "name": {
2601
- "type": "string",
2602
- },
2603
- },
2604
- "$schema": "https://json-schema.org/draft/2020-12/schema",
2605
- "additionalProperties": false,
2606
- "properties": {
2607
- "age": {
2608
- "$ref": "#/$defs/age",
2609
- },
2610
- "first_name": {
2611
- "$ref": "#/$defs/name",
2612
- },
2613
- "last_name": {
2614
- "anyOf": [
2615
- {
2616
- "$ref": "#/$defs/name",
2617
- },
2618
- {
2619
- "type": "null",
2620
- },
2621
- ],
2622
- },
2623
- "middle_name": {
2624
- "$ref": "#/$defs/name",
2625
- },
2626
- },
2627
- "required": [
2628
- "first_name",
2629
- "last_name",
2630
- "age",
2631
- ],
2632
- "type": "object",
2633
- }
2634
- `);
2635
- });
2636
-
2637
- test("escapes JSON Pointer reserved characters in $ref but not in $defs key", () => {
2638
- const User = z.object({ name: z.string() }).meta({ id: "Shared/User~" });
2639
- const result = z.toJSONSchema(z.object({ User }));
2640
- // the $ref pointer escapes `/` -> `~1` and `~` -> `~0` (RFC 6901),
2641
- // while the $defs key keeps the original id
2642
- expect((result.properties!.User as any).$ref).toBe("#/$defs/Shared~1User~0");
2643
- expect(Object.keys(result.$defs!)).toEqual(["Shared/User~"]);
2644
- });
2645
-
2646
- test("escapes JSON Pointer reserved characters in the root $ref", () => {
2647
- const User = z.object({ name: z.string() }).meta({ id: "Shared/User~" });
2648
- const result = z.toJSONSchema(User);
2649
- expect(result.$ref).toBe("#/$defs/Shared~1User~0");
2650
- expect(Object.keys(result.$defs!)).toEqual(["Shared/User~"]);
2651
- });
2652
-
2653
- test("a multipleOf divisor JSON Schema cannot express goes through `unrepresentable`", () => {
2654
- // the keyword must be strictly greater than zero, and NaN/Infinity do not survive JSON at all
2655
- for (const divisor of [0, Number.NaN, Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY]) {
2656
- expect(() => z.toJSONSchema(z.number().multipleOf(divisor))).toThrow(/cannot be represented in JSON Schema/);
2657
- expect(z.toJSONSchema(z.number().multipleOf(divisor), { unrepresentable: "any" })).toMatchObject({
2658
- type: "number",
2659
- });
2660
- expect(z.toJSONSchema(z.number().multipleOf(divisor), { unrepresentable: "any" })).not.toHaveProperty("multipleOf");
2661
- }
2662
-
2663
- // a negative divisor accepts exactly what its absolute value accepts, so it still maps
2664
- expect(z.number().multipleOf(-5).safeParse(10).success).toEqual(true);
2665
- expect(z.number().multipleOf(-5).safeParse(13).success).toEqual(false);
2666
- expect(z.toJSONSchema(z.number().multipleOf(-5))).toMatchObject({ multipleOf: 5 });
2667
- expect(z.toJSONSchema(z.number().multipleOf(0.1))).toMatchObject({ multipleOf: 0.1 });
2668
- });
2669
-
2670
- test("unrepresentable default values go through `unrepresentable`", () => {
2671
- // a bigint default has no reliable JSON encoding, so it is dropped rather than approximated
2672
- expect(z.toJSONSchema(z.bigint().default(0n), { unrepresentable: "any" })).toMatchInlineSnapshot(`
2673
- {
2674
- "$schema": "https://json-schema.org/draft/2020-12/schema",
2675
- }
2676
- `);
2677
- expect(z.toJSONSchema(z.bigint().prefault(2n), { io: "input", unrepresentable: "any" })).toMatchInlineSnapshot(`
2678
- {
2679
- "$schema": "https://json-schema.org/draft/2020-12/schema",
2680
- }
2681
- `);
2682
- // including when nested inside an otherwise representable default
2683
- expect(
2684
- z.toJSONSchema(z.object({ a: z.bigint() }).default({ a: 1n }), { unrepresentable: "any" })
2685
- ).toMatchInlineSnapshot(`
2686
- {
2687
- "$schema": "https://json-schema.org/draft/2020-12/schema",
2688
- "additionalProperties": false,
2689
- "properties": {
2690
- "a": {},
2691
- },
2692
- "required": [
2693
- "a",
2694
- ],
2695
- "type": "object",
2696
- }
2697
- `);
2698
-
2699
- // under the default strict mode the inner type throws first; a representable inner type surfaces the default's own error rather than a raw `JSON.stringify` TypeError
2700
- expect(() => z.toJSONSchema(z.bigint().default(0n))).toThrow("BigInt cannot be represented in JSON Schema");
2701
- expect(() => z.toJSONSchema(z.unknown().default(1n))).toThrow("BigInt defaults cannot be represented in JSON Schema");
2702
-
2703
- // representable defaults are untouched
2704
- expect(z.toJSONSchema(z.object({ a: z.number() }).default({ a: 2 }))).toMatchInlineSnapshot(`
2705
- {
2706
- "$schema": "https://json-schema.org/draft/2020-12/schema",
2707
- "additionalProperties": false,
2708
- "default": {
2709
- "a": 2,
2710
- },
2711
- "properties": {
2712
- "a": {
2713
- "type": "number",
2714
- },
2715
- },
2716
- "required": [
2717
- "a",
2718
- ],
2719
- "type": "object",
2720
- }
2721
- `);
2722
- });
2723
-
2724
- test("an `unrepresentable` handler can represent a bigint default", () => {
2725
- // one handler covers both the type and its default, so no `unrepresentable: "any"` is needed and every other unrepresentable type still throws
2726
- expect(
2727
- z.toJSONSchema(z.object({ startAt: z.coerce.bigint().optional().default(0n) }), {
2728
- io: "input",
2729
- unrepresentable: ({ zodSchema }) => {
2730
- const def = zodSchema._zod.def;
2731
- if (def.type === "bigint") return { type: "integer", format: "int64" };
2732
- if (def.type === "default") return { default: String(def.defaultValue) };
2733
- return "throw";
2734
- },
2735
- })
2736
- ).toMatchInlineSnapshot(`
2737
- {
2738
- "$schema": "https://json-schema.org/draft/2020-12/schema",
2739
- "properties": {
2740
- "startAt": {
2741
- "default": "0",
2742
- "format": "int64",
2743
- "type": "integer",
2744
- },
2745
- },
2746
- "type": "object",
2747
- }
2748
- `);
2749
-
2750
- // a handler may also drop just the default while still representing the type
2751
- expect(
2752
- z.toJSONSchema(z.bigint().default(0n), {
2753
- unrepresentable: ({ zodSchema }) =>
2754
- zodSchema._zod.def.type === "bigint" ? { type: "integer", format: "int64" } : "any",
2755
- })
2756
- ).toMatchInlineSnapshot(`
2757
- {
2758
- "$schema": "https://json-schema.org/draft/2020-12/schema",
2759
- "format": "int64",
2760
- "type": "integer",
2761
- }
2762
- `);
2763
- });
2764
-
2765
- test("unrepresentable literal values are ignored", () => {
2766
- const a = z.toJSONSchema(z.literal(["hello", null, 5, BigInt(1324), undefined]), { unrepresentable: "any" });
2767
- expect(a).toMatchInlineSnapshot(`
2768
- {
2769
- "$schema": "https://json-schema.org/draft/2020-12/schema",
2770
- "enum": [
2771
- "hello",
2772
- null,
2773
- 5,
2774
- 1324,
2775
- ],
2776
- }
2777
- `);
2778
-
2779
- const b = z.toJSONSchema(z.literal([undefined, null, 5, BigInt(1324)]), {
2780
- unrepresentable: "any",
2781
- });
2782
- expect(b).toMatchInlineSnapshot(`
2783
- {
2784
- "$schema": "https://json-schema.org/draft/2020-12/schema",
2785
- "enum": [
2786
- null,
2787
- 5,
2788
- 1324,
2789
- ],
2790
- }
2791
- `);
2792
-
2793
- const c = z.toJSONSchema(z.literal([undefined]), {
2794
- unrepresentable: "any",
2795
- });
2796
- expect(c).toMatchInlineSnapshot(`
2797
- {
2798
- "$schema": "https://json-schema.org/draft/2020-12/schema",
2799
- }
2800
- `);
2801
- });
2802
-
2803
- test("describe with id", () => {
2804
- const jobId = z.string().meta({ id: "jobId" });
2805
-
2806
- const a = z.toJSONSchema(
2807
- z.object({
2808
- current: jobId.describe("Current job"),
2809
- previous: jobId.describe("Previous job"),
2810
- })
2811
- );
2812
- expect(a).toMatchInlineSnapshot(`
2813
- {
2814
- "$defs": {
2815
- "jobId": {
2816
- "type": "string",
2817
- },
2818
- },
2819
- "$schema": "https://json-schema.org/draft/2020-12/schema",
2820
- "additionalProperties": false,
2821
- "properties": {
2822
- "current": {
2823
- "$ref": "#/$defs/jobId",
2824
- "description": "Current job",
2825
- },
2826
- "previous": {
2827
- "$ref": "#/$defs/jobId",
2828
- "description": "Previous job",
2829
- },
2830
- },
2831
- "required": [
2832
- "current",
2833
- "previous",
2834
- ],
2835
- "type": "object",
2836
- }
2837
- `);
2838
- });
2839
-
2840
- test("id is stripped from $defs entries (draft-2020-12)", () => {
2841
- // The `id` in `.meta()` is a registration tag — it determines the $defs key but should not leak into the definition body, where it is redundant.
2842
- const inner = z.string().meta({ id: "Inner" });
2843
- const result = z.toJSONSchema(z.object({ a: inner, b: inner }));
2844
- expect(result.$defs?.Inner).toEqual({ type: "string" });
2845
- expect((result.$defs?.Inner as any).id).toBeUndefined();
2846
- });
2847
-
2848
- test("id is stripped from definitions entries (draft-04)", () => {
2849
- // In draft-04, `id` is a reserved keyword that sets a base URI for the subschema. Leaking Zod's registration tag here is semantically wrong, so ensure it is stripped.
2850
- const inner = z.string().meta({ id: "Inner" });
2851
- const result = z.toJSONSchema(z.object({ a: inner, b: inner }), { target: "draft-04" }) as any;
2852
- expect(result.definitions?.Inner).toEqual({ type: "string" });
2853
- expect(result.definitions?.Inner?.id).toBeUndefined();
2854
- });
2855
-
2856
- test("id is stripped from root schema", () => {
2857
- // The registration tag should not appear on the root either.
2858
- const A = z.object({ name: z.string() }).meta({ id: "A" });
2859
- const result = z.toJSONSchema(A);
2860
- expect((result as any).id).toBeUndefined();
2861
- });
2862
-
2863
- test("root schema with id is hoisted into $defs", () => {
2864
- const A = z.object({ name: z.string() }).meta({ id: "A" });
2865
- const result = z.toJSONSchema(A);
2866
-
2867
- expect(result).toEqual({
2868
- $schema: "https://json-schema.org/draft/2020-12/schema",
2869
- $ref: "#/$defs/A",
2870
- $defs: {
2871
- A: {
2872
- type: "object",
2873
- properties: {
2874
- name: {
2875
- type: "string",
2876
- },
2877
- },
2878
- required: ["name"],
2879
- additionalProperties: false,
2880
- },
2881
- },
2882
- });
2883
- });
2884
-
2885
- test("root schema with id uses definitions on legacy targets", () => {
2886
- const A = z.object({ name: z.string() }).meta({ id: "A" });
2887
- const result = z.toJSONSchema(A, { target: "draft-07" });
2888
-
2889
- expect(result).toEqual({
2890
- $schema: "http://json-schema.org/draft-07/schema#",
2891
- $ref: "#/definitions/A",
2892
- definitions: {
2893
- A: {
2894
- type: "object",
2895
- properties: {
2896
- name: {
2897
- type: "string",
2898
- },
2899
- },
2900
- required: ["name"],
2901
- additionalProperties: false,
2902
- },
2903
- },
2904
- });
2905
- });
2906
-
2907
- test("id is observable in override callback", () => {
2908
- // The strip happens after override callbacks run, so userland override code can still read `jsonSchema.id` if it wants to.
2909
- const inner = z.string().meta({ id: "Inner" });
2910
- const seenIds: Array<string | undefined> = [];
2911
- z.toJSONSchema(z.object({ a: inner }), {
2912
- override: ({ jsonSchema }) => {
2913
- if (jsonSchema.id !== undefined) seenIds.push(jsonSchema.id as string);
2914
- },
2915
- });
2916
- expect(seenIds).toContain("Inner");
2917
- });
2918
-
2919
- test("describe with id on wrapper", () => {
2920
- // Test that $ref propagation works when processor sets a different ref (readonly -> innerType) but parent was extracted due to having an id
2921
- const roJobId = z.string().readonly().meta({ id: "roJobId" });
2922
-
2923
- const a = z.toJSONSchema(
2924
- z.object({
2925
- current: roJobId.describe("Current readonly job"),
2926
- previous: roJobId.describe("Previous readonly job"),
2927
- })
2928
- );
2929
- expect(a).toMatchInlineSnapshot(`
2930
- {
2931
- "$defs": {
2932
- "roJobId": {
2933
- "readOnly": true,
2934
- "type": "string",
2935
- },
2936
- },
2937
- "$schema": "https://json-schema.org/draft/2020-12/schema",
2938
- "additionalProperties": false,
2939
- "properties": {
2940
- "current": {
2941
- "$ref": "#/$defs/roJobId",
2942
- "description": "Current readonly job",
2943
- },
2944
- "previous": {
2945
- "$ref": "#/$defs/roJobId",
2946
- "description": "Previous readonly job",
2947
- },
2948
- },
2949
- "required": [
2950
- "current",
2951
- "previous",
2952
- ],
2953
- "type": "object",
2954
- }
2955
- `);
2956
- });
2957
-
2958
- test("overwrite id", () => {
2959
- const jobId = z.string().meta({ id: "aaa" });
2960
-
2961
- const a = z.toJSONSchema(
2962
- z.object({
2963
- current: jobId,
2964
- previous: jobId.meta({ id: "bbb" }),
2965
- })
2966
- );
2967
- expect(a).toMatchInlineSnapshot(`
2968
- {
2969
- "$defs": {
2970
- "aaa": {
2971
- "type": "string",
2972
- },
2973
- "bbb": {
2974
- "$ref": "#/$defs/aaa",
2975
- },
2976
- },
2977
- "$schema": "https://json-schema.org/draft/2020-12/schema",
2978
- "additionalProperties": false,
2979
- "properties": {
2980
- "current": {
2981
- "$ref": "#/$defs/aaa",
2982
- },
2983
- "previous": {
2984
- "$ref": "#/$defs/bbb",
2985
- },
2986
- },
2987
- "required": [
2988
- "current",
2989
- "previous",
2990
- ],
2991
- "type": "object",
2992
- }
2993
- `);
2994
-
2995
- const b = z.toJSONSchema(
2996
- z.object({
2997
- current: jobId,
2998
- previous: jobId.meta({ id: "ccc" }),
2999
- }),
3000
- {
3001
- reused: "ref",
3002
- }
3003
- );
3004
- expect(b).toMatchInlineSnapshot(`
3005
- {
3006
- "$defs": {
3007
- "aaa": {
3008
- "type": "string",
3009
- },
3010
- "ccc": {
3011
- "$ref": "#/$defs/aaa",
3012
- },
3013
- },
3014
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3015
- "additionalProperties": false,
3016
- "properties": {
3017
- "current": {
3018
- "$ref": "#/$defs/aaa",
3019
- },
3020
- "previous": {
3021
- "$ref": "#/$defs/ccc",
3022
- },
3023
- },
3024
- "required": [
3025
- "current",
3026
- "previous",
3027
- ],
3028
- "type": "object",
3029
- }
3030
- `);
3031
- });
3032
-
3033
- test("overwrite descriptions", () => {
3034
- const field = z.string().describe("a").describe("b").describe("c");
3035
-
3036
- const a = z.toJSONSchema(
3037
- z.object({
3038
- d: field.describe("d"),
3039
- e: field.describe("e"),
3040
- })
3041
- );
3042
- expect(a).toMatchInlineSnapshot(`
3043
- {
3044
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3045
- "additionalProperties": false,
3046
- "properties": {
3047
- "d": {
3048
- "description": "d",
3049
- "type": "string",
3050
- },
3051
- "e": {
3052
- "description": "e",
3053
- "type": "string",
3054
- },
3055
- },
3056
- "required": [
3057
- "d",
3058
- "e",
3059
- ],
3060
- "type": "object",
3061
- }
3062
- `);
3063
-
3064
- const b = z.toJSONSchema(
3065
- z.object({
3066
- d: field.describe("d"),
3067
- e: field.describe("e"),
3068
- }),
3069
- {
3070
- reused: "ref",
3071
- }
3072
- );
3073
- expect(b).toMatchInlineSnapshot(`
3074
- {
3075
- "$defs": {
3076
- "__schema0": {
3077
- "description": "c",
3078
- "type": "string",
3079
- },
3080
- },
3081
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3082
- "additionalProperties": false,
3083
- "properties": {
3084
- "d": {
3085
- "$ref": "#/$defs/__schema0",
3086
- "description": "d",
3087
- },
3088
- "e": {
3089
- "$ref": "#/$defs/__schema0",
3090
- "description": "e",
3091
- },
3092
- },
3093
- "required": [
3094
- "d",
3095
- "e",
3096
- ],
3097
- "type": "object",
3098
- }
3099
- `);
3100
- });
3101
-
3102
- test("top-level readonly", () => {
3103
- const A = z
3104
- .object({
3105
- name: z.string(),
3106
- get b() {
3107
- return B;
3108
- },
3109
- })
3110
- .readonly()
3111
- .meta({ id: "A" });
3112
- // z.globalRegistry.add(A, { id: "A" });
3113
- // .meta({ id: "A" });
3114
-
3115
- const B = z
3116
- .object({
3117
- name: z.string(),
3118
- get a() {
3119
- return A;
3120
- },
3121
- })
3122
- .readonly()
3123
- .meta({ id: "B" });
3124
- // z.globalRegistry.add(B, { id: "B" });
3125
- // .meta({ id: "B" });
3126
-
3127
- const result = z.toJSONSchema(A);
3128
- expect(result).toEqual({
3129
- $schema: "https://json-schema.org/draft/2020-12/schema",
3130
- $ref: "#/$defs/A",
3131
- $defs: {
3132
- A: {
3133
- additionalProperties: false,
3134
- properties: {
3135
- b: {
3136
- $ref: "#/$defs/B",
3137
- },
3138
- name: {
3139
- type: "string",
3140
- },
3141
- },
3142
- readOnly: true,
3143
- required: ["name", "b"],
3144
- type: "object",
3145
- },
3146
- B: {
3147
- additionalProperties: false,
3148
- properties: {
3149
- a: {
3150
- $ref: "#/$defs/A",
3151
- },
3152
- name: {
3153
- type: "string",
3154
- },
3155
- },
3156
- readOnly: true,
3157
- required: ["name", "a"],
3158
- type: "object",
3159
- },
3160
- },
3161
- });
3162
- });
3163
-
3164
- test("basic registry", () => {
3165
- const myRegistry = z.registry<{ id: string }>();
3166
- const User = z.object({
3167
- name: z.string(),
3168
- get posts() {
3169
- return z.array(Post);
3170
- },
3171
- });
3172
-
3173
- const Post = z.object({
3174
- title: z.string(),
3175
- content: z.string(),
3176
- get author() {
3177
- return User;
3178
- },
3179
- });
3180
-
3181
- myRegistry.add(User, { id: "User" });
3182
- myRegistry.add(Post, { id: "Post" });
3183
-
3184
- const result = z.toJSONSchema(myRegistry, {
3185
- uri: (id) => `https://example.com/${id}.json`,
3186
- });
3187
- expect(result).toMatchInlineSnapshot(`
3188
- {
3189
- "schemas": {
3190
- "Post": {
3191
- "$id": "https://example.com/Post.json",
3192
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3193
- "additionalProperties": false,
3194
- "properties": {
3195
- "author": {
3196
- "$ref": "https://example.com/User.json",
3197
- },
3198
- "content": {
3199
- "type": "string",
3200
- },
3201
- "title": {
3202
- "type": "string",
3203
- },
3204
- },
3205
- "required": [
3206
- "title",
3207
- "content",
3208
- "author",
3209
- ],
3210
- "type": "object",
3211
- },
3212
- "User": {
3213
- "$id": "https://example.com/User.json",
3214
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3215
- "additionalProperties": false,
3216
- "properties": {
3217
- "name": {
3218
- "type": "string",
3219
- },
3220
- "posts": {
3221
- "items": {
3222
- "$ref": "https://example.com/Post.json",
3223
- },
3224
- "type": "array",
3225
- },
3226
- },
3227
- "required": [
3228
- "name",
3229
- "posts",
3230
- ],
3231
- "type": "object",
3232
- },
3233
- },
3234
- }
3235
- `);
3236
- });
3237
-
3238
- function countMapScanWork<T>(convert: () => T): { result: T; work: number } {
3239
- const entries = Map.prototype.entries;
3240
- const values = Map.prototype.values;
3241
- let work = 0;
3242
- const entriesSpy = vi.spyOn(Map.prototype, "entries").mockImplementation(function (this: Map<unknown, unknown>) {
3243
- work += this.size;
3244
- return entries.call(this);
3245
- } as typeof Map.prototype.entries);
3246
- const valuesSpy = vi.spyOn(Map.prototype, "values").mockImplementation(function (this: Map<unknown, unknown>) {
3247
- work += this.size;
3248
- return values.call(this);
3249
- } as typeof Map.prototype.values);
3250
- try {
3251
- return { result: convert(), work };
3252
- } finally {
3253
- entriesSpy.mockRestore();
3254
- valuesSpy.mockRestore();
3255
- }
3256
- }
3257
-
3258
- test("large registry conversion performs linear map-scan work", () => {
3259
- const count = 64;
3260
- const convert = (size: number, withIntersection: boolean) => {
3261
- const registry = z.registry<{ id: string }>();
3262
- for (let i = 0; i < size; i++) {
3263
- registry.add(
3264
- z.object({ id: z.string(), name: z.string(), count: z.number(), nested: z.object({ a: z.boolean() }) }),
3265
- { id: `Type${i}` }
3266
- );
3267
- }
3268
- if (withIntersection) registry.add(z.object({ a: z.string() }).and(z.object({ b: z.string() })), { id: "Inter" });
3269
-
3270
- return countMapScanWork(() => z.toJSONSchema(registry, { uri: (id) => `https://example.com/${id}.json` }));
3271
- };
3272
-
3273
- const plain = convert(count, false);
3274
- const plainDouble = convert(count * 2, false);
3275
- expect(Object.keys(plain.result.schemas)).toHaveLength(count);
3276
- expect(plain.result.schemas.Type0).toMatchObject({
3277
- $id: "https://example.com/Type0.json",
3278
- type: "object",
3279
- properties: { nested: { type: "object" } },
3280
- });
3281
- expect(plain.result.schemas[`Type${count - 1}`]!.$id).toBe(`https://example.com/Type${count - 1}.json`);
3282
- expect(plain.work).toBeGreaterThan(0);
3283
- expect(plainDouble.work).toBeLessThanOrEqual(plain.work * 2);
3284
-
3285
- const folded = convert(count, true);
3286
- const foldedDouble = convert(count * 2, true);
3287
- expect(folded.result.schemas.Inter).toMatchObject({ type: "object", properties: { a: {}, b: {} } });
3288
- expect(folded.work).toBeGreaterThan(0);
3289
- expect(foldedDouble.work).toBeLessThanOrEqual(folded.work * 2);
3290
- });
3291
-
3292
- test("a registry of records with numeric keys performs linear map-scan work", () => {
3293
- const count = 64;
3294
- const convert = (size: number, key: (i: number) => z.core.$ZodType) => {
3295
- const registry = z.registry<{ id: string }>();
3296
- for (let i = 0; i < size; i++) {
3297
- registry.add(z.object({ m: z.record(key(i) as z.core.$ZodRecordKey, z.boolean()) }), { id: `Type${i}` });
3298
- }
3299
- return countMapScanWork(() => z.toJSONSchema(registry, { uri: (id) => `https://example.com/${id}.json` }));
3300
- };
3301
-
3302
- const numeric = convert(count, () => z.number());
3303
- const numericDouble = convert(count * 2, () => z.number());
3304
- expect(numeric.result.schemas.Type0).toMatchObject({
3305
- properties: { m: { propertyNames: { type: "string", pattern: "^-?\\d+(?:\\.\\d+)?$" } } },
3306
- });
3307
- expect(numeric.work).toBeGreaterThan(0);
3308
- expect(numericDouble.work).toBeLessThanOrEqual(numeric.work * 2);
3309
-
3310
- const extracted = convert(count, (i) => z.number().meta({ id: `Key${i}` }));
3311
- const extractedDouble = convert(count * 2, (i) => z.number().meta({ id: `Key${i}` }));
3312
- expect(extracted.result.schemas.Type0).toMatchObject({
3313
- properties: { m: { propertyNames: { type: "string", pattern: "^-?\\d+(?:\\.\\d+)?$" } } },
3314
- });
3315
- expect(extracted.work).toBeGreaterThan(0);
3316
- expect(extractedDouble.work).toBeLessThanOrEqual(extracted.work * 2);
3317
- });
3318
-
3319
- test("registry extracts unregistered subschemas into __shared", () => {
3320
- const registry = z.registry<{ id: string }>();
3321
- const address = z.object({ street: z.string() }).meta({ id: "Address" });
3322
- registry.add(z.object({ home: address, work: address }), { id: "Person" });
3323
- registry.add(z.object({ hq: address }), { id: "Company" });
3324
-
3325
- const { schemas } = z.toJSONSchema(registry, { uri: (id) => `https://example.com/${id}.json` });
3326
-
3327
- expect(schemas.__shared).toMatchInlineSnapshot(`
3328
- {
3329
- "$defs": {
3330
- "Address": {
3331
- "additionalProperties": false,
3332
- "properties": {
3333
- "street": {
3334
- "type": "string",
3335
- },
3336
- },
3337
- "required": [
3338
- "street",
3339
- ],
3340
- "type": "object",
3341
- },
3342
- },
3343
- }
3344
- `);
3345
- expect(schemas.Person).toMatchInlineSnapshot(`
3346
- {
3347
- "$id": "https://example.com/Person.json",
3348
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3349
- "additionalProperties": false,
3350
- "properties": {
3351
- "home": {
3352
- "$ref": "https://example.com/__shared.json#/$defs/Address",
3353
- },
3354
- "work": {
3355
- "$ref": "https://example.com/__shared.json#/$defs/Address",
3356
- },
3357
- },
3358
- "required": [
3359
- "home",
3360
- "work",
3361
- ],
3362
- "type": "object",
3363
- }
3364
- `);
3365
- // Company is emitted after Person, so it only resolves if the shared $defs built on the first finalize are still reachable — the pass that writes them no longer runs per schema.
3366
- expect(schemas.Company!.properties!.hq).toEqual({
3367
- $ref: "https://example.com/__shared.json#/$defs/Address",
3368
- });
3369
- });
3370
-
3371
- test("registry extracts reused subschemas into __shared without an id", () => {
3372
- const registry = z.registry<{ id: string }>();
3373
- const shared = z.object({ q: z.string() });
3374
- registry.add(z.object({ a: shared, b: shared }), { id: "First" });
3375
- registry.add(z.object({ c: shared }), { id: "Second" });
3376
-
3377
- const { schemas } = z.toJSONSchema(registry, { uri: (id) => `${id}.json`, reused: "ref" });
3378
-
3379
- // The id is counter-generated, so this pins that ctx.counter is consumed exactly once.
3380
- expect(Object.keys(schemas.__shared!.$defs!)).toEqual(["schema0"]);
3381
- expect(schemas.First!.properties!.a).toEqual({ $ref: "__shared.json#/$defs/schema0" });
3382
- expect(schemas.Second!.properties!.c).toEqual({ $ref: "__shared.json#/$defs/schema0" });
3383
- });
3384
-
3385
- test("JSONSchemaGenerator re-runs shared passes when emit params change", () => {
3386
- const shared = z.object({ s: z.string() });
3387
- const a = z.object({ x: shared, y: shared });
3388
- const registry = z.registry<{ id: string }>();
3389
- registry.add(a, { id: "A" });
3390
-
3391
- const gen = new z.core.JSONSchemaGenerator({ target: "draft-2020-12" });
3392
- gen.process(a);
3393
- const defs: Record<string, any> = {};
3394
- const external = { registry, uri: (id: string) => `${id}.json`, defs };
3395
-
3396
- gen.emit(a, { external, reused: "inline" });
3397
- // Same `external`, different `reused` — the second emit must still extract `shared`.
3398
- const second: any = gen.emit(a, { external, reused: "ref" });
3399
-
3400
- expect(Object.keys(defs)).toEqual(["schema0"]);
3401
- expect(second.properties.x).toEqual({ $ref: "__shared.json#/$defs/schema0" });
3402
- expect(second.properties.y).toEqual({ $ref: "__shared.json#/$defs/schema0" });
3403
- });
3404
-
3405
- test("JSONSchemaGenerator still throws on cycles when a later emit asks for it", () => {
3406
- const Node: any = z.object({
3407
- v: z.string(),
3408
- get next() {
3409
- return Node;
3410
- },
3411
- });
3412
- const registry = z.registry<{ id: string }>();
3413
- registry.add(Node, { id: "Node" });
3414
-
3415
- const gen = new z.core.JSONSchemaGenerator({ target: "draft-2020-12" });
3416
- gen.process(Node);
3417
- const external = { registry, uri: (id: string) => `${id}.json`, defs: {} };
3418
-
3419
- gen.emit(Node, { external, cycles: "ref" });
3420
- expect(() => gen.emit(Node, { external, cycles: "throw" })).toThrow(/Cycle detected/);
3421
- });
3422
-
3423
- test("JSONSchemaGenerator re-runs shared passes on a no-params emit", () => {
3424
- const shared = z.object({ s: z.string() });
3425
- const a = z.object({ x: shared });
3426
- const registry = z.registry<{ id: string }>();
3427
- registry.add(a, { id: "A" });
3428
-
3429
- const gen = new z.core.JSONSchemaGenerator({ target: "draft-2020-12" });
3430
- gen.process(a);
3431
- const defs: Record<string, any> = {};
3432
- gen.emit(a, { external: { registry, uri: (id: string) => `${id}.json`, defs }, reused: "ref" });
3433
-
3434
- // Re-processing an already-seen schema bumps `seen.count`, which `extractDefs` branches on under `reused: "ref"` — and it returns early, so it cannot clear the guards itself.
3435
- gen.process(shared);
3436
- const second: any = gen.emit(a);
3437
-
3438
- expect(Object.keys(defs)).toEqual(["schema0"]);
3439
- expect(second.properties.x).toEqual({ $ref: "__shared.json#/$defs/schema0" });
3440
- });
3441
-
3442
- test("_ref", () => {
3443
- // const a = z.promise(z.string().describe("a"));
3444
- const a = z.toJSONSchema(z.promise(z.string().describe("a")));
3445
- expect(a).toMatchInlineSnapshot(`
3446
- {
3447
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3448
- "description": "a",
3449
- "type": "string",
3450
- }
3451
- `);
3452
-
3453
- const b = z.toJSONSchema(z.lazy(() => z.string().describe("a")));
3454
- expect(b).toMatchInlineSnapshot(`
3455
- {
3456
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3457
- "description": "a",
3458
- "type": "string",
3459
- }
3460
- `);
3461
-
3462
- const c = z.toJSONSchema(z.optional(z.string().describe("a")));
3463
- expect(c).toMatchInlineSnapshot(`
3464
- {
3465
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3466
- "description": "a",
3467
- "type": "string",
3468
- }
3469
- `);
3470
-
3471
- const d = z.toJSONSchema(z.string().meta({ id: "foo" }).describe("bar").optional());
3472
- expect(d).toMatchInlineSnapshot(`
3473
- {
3474
- "$defs": {
3475
- "foo": {
3476
- "type": "string",
3477
- },
3478
- },
3479
- "$ref": "#/$defs/foo",
3480
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3481
- "description": "bar",
3482
- }
3483
- `);
3484
- });
3485
-
3486
- test("defaults/prefaults", () => {
3487
- const a = z
3488
- .string()
3489
- .transform((val) => val.length)
3490
- .pipe(z.number());
3491
- const b = a.prefault("hello");
3492
- const c = a.default(1234);
3493
-
3494
- // a
3495
- expect(z.toJSONSchema(a)).toMatchInlineSnapshot(`
3496
- {
3497
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3498
- "type": "number",
3499
- }
3500
- `);
3501
- expect(z.toJSONSchema(a, { io: "input" })).toMatchInlineSnapshot(`
3502
- {
3503
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3504
- "type": "string",
3505
- }
3506
- `);
3507
-
3508
- // b
3509
- expect(z.toJSONSchema(b)).toMatchInlineSnapshot(`
3510
- {
3511
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3512
- "type": "number",
3513
- }
3514
- `);
3515
- expect(z.toJSONSchema(b, { io: "input" })).toMatchInlineSnapshot(`
3516
- {
3517
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3518
- "default": "hello",
3519
- "type": "string",
3520
- }
3521
- `);
3522
- // c
3523
- expect(z.toJSONSchema(c)).toMatchInlineSnapshot(`
3524
- {
3525
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3526
- "default": 1234,
3527
- "type": "number",
3528
- }
3529
- `);
3530
- expect(z.toJSONSchema(c, { io: "input" })).toMatchInlineSnapshot(`
3531
- {
3532
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3533
- "type": "string",
3534
- }
3535
- `);
3536
- });
3537
-
3538
- test("catch on a transforming schema", () => {
3539
- const a = z
3540
- .string()
3541
- .transform((val) => val.length)
3542
- .pipe(z.number())
3543
- .catch(0);
3544
-
3545
- expect(z.toJSONSchema(a)).toMatchInlineSnapshot(`
3546
- {
3547
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3548
- "default": 0,
3549
- "type": "number",
3550
- }
3551
- `);
3552
- // catch values are output-typed, so they are not valid input
3553
- expect(z.toJSONSchema(a, { io: "input" })).toMatchInlineSnapshot(`
3554
- {
3555
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3556
- "type": "string",
3557
- }
3558
- `);
3559
-
3560
- // the catch no longer hides the inner transform from ancestors, so their output-typed metadata is stripped too — matching a bare nested transform
3561
- expect(z.toJSONSchema(z.object({ a }).meta({ examples: [{ a: 1 }] }), { io: "input" })).toMatchInlineSnapshot(`
3562
- {
3563
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3564
- "properties": {
3565
- "a": {
3566
- "type": "string",
3567
- },
3568
- },
3569
- "required": [
3570
- "a",
3571
- ],
3572
- "type": "object",
3573
- }
3574
- `);
3575
- });
3576
-
3577
- test("falsy prefaults (false, 0, empty string)", () => {
3578
- // boolean prefault false
3579
- const a = z.boolean().prefault(false);
3580
- expect(z.toJSONSchema(a, { io: "input" })).toMatchInlineSnapshot(`
3581
- {
3582
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3583
- "default": false,
3584
- "type": "boolean",
3585
- }
3586
- `);
3587
-
3588
- // number prefault 0
3589
- const b = z.number().prefault(0);
3590
- expect(z.toJSONSchema(b, { io: "input" })).toMatchInlineSnapshot(`
3591
- {
3592
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3593
- "default": 0,
3594
- "type": "number",
3595
- }
3596
- `);
3597
-
3598
- // string prefault empty string
3599
- const c = z.string().prefault("");
3600
- expect(z.toJSONSchema(c, { io: "input" })).toMatchInlineSnapshot(`
3601
- {
3602
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3603
- "default": "",
3604
- "type": "string",
3605
- }
3606
- `);
3607
- });
3608
-
3609
- test("input type", () => {
3610
- const schema = z.object({
3611
- a: z.string(),
3612
- b: z.string().optional(),
3613
- c: z.string().default("hello"),
3614
- d: z.string().nullable(),
3615
- e: z.string().prefault("hello"),
3616
- f: z.string().catch("hello"),
3617
- g: z.never(),
3618
- h: z.union([z.string(), z.number().default(2)]),
3619
- i: z.union([z.string(), z.string().optional()]),
3620
- });
3621
- expect(z.toJSONSchema(schema, { io: "input" })).toMatchInlineSnapshot(`
3622
- {
3623
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3624
- "properties": {
3625
- "a": {
3626
- "type": "string",
3627
- },
3628
- "b": {
3629
- "type": "string",
3630
- },
3631
- "c": {
3632
- "default": "hello",
3633
- "type": "string",
3634
- },
3635
- "d": {
3636
- "type": [
3637
- "string",
3638
- "null",
3639
- ],
3640
- },
3641
- "e": {
3642
- "default": "hello",
3643
- "type": "string",
3644
- },
3645
- "f": {
3646
- "default": "hello",
3647
- "type": "string",
3648
- },
3649
- "g": {
3650
- "not": {},
3651
- },
3652
- "h": {
3653
- "anyOf": [
3654
- {
3655
- "type": "string",
3656
- },
3657
- {
3658
- "default": 2,
3659
- "type": "number",
3660
- },
3661
- ],
3662
- },
3663
- "i": {
3664
- "type": "string",
3665
- },
3666
- },
3667
- "required": [
3668
- "a",
3669
- "d",
3670
- "f",
3671
- "g",
3672
- ],
3673
- "type": "object",
3674
- }
3675
- `);
3676
- expect(z.toJSONSchema(schema, { io: "output" })).toMatchInlineSnapshot(`
3677
- {
3678
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3679
- "additionalProperties": false,
3680
- "properties": {
3681
- "a": {
3682
- "type": "string",
3683
- },
3684
- "b": {
3685
- "type": "string",
3686
- },
3687
- "c": {
3688
- "default": "hello",
3689
- "type": "string",
3690
- },
3691
- "d": {
3692
- "type": [
3693
- "string",
3694
- "null",
3695
- ],
3696
- },
3697
- "e": {
3698
- "type": "string",
3699
- },
3700
- "f": {
3701
- "default": "hello",
3702
- "type": "string",
3703
- },
3704
- "g": {
3705
- "not": {},
3706
- },
3707
- "h": {
3708
- "anyOf": [
3709
- {
3710
- "type": "string",
3711
- },
3712
- {
3713
- "default": 2,
3714
- "type": "number",
3715
- },
3716
- ],
3717
- },
3718
- "i": {
3719
- "type": "string",
3720
- },
3721
- },
3722
- "required": [
3723
- "a",
3724
- "c",
3725
- "d",
3726
- "e",
3727
- "f",
3728
- "g",
3729
- "h",
3730
- ],
3731
- "type": "object",
3732
- }
3733
- `);
3734
- });
3735
-
3736
- test("examples on pipe", () => {
3737
- const schema = z
3738
- .string()
3739
- .meta({ examples: ["test"] })
3740
- .transform(Number)
3741
- // .pipe(z.transform(Number).meta({ examples: [4] }))
3742
- .meta({ examples: [4] });
3743
-
3744
- const i = z.toJSONSchema(schema, { io: "input", unrepresentable: "any" });
3745
- expect(i).toMatchInlineSnapshot(`
3746
- {
3747
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3748
- "examples": [
3749
- "test",
3750
- ],
3751
- "type": "string",
3752
- }
3753
- `);
3754
- const o = z.toJSONSchema(schema, { io: "output", unrepresentable: "any" });
3755
- expect(o).toMatchInlineSnapshot(`
3756
- {
3757
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3758
- "examples": [
3759
- 4,
3760
- ],
3761
- }
3762
- `);
3763
- });
3764
-
3765
- // test("number checks", () => {
3766
- // expect(z.toJSONSchema(z.number().int())).toMatchInlineSnapshot(`
3767
- // {
3768
- // "maximum": 9007199254740991,
3769
- // "minimum": -9007199254740991,
3770
- // "type": "integer",
3771
- // }
3772
- // `);
3773
- // expect(z.toJSONSchema(z.int())).toMatchInlineSnapshot(`
3774
- // {
3775
- // "maximum": 9007199254740991,
3776
- // "minimum": -9007199254740991,
3777
- // "type": "integer",
3778
- // }
3779
- // `);
3780
- // expect(z.toJSONSchema(z.int().positive())).toMatchInlineSnapshot(`
3781
- // {
3782
- // "exclusiveMinimum": 0,
3783
- // "maximum": 9007199254740991,
3784
- // "minimum": -9007199254740991,
3785
- // "type": "integer",
3786
- // }
3787
- // `);
3788
- // expect(z.toJSONSchema(z.int().nonnegative())).toMatchInlineSnapshot(`
3789
- // {
3790
- // "maximum": 9007199254740991,
3791
- // "minimum": 0,
3792
- // "type": "integer",
3793
- // }
3794
- // `);
3795
- // expect(z.toJSONSchema(z.int().gt(0))).toMatchInlineSnapshot(`
3796
- // {
3797
- // "exclusiveMinimum": 0,
3798
- // "maximum": 9007199254740991,
3799
- // "minimum": -9007199254740991,
3800
- // "type": "integer",
3801
- // }
3802
- // `);
3803
- // expect(z.toJSONSchema(z.int().gte(0))).toMatchInlineSnapshot(`
3804
- // {
3805
- // "maximum": 9007199254740991,
3806
- // "minimum": 0,
3807
- // "type": "integer",
3808
- // }
3809
- // `);
3810
-
3811
- // });
3812
-
3813
- test("use output type for preprocess", () => {
3814
- const a = z.preprocess((val) => String(val), z.string());
3815
-
3816
- expect(z.toJSONSchema(a, { io: "input" })).toMatchInlineSnapshot(`
3817
- {
3818
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3819
- "type": "string",
3820
- }
3821
- `);
3822
- });
3823
-
3824
- test("object property with preprocess stays required in input JSON schema", () => {
3825
- const schema = z.object({
3826
- noPreprocess: z.string(),
3827
- withPreprocess: z.preprocess((v) => v, z.string()),
3828
- optionalPreprocess: z.preprocess((v) => v, z.string().optional()),
3829
- });
3830
-
3831
- // A preprocessed property is only optional when its inner schema is — the
3832
- // transform wrapper must not make a required property optional in the input
3833
- // JSON schema (matches runtime: `schema.parse({})` rejects `withPreprocess`).
3834
- expect(z.toJSONSchema(schema, { io: "input" })).toMatchInlineSnapshot(`
3835
- {
3836
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3837
- "properties": {
3838
- "noPreprocess": {
3839
- "type": "string",
3840
- },
3841
- "optionalPreprocess": {
3842
- "type": "string",
3843
- },
3844
- "withPreprocess": {
3845
- "type": "string",
3846
- },
3847
- },
3848
- "required": [
3849
- "noPreprocess",
3850
- "withPreprocess",
3851
- ],
3852
- "type": "object",
3853
- }
3854
- `);
3855
- });
3856
-
3857
- test("input JSON schema resolves requiredness past transform and catch wrappers", () => {
3858
- const required = (schema: z.ZodObject) =>
3859
- (z.toJSONSchema(schema, { io: "input" }) as z.core.JSONSchema.ObjectSchema).required;
3860
- const id = (v: unknown) => v;
3861
-
3862
- // catch observes an absent key at runtime, but its declared input type stays required (#5003)
3863
- expect(required(z.object({ a: z.string().catch("x") }))).toEqual(["a"]);
3864
- expect(required(z.object({ a: z.string().optional().catch("x") }))).toBeUndefined();
3865
- // nested preprocess and the legacy transform-pipe form both resolve through to the inner schema
3866
- expect(required(z.object({ a: z.preprocess(id, z.preprocess(id, z.string())) }))).toEqual(["a"]);
3867
- expect(required(z.object({ a: z.transform((v: unknown) => String(v)).pipe(z.string()) }))).toEqual(["a"]);
3868
- });
3869
-
3870
- test("object required keys preserve shape order and direction", () => {
3871
- const symbol = Symbol("symbol");
3872
- const shape: z.ZodRawShape = {
3873
- 10: z.string(),
3874
- 2: z.string().optional(),
3875
- plain: z.string(),
3876
- optional: z.string().optional(),
3877
- defaulted: z.string().default("x"),
3878
- caught: z.string().catch("x"),
3879
- [symbol]: z.string(),
3880
- };
3881
- Object.defineProperty(shape, "__proto__", { value: z.string(), enumerable: true });
3882
- Object.defineProperty(shape, "hidden", { value: z.string(), enumerable: false });
3883
-
3884
- const input = z.toJSONSchema(z.object(shape), { io: "input", unrepresentable: "any" });
3885
- const output = z.toJSONSchema(z.object(shape), { io: "output", unrepresentable: "any" });
3886
-
3887
- expect(Object.keys(input.properties!)).toEqual(["2", "10", "plain", "optional", "defaulted", "caught", "__proto__"]);
3888
- expect(input.required).toEqual(["10", "plain", "caught", "__proto__"]);
3889
- expect(output.required).toEqual(["10", "plain", "defaulted", "caught", "__proto__"]);
3890
- expect(Object.prototype.hasOwnProperty.call(input.properties!, "__proto__")).toBe(true);
3891
- expect(input.properties).not.toHaveProperty("hidden");
3892
- expect(Object.getOwnPropertySymbols(input.properties!)).toEqual([]);
3893
- });
3894
-
3895
- test("strip output-side examples from input JSON schema for codec", () => {
3896
- const codec = z
3897
- .codec(z.string(), z.number(), { decode: (s) => Number(s), encode: (n) => String(n) })
3898
- .meta({ examples: [42] });
3899
-
3900
- expect(z.toJSONSchema(codec, { io: "input" })).toMatchInlineSnapshot(`
3901
- {
3902
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3903
- "type": "string",
3904
- }
3905
- `);
3906
- expect(z.toJSONSchema(codec, { io: "output" })).toMatchInlineSnapshot(`
3907
- {
3908
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3909
- "examples": [
3910
- 42,
3911
- ],
3912
- "type": "number",
3913
- }
3914
- `);
3915
- });
3916
-
3917
- // test("isTransforming", () => {
3918
- // const tx = z.core.isTransforming;
3919
- // expect(tx(z.string())).toEqual(false);
3920
- // expect(tx(z.string().transform((val) => val))).toEqual(true);
3921
- // expect(tx(z.string().pipe(z.string()))).toEqual(false);
3922
- // expect(
3923
- // tx(
3924
- // z
3925
- // .string()
3926
- // .transform((val) => val)
3927
- // .pipe(z.string())
3928
- // )
3929
- // ).toEqual(true);
3930
-
3931
- // const a = z.transform((val) => val);
3932
- // expect(tx(z.transform((val) => val))).toEqual(true);
3933
- // expect(tx(a.optional())).toEqual(true);
3934
-
3935
- // const b = z.string().optional();
3936
- // expect(tx(b)).toEqual(false);
3937
-
3938
- // const c = z.string().prefault("hello");
3939
- // expect(tx(c)).toEqual(false);
3940
-
3941
- // const d = z.string().default("hello");
3942
- // expect(tx(d)).toEqual(false);
3943
- // });
3944
-
3945
- test("flatten simple intersections", () => {
3946
- const FirstSchema = z.object({
3947
- testNum: z.number(),
3948
- });
3949
-
3950
- const SecondSchema = z.object({
3951
- testStr: z.string(),
3952
- });
3953
-
3954
- const ThirdSchema = z.object({
3955
- testBool: z.boolean(),
3956
- });
3957
-
3958
- const HelloSchema = FirstSchema.and(SecondSchema).and(ThirdSchema).describe("123");
3959
-
3960
- // Zod 3
3961
- // console.log(JSON.stringify(zodToJsonSchema(HelloSchema), null, 2));
3962
-
3963
- // Zod 4
3964
- const result = z.toJSONSchema(HelloSchema, { target: "draft-7" });
3965
- expect(result).toMatchInlineSnapshot(`
3966
- {
3967
- "$schema": "http://json-schema.org/draft-07/schema#",
3968
- "additionalProperties": false,
3969
- "description": "123",
3970
- "properties": {
3971
- "testBool": {
3972
- "type": "boolean",
3973
- },
3974
- "testNum": {
3975
- "type": "number",
3976
- },
3977
- "testStr": {
3978
- "type": "string",
3979
- },
3980
- },
3981
- "required": [
3982
- "testNum",
3983
- "testStr",
3984
- "testBool",
3985
- ],
3986
- "type": "object",
3987
- }
3988
- `);
3989
- });
3990
-
3991
- test("z.file()", () => {
3992
- const a = z.file();
3993
- expect(z.toJSONSchema(a)).toMatchInlineSnapshot(`
3994
- {
3995
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3996
- "contentEncoding": "binary",
3997
- "format": "binary",
3998
- "type": "string",
3999
- }
4000
- `);
4001
-
4002
- const b = z.file().mime("image/png").min(1000).max(10000);
4003
- expect(z.toJSONSchema(b)).toMatchInlineSnapshot(`
4004
- {
4005
- "$schema": "https://json-schema.org/draft/2020-12/schema",
4006
- "contentEncoding": "binary",
4007
- "contentMediaType": "image/png",
4008
- "format": "binary",
4009
- "maxLength": 10000,
4010
- "minLength": 1000,
4011
- "type": "string",
4012
- }
4013
- `);
4014
-
4015
- const c = z.file().mime(["image/png", "image/jpg"]).min(1000).max(10000);
4016
- expect(z.toJSONSchema(c)).toMatchInlineSnapshot(`
4017
- {
4018
- "$schema": "https://json-schema.org/draft/2020-12/schema",
4019
- "anyOf": [
4020
- {
4021
- "contentMediaType": "image/png",
4022
- },
4023
- {
4024
- "contentMediaType": "image/jpg",
4025
- },
4026
- ],
4027
- "contentEncoding": "binary",
4028
- "format": "binary",
4029
- "maxLength": 10000,
4030
- "minLength": 1000,
4031
- "type": "string",
4032
- }
4033
- `);
4034
- });
4035
-
4036
- test("custom toJSONSchema", () => {
4037
- const schema = z.instanceof(Date);
4038
- schema._zod.toJSONSchema = () => ({
4039
- type: "string",
4040
- format: "date-time",
4041
- });
4042
-
4043
- expect(z.toJSONSchema(schema)).toMatchInlineSnapshot(`
4044
- {
4045
- "$schema": "https://json-schema.org/draft/2020-12/schema",
4046
- "format": "date-time",
4047
- "type": "string",
4048
- }
4049
- `);
4050
- });
4051
-
4052
- test("cycle detection - root", () => {
4053
- const schema = z.object({
4054
- name: z.string(),
4055
- get subcategories() {
4056
- return z.array(schema);
4057
- },
4058
- });
4059
-
4060
- expect(() => z.toJSONSchema(schema, { cycles: "throw" })).toThrowErrorMatchingInlineSnapshot(`
4061
- [Error: Cycle detected: #/properties/subcategories/items/<root>
4062
-
4063
- Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.]
4064
- `);
4065
- });
4066
-
4067
- test("cycle detection - mutual recursion", () => {
4068
- const A = z.object({
4069
- name: z.string(),
4070
- get subcategories() {
4071
- return z.array(B);
4072
- },
4073
- });
4074
-
4075
- const B = z.object({
4076
- name: z.string(),
4077
- get subcategories() {
4078
- return z.array(A);
4079
- },
4080
- });
4081
-
4082
- expect(() => z.toJSONSchema(A, { cycles: "throw" })).toThrowErrorMatchingInlineSnapshot(`
4083
- [Error: Cycle detected: #/properties/subcategories/items/properties/subcategories/items/<root>
4084
-
4085
- Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.]
4086
- `);
4087
- });
4088
-
4089
- test("recursive lazy with describe does not stack overflow", () => {
4090
- const NodeSchema: z.ZodType = z.lazy(() =>
4091
- z
4092
- .object({
4093
- value: z.string().describe("node value"),
4094
- children: z.array(NodeSchema.describe("child node")).optional().describe("child list"),
4095
- })
4096
- .describe("tree node")
4097
- );
4098
-
4099
- const result = z.toJSONSchema(NodeSchema, { cycles: "ref", reused: "ref" });
4100
- expect(result).toBeDefined();
4101
- expect(result.$defs).toBeDefined();
4102
- });
4103
-
4104
- test("__proto__ shape key is emitted as an own property", () => {
4105
- const schema = z.object({ ["__proto__"]: z.literal("admin"), role: z.string() });
4106
- const result = z.toJSONSchema(schema, { io: "input" });
4107
-
4108
- expect(result.required).toEqual(["__proto__", "role"]);
4109
- // every required key needs a matching entry in properties
4110
- for (const key of result.required!) {
4111
- expect(Object.prototype.hasOwnProperty.call(result.properties, key)).toBe(true);
4112
- }
4113
- expect(JSON.parse(JSON.stringify(result)).properties.__proto__).toEqual({ type: "string", const: "admin" });
4114
- });
4115
-
4116
- test("__proto__ registry id is emitted as an own entry", () => {
4117
- const myRegistry = z.registry<{ id: string }>();
4118
- myRegistry.add(z.object({ a: z.string() }), { id: "__proto__" });
4119
- myRegistry.add(z.object({ b: z.string() }), { id: "normal" });
4120
-
4121
- expect(Object.keys(z.toJSONSchema(myRegistry).schemas)).toEqual(["__proto__", "normal"]);
4122
- });
4123
-
4124
- test("__proto__ def id emits a resolvable $ref", () => {
4125
- const myRegistry = z.registry<{ id: string }>();
4126
- const Inner = z.object({ x: z.string() });
4127
- myRegistry.add(Inner, { id: "__proto__" });
4128
-
4129
- const json = JSON.parse(JSON.stringify(z.toJSONSchema(z.object({ a: Inner, b: Inner }), { metadata: myRegistry })));
4130
- expect(json.properties.a.$ref).toBe("#/$defs/__proto__");
4131
- expect(json.$defs.__proto__).toBeDefined();
4132
- });
4133
-
4134
- test("__proto__ patternProperties key is emitted as an own property", () => {
4135
- const result = z.toJSONSchema(z.looseRecord(z.string().regex(/__proto__/), z.string()));
4136
-
4137
- expect(Object.getPrototypeOf(result.patternProperties)).toBe(Object.prototype);
4138
- expect(Object.prototype.hasOwnProperty.call(result.patternProperties, "__proto__")).toBe(true);
4139
- expect(result.patternProperties?.__proto__).toEqual({ type: "string" });
4140
- });
4141
-
4142
- test("__proto__ metadata survives direct and wrapper metadata merges", () => {
4143
- for (const schema of [z.string(), z.readonly(z.string())]) {
4144
- const registry = z.registry<Record<string, unknown>>();
4145
- registry.add(schema, Object.fromEntries([["__proto__", { marker: true }]]));
4146
-
4147
- const result: any = z.toJSONSchema(schema, { metadata: registry });
4148
- expect(Object.getPrototypeOf(result)).toBe(Object.prototype);
4149
- expect(Object.prototype.hasOwnProperty.call(result, "__proto__")).toBe(true);
4150
- expect(result.__proto__).toEqual({ marker: true });
4151
- expect(JSON.parse(JSON.stringify(result)).__proto__).toEqual({ marker: true });
4152
- }
4153
- });
4154
-
4155
- test("partialRecord does not require finite keys", () => {
4156
- const result = z.toJSONSchema(z.partialRecord(z.enum(["__proto__", "b"]), z.string()));
4157
-
4158
- expect(result.required).toBeUndefined();
4159
- expect(result.propertyNames).toEqual({ type: "string", enum: ["__proto__", "b"] });
4160
- expect(result.additionalProperties).toEqual({ type: "string" });
4161
- });
4162
-
4163
- describe("unrepresentable callback", () => {
4164
- test("is consulted for every unrepresentable type", () => {
4165
- const seen: string[] = [];
4166
- const collect: z.core.UnrepresentableHandler<z.core.$ZodTypes> = ({ zodSchema }) => {
4167
- seen.push(zodSchema._zod.def.type);
4168
- return "any";
4169
- };
4170
-
4171
- const schemas = [
4172
- z.bigint(),
4173
- z.symbol(),
4174
- z.undefined(),
4175
- z.void(),
4176
- z.date(),
4177
- z.nan(),
4178
- z.custom<string>(),
4179
- z.map(z.string(), z.string()),
4180
- z.set(z.string()),
4181
- z.transform((x: unknown) => x),
4182
- z.literal([undefined]),
4183
- z.literal([1n]),
4184
- z.string().catch(() => {
4185
- throw new Error("dynamic");
4186
- }),
4187
- // z.function() is not a ZodType, but its processor is reachable through the same path
4188
- z.function() as unknown as z.ZodType,
4189
- ];
4190
- for (const schema of schemas) z.toJSONSchema(schema, { unrepresentable: collect });
4191
-
4192
- expect(seen).toEqual([
4193
- "bigint",
4194
- "symbol",
4195
- "undefined",
4196
- "void",
4197
- "date",
4198
- "nan",
4199
- "custom",
4200
- "map",
4201
- "set",
4202
- "transform",
4203
- "literal",
4204
- "literal",
4205
- "catch",
4206
- "function",
4207
- ]);
4208
- });
4209
-
4210
- test("returned JSON Schema replaces the unrepresentable node", () => {
4211
- // the motivating case: represent dates, keep throwing for everything else
4212
- const params: z.core.ToJSONSchemaParams = {
4213
- unrepresentable: ({ zodSchema }) =>
4214
- zodSchema._zod.def.type === "date" ? { type: "string", format: "date-time" } : "throw",
4215
- };
4216
- expect(z.toJSONSchema(z.object({ when: z.date() }), params)).toMatchInlineSnapshot(`
4217
- {
4218
- "$schema": "https://json-schema.org/draft/2020-12/schema",
4219
- "additionalProperties": false,
4220
- "properties": {
4221
- "when": {
4222
- "format": "date-time",
4223
- "type": "string",
4224
- },
4225
- },
4226
- "required": [
4227
- "when",
4228
- ],
4229
- "type": "object",
4230
- }
4231
- `);
4232
- expect(() => z.toJSONSchema(z.object({ id: z.bigint() }), params)).toThrow(
4233
- "BigInt cannot be represented in JSON Schema"
4234
- );
4235
- });
4236
-
4237
- test("`throw` and `undefined` returns produce the default error", () => {
4238
- expect(() => z.toJSONSchema(z.date(), { unrepresentable: () => "throw" })).toThrow(
4239
- "Date cannot be represented in JSON Schema"
4240
- );
4241
- expect(() => z.toJSONSchema(z.date(), { unrepresentable: () => undefined })).toThrow(
4242
- "Date cannot be represented in JSON Schema"
4243
- );
4244
- });
4245
-
4246
- test("`any` return matches the string option", () => {
4247
- expect(z.toJSONSchema(z.date(), { unrepresentable: () => "any" })).toEqual(
4248
- z.toJSONSchema(z.date(), { unrepresentable: "any" })
4249
- );
4250
- });
4251
-
4252
- test("`message` distinguishes sites that share a schema", () => {
4253
- const seen: string[] = [];
4254
- expect(
4255
- z.toJSONSchema(z.literal([undefined, 1n, "a"]), {
4256
- unrepresentable: ({ zodSchema, message }) => {
4257
- seen.push(`${zodSchema._zod.def.type}: ${message}`);
4258
- return "any";
4259
- },
4260
- })
4261
- ).toMatchInlineSnapshot(`
4262
- {
4263
- "$schema": "https://json-schema.org/draft/2020-12/schema",
4264
- "enum": [
4265
- 1,
4266
- "a",
4267
- ],
4268
- }
4269
- `);
4270
- // same `zodSchema`, different message -- the only way to tell the two literal sites apart
4271
- expect(seen).toEqual([
4272
- "literal: Literal `undefined` cannot be represented in JSON Schema",
4273
- "literal: BigInt literals cannot be represented in JSON Schema",
4274
- ]);
4275
- });
4276
-
4277
- test("errors thrown by the callback propagate", () => {
4278
- expect(() =>
4279
- z.toJSONSchema(z.object({ when: z.date() }), {
4280
- unrepresentable: ({ zodSchema, path }) => {
4281
- throw new Error(`${zodSchema._zod.def.type} at /${path.join("/")}`);
4282
- },
4283
- })
4284
- ).toThrow("date at /properties/when");
4285
- });
4286
-
4287
- test("runs before `override`", () => {
4288
- const order: string[] = [];
4289
- expect(
4290
- z.toJSONSchema(z.date(), {
4291
- unrepresentable: () => {
4292
- order.push("unrepresentable");
4293
- return { type: "string" };
4294
- },
4295
- override: (ctx) => {
4296
- order.push("override");
4297
- if (ctx.jsonSchema.type === "string") ctx.jsonSchema.format = "date-time";
4298
- },
4299
- })
4300
- ).toMatchInlineSnapshot(`
4301
- {
4302
- "$schema": "https://json-schema.org/draft/2020-12/schema",
4303
- "format": "date-time",
4304
- "type": "string",
4305
- }
4306
- `);
4307
- expect(order).toEqual(["unrepresentable", "override"]);
4308
- });
4309
-
4310
- test("a returned schema replaces the whole literal", () => {
4311
- expect(
4312
- z.toJSONSchema(z.literal(["a", 1n]), {
4313
- unrepresentable: () => ({ type: "string", pattern: "^\\d+$" }),
4314
- })
4315
- ).toMatchInlineSnapshot(`
4316
- {
4317
- "$schema": "https://json-schema.org/draft/2020-12/schema",
4318
- "pattern": "^\\d+$",
4319
- "type": "string",
4320
- }
4321
- `);
4322
-
4323
- // "any" keeps the existing per-value behavior: undefined dropped, bigint coerced
4324
- expect(z.toJSONSchema(z.literal(["a", 1n, undefined]), { unrepresentable: () => "any" })).toEqual(
4325
- z.toJSONSchema(z.literal(["a", 1n, undefined]), { unrepresentable: "any" })
4326
- );
4327
- });
4328
-
4329
- const dateToString: z.core.ToJSONSchemaParams["unrepresentable"] = ({ zodSchema }) =>
4330
- zodSchema._zod.def.type === "date" ? { type: "string", format: "date-time" } : "throw";
4331
-
4332
- test("emits a valid OpenAPI 3.0 schema", async () => {
4333
- const jsonSchema = z.toJSONSchema(z.object({ start: z.date() }), {
4334
- target: "openapi-3.0",
4335
- unrepresentable: dateToString,
4336
- });
4337
- expect(jsonSchema).toMatchInlineSnapshot(`
4338
- {
4339
- "additionalProperties": false,
4340
- "properties": {
4341
- "start": {
4342
- "format": "date-time",
4343
- "type": "string",
4344
- },
4345
- },
4346
- "required": [
4347
- "start",
4348
- ],
4349
- "type": "object",
4350
- }
4351
- `);
4352
- await expect(validateOpenAPI30Schema(jsonSchema)).resolves.toBe(true);
4353
- });
4354
-
4355
- test("the returned schema survives extraction into $defs", () => {
4356
- const When = z.date().meta({ id: "When" });
4357
- expect(
4358
- z.toJSONSchema(z.object({ start: When, end: When }), { unrepresentable: dateToString })
4359
- ).toMatchInlineSnapshot(`
4360
- {
4361
- "$defs": {
4362
- "When": {
4363
- "format": "date-time",
4364
- "type": "string",
4365
- },
4366
- },
4367
- "$schema": "https://json-schema.org/draft/2020-12/schema",
4368
- "additionalProperties": false,
4369
- "properties": {
4370
- "end": {
4371
- "$ref": "#/$defs/When",
4372
- },
4373
- "start": {
4374
- "$ref": "#/$defs/When",
4375
- },
4376
- },
4377
- "required": [
4378
- "start",
4379
- "end",
4380
- ],
4381
- "type": "object",
4382
- }
4383
- `);
4384
- });
4385
-
4386
- test("applies to dynamic catch values", () => {
4387
- const schema = z.string().catch(() => {
4388
- throw new Error("dynamic");
4389
- });
4390
- expect(
4391
- z.toJSONSchema(schema, {
4392
- unrepresentable: () => ({ default: "fallback" }),
4393
- })
4394
- ).toMatchInlineSnapshot(`
4395
- {
4396
- "$schema": "https://json-schema.org/draft/2020-12/schema",
4397
- "default": "fallback",
4398
- "type": "string",
4399
- }
4400
- `);
4401
- });
4402
- });
4403
-
4404
- describe("intersection folding", () => {
4405
- const TARGETS = ["draft-2020-12", "draft-07", "draft-04", "openapi-3.0"] as const;
4406
- const body = (schema: z.ZodType, params?: Parameters<typeof z.toJSONSchema>[1]) => {
4407
- const { $schema, ...rest } = z.toJSONSchema(schema, params) as Record<string, unknown>;
4408
- return rest;
4409
- };
4410
-
4411
- test("two objects become one object", () => {
4412
- expect(body(z.object({ name: z.string() }).and(z.object({ age: z.number() })))).toMatchInlineSnapshot(`
4413
- {
4414
- "additionalProperties": false,
4415
- "properties": {
4416
- "age": {
4417
- "type": "number",
4418
- },
4419
- "name": {
4420
- "type": "string",
4421
- },
4422
- },
4423
- "required": [
4424
- "name",
4425
- "age",
4426
- ],
4427
- "type": "object",
4428
- }
4429
- `);
4430
- });
4431
-
4432
- test("the folded shape is identical on every target", () => {
4433
- const schema = z.object({ name: z.string() }).and(z.object({ age: z.number() }));
4434
- const bodies = TARGETS.map((target) => body(schema, { target }));
4435
- for (const emitted of bodies) expect(emitted).toEqual(bodies[0]);
4436
- });
4437
-
4438
- test("closed only when every member is closed", () => {
4439
- expect(body(z.strictObject({ a: z.string() }).and(z.strictObject({ b: z.number() })))).toMatchObject({
4440
- additionalProperties: false,
4441
- });
4442
- // A loose member keeps the intersection open, which is what the parser does: it merges both results, so the loose side's extra keys survive.
4443
- expect(body(z.looseObject({ a: z.string() }).and(z.object({ b: z.number() })))).not.toHaveProperty(
4444
- "additionalProperties"
4445
- );
4446
- });
4447
-
4448
- test("chained and nested intersections fold flat", () => {
4449
- const chained = z
4450
- .object({ a: z.string() })
4451
- .and(z.object({ b: z.string() }))
4452
- .and(z.object({ c: z.string() }));
4453
- expect(body(chained)).toMatchObject({ properties: { a: {}, b: {}, c: {} }, required: ["a", "b", "c"] });
4454
- const nested = z.object({ a: z.string() }).and(z.object({ b: z.string() }).and(z.object({ c: z.string() })));
4455
- expect(body(nested)).toEqual(body(chained));
4456
- });
4457
-
4458
- test("required is the union, and an optional key stays optional", () => {
4459
- expect(body(z.object({ a: z.string().optional() }).and(z.object({ b: z.string() })))).toMatchObject({
4460
- properties: { a: { type: "string" }, b: { type: "string" } },
4461
- required: ["b"],
4462
- });
4463
- });
4464
-
4465
- test("a key both members declare has to satisfy both", () => {
4466
- // identical declarations collapse
4467
- expect(body(z.object({ k: z.string() }).and(z.object({ k: z.string() })))).toMatchObject({
4468
- properties: { k: { type: "string" } },
4469
- });
4470
- // object declarations fold, matching the parser's deep merge
4471
- expect(
4472
- body(z.object({ k: z.object({ a: z.string() }) }).and(z.object({ k: z.object({ b: z.string() }) })))
4473
- ).toMatchObject({
4474
- properties: { k: { type: "object", properties: { a: {}, b: {} }, required: ["a", "b"] } },
4475
- });
4476
- // anything else stays an intersection one level down
4477
- expect(body(z.object({ k: z.string() }).and(z.object({ k: z.number() })))).toMatchObject({
4478
- properties: { k: { allOf: [{ type: "string" }, { type: "number" }] } },
4479
- });
4480
- });
4481
-
4482
- test("an intersection distributes over a union", () => {
4483
- const schema = z
4484
- .object({ name: z.string() })
4485
- .and(
4486
- z.discriminatedUnion("type", [
4487
- z.object({ type: z.literal("a"), value: z.string() }),
4488
- z.object({ type: z.literal("b"), count: z.number() }),
4489
- ])
4490
- );
4491
- expect(body(schema)).toMatchObject({
4492
- oneOf: [
4493
- { type: "object", properties: { name: {}, type: {}, value: {} }, additionalProperties: false },
4494
- { type: "object", properties: { name: {}, type: {}, count: {} }, additionalProperties: false },
4495
- ],
4496
- });
4497
- const inclusive = z
4498
- .object({ name: z.string() })
4499
- .and(z.union([z.object({ v: z.string() }), z.object({ c: z.number() })]));
4500
- expect(body(inclusive)).toMatchObject({
4501
- anyOf: [{ properties: { name: {}, v: {} } }, { properties: { name: {}, c: {} } }],
4502
- });
4503
- });
4504
-
4505
- test("input conversion has nothing to close", () => {
4506
- expect(body(z.object({ a: z.string() }).and(z.object({ b: z.string() })), { io: "input" })).toEqual({
4507
- type: "object",
4508
- properties: { a: { type: "string" }, b: { type: "string" } },
4509
- required: ["a", "b"],
4510
- });
4511
- });
4512
-
4513
- test("folds through a property and through z.lazy", () => {
4514
- expect(body(z.object({ inner: z.object({ a: z.string() }).and(z.object({ b: z.string() })) }))).toMatchObject({
4515
- properties: { inner: { type: "object", properties: { a: {}, b: {} } } },
4516
- });
4517
- const self: z.ZodType = z.lazy(() => z.object({ a: z.string() }).and(z.object({ next: z.optional(self) })));
4518
- expect(body(self)).toMatchObject({ type: "object", properties: { a: {}, next: { $ref: "#" } } });
4519
- });
4520
-
4521
- test("metadata on the intersection itself survives", () => {
4522
- expect(
4523
- body(
4524
- z
4525
- .object({ a: z.string() })
4526
- .and(z.object({ b: z.string() }))
4527
- .meta({ title: "T" })
4528
- )
4529
- ).toMatchObject({
4530
- title: "T",
4531
- type: "object",
4532
- properties: { a: {}, b: {} },
4533
- });
4534
- });
4535
-
4536
- test("a catchall constrains the sibling's keys too", () => {
4537
- // The catchall member does not declare `b`, so its `additionalProperties` is what it demands of `b`. Folding `b` into `properties` has to carry that demand across, or the key would escape it.
4538
- const schema = z
4539
- .object({ a: z.string() })
4540
- .catchall(z.number())
4541
- .and(z.object({ b: z.string() }));
4542
- expect(body(schema)).toEqual({
4543
- type: "object",
4544
- properties: { a: { type: "string" }, b: { allOf: [{ type: "number" }, { type: "string" }] } },
4545
- required: ["a", "b"],
4546
- additionalProperties: { type: "number" },
4547
- });
4548
- });
4549
-
4550
- test("two catchalls both constrain the keys neither declares", () => {
4551
- const schema = z
4552
- .object({})
4553
- .catchall(z.number())
4554
- .and(z.object({}).catchall(z.number().min(0)));
4555
- expect(body(schema)).toEqual({
4556
- type: "object",
4557
- properties: {},
4558
- additionalProperties: { allOf: [{ type: "number" }, { type: "number", minimum: 0 }] },
4559
- });
4560
- expect(schema.safeParse({ zz: 5 }).success).toBe(true);
4561
- expect(schema.safeParse({ zz: -1 }).success).toBe(false);
4562
- });
4563
-
4564
- test("the emitted openness agrees with the parser for every pair of object modes", () => {
4565
- const modes = {
4566
- strip: (shape: z.ZodRawShape) => z.object(shape),
4567
- strict: (shape: z.ZodRawShape) => z.strictObject(shape),
4568
- loose: (shape: z.ZodRawShape) => z.looseObject(shape),
4569
- catchall: (shape: z.ZodRawShape) => z.object(shape).catchall(z.number()),
4570
- };
4571
- const grid: Record<string, unknown> = {};
4572
- for (const [leftName, left] of Object.entries(modes)) {
4573
- for (const [rightName, right] of Object.entries(modes)) {
4574
- const schema = left({ a: z.string() }).and(right({ b: z.number() }));
4575
- const emitted = body(schema) as { additionalProperties?: unknown };
4576
- grid[`${leftName} & ${rightName}`] = emitted.additionalProperties ?? "open";
4577
-
4578
- // Whatever the emitted keyword says, it has to agree with what the parser does with a key neither member declares.
4579
- const parsed = schema.safeParse({ a: "s", b: 1, zz: 7 });
4580
- const keepsUnknown = parsed.success && Object.prototype.hasOwnProperty.call(parsed.data, "zz");
4581
- if (keepsUnknown) expect(emitted.additionalProperties).not.toBe(false);
4582
- }
4583
- }
4584
- expect(grid).toMatchInlineSnapshot(`
4585
- {
4586
- "catchall & catchall": {
4587
- "type": "number",
4588
- },
4589
- "catchall & loose": {
4590
- "type": "number",
4591
- },
4592
- "catchall & strict": {
4593
- "type": "number",
4594
- },
4595
- "catchall & strip": {
4596
- "type": "number",
4597
- },
4598
- "loose & catchall": {
4599
- "type": "number",
4600
- },
4601
- "loose & loose": "open",
4602
- "loose & strict": "open",
4603
- "loose & strip": "open",
4604
- "strict & catchall": {
4605
- "type": "number",
4606
- },
4607
- "strict & loose": "open",
4608
- "strict & strict": false,
4609
- "strict & strip": false,
4610
- "strip & catchall": {
4611
- "type": "number",
4612
- },
4613
- "strip & loose": "open",
4614
- "strip & strict": false,
4615
- "strip & strip": false,
4616
- }
4617
- `);
4618
- });
4619
-
4620
- test("a __proto__ key stays an own property", () => {
4621
- const folded = body(z.object({ ["__proto__"]: z.string() }).and(z.object({ b: z.number() }))) as any;
4622
- expect(Object.prototype.hasOwnProperty.call(folded.properties, "__proto__")).toBe(true);
4623
- expect(folded.required).toEqual(["__proto__", "b"]);
4624
- });
4625
- });
4626
-
4627
- describe("intersection folding declines", () => {
4628
- // Every case here keeps the `allOf` it produces today. The fold only understands the four object keywords, so a member carrying anything else is left alone rather than having a constraint dropped or an annotation re-scoped.
4629
- const allOf = (schema: z.ZodType, params?: Parameters<typeof z.toJSONSchema>[1]) =>
4630
- (z.toJSONSchema(schema, params) as any).allOf;
4631
-
4632
- test("a member that is a reference keeps its reference", () => {
4633
- const named = z.object({ a: z.string() }).meta({ id: "Named" });
4634
- expect(allOf(named.and(z.object({ b: z.string() })))[0]).toEqual({ $ref: "#/$defs/Named" });
4635
-
4636
- const shared = z.object({ c: z.string() });
4637
- const reused = z.toJSONSchema(z.object({ x: shared.and(z.object({ d: z.string() })), y: shared }), {
4638
- reused: "ref",
4639
- }) as any;
4640
- expect(reused.properties.x.allOf[0]).toEqual({ $ref: "#/$defs/__schema0" });
4641
-
4642
- const cyclic: any = z.object({
4643
- get next() {
4644
- return z.optional(cyclic);
4645
- },
4646
- n: z.string(),
4647
- });
4648
- expect(allOf(cyclic.and(z.object({ m: z.string() })))[0].$ref).toBe("#/$defs/__schema0");
4649
- });
4650
-
4651
- test("an annotated member keeps its place", () => {
4652
- expect(
4653
- allOf(
4654
- z
4655
- .object({ a: z.string() })
4656
- .describe("A")
4657
- .and(z.object({ b: z.string() }))
4658
- )[0]
4659
- ).toMatchObject({
4660
- description: "A",
4661
- });
4662
- });
4663
-
4664
- test("members that are not plain objects are left alone", () => {
4665
- expect(allOf(z.intersection(z.string().min(2), z.string().max(5)))).toHaveLength(2);
4666
- expect(allOf(z.object({ a: z.string() }).and(z.nullable(z.object({ b: z.string() }))))).toHaveLength(2);
4667
- expect(
4668
- allOf(z.object({ label: z.string() }).and(z.looseRecord(z.string().regex(/^label:[a-z]{2}$/), z.string())))
4669
- ).toHaveLength(2);
4670
- });
4671
-
4672
- test("a shared member is never rewritten for its other uses", () => {
4673
- const shared = z.object({ c: z.string() });
4674
- const result = z.toJSONSchema(z.object({ x: shared.and(z.object({ d: z.string() })), y: shared })) as any;
4675
- expect(result.properties.x).toMatchObject({ properties: { c: {}, d: {} }, additionalProperties: false });
4676
- // `y` is the same Zod schema, emitted separately, and keeps the closedness it had on its own.
4677
- expect(result.properties.y).toEqual({
4678
- type: "object",
4679
- properties: { c: { type: "string" } },
4680
- required: ["c"],
4681
- additionalProperties: false,
4682
- });
4683
- });
4684
-
4685
- test("registry conversion keeps its cross-references", () => {
4686
- const registry = z.registry<{ id: string }>();
4687
- const left = z.object({ p: z.string() });
4688
- const right = z.object({ q: z.string() });
4689
- registry.add(left, { id: "P" });
4690
- registry.add(right, { id: "Q" });
4691
- registry.add(left.and(right), { id: "PQ" });
4692
- expect((z.toJSONSchema(registry) as any).schemas.PQ.allOf).toEqual([{ $ref: "P" }, { $ref: "Q" }]);
4693
- });
4694
-
4695
- test("override still runs, and sees the intersection before it folds", () => {
4696
- const schema = z.object({ a: z.string() }).and(z.object({ b: z.string() }));
4697
- const result = z.toJSONSchema(schema, {
4698
- override(ctx) {
4699
- if ((ctx.jsonSchema as any).allOf) (ctx.jsonSchema as any).title = "intersection";
4700
- },
4701
- }) as any;
4702
- expect(result).toMatchObject({ title: "intersection", type: "object", properties: { a: {}, b: {} } });
4703
- });
4704
-
4705
- test("an override that writes object keywords wins over the fold", () => {
4706
- // The override runs first, so anything it puts on the intersection is deliberate. Folding would overwrite it silently, so the fold stands down instead.
4707
- const result = z.toJSONSchema(z.object({ a: z.string() }).and(z.object({ b: z.string() })), {
4708
- override(ctx) {
4709
- if ((ctx.jsonSchema as any).allOf) (ctx.jsonSchema as any).additionalProperties = true;
4710
- },
4711
- }) as any;
4712
- expect(result.additionalProperties).toBe(true);
4713
- expect(result.allOf).toHaveLength(2);
4714
- });
4715
-
4716
- test("more than one union member is left alone rather than multiplied out", () => {
4717
- // The second union lands among the members the first is distributed across, and a union is not an object, so every branch fails to fold and the whole intersection stands down.
4718
- const schema = z
4719
- .object({ a: z.string() })
4720
- .and(z.union([z.object({ v: z.string() }), z.object({ w: z.string() })]))
4721
- .and(z.union([z.object({ x: z.string() }), z.object({ y: z.string() })]));
4722
- expect(allOf(schema)).toHaveLength(3);
4723
- });
4724
- });
4725
-
4726
- test("currency code", () => {
4727
- expect(z.toJSONSchema(z.currencyCode())).toEqual({
4728
- $schema: "https://json-schema.org/draft/2020-12/schema",
4729
- type: "string",
4730
- format: "currency_code",
4731
- pattern: z.regexes.currencyCode.source,
4732
- });
4733
- });