Skip to content

Commit 93cc2fe

Browse files
committed
feat: remove win top bar and added ssh tunnel support
1 parent e85731b commit 93cc2fe

68 files changed

Lines changed: 2313 additions & 352 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

packages/backend/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"oracledb": "^6.10.0",
4141
"pg": "^8.20.0",
4242
"redis": "^5.11.0",
43+
"ssh2": "^1.17.0",
4344
"ts-node": "^10.9.2",
4445
"tsx": "^4.21.0",
4546
"ws": "^8.18.2"

packages/backend/src/adapters/database/sql/mysql-adapter/MySQLAdapter.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import net from 'node:net'
12
import mysql from 'mysql2/promise'
23
import { escapeId } from 'mysql2'
34
import type { ResultSetHeader, RowDataPacket } from 'mysql2'
@@ -12,6 +13,8 @@ import {
1213
import { assertIdentifier } from '../shared/identifier.ts'
1314
import { splitSqlStatements } from '../shared/sql-statements.ts'
1415
import { normalizeWhereClause } from '../shared/where-clause.ts'
16+
import type { ResolvedNetworkTransport, TlsConfig } from '../../../../datasources/shared/transport.ts'
17+
import { createMysqlTlsOptions, getTlsServerName } from '../../../../datasources/shared/transport.ts'
1518

1619
export class MySQLAdapter extends DefaultSQLAdapter {
1720
private connection!: mysql.Connection
@@ -23,6 +26,8 @@ export class MySQLAdapter extends DefaultSQLAdapter {
2326
user: string
2427
password: string
2528
database: string
29+
tls?: TlsConfig
30+
transport?: ResolvedNetworkTransport
2631
},
2732
) {
2833
super()
@@ -81,12 +86,27 @@ export class MySQLAdapter extends DefaultSQLAdapter {
8186
}
8287

8388
async connect() {
89+
const transport = this.options.transport
90+
const connectHost = transport?.connectHost ?? this.options.host
91+
const connectPort = transport?.connectPort ?? this.options.port
92+
const tlsHost = getTlsServerName(this.options.tls, this.options.host)
93+
const useCustomStream = Boolean(transport) || tlsHost !== connectHost
94+
8495
this.connection = await mysql.createConnection({
85-
host: this.options.host,
86-
port: this.options.port,
96+
host: useCustomStream ? tlsHost : connectHost,
97+
port: useCustomStream ? this.options.port : connectPort,
8798
user: this.options.user,
8899
password: this.options.password,
89100
database: this.options.database,
101+
...(useCustomStream
102+
? {
103+
stream: net.connect({
104+
host: connectHost,
105+
port: connectPort,
106+
}),
107+
}
108+
: {}),
109+
ssl: createMysqlTlsOptions(this.options.tls),
90110
waitForConnections: true,
91111
connectionLimit: 10,
92112
queueLimit: 0,

packages/backend/src/adapters/database/sql/postgres-adapter/PostgresAdapter.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import {
1010
import { assertIdentifier } from '../shared/identifier.ts'
1111
import { splitSqlStatements } from '../shared/sql-statements.ts'
1212
import { normalizeWhereClause } from '../shared/where-clause.ts'
13+
import type { ResolvedNetworkTransport, TlsConfig } from '../../../../datasources/shared/transport.ts'
14+
import { createNodeTlsOptions } from '../../../../datasources/shared/transport.ts'
1315

1416
export class PostgresAdapter extends DefaultSQLAdapter {
1517
private client!: Client
@@ -22,6 +24,8 @@ export class PostgresAdapter extends DefaultSQLAdapter {
2224
password: string
2325
database: string
2426
schema?: string
27+
tls?: TlsConfig
28+
transport?: ResolvedNetworkTransport
2529
},
2630
) {
2731
super()
@@ -72,12 +76,14 @@ export class PostgresAdapter extends DefaultSQLAdapter {
7276
}
7377

7478
async connect() {
79+
const transport = this.options.transport
7580
this.client = new Client({
76-
host: this.options.host,
77-
port: this.options.port,
81+
host: transport?.connectHost ?? this.options.host,
82+
port: transport?.connectPort ?? this.options.port,
7883
user: this.options.user,
7984
password: this.options.password,
8085
database: this.options.database,
86+
ssl: createNodeTlsOptions(this.options.tls, transport?.serverHost ?? this.options.host),
8187
})
8288

8389
await this.client.connect()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import type { AppConfig } from './config/app-config.ts'
2+
import type { SshTunnelManager } from './datasources/shared/ssh-tunnel-manager.ts'
23
import type { MetaStore } from './meta/store.ts'
34

45
export type AppContext = {
56
config: AppConfig
67
metaStore: MetaStore
8+
sshTunnelManager: SshTunnelManager
79
}

packages/backend/src/datasources/cassandra/adapter.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import { createRequire } from 'node:module'
22
import type { Client } from 'cassandra-driver'
33
import type * as CassandraNamespace from 'cassandra-driver'
44
import type { QueryResult } from '../../adapters/database/sql/default-sql-adapter/DefaultSQLAdapter.ts'
5+
import type { ResolvedNetworkTransport, TlsConfig } from '../shared/transport.ts'
6+
import { createNodeTlsOptions } from '../shared/transport.ts'
57
import { createSelectResultFromRows, QueryOnlySqlAdapter } from '../shared-sql/query-only-adapter.ts'
68

79
type CassandraConfig = {
@@ -10,7 +12,8 @@ type CassandraConfig = {
1012
user?: string
1113
password?: string
1214
database?: string
13-
ssl?: boolean
15+
tls?: TlsConfig
16+
transport?: ResolvedNetworkTransport
1417
}
1518

1619
type CassandraModule = typeof CassandraNamespace
@@ -29,11 +32,12 @@ export class CassandraSqlAdapter extends QueryOnlySqlAdapter {
2932

3033
async connect() {
3134
const { Client } = this.loadCassandraModule()
35+
const transport = this.config.transport
3236
this.client = new Client({
33-
contactPoints: [this.config.host],
37+
contactPoints: [transport?.connectHost ?? this.config.host],
3438
localDataCenter: 'datacenter1',
3539
protocolOptions: {
36-
port: this.config.port,
40+
port: transport?.connectPort ?? this.config.port,
3741
},
3842
keyspace: this.config.database,
3943
credentials:
@@ -43,7 +47,7 @@ export class CassandraSqlAdapter extends QueryOnlySqlAdapter {
4347
password: this.config.password ?? '',
4448
}
4549
: undefined,
46-
sslOptions: this.config.ssl ? {} : undefined,
50+
sslOptions: createNodeTlsOptions(this.config.tls, transport?.serverHost ?? this.config.host),
4751
})
4852

4953
await this.client.connect()
Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { resolveTcpTransportConfig } from '../shared/runtime.ts'
2+
import { getTransportSecretFields } from '../shared/transport.ts'
13
import { normalizeNetworkSqlConfig } from '../shared-sql/network-config.ts'
24
import type { DataSourceModule } from '../shared/module.ts'
35
import { CassandraSqlAdapter } from './adapter.ts'
@@ -15,27 +17,26 @@ export const cassandraDataSourceModule = {
1517
schemaEditor: false,
1618
resourceBrowser: false,
1719
},
20+
transportSupport: {
21+
ssh: true,
22+
tls: true,
23+
},
1824
},
19-
secretFields: ['password'],
25+
secretFields: ['password', ...getTransportSecretFields({ ssh: true, tls: true })],
2026
normalizeConfig(config) {
2127
return normalizeNetworkSqlConfig(config, {
2228
defaultPort: 9042,
2329
requireUser: false,
2430
requirePassword: false,
2531
requireDatabase: false,
26-
includeSsl: true,
32+
includeTls: true,
33+
includeSsh: true,
2734
})
2835
},
36+
resolveRuntimeConfig(config, context) {
37+
return resolveTcpTransportConfig(config as never, context)
38+
},
2939
createSqlAdapter(config) {
30-
return new CassandraSqlAdapter(
31-
config as {
32-
host: string
33-
port: number
34-
user?: string
35-
password?: string
36-
database?: string
37-
ssl?: boolean
38-
},
39-
)
40+
return new CassandraSqlAdapter(config as never)
4041
},
4142
} satisfies DataSourceModule

packages/backend/src/datasources/clickhouse/adapter.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import { createClient, type ClickHouseClient } from '@clickhouse/client'
2+
import type http from 'node:http'
3+
import type https from 'node:https'
24
import type {
35
QueryResult,
46
SQLCreateTableColumnInput,
@@ -7,6 +9,8 @@ import type {
79
} from '../../adapters/database/sql/default-sql-adapter/DefaultSQLAdapter.ts'
810
import { assertIdentifier } from '../../adapters/database/sql/shared/identifier.ts'
911
import { normalizeWhereClause } from '../../adapters/database/sql/shared/where-clause.ts'
12+
import type { ResolvedNetworkTransport, TlsConfig } from '../shared/transport.ts'
13+
import { createHttpTransportAgent, destroyHttpTransportAgent, isTlsEnabled } from '../shared/transport.ts'
1014
import { createSelectResultFromRows, QueryOnlySqlAdapter } from '../shared-sql/query-only-adapter.ts'
1115

1216
type ClickHouseConfig = {
@@ -15,7 +19,8 @@ type ClickHouseConfig = {
1519
user?: string
1620
password?: string
1721
database?: string
18-
ssl?: boolean
22+
tls?: TlsConfig
23+
transport?: ResolvedNetworkTransport
1924
}
2025

2126
type ClickHouseTableRow = {
@@ -35,6 +40,7 @@ function isSelectLikeStatement(sqlText: string) {
3540

3641
export class ClickHouseSqlAdapter extends QueryOnlySqlAdapter {
3742
private client!: ClickHouseClient
43+
private agent?: http.Agent | https.Agent
3844

3945
constructor(private readonly config: ClickHouseConfig) {
4046
super()
@@ -63,17 +69,32 @@ export class ClickHouseSqlAdapter extends QueryOnlySqlAdapter {
6369
}
6470

6571
async connect() {
66-
const protocol = this.config.ssl ? 'https' : 'http'
72+
const secure = isTlsEnabled(this.config.tls)
73+
const transport = this.config.transport ?? {
74+
connectHost: this.config.host,
75+
connectPort: this.config.port,
76+
serverHost: this.config.host,
77+
serverPort: this.config.port,
78+
tls: this.config.tls,
79+
}
80+
const protocol = secure ? 'https' : 'http'
81+
this.agent = createHttpTransportAgent({
82+
secure,
83+
transport,
84+
})
6785
this.client = createClient({
6886
url: `${protocol}://${this.config.host}:${this.config.port}`,
6987
username: this.config.user,
7088
password: this.config.password,
7189
database: this.database,
90+
http_agent: this.agent,
7291
})
7392
}
7493

7594
async close() {
7695
await this.client?.close()
96+
destroyHttpTransportAgent(this.agent)
97+
this.agent = undefined
7798
}
7899

79100
async getTables() {
Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { resolveTcpTransportConfig } from '../shared/runtime.ts'
2+
import { getTransportSecretFields } from '../shared/transport.ts'
13
import { normalizeNetworkSqlConfig } from '../shared-sql/network-config.ts'
24
import type { DataSourceModule } from '../shared/module.ts'
35
import { ClickHouseSqlAdapter } from './adapter.ts'
@@ -16,27 +18,26 @@ export const clickHouseDataSourceModule = {
1618
tableCreate: true,
1719
resourceBrowser: false,
1820
},
21+
transportSupport: {
22+
ssh: true,
23+
tls: true,
24+
},
1925
},
20-
secretFields: ['password'],
26+
secretFields: ['password', ...getTransportSecretFields({ ssh: true, tls: true })],
2127
normalizeConfig(config) {
2228
return normalizeNetworkSqlConfig(config, {
2329
defaultPort: 8123,
2430
requireUser: false,
2531
requirePassword: false,
2632
requireDatabase: false,
27-
includeSsl: true,
33+
includeTls: true,
34+
includeSsh: true,
2835
})
2936
},
37+
resolveRuntimeConfig(config, context) {
38+
return resolveTcpTransportConfig(config as never, context)
39+
},
3040
createSqlAdapter(config) {
31-
return new ClickHouseSqlAdapter(
32-
config as {
33-
host: string
34-
port: number
35-
user?: string
36-
password?: string
37-
database?: string
38-
ssl?: boolean
39-
},
40-
)
41+
return new ClickHouseSqlAdapter(config as never)
4142
},
4243
} satisfies DataSourceModule
Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import { PostgresAdapter } from '../../adapters/database/sql/postgres-adapter/PostgresAdapter.ts'
2+
import { resolveTcpTransportConfig } from '../shared/runtime.ts'
3+
import { getTransportSecretFields } from '../shared/transport.ts'
24
import { normalizeNetworkSqlConfig } from '../shared-sql/network-config.ts'
35
import type { DataSourceModule } from '../shared/module.ts'
46

@@ -16,28 +18,27 @@ export const cockroachDbDataSourceModule = {
1618
tableCreate: true,
1719
resourceBrowser: false,
1820
},
21+
transportSupport: {
22+
ssh: true,
23+
tls: true,
24+
},
1925
},
20-
secretFields: ['password'],
26+
secretFields: ['password', ...getTransportSecretFields({ ssh: true, tls: true })],
2127
normalizeConfig(config) {
2228
return normalizeNetworkSqlConfig(config, {
2329
defaultPort: 26257,
2430
requireUser: true,
2531
requirePassword: true,
2632
requireDatabase: true,
2733
includeSchema: true,
28-
includeSsl: true,
34+
includeTls: true,
35+
includeSsh: true,
2936
})
3037
},
38+
resolveRuntimeConfig(config, context) {
39+
return resolveTcpTransportConfig(config as never, context)
40+
},
3141
createSqlAdapter(config) {
32-
return new PostgresAdapter(
33-
config as {
34-
host: string
35-
port?: number
36-
user: string
37-
password: string
38-
database: string
39-
schema?: string
40-
},
41-
)
42+
return new PostgresAdapter(config as never)
4243
},
4344
} satisfies DataSourceModule

0 commit comments

Comments
 (0)