fix: ensure module commands respect proxy typeMapping #3261
fix: ensure module commands respect proxy typeMapping #3261watersRand wants to merge 4 commits intoredis:masterfrom
Conversation
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Reviewed by Cursor Bugbot for commit 1fde3a2. Configure here.
| const value = Object.create(fns); | ||
| value._self = this; | ||
| Object.defineProperty(this, name, { value }); | ||
| value._commandOptions = (this as any)._commandOptions ?? null; |
There was a problem hiding this comment.
Namespace getter allocates new object on every access
Medium Severity
The attachNamespace function removes the previous Object.defineProperty(this, name, { value }) caching mechanism. Previously, the namespace object was created once and cached as an own property on the instance, so subsequent accesses (e.g., client.module.echo(...)) returned the same cached object. Now, every single property access triggers the getter and allocates a new Object.create(fns) object with freshly assigned _self and _commandOptions. For high-throughput Redis usage where module commands are called frequently, this introduces unnecessary object allocation and GC pressure on every command invocation.
Reviewed by Cursor Bugbot for commit 1fde3a2. Configure here.


Description
Closes #3055 ,a bug where commands generated via static factories (Modules and Functions) were incorrectly referencing the root client's options (
this._self._commandOptions) instead of the immediate instance's options (this._commandOptions).The Problem:
When using
.withCommandOptions()or.withTypeMapping(), the library creates a proxy object. However, because Modules and Functions were hard-coded to look at the internal_selfreference for their configuration, they completely ignored any user-defined type mappings or timeouts set on the proxy. This effectively broke RESP3 type mapping for all Redis Module commands.The Solution:
#createModuleCommandand#createFunctionCommandto referencethis._commandOptions.sendCommandto prioritize instance-level options.NamespaceProxyClienttype definition to include_commandOptionsto ensure type safety.Allows developers to seamlessly switch between different configurations—such as string vs. binary (Buffer) outputs—across all available commands, including built-in modules, third-party modules, and user-defined libraries (Redis Functions). It enables this flexibility on the fly without the overhead of re-initializing the entire connection or maintaining multiple client instances for different return types.
Checklist
npm testpass with this change (including linting)?Note
Medium Risk
Changes how command options are propagated/merged for module/function namespaces and
sendCommand, which can affect timeouts/type mappings across many commands and could introduce subtle option-inheritance regressions.Overview
Fixes a bug where module/function commands created via static factories ignored options set on proxy clients (e.g., from
withCommandOptions/withTypeMapping) by switching them to readthis._commandOptionsand ensuring namespace proxies inherit the parent client’s_commandOptions.Updates option merging to use prototype-based inheritance (
Object.create+Object.assign) so proxy chains inherit defaults without copying, and adds a regression test asserting module replies respect proxytypeMappingwhile inheriting (not duplicating) other options liketimeout.Reviewed by Cursor Bugbot for commit 1fde3a2. Bugbot is set up for automated code reviews on this repo. Configure here.