Skip to content

Comments

fix(utils): fs utils cleanup#7609

Merged
paulbalaji merged 8 commits intomainfrom
pbio/utils-fs-fixes
Dec 15, 2025
Merged

fix(utils): fs utils cleanup#7609
paulbalaji merged 8 commits intomainfrom
pbio/utils-fs-fixes

Conversation

@paulbalaji
Copy link
Collaborator

@paulbalaji paulbalaji commented Dec 12, 2025

Summary

  • Use stringifyObject in writeJson and writeYaml for proper ethers BigNumber serialization
  • Rename removeEndingSlash to removeTrailingSlash for consistency

Changes

  • writeJson and writeYaml now use stringifyObject to handle ethers BigNumber serialization (converts to hex strings instead of { _hex: "...", _isBigNumber: true })
  • removeEndingSlash renamed to removeTrailingSlash

What's NOT changing

  • Generic type parameters (<T>) on read functions are kept - they provide compile-time type safety
  • eslint-rules stay in @hyperlane-xyz/utils - needed for hyperlane-registry compatibility

Test plan

  • All existing tests pass
  • Build succeeds

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Improved BigNumber serialization in JSON and YAML output handling.
  • Refactor

    • Updated function naming for consistency across utilities.

✏️ Tip: You can customize this high-level summary in your review settings.

paulbalaji and others added 4 commits December 12, 2025 14:18
…lash

- Update writeJson to use stringifyObject instead of JSON.stringify
  to properly handle ethers BigNumber serialization
- Rename removeEndingSlash to removeTrailingSlash for consistency
  with JSDoc and common terminology

Addresses review feedback from #7558 and #7559

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Move sort-yaml-arrays rule to infra/eslint-rules (only consumer)
- Remove unused no-restricted-imports-from-exports rule
- Remove eslint-plugin-yml and yaml-eslint-parser deps from utils
- Export sortNestedArrays, transformYaml, ArraySortConfig from utils

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…ions

Remove generic type parameters from readJson, tryReadJson, readJsonFromDir,
readYamlOrJson, yamlParse, readYaml, tryReadYaml, and readYamlFromDir.

These functions now return the implicit `any` from JSON.parse()/yaml parse(),
avoiding false impression of type validation. Callers are responsible for
ensuring type safety.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@changeset-bot
Copy link

changeset-bot bot commented Dec 12, 2025

🦋 Changeset detected

Latest commit: 7b6b16e

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 19 packages
Name Type
@hyperlane-xyz/utils Patch
@hyperlane-xyz/core Patch
@hyperlane-xyz/aleo-sdk Patch
@hyperlane-xyz/ccip-server Patch
@hyperlane-xyz/cli Patch
@hyperlane-xyz/cosmos-sdk Patch
@hyperlane-xyz/deploy-sdk Patch
@hyperlane-xyz/helloworld Patch
@hyperlane-xyz/http-registry-server Patch
@hyperlane-xyz/infra Patch
@hyperlane-xyz/provider-sdk Patch
@hyperlane-xyz/radix-sdk Patch
@hyperlane-xyz/sdk Patch
@hyperlane-xyz/widgets Patch
@hyperlane-xyz/starknet-core Patch
@hyperlane-xyz/cosmos-types Patch
@hyperlane-xyz/eslint-config Patch
@hyperlane-xyz/github-proxy Patch
@hyperlane-xyz/tsconfig Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

paulbalaji and others added 2 commits December 12, 2025 15:23
Update writeYaml to use stringifyObject (with 'yaml' format) for consistency
with writeJson. This ensures proper ethers BigNumber serialization when
writing YAML files.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Update all call sites in cli and infra packages to remove generic type
arguments after the read functions were changed to return implicit any.
This fixes the build errors caused by "Expected 0 type arguments, but got 1".

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@paulbalaji
Copy link
Collaborator Author

once #7610 is merged and pulled into this branch, the infra-test action will pass again

@paulbalaji paulbalaji marked this pull request as ready for review December 12, 2025 17:16
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 12, 2025

📝 Walkthrough

Walkthrough

This change renames the utility function removeEndingSlash to removeTrailingSlash across the codebase and updates JSON/YAML serialization functions to use stringifyObject for proper BigNumber handling in ethers compatibility.

