Skip to content

feat(redis): add clientInfoTag support with version detection#736

Open
vchomakov wants to merge 9 commits into
unjs:mainfrom
vchomakov:feat/redis-client-info-tag
Open

feat(redis): add clientInfoTag support with version detection#736
vchomakov wants to merge 9 commits into
unjs:mainfrom
vchomakov:feat/redis-client-info-tag

Conversation

@vchomakov
Copy link
Copy Markdown

@vchomakov vchomakov commented Jan 27, 2026

Resolves #735

Description

Adds clientInfoTag support to the Redis driver to leverage Redis's CLIENT SETINFO command.

This feature helps Redis administrators identify which higher-level library is using ioredis by setting a custom tag in the CLIENT SETINFO LIB-NAME command.

Changes

  • Added clientInfoTag option to RedisOptions interface
  • Automatically sets tag to unstorage_vX.X.X using package.json version
  • Supports custom clientInfoTag override
  • Handles cluster mode by passing tag through clusterOptions.redisOptions
  • Added tests for default and custom clientInfoTag behavior
  • Updated documentation

Example Usage

// Default behavior - automatically includes version
const storage = createStorage({
  driver: redisDriver({
    host: 'localhost',
    port: 6379
  })
});
// Results in: CLIENT SETINFO LIB-NAME ioredis(unstorage_v2.0.0-alpha.5)

// Custom tag
const storage = createStorage({
  driver: redisDriver({
    host: 'localhost',
    port: 6379,
    clientInfoTag: 'my-app_v1.0.0'
  })
});
// Results in: CLIENT SETINFO LIB-NAME ioredis(my-app_v1.0.0)

Testing

All existing tests pass (19/19)
Added 2 new tests for clientInfoTag functionality
Build successful
Linter passes
Type checking passes

References

Redis CLIENT SETINFO documentation: https://redis.io/docs/latest/commands/client-setinfo/
ioredis clientInfoTag option: https://github.com/redis/ioredis#client-setinfo

Summary by CodeRabbit

  • New Features

    • Added a clientInfoTag option for the Redis driver to customize the client identification tag used when reporting client info; defaults to a sensible tag derived from the library version when not provided.
  • Tests

    • Added tests ensuring the default clientInfoTag format includes a version-like suffix and that a custom clientInfoTag is applied when supplied.

@vchomakov vchomakov requested a review from pi0 as a code owner January 27, 2026 20:29
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 4, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds an optional clientInfoTag to the Redis driver (defaults to a package-version-derived tag when omitted) and passes it to ioredis so Redis sees CLIENT SETINFO LIB-NAME ioredis(<tag>). Documentation and tests for default and custom tags were added.

Changes

Cohort / File(s) Summary
Documentation
docs/2.drivers/redis.md
Add clientInfoTag option description, default format (version-derived unstorage_vX.X.X) and custom override example.
Driver Implementation
src/drivers/redis.ts
Add clientInfoTag?: string to RedisOptions; introduce getDefaultClientInfoTag() reading package.json version fallback; resolve clientInfoTag = opts.clientInfoTag ?? getDefaultClientInfoTag() and propagate into ioredis Redis and Cluster options.
Tests
test/drivers/redis.test.ts
Add tests asserting default clientInfoTag matches version-like or fallback pattern and that a provided custom clientInfoTag is applied to the driver instance.

Sequence Diagram(s)

sequenceDiagram
  participant App as "App"
  participant Driver as "RedisDriver"
  participant PKG as "package.json"
  participant IoRedis as "ioredis"
  participant Redis as "Redis"

  App->>Driver: create driver(opts)
  alt opts.clientInfoTag provided
    Driver->>IoRedis: init(clientInfoTag = opts.clientInfoTag)
  else clientInfoTag omitted
    Driver->>PKG: read version
    PKG-->>Driver: version or missing
    Driver->>IoRedis: init(clientInfoTag = "unstorage" or "unstorage_vX.X.X")
  end
  IoRedis->>Redis: CLIENT SETINFO LIB-NAME ioredis(<clientInfoTag>)
  Redis-->>IoRedis: OK
  IoRedis-->>Driver: connection established
  Driver-->>App: driver instance
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hopped a tag onto the redis line,
ioredis will whisper this rabbit sign,
version or custom, neat and small,
a tiny stamp so ops can see all,
hop, sniff, and leave a friendly call.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely describes the main change: adding clientInfoTag support with automatic version detection to the Redis driver.
Linked Issues check ✅ Passed The pull request fully implements all coding requirements from issue #735: clientInfoTag option added to RedisOptions, automatic version detection from package.json with fallback, custom tag override support, cluster mode propagation, and test coverage for both default and custom behavior.
Out of Scope Changes check ✅ Passed All changes are scoped to the Redis driver's clientInfoTag feature. Documentation updates, driver implementation, and test additions directly support the stated objectives with no unrelated modifications.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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.

Copy link
Copy Markdown

