diff --git a/Cargo.lock b/Cargo.lock index 7e98a8574e..122904cd2a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1445,6 +1445,12 @@ dependencies = [ "libc", ] +[[package]] +name = "crc16" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "338089f42c427b86394a5ee60ff321da23a5c89c9d89514c829687b26359fcff" + [[package]] name = "crc32fast" version = "1.5.0" @@ -6002,8 +6008,11 @@ dependencies = [ "bytes", "cfg-if", "combine", + "crc16", + "futures-sink", "futures-util", "itoa", + "log", "num-bigint", "percent-encoding", "pin-project-lite", diff --git a/apps/desktop/src/components/connection/ConnectionDialog.vue b/apps/desktop/src/components/connection/ConnectionDialog.vue index 48eb3941ef..916ef9645c 100644 --- a/apps/desktop/src/components/connection/ConnectionDialog.vue +++ b/apps/desktop/src/components/connection/ConnectionDialog.vue @@ -105,6 +105,7 @@ const defaultForm = (): Omit => ({ redis_sentinel_username: "", redis_sentinel_password: "", redis_sentinel_tls: false, + redis_cluster_nodes: "", }); const form = ref(defaultForm()); @@ -362,6 +363,7 @@ watch( redis_sentinel_username: config.redis_sentinel_username || "", redis_sentinel_password: config.redis_sentinel_password || "", redis_sentinel_tls: config.redis_sentinel_tls || false, + redis_cluster_nodes: config.redis_cluster_nodes || "", }; selectedType.value = profile; mongoUseUrl.value = !!config.connection_string; @@ -753,15 +755,29 @@ function connectionConfigForSubmit(id: string): ConnectionConfig { config.redis_sentinel_username = undefined; config.redis_sentinel_password = undefined; config.redis_sentinel_tls = undefined; + config.redis_cluster_nodes = undefined; } else if (config.redis_connection_mode === "sentinel") { config.redis_sentinel_master = config.redis_sentinel_master?.trim() || ""; config.redis_sentinel_nodes = normalizeRedisSentinelNodes(config.redis_sentinel_nodes || ""); config.redis_sentinel_username = config.redis_sentinel_username?.trim() || ""; + config.redis_cluster_nodes = undefined; const firstNode = firstRedisSentinelEndpoint(config.redis_sentinel_nodes); if (firstNode) { config.host = firstNode.host; config.port = firstNode.port; } + } else if (config.redis_connection_mode === "cluster") { + config.redis_sentinel_master = undefined; + config.redis_sentinel_nodes = undefined; + config.redis_sentinel_username = undefined; + config.redis_sentinel_password = undefined; + config.redis_sentinel_tls = undefined; + config.redis_cluster_nodes = normalizeRedisClusterNodes(config.redis_cluster_nodes || ""); + const firstNode = firstRedisClusterEndpoint(config.redis_cluster_nodes); + if (firstNode) { + config.host = firstNode.host; + config.port = firstNode.port; + } } else { config.redis_connection_mode = "standalone"; config.redis_sentinel_master = undefined; @@ -769,6 +785,7 @@ function connectionConfigForSubmit(id: string): ConnectionConfig { config.redis_sentinel_username = undefined; config.redis_sentinel_password = undefined; config.redis_sentinel_tls = undefined; + config.redis_cluster_nodes = undefined; } if (config.db_type !== "mysql" && config.db_type !== "clickhouse") { config.ca_cert_path = undefined; @@ -875,6 +892,14 @@ function normalizePostgresSslMode(value: string): string { } function normalizeRedisSentinelNodes(value: string): string { + return normalizeRedisNodeList(value); +} + +function normalizeRedisClusterNodes(value: string): string { + return normalizeRedisNodeList(value); +} + +function normalizeRedisNodeList(value: string): string { return value .split(/[\n,;]+/) .map((node) => node.trim()) @@ -883,13 +908,21 @@ function normalizeRedisSentinelNodes(value: string): string { } function firstRedisSentinelEndpoint(value?: string): { host: string; port: number } | null { - const first = normalizeRedisSentinelNodes(value || "") + const first = normalizeRedisNodeList(value || "") .split("\n") .find(Boolean); if (!first) return null; return parseRedisEndpoint(first, 26379); } +function firstRedisClusterEndpoint(value?: string): { host: string; port: number } | null { + const first = normalizeRedisNodeList(value || "") + .split("\n") + .find(Boolean); + if (!first) return null; + return parseRedisEndpoint(first, 6379); +} + function parseRedisEndpoint(value: string, defaultPort: number): { host: string; port: number } { const endpoint = value .trim() @@ -1616,7 +1649,7 @@ function openExternalUrl(url: string) {
+
@@ -1669,6 +1711,17 @@ function openExternalUrl(url: string) {
+