Changes

Cohort / File(s) Summary
Changeset Entry
.changeset/beige-foxes-compare.md
Documents two main changes: patch dependency addition and function rename plus serialization updates
Function Rename—Utils
typescript/utils/src/fs/utils.ts, typescript/utils/src/fs/utils.test.ts
Renames removeEndingSlash to removeTrailingSlash in function definition and updates test suite accordingly
Function Rename—Exports
typescript/utils/src/fs/index.ts, typescript/cli/src/utils/files.ts
Updates import and re-export declarations to reference the renamed removeTrailingSlash function
Function Rename—Consumer
typescript/cli/src/commands/warp.ts
Updates import statement to use renamed removeTrailingSlash utility
Serialization Updates
typescript/utils/src/fs/json.ts, typescript/utils/src/fs/yaml.ts
Replaces JSON.stringify and yamlStringify with stringifyObject utility to handle ethers BigNumber serialization

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

The changes follow consistent patterns—mostly straightforward renaming across related files and two similar serialization replacements. Reviewers should verify that:

  • All usages of the renamed function have been updated consistently across the import/export chain
  • The stringifyObject utility properly handles BigNumber serialization in both JSON and YAML contexts

Suggested reviewers

  • yorhodes
  • ltyu
  • Mo-Hussain
  • Xaroz
  • xeno097

Poem

Like an ogre's layers, this change goes deep,
From trailing slashes to BigNumbers to keep,
A rename here, serialization there,
Consistency spreads throughout the air. 🧅✨

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Description check ❓ Inconclusive The description covers the main changes and test results, but doesn't follow the required template structure with all specified sections like 'Related issues' and 'Backward compatibility'. Structure the description to match the template: add 'Related issues' section and explicitly address 'Backward compatibility' implications of the public API function rename.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately reflects the main change - fixing BigNumber serialization in writeJson/writeYaml, though it doesn't mention the function rename which is also a significant part of the changeset.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch pbio/utils-fs-fixes

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@hyper-gonk
Copy link
Contributor

hyper-gonk bot commented Dec 12, 2025

🐳 Monorepo Docker Image Built Successfully

Image Tags:

gcr.io/abacus-labs-dev/hyperlane-monorepo:pr-7609
gcr.io/abacus-labs-dev/hyperlane-monorepo:d4c7029-20251212-172104

Copy link
Contributor

@antigremlin antigremlin left a comment

Choose a reason for hiding this comment

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

That made me think more...

Revert the removal of generic type parameters from JSON/YAML read
functions. Type-casts provide compile-time safety even without runtime
validation, which is better than implicit any.

Also revert moving eslint-rules from utils to infra, as hyperlane-registry
depends on @hyperlane-xyz/utils and uses these rules.

Keep the writeJson/writeYaml stringifyObject changes for BigNumber
serialization and the removeEndingSlash -> removeTrailingSlash rename.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@paulbalaji paulbalaji changed the title refactor(utils): fs utilities cleanup fix(utils): BigNumber serialization in writeJson/writeYaml Dec 12, 2025
@paulbalaji paulbalaji changed the title fix(utils): BigNumber serialization in writeJson/writeYaml fix(utils): fs utils cleanup Dec 12, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
typescript/utils/src/fs/json.ts (1)

10-23: PR objective mismatch: JSON read helpers still expose generics (<T>).
The PR summary says the JSON/YAML read fns dropped generics to avoid implying runtime validation, but readJson<T>, tryReadJson<T>, and readJsonFromDir<T> still have them here. Either update these signatures (and callers) or tweak the PR description/objectives so they match reality.

Also applies to: 52-54

typescript/utils/src/fs/yaml.ts (1)

23-43: PR objective mismatch: YAML read helpers still expose generics (<T>).
Same story as JSON: yamlParse<T>, readYaml<T>, tryReadYaml<T>, readYamlFromDir<T> still carry generics, which conflicts with the stated “remove generics to avoid implying validation.”

Also applies to: 72-74

🧹 Nitpick comments (4)
typescript/utils/src/fs/utils.ts (1)

