[PR #7407] [MERGED] fix(client): deep merge plugin actions to preserve all methods #24192

Closed
opened 2026-04-15 22:13:34 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/better-auth/better-auth/pull/7407
Author: @gustavovalverde
Created: 1/16/2026
Status: Merged
Merged: 1/17/2026
Merged by: @Bekacru

Base: canaryHead: fix/client-plugin-actions-deep-merge


📝 Commits (1)

  • 9845050 fix(client): deep merge plugin actions to preserve all methods

📊 Changes

3 files changed (+89 additions, -4 deletions)

View changed files

📝 packages/better-auth/src/client/client.test.ts (+54 -1)
📝 packages/better-auth/src/client/config.ts (+4 -3)
📝 packages/better-auth/src/client/test-plugin.ts (+31 -0)

📄 Description

Summary

Fixes a bug where client plugin actions with the same top-level key would overwrite each other instead of merging.

When multiple plugins return actions under the same namespace (e.g., signIn), only the last plugin's methods were accessible due to Object.assign performing a shallow merge.

Before:

// Plugin A: { signIn: { methodA: fn } }
// Plugin B: { signIn: { methodB: fn } }
// Result: { signIn: { methodB: fn } }  methodA is lost

After:

// Plugin A: { signIn: { methodA: fn } }
// Plugin B: { signIn: { methodB: fn } }
// Result: { signIn: { methodA: fn, methodB: fn } }  both preserved

This aligns the runtime behavior with the TypeScript types, which already use UnionToIntersection to merge plugin action types; implying deep merge semantics.

Solution

This PR switches to defu for deep merging, to preserve all methods from all plugins.


Summary by cubic

Deep-merge client plugin actions so methods aren’t lost when multiple plugins share the same namespace (e.g., signIn). Uses defu for deep merge and adds tests to confirm methods from all plugins remain available.

  • Bug Fixes
    • Replace Object.assign with defu to deep-merge plugin actions.
    • Preserve all methods under the same top-level key, regardless of plugin order.
    • Add tests covering merge behavior and order independence.

Written for commit 98450509c1. Summary will update on new commits.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/better-auth/better-auth/pull/7407 **Author:** [@gustavovalverde](https://github.com/gustavovalverde) **Created:** 1/16/2026 **Status:** ✅ Merged **Merged:** 1/17/2026 **Merged by:** [@Bekacru](https://github.com/Bekacru) **Base:** `canary` ← **Head:** `fix/client-plugin-actions-deep-merge` --- ### 📝 Commits (1) - [`9845050`](https://github.com/better-auth/better-auth/commit/98450509c160d9f2e7574053ea3872ed4be34f40) fix(client): deep merge plugin actions to preserve all methods ### 📊 Changes **3 files changed** (+89 additions, -4 deletions) <details> <summary>View changed files</summary> 📝 `packages/better-auth/src/client/client.test.ts` (+54 -1) 📝 `packages/better-auth/src/client/config.ts` (+4 -3) 📝 `packages/better-auth/src/client/test-plugin.ts` (+31 -0) </details> ### 📄 Description ## Summary Fixes a bug where client plugin actions with the same top-level key would overwrite each other instead of merging. When multiple plugins return actions under the same namespace (e.g., `signIn`), only the last plugin's methods were accessible due to `Object.assign` performing a shallow merge. **Before:** ```ts // Plugin A: { signIn: { methodA: fn } } // Plugin B: { signIn: { methodB: fn } } // Result: { signIn: { methodB: fn } } methodA is lost ``` **After:** ```ts // Plugin A: { signIn: { methodA: fn } } // Plugin B: { signIn: { methodB: fn } } // Result: { signIn: { methodA: fn, methodB: fn } } both preserved ``` This aligns the runtime behavior with the TypeScript types, which already use `UnionToIntersection` to merge plugin action types; implying deep merge semantics. ## Solution This PR switches to `defu` for deep merging, to preserve all methods from all plugins. <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Deep-merge client plugin actions so methods aren’t lost when multiple plugins share the same namespace (e.g., signIn). Uses defu for deep merge and adds tests to confirm methods from all plugins remain available. - **Bug Fixes** - Replace Object.assign with defu to deep-merge plugin actions. - Preserve all methods under the same top-level key, regardless of plugin order. - Add tests covering merge behavior and order independence. <sup>Written for commit 98450509c160d9f2e7574053ea3872ed4be34f40. Summary will update on new commits.</sup> <!-- End of auto-generated description by cubic. --> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-04-15 22:13:34 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#24192