Skip to content

feat: add COMMAND DOCS support - #3362

Open
Hashim1999164 wants to merge 2 commits into
redis:masterfrom
Hashim1999164:feat/command-docs
Open

feat: add COMMAND DOCS support#3362
Hashim1999164 wants to merge 2 commits into
redis:masterfrom
Hashim1999164:feat/command-docs

Conversation

@Hashim1999164

@Hashim1999164 Hashim1999164 commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds COMMAND DOCS (client.commandDocs) for Redis 7+, including optional command name filters.
  • Transforms RESP2 flat map replies into the RESP3 object shape, including nested arguments and recursive subcommands.
  • Registers the command in the client command index with JSDoc (@since 7.0.0).

Fixes #1934

Why previous attempts were not enough

Test plan

  • parseArgs covers no args, string, and array filters
  • Unit test for RESP2 transformReply[2] nested map/arguments/subcommands
  • Integration: client.commandDocs() and client.commandDocs(['GET', 'SET']) against Redis 7+
  • npm run check:command-jsdoc and lint on changed files

Note

Low Risk
Additive read-only command support with isolated reply parsing; no changes to auth, data paths, or existing commands.

Overview
Adds client.commandDocs / COMMAND_DOCS so callers can fetch Redis command documentation (Redis 7+), with an optional variadic filter for specific command names.

The new command module builds COMMAND DOCS via parseCommand, marks it read-only and non-keyed, and implements transformReply[2] to turn RESP2 flat key-value map replies into structured objects (including nested arguments, recursive subcommands, and reply_schema), honoring typeMapping for Map/Array/plain object shapes. RESP3 relies on the default decoder (transformReply[3] is unset).

Registration in the commands index exposes both COMMAND_DOCS and commandDocs with JSDoc (@since 7.0.0). Tests cover argument parsing, RESP2 reply transformation, and integration against Redis 7+.

Reviewed by Cursor Bugbot for commit fd3f528. Bugbot is set up for automated code reviews on this repo. Configure here.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f94d60805a

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

}
},
transformReply: {
2: (reply: UnwrapReply<Resp2Reply<CommandDocsReply>>) => transformDocsMap(reply),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Honor map type mappings in the RESP2 transform

When an RESP2 client uses withTypeMapping({ [RESP_TYPES.MAP]: Map }) or maps maps to Array, the public return type is adjusted to that representation, but this transform ignores the supplied typeMapping argument and always converts the top-level reply to a plain object. Code that follows the declared type, such as calling docs.get('get'), therefore fails at runtime; pass the mapping through the recursive transforms and produce the requested representation.

Useful? React with 👍 / 👎.

deprecated_since?: BlobStringReply;
replaced_by?: BlobStringReply;
history?: ArrayReply<TuplesReply<[BlobStringReply, BlobStringReply]>>;
arguments?: ArrayReply<ReplyUnion>;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Expose transformed arguments as CommandDocsArgument

For TypeScript consumers, each docs.get.arguments entry is currently inferred as the broad ReplyUnion, so ordinary access such as docs.get.arguments?.[0].name is rejected even though transformArgument returns a CommandDocsArgument object and the integration test uses that shape. Type this field as an array of CommandDocsArgument entries, and make the same correction to the recursive CommandDocsArgument.arguments field.

Useful? React with 👍 / 👎.

@nkaradzhov nkaradzhov left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@Hashim1999164 thanks for the PR!

Three points before merge.

First, the RESP2 transformReply should honor the typeMapping parameter (see transformTuplesReply and CONFIG_GET) so users mapping MAP to Map or Array get consistent results across protocols.

Second, please add an integration test running commandDocs against a real Redis 7 server with RESP 2 client options — the nested transform is currently covered only by a synthetic fixture, which is exactly where the previous PR broke.

Third, drop the NOT_KEYED_COMMAND flag, it has no runtime consumer and the other COMMAND family commands do not set it.

Address review feedback: preserve Map/Array type mappings in the RESP2
transform, and type nested arguments as CommandDocsArgument.
@Hashim1999164

Copy link
Copy Markdown
Contributor Author

Addressed the Codex review notes:

  1. RESP2 transformReply now accepts typeMapping and returns Map / flat Array / plain object according to RESP_TYPES.MAP.
  2. Nested arguments are typed as CommandDocsArgument (including recursive arguments) so docs.get.arguments?.[0].name type-checks.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fd3f52841d

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

return reply as CommandDoc;
}

const doc: Record<string, unknown> = {};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Apply MAP mappings to nested document maps

When an RESP2 client uses withTypeMapping({ [RESP_TYPES.MAP]: Map }), the new outer switch returns a Map, but transformDoc still unconditionally creates a plain object and transformArgument does the same. RESP3 applies the mapping recursively in the decoder, so the same command returns Map<string, object> under RESP2 but Map<string, Map> under RESP3; nested maps also fail to honor the requested mapping. Fresh evidence after the earlier review comment is that the added mapping logic only changes transformDocsMap, while this allocation remains unconditional; apply the mapping consistently to document and argument maps or normalize both protocols to the same declared shape.

Useful? React with 👍 / 👎.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

Reviewed by Cursor Bugbot for commit fd3f528. Configure here.

doc.subcommands = transformDocsMap(value, typeMapping);
break;
case 'reply_schema':
doc.reply_schema = Array.isArray(value) ? transformDoc(value, typeMapping) : value;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

reply_schema misprocessed through command-doc-specific transformer

Low Severity

The reply_schema field (a JSON Schema object) is transformed via transformDoc, which applies command-doc-specific logic for keys named arguments, subcommands, and reply_schema. If the JSON Schema contains a top-level key called arguments with an array value, it gets incorrectly processed through transformArgument, which interprets each array element as a flat key-value pair list representing a CommandDocsArgument. This corrupts the schema data for any overlapping key names.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit fd3f528. Configure here.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for redis command: COMMAND DOCS (R7)

2 participants