5-13: removeTrailingSlash has a couple sharp edges ('/' -> '', only trims one slash, ignores \).
If this is meant to be generally safe, consider preserving root, trimming repeated slashes, and handling Windows separators. Also, if you want a non-breaking rename, keep removeEndingSlash as a deprecated alias.

 export function removeTrailingSlash(dirPath: string): string {
-  if (dirPath.endsWith('/')) {
-    return dirPath.slice(0, -1);
-  }
-  return dirPath;
+  if (!dirPath) return dirPath;
+  // Preserve POSIX root
+  if (dirPath === '/') return dirPath;
+  // Trim one-or-more trailing separators (POSIX + Windows)
+  return dirPath.replace(/[\\/]+$/, '');
 }
+
+/** @deprecated Use removeTrailingSlash */
+export function removeEndingSlash(dirPath: string): string {
+  return removeTrailingSlash(dirPath);
+}
typescript/utils/src/fs/index.ts (1)

6-15: Public export updated—consider exporting a deprecated removeEndingSlash alias too (if you want non-breaking).
If you take the alias approach in typescript/utils/src/fs/utils.ts, re-export it here so downstreams don’t get smacked.

typescript/utils/src/fs/utils.test.ts (1)

6-47: Tests updated fine—maybe add edge cases if you harden the impl.
If you accept the suggested replace(/[\\/]+$/, '') style trim, add cases for '/', '////', and 'C:\\path\\' (if Windows support matters).

typescript/cli/src/utils/files.ts (1)

7-28: Rename propagation through CLI re-exports looks clean.
If you decide to keep a deprecated removeEndingSlash for compatibility, you may also want to re-export it from here (temporarily) to keep CLI-side imports steady.

Also applies to: 34-54

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0e53681 and 7b6b16e.