@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: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/drivers/redis.ts`:
- Around line 58-60: The getDefaultClientInfoTag function currently assumes
pkg.version exists; update getDefaultClientInfoTag to guard against
missing/empty pkg.version (from the package import) and return the fallback
string "unstorage" when version is falsy, otherwise return the current
`unstorage_v${pkg.version}` tag; locate and modify the getDefaultClientInfoTag
function and the use of pkg.version to perform a truthy check (e.g., if
(!pkg.version) return "unstorage") before constructing the versioned tag.
- Around line 62-63: The file incorrectly wraps the driver declaration with an
undefined defineDriver(...) and creates duplicate default exports; remove the
defineDriver(...) wrapper so the top-level const driver:
DriverFactory<RedisOptions, Redis | Cluster> = (opts) => { ... } stands alone,
ensure there is only a single default export (leave export default driver; at
the bottom), and delete the extraneous export/default around defineDriver and
any other duplicate export statements referencing driver or defineDriver.

In `@test/drivers/redis.test.ts`:
- Around line 41-42: The test is referencing an undefined variable `driver`;
change the lookup to use the TestContext's driver (ctx.driver) instead: call
ctx.driver.getInstance?.() to obtain the instance and read (instance?.options as
any)?.clientInfoTag from that instance; also ensure any use of `binaryDriver` in
this scope is replaced with the appropriate ctx.driver or removed if not
available. Locate occurrences around getInstance and clientInfoTag in the test
callback and update them to use ctx.driver so the TestContext-provided driver is
used consistently.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e8e500b4-58a1-482a-8b14-a6aff2bbb4c6

📥 Commits

Reviewing files that changed from the base of the PR and between 0fd3f38 and 6d10877.

📒 Files selected for processing (3)
  • docs/2.drivers/redis.md
  • src/drivers/redis.ts
  • test/drivers/redis.test.ts

Comment thread src/drivers/redis.ts
Comment thread src/drivers/redis.ts Outdated
Comment thread test/drivers/redis.test.ts Outdated
Copy link
Copy Markdown

@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

🧹 Nitpick comments (1)
test/drivers/redis.test.ts (1)

40-45: Strengthen these tests around the actual default and cluster paths.

Line 44 still allows the "unstorage" fallback even though this repo should produce a versioned tag, and both tests only exercise the standalone new Redis(...) branch. A broken package.json import or a regression in clusterOptions.redisOptions.clientInfoTag would still pass.

🧪 Tighten the standalone assertion
-        // Should be either "unstorage_vX.X.X" or "unstorage" (fallback)
-        expect(tag).toMatch(/^unstorage(_v[\d.]+.*)?$/);
+        expect(tag).toMatch(/^unstorage_v[\d.]+.*$/);

Please add a separate cluster-mode assertion as well.

Also applies to: 47-55

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/drivers/redis.test.ts` around lines 40 - 45, Tighten the tests to assert
the actual versioned clientInfoTag and add a cluster-mode assertion: update the
standalone test that reads instance = ctx.driver.getInstance?.() / tag =
(instance?.options as any)?.clientInfoTag to require the versioned form (e.g.,
matching /^unstorage_v[\d.]+/) instead of allowing the "unstorage" fallback, and
add a new assertion that constructs/uses the cluster path (inspect
clusterOptions.redisOptions.clientInfoTag or create a cluster instance) and
asserts its clientInfoTag also matches the versioned pattern; target the
existing symbols ctx.driver.getInstance, new Redis(...) code path, and
clusterOptions.redisOptions.clientInfoTag when adding the additional test.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/drivers/redis.ts`:
- Around line 79-84: The clusterOptions construction currently lets
options.clusterOptions.redisOptions overwrite the top-level clientInfoTag;
change the merge so the top-level clientInfoTag is authoritative (e.g., spread
options.clusterOptions?.redisOptions first and then set clientInfoTag, or
Object.assign with clientInfoTag last) so that clientInfoTag from options always
overrides any nested value when building clusterOptions.redisOptions.

---

Nitpick comments:
In `@test/drivers/redis.test.ts`:
- Around line 40-45: Tighten the tests to assert the actual versioned
clientInfoTag and add a cluster-mode assertion: update the standalone test that
reads instance = ctx.driver.getInstance?.() / tag = (instance?.options as
any)?.clientInfoTag to require the versioned form (e.g., matching
/^unstorage_v[\d.]+/) instead of allowing the "unstorage" fallback, and add a
new assertion that constructs/uses the cluster path (inspect
clusterOptions.redisOptions.clientInfoTag or create a cluster instance) and
asserts its clientInfoTag also matches the versioned pattern; target the
existing symbols ctx.driver.getInstance, new Redis(...) code path, and
clusterOptions.redisOptions.clientInfoTag when adding the additional test.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3d70b523-109f-424d-a299-bc2c4420664b

📥 Commits

Reviewing files that changed from the base of the PR and between 234ccac and c9a4f14.

📒 Files selected for processing (2)
  • src/drivers/redis.ts
  • test/drivers/redis.test.ts

Comment thread src/drivers/redis.ts
@vchomakov
Copy link
Copy Markdown
Author

Dear @pi0 , I would appreciate a review of this change. Thanks!

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 clientInfoTag support to Redis driver

1 participant