Skip to content

Commit 9614987

Browse files
committed
fix(init): option parsing
1 parent ff6f3a5 commit 9614987

File tree

4 files changed

+69
-15
lines changed

4 files changed

+69
-15
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import assert from "node:assert";
2+
import { createClient } from "../../";
3+
4+
describe("EnterpriseMaintenanceManager does not prevent proper options parsing", () => {
5+
it("should not throw when initializing without options", async () => {
6+
const client = createClient();
7+
assert.doesNotThrow(async () => {
8+
//Expected to reject because there is no url or socket provided and there is no running server on localhost
9+
await assert.rejects(client.connect);
10+
});
11+
});
12+
13+
it("should not throw when initializing without url/socket and with maint", async () => {
14+
const client = createClient({
15+
maintNotifications: "enabled",
16+
RESP: 3,
17+
});
18+
assert.doesNotThrow(async () => {
19+
//Expected to reject because there is no url or socket provided and there is no running server on localhost
20+
await assert.rejects(client.connect);
21+
});
22+
});
23+
it("should not throw when initializing with url and with maint", async () => {
24+
const client = createClient({
25+
maintNotifications: "enabled",
26+
RESP: 3,
27+
url: "redis://localhost:6379",
28+
});
29+
assert.doesNotThrow(async () => {
30+
//Expected to reject because there is no url or socket provided and there is no running server on localhost
31+
await assert.rejects(client.connect);
32+
});
33+
});
34+
35+
it("should not throw when initializing with socket and with maint", async () => {
36+
const client = createClient({
37+
maintNotifications: "enabled",
38+
RESP: 3,
39+
socket: {
40+
host: "localhost",
41+
port: 6379,
42+
},
43+
});
44+
assert.doesNotThrow(async () => {
45+
//Expected to reject because there is no url or socket provided and there is no running server on localhost
46+
await assert.rejects(client.connect);
47+
});
48+
});
49+
});

packages/client/lib/client/enterprise-maintenance-manager.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { isIP } from "net";
55
import { lookup } from "dns/promises";
66
import assert from "node:assert";
77
import { setTimeout } from "node:timers/promises";
8-
import RedisSocket from "./socket";
8+
import RedisSocket, { RedisTcpSocketOptions } from "./socket";
99
import diagnostics_channel from "node:diagnostics_channel";
1010

1111
export const MAINTENANCE_EVENTS = {
@@ -80,15 +80,21 @@ export default class EnterpriseMaintenanceManager {
8080
}
8181

8282
static async getHandshakeCommand(
83-
tls: boolean,
84-
host: string,
8583
options: RedisClientOptions,
8684
): Promise<
8785
| { cmd: Array<RedisArgument>; errorHandler: (error: Error) => void }
8886
| undefined
8987
> {
9088
if (options.maintNotifications === "disabled") return;
9189

90+
const host = options.url
91+
? new URL(options.url).hostname
92+
: (options.socket as RedisTcpSocketOptions | undefined)?.host;
93+
94+
if (!host) return;
95+
96+
const tls = options.socket?.tls ?? false
97+
9298
const movingEndpointType = await determineEndpoint(tls, host, options);
9399
return {
94100
cmd: [

packages/client/lib/client/index.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { strict as assert } from 'node:assert';
22
import testUtils, { GLOBAL, waitTillBeenCalled } from '../test-utils';
33
import RedisClient, { RedisClientOptions, RedisClientType } from '.';
4-
import { AbortError, ClientClosedError, ClientOfflineError, ConnectionTimeoutError, DisconnectsClientError, ErrorReply, MultiErrorReply, SocketClosedUnexpectedlyError, TimeoutError, WatchError } from '../errors';
4+
import { AbortError, ClientClosedError, ClientOfflineError, ConnectionTimeoutError, DisconnectsClientError, ErrorReply, MultiErrorReply, TimeoutError, WatchError } from '../errors';
55
import { defineScript } from '../lua-script';
66
import { spy, stub } from 'sinon';
77
import { once } from 'node:events';

packages/client/lib/client/index.ts

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import COMMANDS from '../commands';
2-
import RedisSocket, { RedisSocketOptions, RedisTcpSocketOptions } from './socket';
2+
import RedisSocket, { RedisSocketOptions } from './socket';
33
import { BasicAuth, CredentialsError, CredentialsProvider, StreamingCredentialsProvider, UnableToObtainNewCredentialsError, Disposable } from '../authx';
44
import RedisCommandsQueue, { CommandOptions } from './commands-queue';
55
import { EventEmitter } from 'node:events';
@@ -429,7 +429,7 @@ export default class RedisClient<
429429
return parsed;
430430
}
431431

432-
readonly #options?: RedisClientOptions<M, F, S, RESP, TYPE_MAPPING>;
432+
readonly #options: RedisClientOptions<M, F, S, RESP, TYPE_MAPPING>;
433433
#socket: RedisSocket;
434434
readonly #queue: RedisCommandsQueue;
435435
#selectedDB = 0;
@@ -541,10 +541,10 @@ export default class RedisClient<
541541

542542
}
543543

544-
#initiateOptions(options?: RedisClientOptions<M, F, S, RESP, TYPE_MAPPING>): RedisClientOptions<M, F, S, RESP, TYPE_MAPPING> | undefined {
544+
#initiateOptions(options: RedisClientOptions<M, F, S, RESP, TYPE_MAPPING> = {}): RedisClientOptions<M, F, S, RESP, TYPE_MAPPING> {
545545

546546
// Convert username/password to credentialsProvider if no credentialsProvider is already in place
547-
if (!options?.credentialsProvider && (options?.username || options?.password)) {
547+
if (!options.credentialsProvider && (options.username || options.password)) {
548548

549549
options.credentialsProvider = {
550550
type: 'async-credentials-provider',
@@ -555,19 +555,19 @@ export default class RedisClient<
555555
};
556556
}
557557

558-
if (options?.database) {
558+
if (options.database) {
559559
this._self.#selectedDB = options.database;
560560
}
561561

562-
if (options?.commandOptions) {
562+
if (options.commandOptions) {
563563
this._commandOptions = options.commandOptions;
564564
}
565565

566-
if(options?.maintNotifications !== 'disabled') {
567-
EnterpriseMaintenanceManager.setupDefaultMaintOptions(options!);
566+
if(options.maintNotifications !== 'disabled') {
567+
EnterpriseMaintenanceManager.setupDefaultMaintOptions(options);
568568
}
569569

570-
if (options?.url) {
570+
if (options.url) {
571571
const parsedOptions = RedisClient.parseOptions(options);
572572
if (parsedOptions?.database) {
573573
this._self.#selectedDB = parsedOptions.database;
@@ -748,8 +748,7 @@ export default class RedisClient<
748748
commands.push({cmd: this.#clientSideCache.trackingOn()});
749749
}
750750

751-
const { tls, host } = this.#options!.socket as RedisTcpSocketOptions;
752-
const maintenanceHandshakeCmd = await EnterpriseMaintenanceManager.getHandshakeCommand(!!tls, host!, this.#options!);
751+
const maintenanceHandshakeCmd = await EnterpriseMaintenanceManager.getHandshakeCommand(this.#options);
753752
if(maintenanceHandshakeCmd) {
754753
commands.push(maintenanceHandshakeCmd);
755754
};

0 commit comments

Comments
 (0)