Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
"big.js": "^7.0.1",
"cosmjs-types": "^0.9.0",
"immer": "^10.1.1",
"zod": "^3.25.62"
"zod": "^4.0.17"
Copy link
Contributor

@coderabbitai coderabbitai bot Aug 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Consider making zod a peerDependency (to avoid duplicate instances and type incompatibilities)

If any exported APIs expose Zod schemas/types or consumers are expected to use z.infer on your exported schemas, zod should be a peerDependency (and a devDependency for local build/tests) rather than a runtime dependency. This prevents multiple Zod copies in downstream apps and avoids type identity issues.

To decide, scan for Zod usage in exported surfaces:

If results indicate exposure, consider this change:

   "dependencies": {
@@
-    "zod": "^4.0.17"
+  },
+  "peerDependencies": {
+    "zod": "^4.0.0"
   },
   "devDependencies": {
@@
+    "zod": "^4.0.17",

If Zod is strictly internal and never leaks through the public API, keeping it in dependencies is acceptable.


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Exported symbols that reference z.* =="
rg -n --no-heading $'^export\\s+(type|interface|const|function|class)\\b[^{=]*\\{?[^\\n]*\\bz\\.' -S || true

echo
echo "== Exported types using z.infer =="
rg -n --no-heading $'^export\\s+type\\b[^=]*=\\s*z\\.infer' -S || true

echo
echo "== Direct re-exports from zod (should be none) =="
rg -n --no-heading $'^export\\s+\\*\\s+from\\s+[\'"]zod[\'"]' -S || true

Length of output: 4532


Move Zod into peerDependencies & devDependencies

Zod schemas and z.infer types are exposed in your public API (see src/schema/**/*.ts and src/utils/find-move-events.ts), so you must declare Zod as a peerDependency (and as a devDependency for tests/build) rather than a runtime dependency:

• Remove from dependencies (currently at package.json:61)
• Add to peerDependencies (e.g. "zod": "^4.0.0")
• Add to devDependencies (e.g. "zod": "^4.0.17")

Suggested diff in package.json:

   "dependencies": {
-    "zod": "^4.0.17"
   },
+  "peerDependencies": {
+    "zod": "^4.0.0"
+  },
   "devDependencies": {
+    "zod": "^4.0.17",
     …other dev deps
   }

Note: if you officially support Yarn (classic/berry), you may keep Zod in dependencies to ensure installation for Yarn users (since Yarn does not auto‐install peerDependencies) while still declaring it as a peerDependency to avoid duplicate instances.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"zod": "^4.0.17"
"dependencies": {
},
"peerDependencies": {
"zod": "^4.0.0"
},
"devDependencies": {
"zod": "^4.0.17",
…other dev deps
}

💡 Verification agent

🧩 Analysis chain

Major version bump to Zod v4: audit for breaking changes and ESM/CJS interop

Upgrading from v3 → v4 is a breaking change. Given this package publishes both ESM and CJS builds (Lines 14–28), verify:

  • Zod v4 compatibility with your current usage.
  • Whether Zod v4 is ESM-only and how tsup handles it for your CJS output. If Zod remains externalized and ESM-only, requiring it from CJS can break.

Run the following to quickly assess impact in-repo and locate build config:

And please fetch authoritative details on v4 to confirm expectations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Zod import sites =="
rg -n --no-heading $'from\\s+[\'"]zod[\'"]|require\\([\'"]zod[\'"]\\)' -S || true

echo
echo "== Potentially brittle deep imports (should be none) =="
rg -n --no-heading $'from\\s+[\'"]zod/|require\\([\'"]zod/' -S || true

echo
echo "== Common Zod API usage overview (for migration review) =="
rg -n --no-heading $'\\bz\\.(object|array|union|discriminatedUnion|enum|nativeEnum|string|number|bigint|boolean|date|literal|tuple|record|map|set|nullable|optional|default|catch|transform|preprocess|refine|superRefine|effects|coerce)' -S || true

echo
echo "== tsup configuration (to validate externals/bundling) =="
fd -H -a '^tsup\\.config\\.(ts|js|cjs|mjs)$' || true

Length of output: 25136


🌐 Web query:

Zod v4 migration guide and breaking changes. Also, does Zod v4 ship a CommonJS build or is it ESM-only?

💡 Result:

Zod v4 introduces several breaking changes (with an official migration guide), and it is published in a way that supports both ESM and CommonJS consumers—but Zod v4 is accessed via the subpath import zod/v4, which can require Node/TypeScript “Node16/NodeNext/Bundler” module resolution when used from CommonJS toolchains.[5][8][9]

Key Zod v4 breaking changes and migration notes

  • Error path handling: Zod 4’s new parsing architecture no longer eagerly computes ctx.path; direct access to ctx.path was dropped to enable performance gains.[5]
  • Function-as-second-argument overload removed: The old “horrifying overload” for refinements/transformers that accepted a function as a second argument has been removed; migrate to the v4 API forms documented in the guide.[5]
  • Optional shorthand creators removed: Undocumented shorthands like z.ostring(), z.onumber(), etc., were dropped; switch to z.string().optional(), z.number().optional(), etc.[5]
  • Static .create() factories removed: All Zod classes no longer have a static .create(); use the standalone factory functions (e.g., z.object(...), z.string(), etc.).[5]
  • z.record() changes:
    • Single-argument usage removed; you must provide both key and value schemas where appropriate.[5]
    • Enum key support improved: passing an enum as the key schema now infers exhaustive records and enforces all enum keys exist; to get the old “partial” behavior use the new z.partialRecord().[5]
  • z.intersection() behavior: On merge conflicts of incompatible results, Zod 4 now throws a regular Error (not a ZodError with "invalid_intersection_types"), signaling a structural schema issue.[5]

Official migration resources and ecosystem transition

  • Versioning approach: Zod 4 is exported first at subpath "zod/v4" alongside Zod 3 at the root ("zod") and at "zod/v3", enabling incremental migration across apps and libraries; later, the package root switches to export Zod 4 while "zod/v4" remains available.[8]
  • Practical impact: If you import from "zod/v4" you’re on v4 APIs; if you import from "zod" you may still be on v3 until the root flips (noted as already completed on that page). Libraries should import only from the versioned subpaths to remain compatible.[8]
  • Community codemod: A community-maintained codemod zod-v3-to-v4 is available to help update common API changes (error handling, object/string APIs, and other breaking changes).[1][5]

ESM vs. CommonJS: does Zod v4 ship a CJS build?

  • Packaging and consumption: The maintainers deliberately ship Zod 4 via the "zod/v4" subpath along with Zod 3, and it is consumable from both ESM and CommonJS projects; however, TypeScript module resolution needs to be compatible with package subpath exports (Node16/NodeNext/Bundler) when importing "zod/v4" from CJS builds.[8][9]
  • Reported CJS friction and workaround: Users compiling a CommonJS build reported “Cannot find module 'zod/v4'” under classic TS moduleResolution; switching tsconfig to module: "Node16" and moduleResolution: "Node16" resolved it, aligning TS with Node’s subpath exports resolution.[9] If you remain purely "commonjs" with classic resolution, you may see TS1479 or resolution errors; dynamic import("zod/v4") is another workaround suggested by TypeScript when mixing CJS with ESM exports.[9]
  • Summary: Zod v4 is not “ESM-only,” but its subpath export and type resolution expect modern Node/TypeScript module resolution settings. In CommonJS projects, configure TS to Node16/NodeNext/Bundler or use dynamic import if you cannot change settings.[8][9]

Additional notes and cautions

  • Zod 3 and 4 co-publishing: During the transition, Zod 3 continued to be published while including Zod 4 under subpaths; some users found that upgrading Zod 3 to late 3.25.x inadvertently pulled in v4 code that requires newer TS (TS 5.x), causing breakages in TS 4.x toolchains. Pin to earlier 3.x if you must stay on TS 4.x.[2][8]
  • Learning resources: The v4 migration guide lists changes in order of impact and is the canonical source for updating code.[5] A video overview is also available for a practical tour of new features.[7] A codemod can automate common changes.[1]

If you share a small snippet of your current Zod v3 usage, I can map the exact v4 replacements and flag any path/error handling you’ll need to adjust.[5][1]

Citations:


Major version bump to Zod v4: replace default import & verify build interop

  • In src/schema/transaction.ts, change the default import to a named import (v4 no longer provides a default export):
    - import z from "zod";
    + import { z } from "zod";
  • No deep imports of zod/… were found—every schema uses top-level APIs (z.object, z.union, z.preprocess, z.coerce, etc.), all compatible with v4.
  • Zod v4 ships both ESM and CJS from the root "zod"; double-check your tsup build (inline CLI flags in package.json) to ensure:
    zod is either externalized or bundled correctly in both your ESM and CJS outputs
    • your TypeScript moduleResolution (e.g. Node16/NodeNext) aligns with Node’s subpath export rules if you ever switch to zod/v4

Committable suggestion skipped: line range outside the PR's diff.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@evilpeach any idea?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me check and test it first.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please consider yarn which does not automatically install peerDependencies.

},
"devDependencies": {
"@eslint/js": "^9.28.0",
Expand Down
30 changes: 15 additions & 15 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.