Skip to content

Remap: duplicate targets#3025

Merged
RobinTail merged 6 commits intomasterfrom
remap-duplicate-targets
Oct 27, 2025
Merged

Remap: duplicate targets#3025
RobinTail merged 6 commits intomasterfrom
remap-duplicate-targets

Conversation

@RobinTail
Copy link
Copy Markdown
Owner

@RobinTail RobinTail commented Oct 26, 2025

#2878 (comment)

Summary by CodeRabbit

  • Bug Fixes

    • Remap now detects and rejects duplicate target keys in mappings to prevent key collisions.
  • Tests

    • Added a runtime test asserting an error is thrown for duplicate mapping targets.
  • Documentation

    • CHANGELOG updated to document the remap duplicate-target fix (v2.1.0).

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Oct 26, 2025

Walkthrough

Adds an internal helper that filters undefined mappings, validates duplicate target keys, and returns a rename transformer; updates remap parameter type to accept the helper's mapping shape or a function; adds a test asserting an error for duplicate target keys and updates the changelog.

Changes

Cohort / File(s) Summary
Remap implementation
zod-plugin/src/remap.ts
Introduced makeTransformer(mapping) to remove undefined mappings, detect duplicate target keys, and produce a transformer via R.renameKeys; changed remap parameter type to `Parameters[0]
Tests: duplicate-target detection
zod-plugin/tests/runtime.spec.ts
Added a test asserting remap() throws when two source keys map to the same target key.
Changelog
zod-plugin/CHANGELOG.md
Added v2.1.0 entry documenting the bug fix: remap() now throws on duplicate target keys.

Sequence Diagram(s)

sequenceDiagram
  participant Caller as remap(caller)
  participant Make as makeTransformer
  participant Validator as duplicateCheck
  participant Ramda as R.renameKeys
  participant Transformer as transformer

  Caller->>Make: pass mapping (object)
  Make->>Validator: filter undefined, collect targets
  alt duplicates found
    Validator-->>Make: throw Error
    Make-->>Caller: Error
  else no duplicates
    Validator->>Ramda: build rename transformer
    Ramda-->>Make: transformer
    Make-->>Caller: transformer
    Caller->>Transformer: apply transformer to input
    Transformer-->>Caller: transformed object
  end

  Note over Caller: If `tool` is a function (Mapper), remap uses it directly (no Make step)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–30 minutes

  • Inspect duplicate-target detection (edge cases: undefined/null/empty mappings).
  • Verify updated remap type and any call sites or exports.
  • Confirm test accurately asserts thrown error and message.

Possibly related PRs

Suggested labels

refactoring

Poem

🐰 I hop through maps with tidy paws and care,
I filter nil and catch twins hiding there.
One key, one home — no duplicates allowed,
I rename with grace and make changelogs proud. 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "Remap: duplicate targets" directly and accurately captures the primary change in this pull request. The changeset adds duplicate target key validation to the remap() function across the implementation (remap.ts), tests (runtime.spec.ts), and documentation (CHANGELOG.md). The title is concise, specific, and clearly indicates that the remap functionality now addresses duplicate targets, making it immediately understandable to someone reviewing commit history.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch remap-duplicate-targets

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7da9c73 and 2e5baf4.

📒 Files selected for processing (1)
  • zod-plugin/CHANGELOG.md (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • zod-plugin/CHANGELOG.md

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.

@coveralls-official
Copy link
Copy Markdown

coveralls-official Bot commented Oct 26, 2025

Coverage Status

coverage: 100.0%. remained the same
when pulling 2e5baf4 on remap-duplicate-targets
into 2777e0b on master.

@RobinTail RobinTail marked this pull request as ready for review October 27, 2025 05:09
Copy link
Copy Markdown
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: 0

🧹 Nitpick comments (2)
zod-plugin/src/remap.ts (1)

30-36: LGTM! Consider enhancing the error message.

The duplicate detection logic is correct and the validation approach is sound. The TODO comment acknowledges the generic naming.

Consider making the error message more actionable by identifying the specific duplicate target:

 const ensure = (tool: Record<string, string>) => {
   const targets = Object.values(tool);
   if (new Set(targets).size !== targets.length)
-    throw new Error("remap(): duplicate target keys", { cause: tool });
+    {
+      const duplicates = targets.filter((val, idx) => targets.indexOf(val) !== idx);
+      throw new Error(`remap(): duplicate target keys: ${[...new Set(duplicates)].join(", ")}`, { cause: tool });
+    }
   return tool;
 };
zod-plugin/tests/runtime.spec.ts (1)

120-125: LGTM! Comprehensive test coverage.

The test properly validates the duplicate target key detection. The error pattern matching is appropriate and the test case clearly demonstrates the expected behavior.

Consider adding an edge case test for multiple duplicates (e.g., { a: "x", b: "x", c: "y", d: "y" }) to ensure the validation catches all duplicates, not just the first one.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2777e0b and 9c56bb6.

📒 Files selected for processing (2)
  • zod-plugin/src/remap.ts (1 hunks)
  • zod-plugin/tests/runtime.spec.ts (1 hunks)
🔇 Additional comments (2)
zod-plugin/src/remap.ts (2)

41-41: LGTM! Type signature improvement.

The change to Partial<Record<string, string>> properly reflects the runtime behavior where undefined values are filtered out with R.reject(R.isNil, tool). This provides better type safety and flexibility for partial mappings.


44-46: Consider validating function mappers as well.

The implementation correctly filters nil values before validation. However, when tool is a function (Mapper), the duplicate target validation is bypassed. If a custom mapper function produces duplicate targets, the resulting schema might exhibit unexpected behavior.

Should custom mapper functions be validated for duplicate targets after execution? This could be done by wrapping the function result with ensure() or documenting this as a caller responsibility.

Copy link
Copy Markdown
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: 0

🧹 Nitpick comments (1)
zod-plugin/CHANGELOG.md (1)

5-7: Clarify the phrasing for the duplicate target key validation behavior.

The changelog entry uses past tense ("would throw") which could be ambiguous. Consider rephrasing to present tense ("now throws") for clarity about the new behavior.

Suggested revision:

- `ZodObject::remap()` would throw an `Error` if duplicate target keys found in its argument.
+ `ZodObject::remap()` now throws an `Error` if duplicate target keys are found in its argument.

Additionally, please verify that this changelog entry accurately reflects the implementation in zod-plugin/src/remap.ts by reviewing the actual validation logic and corresponding test case in zod-plugin/tests/runtime.spec.ts.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7a3f123 and 7da9c73.

📒 Files selected for processing (1)
  • zod-plugin/CHANGELOG.md (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-08-05T14:43:24.702Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2869
File: zod-plugin/package.json:42-44
Timestamp: 2025-08-05T14:43:24.702Z
Learning: Zod version 4 has been officially released and is stable. As of August 2025, the latest published version is 4.0.14 (published July 30, 2025). Zod v4 is available on npm and can be used in peer dependencies with version constraints like "^4.0.0".

Applied to files:

  • zod-plugin/CHANGELOG.md
📚 Learning: 2025-05-27T19:27:13.492Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: express-zod-api/tests/form-schema.spec.ts:31-31
Timestamp: 2025-05-27T19:27:13.492Z
Learning: Zod version 3.25.0 and later expose the Zod v4 API through the special import paths "zod/v4" and "zod/v4/core", allowing v4 features like .loose() to be used even when the package.json dependency shows a 3.x version.

Applied to files:

  • zod-plugin/CHANGELOG.md
⏰ 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). (1)
  • GitHub Check: report

@RobinTail RobinTail added the enhancement New feature or request label Oct 27, 2025
@RobinTail RobinTail merged commit b8bc7c0 into master Oct 27, 2025
13 checks passed
@RobinTail RobinTail deleted the remap-duplicate-targets branch October 27, 2025 08:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request prevention

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant