Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"lint:changed": "node scripts/lint-changed.mjs",
"test": "npm run cleanup && npm run test --workspaces --if-present",
"build": "tsc --build",
"repl": "node scripts/repl.mjs",
"check:command-jsdoc": "tsx scripts/check-command-jsdoc.ts",
"documentation": "typedoc --entryPointStrategy packages --entryPoints ./packages/client ./packages/bloom ./packages/json ./packages/search ./packages/time-series ./packages/entraid ./packages/redis --out ./documentation",
"gh-pages": "gh-pages -d ./documentation -e ./documentation -u 'documentation-bot <documentation@bot>'",
Expand Down
39 changes: 39 additions & 0 deletions scripts/repl.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Opens a Node REPL with a connected `client` in scope.
// Uses the built packages, so run `npm run build` after source changes.
// Target another server with `npm run repl -- --host <host> --port <port>`
// (either flag alone is fine) or with REDIS_URL. Flags win over REDIS_URL.
import repl from 'node:repl';
import { parseArgs } from 'node:util';
import { createClient } from 'redis';

const { values: { host, port } } = parseArgs({
options: {
host: { type: 'string', short: 'h' },
port: { type: 'string', short: 'p' }
}
});

const url = host || port
? `redis://${host ?? 'localhost'}:${port ?? 6379}`

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 Bracket IPv6 host literals before forming the URL

When the new host flag is given a bare IPv6 literal such as --host ::1, this builds redis://::1:6379; RedisClient.parseURL() passes that to the WHATWG URL parser, which throws ERR_INVALID_URL, even though the client supports bracketed IPv6 Redis URLs. Detect and bracket IPv6 literals or pass host and port as socket options directly.

Useful? React with 👍 / 👎.

: process.env.REDIS_URL ?? 'redis://localhost:6379';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

IPv6 hosts build invalid Redis URLs

Low Severity

--host is interpolated into a redis:// URL without bracketing IPv6 literals. createClient then runs that string through parseURL, which uses the WHATWG URL parser and throws Invalid URL instead of connecting.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 69ee000. Configure here.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

IPv6 hosts produce invalid URLs

Low Severity

Flag-based URL construction interpolates --host directly into a redis:// URL. An IPv6 literal is a valid host value but is not bracketed, so createClient rejects the URL as invalid instead of connecting.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit c3e36dd. Configure here.

const client = createClient({ url });
// Connection errors such as ECONNREFUSED carry the reason in `code`, not `message`.
const reason = err => err.code ?? err.message;

// Exit if the first connect fails; after that, keep the default reconnects.
const onConnectError = err => {
console.error(`Could not connect to ${url}: ${reason(err)}`);
process.exit(1);
};
client.once('error', onConnectError);
await client.connect();
client.off('error', onConnectError);
client.on('error', err => console.error('Redis client error:', reason(err)));
console.log(`Connected to ${url}. Use \`client\`, e.g. await client.ping()`);

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 Redact credentials before echoing REDIS_URL

When REDIS_URL contains credentials such as redis://user:secret@host, this success message and the connection-error message interpolate the unmodified URL, exposing the password in terminal scrollback or captured output. Preserve the raw URL for createClient, but print a separately redacted display URL.

Useful? React with 👍 / 👎.


const server = repl.start('redis> ');
server.context.client = client;
server.on('exit', async () => {
client.destroy();
process.exit();
});
Loading