📒 Files selected for processing (8)
  • .changeset/beige-foxes-compare.md (1 hunks)
  • typescript/cli/src/commands/warp.ts (2 hunks)
  • typescript/cli/src/utils/files.ts (2 hunks)
  • typescript/utils/src/fs/index.ts (1 hunks)
  • typescript/utils/src/fs/json.ts (2 hunks)
  • typescript/utils/src/fs/utils.test.ts (2 hunks)
  • typescript/utils/src/fs/utils.ts (1 hunks)
  • typescript/utils/src/fs/yaml.ts (2 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: paulbalaji
Repo: hyperlane-xyz/hyperlane-monorepo PR: 6943
File: rust/main/config/mainnet_config.json:965-965
Timestamp: 2025-08-26T13:46:37.695Z
Learning: In the repository hyperlane-xyz/hyperlane-monorepo, skip reviewing the file rust/main/config/testnet_config.json in future code reviews as requested by paulbalaji.
Learnt from: paulbalaji
Repo: hyperlane-xyz/hyperlane-monorepo PR: 6943
File: rust/main/config/mainnet_config.json:965-965
Timestamp: 2025-08-26T13:46:37.695Z
Learning: In the repository hyperlane-xyz/hyperlane-monorepo, skip reviewing the file rust/main/config/mainnet_config.json in future code reviews as requested by paulbalaji.
Learnt from: paulbalaji
Repo: hyperlane-xyz/hyperlane-monorepo PR: 6943
File: rust/main/config/testnet_config.json:34-35
Timestamp: 2025-08-26T13:45:52.227Z
Learning: Skip reviewing mainnet_config.json and testnet_config.json configuration files in typescript/infra/config/ and rust/main/config/ directories as requested by paulbalaji to reduce review noise.
Learnt from: ltyu
Repo: hyperlane-xyz/hyperlane-monorepo PR: 7577
File: typescript/cli/src/commands/submit.ts:60-71
Timestamp: 2025-12-11T16:29:47.997Z
Learning: In the hyperlane-xyz/hyperlane-monorepo repository, the `writeYamlOrJson` utility function (from typescript/cli/src/utils/files.ts) automatically handles directory creation when writing files, so there's no need to explicitly check or create directories before calling it.
Learnt from: paulbalaji
Repo: hyperlane-xyz/hyperlane-monorepo PR: 6943
File: typescript/infra/config/environments/testnet4/ism/verification.json:3835-3939
Timestamp: 2025-08-26T13:45:29.848Z
Learning: Skip reviewing verification.json files in typescript/infra/config/environments/testnet4/ism/verification.json and similar verification.json files as requested by paulbalaji.
📚 Learning: 2025-12-11T16:29:47.997Z
Learnt from: ltyu
Repo: hyperlane-xyz/hyperlane-monorepo PR: 7577
File: typescript/cli/src/commands/submit.ts:60-71
Timestamp: 2025-12-11T16:29:47.997Z
Learning: In the hyperlane-xyz/hyperlane-monorepo repository, the `writeYamlOrJson` utility function (from typescript/cli/src/utils/files.ts) automatically handles directory creation when writing files, so there's no need to explicitly check or create directories before calling it.

Applied to files:

  • typescript/cli/src/commands/warp.ts
  • typescript/utils/src/fs/yaml.ts
🧬 Code graph analysis (4)
typescript/utils/src/fs/utils.ts (2)
typescript/cli/src/utils/files.ts (1)
  • removeTrailingSlash (39-39)
typescript/utils/src/fs/index.ts (1)
  • removeTrailingSlash (11-11)
typescript/utils/src/fs/utils.test.ts (3)
typescript/cli/src/utils/files.ts (1)
  • removeTrailingSlash (39-39)
typescript/utils/src/fs/index.ts (1)
  • removeTrailingSlash (11-11)
typescript/utils/src/fs/utils.ts (1)
  • removeTrailingSlash (8-13)
typescript/utils/src/fs/json.ts (2)
typescript/utils/src/fs/utils.ts (1)
  • writeToFile (77-80)
typescript/utils/src/index.ts (1)
  • stringifyObject (157-157)
typescript/utils/src/fs/yaml.ts (3)
typescript/utils/src/fs/index.ts (2)
  • writeYaml (31-31)
  • writeToFile (14-14)
typescript/utils/src/fs/utils.ts (1)
  • writeToFile (77-80)
typescript/utils/src/index.ts (1)
  • stringifyObject (157-157)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (60)
  • GitHub Check: cli-evm-e2e-matrix (core-read)
  • GitHub Check: cli-evm-e2e-matrix (warp-check-4)
  • GitHub Check: cli-evm-e2e-matrix (warp-send)
  • GitHub Check: cli-evm-e2e-matrix (warp-extend-basic)
  • GitHub Check: cli-evm-e2e-matrix (warp-extend-config)
  • GitHub Check: cli-evm-e2e-matrix (warp-check-1)
  • GitHub Check: cli-evm-e2e-matrix (warp-apply-simple-updates)
  • GitHub Check: cli-evm-e2e-matrix (warp-read)
  • GitHub Check: cli-evm-e2e-matrix (warp-deploy-1)
  • GitHub Check: cli-evm-e2e-matrix (warp-check-5)
  • GitHub Check: cli-evm-e2e-matrix (warp-apply-rebalancing-config)
  • GitHub Check: cli-evm-e2e-matrix (warp-apply-hook-updates)
  • GitHub Check: cli-evm-e2e-matrix (relay)
  • GitHub Check: cli-evm-e2e-matrix (warp-apply-submitters)
  • GitHub Check: cli-evm-e2e-matrix (core-apply)
  • GitHub Check: cli-evm-e2e-matrix (warp-extend-recovery)
  • GitHub Check: cli-evm-e2e-matrix (warp-check-2)
  • GitHub Check: cli-evm-e2e-matrix (core-deploy)
  • GitHub Check: cli-evm-e2e-matrix (warp-check-3)
  • GitHub Check: cli-evm-e2e-matrix (core-check)
  • GitHub Check: cli-evm-e2e-matrix (warp-apply-ism-updates)
  • GitHub Check: cli-evm-e2e-matrix (warp-init)
  • GitHub Check: cli-evm-e2e-matrix (warp-bridge-2)
  • GitHub Check: cli-evm-e2e-matrix (warp-apply-ownership-updates)
  • GitHub Check: cli-evm-e2e-matrix (warp-deploy-2)
  • GitHub Check: cli-evm-e2e-matrix (warp-bridge-1)
  • GitHub Check: cli-evm-e2e-matrix (warp-rebalancer)
  • GitHub Check: cli-evm-e2e-matrix (core-init)
  • GitHub Check: cli-cross-chain-e2e-matrix (warp-apply)
  • GitHub Check: env-test-matrix (mainnet3, ethereum, core)
  • GitHub Check: env-test-matrix (mainnet3, optimism, igp)
  • GitHub Check: env-test-matrix (testnet4, sepolia, core)
  • GitHub Check: env-test-matrix (mainnet3, arbitrum, igp)
  • GitHub Check: env-test-matrix (mainnet3, arbitrum, core)
  • GitHub Check: env-test-matrix (mainnet3, optimism, core)
  • GitHub Check: cli-cosmos-e2e-matrix (warp-read)
  • GitHub Check: env-test-matrix (mainnet3, ethereum, igp)
  • GitHub Check: cli-radix-e2e-matrix (warp-apply-ownership-updates)
  • GitHub Check: cli-radix-e2e-matrix (warp-deploy)
  • GitHub Check: yarn-test-run
  • GitHub Check: cli-radix-e2e-matrix (core-deploy)
  • GitHub Check: cli-radix-e2e-matrix (core-apply)
  • GitHub Check: cli-cosmos-e2e-matrix (warp-deploy)
  • GitHub Check: cli-cross-chain-e2e-matrix (warp-deploy)
  • GitHub Check: cli-cosmos-e2e-matrix (core-read)
  • GitHub Check: cli-cosmos-e2e-matrix (core-check)
  • GitHub Check: cli-cosmos-e2e-matrix (core-deploy)
  • GitHub Check: cli-cosmos-e2e-matrix (core-apply)
  • GitHub Check: cosmos-sdk-e2e-run
  • GitHub Check: cli-radix-e2e-matrix (warp-apply-route-extension)
  • GitHub Check: cli-install-test-run
  • GitHub Check: aleo-sdk-e2e-run
  • GitHub Check: infra-test
  • GitHub Check: e2e-matrix (evm)
  • GitHub Check: agent-configs (testnet4)
  • GitHub Check: lint-prettier
  • GitHub Check: agent-configs (mainnet3)
  • GitHub Check: lander-coverage
  • GitHub Check: lint-rs
  • GitHub Check: test-rs
🔇 Additional comments (3)
typescript/utils/src/fs/json.ts (1)

3-3: Good move switching writeJson to stringifyObject, but verify determinism + BigNumber coverage.
This should fix ethers BigNumber serialization, but I’d double-check stringifyObject(..., 'json', 2) is stable (key ordering if you rely on clean diffs) and handles the BigNumber variants you care about (ethers v5 BigNumber, ethers v6 types, bigint).

Also applies to: 25-31

typescript/cli/src/commands/warp.ts (1)

41-47: Rename usage looks wired up right (coerce now calls removeTrailingSlash).
Nothing spooky here—just make sure there aren’t any lingering removeEndingSlash imports in other CLI commands.

Also applies to: 122-127

typescript/utils/src/fs/yaml.ts (1)

10-12: The implementation already preserves output stability and handles BigNumber correctly. Line 232 in stringifyObject includes sortMapEntries: true when calling yamlStringify, so deterministic ordering is maintained. BigNumber serialization is handled via ethersBigNumberSerializer (passed to JSON.stringify first), which converts ethers BigNumber objects and native bigint types to strings before the YAML conversion step. The two-step serialization approach is solid—no action needed here.

@paulbalaji paulbalaji enabled auto-merge December 15, 2025 14:49
@paulbalaji paulbalaji added this pull request to the merge queue Dec 15, 2025
Merged via the queue into main with commit b3ebc08 Dec 15, 2025
87 checks passed
@paulbalaji paulbalaji deleted the pbio/utils-fs-fixes branch December 15, 2025 15:00
@github-project-automation github-project-automation bot moved this from In Review to Done in Hyperlane Tasks Dec 15, 2025
@codecov
Copy link

codecov bot commented Dec 15, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 0.00%. Comparing base (0e53681) to head (7b6b16e).
⚠️ Report is 4 commits behind head on main.

Additional details and impacted files
@@     Coverage Diff      @@
##   main   #7609   +/-   ##
============================
============================
Components Coverage Δ
core ∅ <ø> (∅)
hooks ∅ <ø> (∅)
isms ∅ <ø> (∅)
token ∅ <ø> (∅)
middlewares ∅ <ø> (∅)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants