@squadbase/vite-server 0.1.12-dev.93b8799 → 0.1.17-dev.24af54e
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +12128 -934
- package/dist/connectors/airtable-oauth.js +248 -46
- package/dist/connectors/airtable.js +285 -51
- package/dist/connectors/amplitude.js +288 -47
- package/dist/connectors/anthropic.js +126 -47
- package/dist/connectors/asana.js +293 -49
- package/dist/connectors/attio.js +268 -49
- package/dist/connectors/aws-billing.js +253 -46
- package/dist/connectors/azure-sql.js +387 -102
- package/dist/connectors/backlog-api-key.js +283 -47
- package/dist/connectors/clickup.js +304 -49
- package/dist/connectors/cosmosdb.js +271 -50
- package/dist/connectors/customerio.js +285 -47
- package/dist/connectors/dbt.js +306 -47
- package/dist/connectors/freshdesk.js +308 -53
- package/dist/connectors/freshsales.js +299 -52
- package/dist/connectors/freshservice.js +327 -53
- package/dist/connectors/gamma.js +293 -52
- package/dist/connectors/gemini.js +125 -47
- package/dist/connectors/github.js +352 -49
- package/dist/connectors/gmail-oauth.js +170 -7
- package/dist/connectors/gmail.js +316 -47
- package/dist/connectors/google-ads.js +254 -46
- package/dist/connectors/google-analytics-oauth.js +276 -46
- package/dist/connectors/google-analytics.js +378 -49
- package/dist/connectors/google-audit-log.js +404 -47
- package/dist/connectors/google-calendar-oauth.js +225 -46
- package/dist/connectors/google-calendar.js +325 -47
- package/dist/connectors/google-docs.js +186 -6
- package/dist/connectors/google-drive.js +228 -5
- package/dist/connectors/google-search-console-oauth.js +222 -46
- package/dist/connectors/google-sheets.js +238 -47
- package/dist/connectors/google-slides.js +171 -6
- package/dist/connectors/grafana.js +298 -49
- package/dist/connectors/hubspot-oauth.js +174 -5
- package/dist/connectors/hubspot.js +272 -49
- package/dist/connectors/influxdb.js +382 -51
- package/dist/connectors/intercom-oauth.js +176 -5
- package/dist/connectors/intercom.js +268 -49
- package/dist/connectors/jdbc.js +728 -110
- package/dist/connectors/jira-api-key.js +292 -47
- package/dist/connectors/kintone-api-token.js +247 -47
- package/dist/connectors/kintone.js +294 -47
- package/dist/connectors/linear.js +296 -49
- package/dist/connectors/linkedin-ads.js +234 -50
- package/dist/connectors/mailchimp-oauth.js +234 -46
- package/dist/connectors/mailchimp.js +286 -49
- package/dist/connectors/meta-ads-oauth.js +239 -48
- package/dist/connectors/meta-ads.js +251 -50
- package/dist/connectors/mixpanel.js +304 -47
- package/dist/connectors/monday.js +326 -49
- package/dist/connectors/mongodb.js +285 -57
- package/dist/connectors/notion-oauth.js +197 -5
- package/dist/connectors/notion.js +289 -51
- package/dist/connectors/openai.js +125 -47
- package/dist/connectors/oracle.js +405 -103
- package/dist/connectors/outlook-oauth.js +170 -5
- package/dist/connectors/powerbi-oauth.js +217 -5
- package/dist/connectors/salesforce.js +350 -49
- package/dist/connectors/semrush.js +280 -49
- package/dist/connectors/sentry.js +255 -50
- package/dist/connectors/shopify-oauth.js +153 -5
- package/dist/connectors/shopify.js +323 -47
- package/dist/connectors/sqlserver.js +381 -102
- package/dist/connectors/stripe-api-key.js +235 -46
- package/dist/connectors/stripe-oauth.js +168 -5
- package/dist/connectors/supabase.js +269 -48
- package/dist/connectors/tableau.js +337 -206
- package/dist/connectors/tiktok-ads.js +245 -48
- package/dist/connectors/wix-store.js +286 -49
- package/dist/connectors/zendesk-oauth.js +205 -5
- package/dist/connectors/zendesk.js +324 -47
- package/dist/index.d.ts +149 -1
- package/dist/index.js +18297 -6886
- package/dist/main.js +12785 -1382
- package/dist/vite-plugin.js +12140 -936
- package/package.json +1 -1
package/dist/connectors/jdbc.js
CHANGED
|
@@ -1,105 +1,70 @@
|
|
|
1
|
-
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
description;
|
|
6
|
-
envVarBaseKey;
|
|
7
|
-
type;
|
|
8
|
-
secret;
|
|
9
|
-
required;
|
|
10
|
-
constructor(config) {
|
|
11
|
-
this.slug = config.slug;
|
|
12
|
-
this.name = config.name;
|
|
13
|
-
this.description = config.description;
|
|
14
|
-
this.envVarBaseKey = config.envVarBaseKey;
|
|
15
|
-
this.type = config.type;
|
|
16
|
-
this.secret = config.secret;
|
|
17
|
-
this.required = config.required;
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Get the parameter value from a ConnectorConnectionObject.
|
|
21
|
-
*/
|
|
22
|
-
getValue(connection2) {
|
|
23
|
-
const param = connection2.parameters.find(
|
|
24
|
-
(p) => p.parameterSlug === this.slug
|
|
25
|
-
);
|
|
26
|
-
if (!param || param.value == null) {
|
|
27
|
-
throw new Error(
|
|
28
|
-
`Parameter "${this.slug}" not found or has no value in connection "${connection2.id}"`
|
|
29
|
-
);
|
|
30
|
-
}
|
|
31
|
-
return param.value;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Try to get the parameter value. Returns undefined if not found (for optional params).
|
|
35
|
-
*/
|
|
36
|
-
tryGetValue(connection2) {
|
|
37
|
-
const param = connection2.parameters.find(
|
|
38
|
-
(p) => p.parameterSlug === this.slug
|
|
39
|
-
);
|
|
40
|
-
if (!param || param.value == null) return void 0;
|
|
41
|
-
return param.value;
|
|
42
|
-
}
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
+
var __esm = (fn, res) => function __init() {
|
|
4
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
43
5
|
};
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
sshHost: new ParameterDefinition({
|
|
48
|
-
slug: "ssh-host",
|
|
49
|
-
name: "SSH Tunnel Host",
|
|
50
|
-
description: "Optional. Hostname of the SSH bastion to tunnel through. Leave empty to connect directly.",
|
|
51
|
-
envVarBaseKey: "SSH_TUNNEL_HOST",
|
|
52
|
-
type: "text",
|
|
53
|
-
secret: false,
|
|
54
|
-
required: false
|
|
55
|
-
}),
|
|
56
|
-
sshPort: new ParameterDefinition({
|
|
57
|
-
slug: "ssh-port",
|
|
58
|
-
name: "SSH Tunnel Port",
|
|
59
|
-
description: "Optional. SSH port of the bastion host (default: 22).",
|
|
60
|
-
envVarBaseKey: "SSH_TUNNEL_PORT",
|
|
61
|
-
type: "text",
|
|
62
|
-
secret: false,
|
|
63
|
-
required: false
|
|
64
|
-
}),
|
|
65
|
-
sshUsername: new ParameterDefinition({
|
|
66
|
-
slug: "ssh-username",
|
|
67
|
-
name: "SSH Tunnel Username",
|
|
68
|
-
description: "Optional. Username for SSH authentication. Required when SSH Tunnel Host is set.",
|
|
69
|
-
envVarBaseKey: "SSH_TUNNEL_USERNAME",
|
|
70
|
-
type: "text",
|
|
71
|
-
secret: false,
|
|
72
|
-
required: false
|
|
73
|
-
}),
|
|
74
|
-
sshPrivateKeyBase64: new ParameterDefinition({
|
|
75
|
-
slug: "ssh-private-key-base64",
|
|
76
|
-
name: "SSH Private Key",
|
|
77
|
-
description: "Optional. Private key (PEM, base64-encoded) used for SSH authentication. Required when SSH Tunnel Host is set.",
|
|
78
|
-
envVarBaseKey: "SSH_TUNNEL_PRIVATE_KEY_BASE64",
|
|
79
|
-
type: "base64EncodedText",
|
|
80
|
-
secret: true,
|
|
81
|
-
required: false
|
|
82
|
-
}),
|
|
83
|
-
sshPassphrase: new ParameterDefinition({
|
|
84
|
-
slug: "ssh-passphrase",
|
|
85
|
-
name: "SSH Private Key Passphrase",
|
|
86
|
-
description: "Optional. Passphrase for the SSH private key, if it is encrypted.",
|
|
87
|
-
envVarBaseKey: "SSH_TUNNEL_PASSPHRASE",
|
|
88
|
-
type: "text",
|
|
89
|
-
secret: true,
|
|
90
|
-
required: false
|
|
91
|
-
})
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
92
9
|
};
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
10
|
+
|
|
11
|
+
// ../connectors/src/parameter-definition.ts
|
|
12
|
+
var ParameterDefinition;
|
|
13
|
+
var init_parameter_definition = __esm({
|
|
14
|
+
"../connectors/src/parameter-definition.ts"() {
|
|
15
|
+
"use strict";
|
|
16
|
+
ParameterDefinition = class {
|
|
17
|
+
slug;
|
|
18
|
+
name;
|
|
19
|
+
description;
|
|
20
|
+
envVarBaseKey;
|
|
21
|
+
type;
|
|
22
|
+
secret;
|
|
23
|
+
required;
|
|
24
|
+
constructor(config) {
|
|
25
|
+
this.slug = config.slug;
|
|
26
|
+
this.name = config.name;
|
|
27
|
+
this.description = config.description;
|
|
28
|
+
this.envVarBaseKey = config.envVarBaseKey;
|
|
29
|
+
this.type = config.type;
|
|
30
|
+
this.secret = config.secret;
|
|
31
|
+
this.required = config.required;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Get the parameter value from a ConnectorConnectionObject.
|
|
35
|
+
*/
|
|
36
|
+
getValue(connection2) {
|
|
37
|
+
const param = connection2.parameters.find(
|
|
38
|
+
(p) => p.parameterSlug === this.slug
|
|
39
|
+
);
|
|
40
|
+
if (!param || param.value == null) {
|
|
41
|
+
throw new Error(
|
|
42
|
+
`Parameter "${this.slug}" not found or has no value in connection "${connection2.id}"`
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
return param.value;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Try to get the parameter value. Returns undefined if not found (for optional params).
|
|
49
|
+
*/
|
|
50
|
+
tryGetValue(connection2) {
|
|
51
|
+
const param = connection2.parameters.find(
|
|
52
|
+
(p) => p.parameterSlug === this.slug
|
|
53
|
+
);
|
|
54
|
+
if (!param || param.value == null) return void 0;
|
|
55
|
+
return param.value;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
96
58
|
}
|
|
97
59
|
});
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
60
|
+
|
|
61
|
+
// ../connectors/src/lib/ssh-tunnel.ts
|
|
62
|
+
var ssh_tunnel_exports = {};
|
|
63
|
+
__export(ssh_tunnel_exports, {
|
|
64
|
+
connectionParamsToRecord: () => connectionParamsToRecord,
|
|
65
|
+
maybeOpenSshTunnel: () => maybeOpenSshTunnel,
|
|
66
|
+
maybeOpenSshTunnelHostPort: () => maybeOpenSshTunnelHostPort,
|
|
67
|
+
sshTunnelParameters: () => sshTunnelParameters
|
|
103
68
|
});
|
|
104
69
|
function connectionParamsToRecord(connection2) {
|
|
105
70
|
const out = {};
|
|
@@ -185,11 +150,80 @@ async function maybeOpenSshTunnel(params, connectionUrl, defaultDbPort) {
|
|
|
185
150
|
close: tunnel.close
|
|
186
151
|
};
|
|
187
152
|
}
|
|
153
|
+
var sshTunnelParameters, NOOP_TUNNEL, NOOP_TUNNEL_HOSTPORT;
|
|
154
|
+
var init_ssh_tunnel = __esm({
|
|
155
|
+
"../connectors/src/lib/ssh-tunnel.ts"() {
|
|
156
|
+
"use strict";
|
|
157
|
+
init_parameter_definition();
|
|
158
|
+
sshTunnelParameters = {
|
|
159
|
+
sshHost: new ParameterDefinition({
|
|
160
|
+
slug: "ssh-host",
|
|
161
|
+
name: "SSH Tunnel Host",
|
|
162
|
+
description: "Optional. Hostname of the SSH bastion to tunnel through. Leave empty to connect directly.",
|
|
163
|
+
envVarBaseKey: "SSH_TUNNEL_HOST",
|
|
164
|
+
type: "text",
|
|
165
|
+
secret: false,
|
|
166
|
+
required: false
|
|
167
|
+
}),
|
|
168
|
+
sshPort: new ParameterDefinition({
|
|
169
|
+
slug: "ssh-port",
|
|
170
|
+
name: "SSH Tunnel Port",
|
|
171
|
+
description: "Optional. SSH port of the bastion host (default: 22).",
|
|
172
|
+
envVarBaseKey: "SSH_TUNNEL_PORT",
|
|
173
|
+
type: "text",
|
|
174
|
+
secret: false,
|
|
175
|
+
required: false
|
|
176
|
+
}),
|
|
177
|
+
sshUsername: new ParameterDefinition({
|
|
178
|
+
slug: "ssh-username",
|
|
179
|
+
name: "SSH Tunnel Username",
|
|
180
|
+
description: "Optional. Username for SSH authentication. Required when SSH Tunnel Host is set.",
|
|
181
|
+
envVarBaseKey: "SSH_TUNNEL_USERNAME",
|
|
182
|
+
type: "text",
|
|
183
|
+
secret: false,
|
|
184
|
+
required: false
|
|
185
|
+
}),
|
|
186
|
+
sshPrivateKeyBase64: new ParameterDefinition({
|
|
187
|
+
slug: "ssh-private-key-base64",
|
|
188
|
+
name: "SSH Private Key",
|
|
189
|
+
description: "Optional. Private key (PEM, base64-encoded) used for SSH authentication. Required when SSH Tunnel Host is set.",
|
|
190
|
+
envVarBaseKey: "SSH_TUNNEL_PRIVATE_KEY_BASE64",
|
|
191
|
+
type: "base64EncodedText",
|
|
192
|
+
secret: true,
|
|
193
|
+
required: false
|
|
194
|
+
}),
|
|
195
|
+
sshPassphrase: new ParameterDefinition({
|
|
196
|
+
slug: "ssh-passphrase",
|
|
197
|
+
name: "SSH Private Key Passphrase",
|
|
198
|
+
description: "Optional. Passphrase for the SSH private key, if it is encrypted.",
|
|
199
|
+
envVarBaseKey: "SSH_TUNNEL_PASSPHRASE",
|
|
200
|
+
type: "text",
|
|
201
|
+
secret: true,
|
|
202
|
+
required: false
|
|
203
|
+
})
|
|
204
|
+
};
|
|
205
|
+
NOOP_TUNNEL = (connectionUrl) => ({
|
|
206
|
+
connectionUrl,
|
|
207
|
+
close: async () => {
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
NOOP_TUNNEL_HOSTPORT = (host, port) => ({
|
|
211
|
+
host,
|
|
212
|
+
port,
|
|
213
|
+
close: async () => {
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
});
|
|
188
218
|
|
|
189
219
|
// ../connectors/src/connectors/sqlserver/utils.ts
|
|
190
|
-
var
|
|
191
|
-
|
|
192
|
-
|
|
220
|
+
var utils_exports = {};
|
|
221
|
+
__export(utils_exports, {
|
|
222
|
+
parseSqlServerJdbcUrl: () => parseSqlServerJdbcUrl,
|
|
223
|
+
redactSqlServerUrl: () => redactSqlServerUrl,
|
|
224
|
+
runSqlServerSetupQuery: () => runSqlServerSetupQuery,
|
|
225
|
+
toMssqlConfig: () => toMssqlConfig
|
|
226
|
+
});
|
|
193
227
|
function parseBoolean(value) {
|
|
194
228
|
if (value == null) return void 0;
|
|
195
229
|
const lower = value.toLowerCase();
|
|
@@ -256,8 +290,34 @@ function toMssqlConfig(parsed, defaults = {}) {
|
|
|
256
290
|
function redactSqlServerUrl(jdbcUrl) {
|
|
257
291
|
return jdbcUrl.replace(/(:\/\/)([^@/;]+)@/, "$1***@").replace(/(password\s*=\s*)([^;]+)/gi, "$1***");
|
|
258
292
|
}
|
|
293
|
+
async function runSqlServerSetupQuery(params, sql, forceEncrypt) {
|
|
294
|
+
const { runMssqlQuery: runMssqlQuery2 } = await Promise.resolve().then(() => (init_mssql_runner(), mssql_runner_exports));
|
|
295
|
+
const parsed = parseSqlServerJdbcUrl(params["jdbc-url"] ?? "", {
|
|
296
|
+
username: params["username"],
|
|
297
|
+
password: params["password"]
|
|
298
|
+
});
|
|
299
|
+
const result = await runMssqlQuery2(parsed, sql, {
|
|
300
|
+
forceEncrypt,
|
|
301
|
+
tunnelParams: params
|
|
302
|
+
});
|
|
303
|
+
return result.rows;
|
|
304
|
+
}
|
|
305
|
+
var SQLSERVER_PREFIX_RE, TRUE_VALUES, FALSE_VALUES;
|
|
306
|
+
var init_utils = __esm({
|
|
307
|
+
"../connectors/src/connectors/sqlserver/utils.ts"() {
|
|
308
|
+
"use strict";
|
|
309
|
+
SQLSERVER_PREFIX_RE = /^(?:jdbc:)?sqlserver:\/\//i;
|
|
310
|
+
TRUE_VALUES = /* @__PURE__ */ new Set(["true", "1", "yes"]);
|
|
311
|
+
FALSE_VALUES = /* @__PURE__ */ new Set(["false", "0", "no"]);
|
|
312
|
+
}
|
|
313
|
+
});
|
|
259
314
|
|
|
260
315
|
// ../connectors/src/lib/mssql-runner.ts
|
|
316
|
+
var mssql_runner_exports = {};
|
|
317
|
+
__export(mssql_runner_exports, {
|
|
318
|
+
checkMssqlConnection: () => checkMssqlConnection,
|
|
319
|
+
runMssqlQuery: () => runMssqlQuery
|
|
320
|
+
});
|
|
261
321
|
async function importMssql() {
|
|
262
322
|
const mod = await import("mssql");
|
|
263
323
|
return mod.default ?? mod;
|
|
@@ -306,11 +366,23 @@ async function checkMssqlConnection(url, credentials, options = {}) {
|
|
|
306
366
|
return { success: false, error: msg };
|
|
307
367
|
}
|
|
308
368
|
}
|
|
369
|
+
var init_mssql_runner = __esm({
|
|
370
|
+
"../connectors/src/lib/mssql-runner.ts"() {
|
|
371
|
+
"use strict";
|
|
372
|
+
init_ssh_tunnel();
|
|
373
|
+
init_utils();
|
|
374
|
+
}
|
|
375
|
+
});
|
|
309
376
|
|
|
310
377
|
// ../connectors/src/connectors/oracle/utils.ts
|
|
311
|
-
var
|
|
312
|
-
|
|
313
|
-
|
|
378
|
+
var utils_exports2 = {};
|
|
379
|
+
__export(utils_exports2, {
|
|
380
|
+
parseOracleConnectStringHostPort: () => parseOracleConnectStringHostPort,
|
|
381
|
+
parseOracleJdbcUrl: () => parseOracleJdbcUrl,
|
|
382
|
+
redactOracleUrl: () => redactOracleUrl,
|
|
383
|
+
rewriteOracleConnectStringHostPort: () => rewriteOracleConnectStringHostPort,
|
|
384
|
+
runOracleSetupQuery: () => runOracleSetupQuery
|
|
385
|
+
});
|
|
314
386
|
function parseOracleJdbcUrl(jdbcUrl, options = {}) {
|
|
315
387
|
const trimmed = jdbcUrl.trim();
|
|
316
388
|
if (JDBC_OCI_PREFIX_RE.test(trimmed)) {
|
|
@@ -382,9 +454,34 @@ function rewriteOracleConnectStringHostPort(connectString, host, port) {
|
|
|
382
454
|
if (!parts) return connectString;
|
|
383
455
|
return `${host}:${port}${parts.trailing}`;
|
|
384
456
|
}
|
|
457
|
+
async function runOracleSetupQuery(params, sql) {
|
|
458
|
+
const { runOracleQuery: runOracleQuery2 } = await Promise.resolve().then(() => (init_oracle_runner(), oracle_runner_exports));
|
|
459
|
+
const parsed = parseOracleJdbcUrl(params["jdbc-url"] ?? "", {
|
|
460
|
+
username: params["username"],
|
|
461
|
+
password: params["password"]
|
|
462
|
+
});
|
|
463
|
+
const cleanSql = sql.replace(/;\s*$/, "");
|
|
464
|
+
const result = await runOracleQuery2(parsed, cleanSql, {
|
|
465
|
+
tunnelParams: params
|
|
466
|
+
});
|
|
467
|
+
return result.rows;
|
|
468
|
+
}
|
|
469
|
+
var JDBC_THIN_PREFIX_RE, JDBC_OCI_PREFIX_RE, URL_PREFIX_RE;
|
|
470
|
+
var init_utils2 = __esm({
|
|
471
|
+
"../connectors/src/connectors/oracle/utils.ts"() {
|
|
472
|
+
"use strict";
|
|
473
|
+
JDBC_THIN_PREFIX_RE = /^jdbc:oracle:thin:/i;
|
|
474
|
+
JDBC_OCI_PREFIX_RE = /^jdbc:oracle:oci/i;
|
|
475
|
+
URL_PREFIX_RE = /^oracle:\/\//i;
|
|
476
|
+
}
|
|
477
|
+
});
|
|
385
478
|
|
|
386
479
|
// ../connectors/src/lib/oracle-runner.ts
|
|
387
|
-
var
|
|
480
|
+
var oracle_runner_exports = {};
|
|
481
|
+
__export(oracle_runner_exports, {
|
|
482
|
+
checkOracleConnection: () => checkOracleConnection,
|
|
483
|
+
runOracleQuery: () => runOracleQuery
|
|
484
|
+
});
|
|
388
485
|
async function importOracleDb() {
|
|
389
486
|
let mod;
|
|
390
487
|
try {
|
|
@@ -460,8 +557,22 @@ async function checkOracleConnection(url, credentials, options = {}) {
|
|
|
460
557
|
return { success: false, error: msg };
|
|
461
558
|
}
|
|
462
559
|
}
|
|
560
|
+
var GLOBAL_ORACLEDB_PATH;
|
|
561
|
+
var init_oracle_runner = __esm({
|
|
562
|
+
"../connectors/src/lib/oracle-runner.ts"() {
|
|
563
|
+
"use strict";
|
|
564
|
+
init_ssh_tunnel();
|
|
565
|
+
init_utils2();
|
|
566
|
+
GLOBAL_ORACLEDB_PATH = "/usr/lib/node_modules/oracledb/index.js";
|
|
567
|
+
}
|
|
568
|
+
});
|
|
463
569
|
|
|
464
570
|
// ../connectors/src/lib/pg-pool.ts
|
|
571
|
+
var pg_pool_exports = {};
|
|
572
|
+
__export(pg_pool_exports, {
|
|
573
|
+
attachStatementTimeout: () => attachStatementTimeout,
|
|
574
|
+
withStatementTimeout: () => withStatementTimeout
|
|
575
|
+
});
|
|
465
576
|
function attachStatementTimeout(pool, statementTimeoutMs) {
|
|
466
577
|
pool.on("connect", (client) => {
|
|
467
578
|
void client.query(`SET statement_timeout = ${statementTimeoutMs}`).catch(() => {
|
|
@@ -486,8 +597,23 @@ async function withStatementTimeout(promise, statementTimeoutMs) {
|
|
|
486
597
|
if (timer) clearTimeout(timer);
|
|
487
598
|
}
|
|
488
599
|
}
|
|
600
|
+
var init_pg_pool = __esm({
|
|
601
|
+
"../connectors/src/lib/pg-pool.ts"() {
|
|
602
|
+
"use strict";
|
|
603
|
+
}
|
|
604
|
+
});
|
|
605
|
+
|
|
606
|
+
// ../connectors/src/connectors/jdbc/sdk/index.ts
|
|
607
|
+
init_mssql_runner();
|
|
608
|
+
init_oracle_runner();
|
|
609
|
+
init_pg_pool();
|
|
610
|
+
init_ssh_tunnel();
|
|
611
|
+
init_utils();
|
|
612
|
+
init_utils2();
|
|
489
613
|
|
|
490
614
|
// ../connectors/src/connectors/jdbc/parameters.ts
|
|
615
|
+
init_parameter_definition();
|
|
616
|
+
init_ssh_tunnel();
|
|
491
617
|
var parameters = {
|
|
492
618
|
jdbcUrl: new ParameterDefinition({
|
|
493
619
|
slug: "jdbc-url",
|
|
@@ -608,6 +734,91 @@ function parseJdbcUrl(jdbcUrl, options = {}) {
|
|
|
608
734
|
function redactJdbcUrl(jdbcUrl) {
|
|
609
735
|
return jdbcUrl.replace(/(:\/\/)([^@/]+)@/, "$1***@").replace(/(password\s*=\s*)([^;&]+)/gi, "$1***");
|
|
610
736
|
}
|
|
737
|
+
async function runJdbcSetupQuery(params, sql, values) {
|
|
738
|
+
const jdbcUrl = params["jdbc-url"] ?? "";
|
|
739
|
+
const username = params["username"] || void 0;
|
|
740
|
+
const password = params["password"] || void 0;
|
|
741
|
+
const parsed = parseJdbcUrl(jdbcUrl, { username, password });
|
|
742
|
+
if (parsed.driver === "sqlserver") {
|
|
743
|
+
const { parseSqlServerJdbcUrl: parseSqlServerJdbcUrl2 } = await Promise.resolve().then(() => (init_utils(), utils_exports));
|
|
744
|
+
const { runMssqlQuery: runMssqlQuery2 } = await Promise.resolve().then(() => (init_mssql_runner(), mssql_runner_exports));
|
|
745
|
+
const sqlParsed = parseSqlServerJdbcUrl2(parsed.originalUrl, {
|
|
746
|
+
username,
|
|
747
|
+
password
|
|
748
|
+
});
|
|
749
|
+
const result = await runMssqlQuery2(sqlParsed, sql, { tunnelParams: params });
|
|
750
|
+
return result.rows;
|
|
751
|
+
}
|
|
752
|
+
if (parsed.driver === "oracle") {
|
|
753
|
+
const { parseOracleJdbcUrl: parseOracleJdbcUrl2 } = await Promise.resolve().then(() => (init_utils2(), utils_exports2));
|
|
754
|
+
const { runOracleQuery: runOracleQuery2 } = await Promise.resolve().then(() => (init_oracle_runner(), oracle_runner_exports));
|
|
755
|
+
const oracleParsed = parseOracleJdbcUrl2(parsed.originalUrl, {
|
|
756
|
+
username,
|
|
757
|
+
password
|
|
758
|
+
});
|
|
759
|
+
const cleanSql = sql.replace(/;\s*$/, "");
|
|
760
|
+
const result = await runOracleQuery2(oracleParsed, cleanSql, {
|
|
761
|
+
tunnelParams: params
|
|
762
|
+
});
|
|
763
|
+
return result.rows;
|
|
764
|
+
}
|
|
765
|
+
const { maybeOpenSshTunnel: maybeOpenSshTunnel2 } = await Promise.resolve().then(() => (init_ssh_tunnel(), ssh_tunnel_exports));
|
|
766
|
+
const tunnel = await maybeOpenSshTunnel2(
|
|
767
|
+
params,
|
|
768
|
+
parsed.nativeUrl,
|
|
769
|
+
parsed.defaultPort
|
|
770
|
+
);
|
|
771
|
+
if (parsed.driver === "postgresql") {
|
|
772
|
+
const { Pool } = await import("pg");
|
|
773
|
+
const { attachStatementTimeout: attachStatementTimeout2, withStatementTimeout: withStatementTimeout2 } = await Promise.resolve().then(() => (init_pg_pool(), pg_pool_exports));
|
|
774
|
+
const pool2 = new Pool({
|
|
775
|
+
connectionString: tunnel.connectionUrl,
|
|
776
|
+
ssl: { rejectUnauthorized: false },
|
|
777
|
+
connectionTimeoutMillis: 1e4
|
|
778
|
+
});
|
|
779
|
+
attachStatementTimeout2(pool2, 3e4);
|
|
780
|
+
try {
|
|
781
|
+
const result = await withStatementTimeout2(
|
|
782
|
+
pool2.query(sql, values ?? []),
|
|
783
|
+
3e4
|
|
784
|
+
);
|
|
785
|
+
return result.rows;
|
|
786
|
+
} finally {
|
|
787
|
+
await pool2.end();
|
|
788
|
+
await tunnel.close();
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
const mysql = await import("mysql2/promise");
|
|
792
|
+
const pool = mysql.createPool({
|
|
793
|
+
uri: tunnel.connectionUrl,
|
|
794
|
+
connectTimeout: 1e4
|
|
795
|
+
});
|
|
796
|
+
try {
|
|
797
|
+
const queryPromise = pool.query(sql, values ?? []);
|
|
798
|
+
const timeoutPromise = new Promise(
|
|
799
|
+
(_, reject) => setTimeout(
|
|
800
|
+
() => reject(new Error("Query timed out after 30 seconds")),
|
|
801
|
+
3e4
|
|
802
|
+
)
|
|
803
|
+
);
|
|
804
|
+
const [rows] = await Promise.race([queryPromise, timeoutPromise]);
|
|
805
|
+
return Array.isArray(rows) ? rows : [];
|
|
806
|
+
} finally {
|
|
807
|
+
await pool.end();
|
|
808
|
+
await tunnel.close();
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
function getJdbcDialect(params) {
|
|
812
|
+
try {
|
|
813
|
+
const parsed = parseJdbcUrl(params["jdbc-url"] ?? "", {
|
|
814
|
+
username: params["username"] || void 0,
|
|
815
|
+
password: params["password"] || void 0
|
|
816
|
+
});
|
|
817
|
+
return parsed.driver;
|
|
818
|
+
} catch {
|
|
819
|
+
return null;
|
|
820
|
+
}
|
|
821
|
+
}
|
|
611
822
|
|
|
612
823
|
// ../connectors/src/connectors/jdbc/sdk/index.ts
|
|
613
824
|
function createClient(params) {
|
|
@@ -771,6 +982,20 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
771
982
|
* `runSetupFlow` from `setup-flow.ts`.
|
|
772
983
|
*/
|
|
773
984
|
setup;
|
|
985
|
+
/**
|
|
986
|
+
* Opt-out of the default "verify before save" behavior on connection
|
|
987
|
+
* creation. The backend invokes `checkConnection` synchronously while
|
|
988
|
+
* creating the connection and aborts (no row inserted) if it fails — this
|
|
989
|
+
* flag disables that for connectors where the check cannot succeed pre-save:
|
|
990
|
+
*
|
|
991
|
+
* - `squadbase-db` populates `connection-url` only after Neon provisioning
|
|
992
|
+
* - OAuth connectors require an OAuth-aware proxyFetch keyed by the
|
|
993
|
+
* connectionId, which doesn't exist until the row is saved
|
|
994
|
+
*
|
|
995
|
+
* Exceptions are the explicit position; new credential-input connectors get
|
|
996
|
+
* the default verify-on-create behavior without opt-in.
|
|
997
|
+
*/
|
|
998
|
+
skipConnectionCheckOnCreate;
|
|
774
999
|
constructor(config) {
|
|
775
1000
|
this.slug = config.slug;
|
|
776
1001
|
this.authType = config.authType;
|
|
@@ -788,6 +1013,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
788
1013
|
this.query = config.query;
|
|
789
1014
|
this.checkConnection = config.checkConnection;
|
|
790
1015
|
this.setup = config.setup;
|
|
1016
|
+
this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
|
|
791
1017
|
}
|
|
792
1018
|
get connectorKey() {
|
|
793
1019
|
return _ConnectorPlugin.deriveKey(this.slug, this.authType);
|
|
@@ -852,6 +1078,51 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
852
1078
|
}
|
|
853
1079
|
};
|
|
854
1080
|
|
|
1081
|
+
// ../connectors/src/setup-flow.ts
|
|
1082
|
+
async function runSetupFlow(flow, params, ctx, config) {
|
|
1083
|
+
const runtime = {
|
|
1084
|
+
params,
|
|
1085
|
+
language: ctx.language,
|
|
1086
|
+
config
|
|
1087
|
+
};
|
|
1088
|
+
let state = flow.initialState();
|
|
1089
|
+
let answerIdx = 0;
|
|
1090
|
+
for (const step of flow.steps) {
|
|
1091
|
+
const ans = ctx.answers[answerIdx];
|
|
1092
|
+
if (ans && ans.questionSlug === step.slug) {
|
|
1093
|
+
state = step.applyAnswer(state, ans.answer);
|
|
1094
|
+
answerIdx += 1;
|
|
1095
|
+
continue;
|
|
1096
|
+
}
|
|
1097
|
+
if (step.type === "text") {
|
|
1098
|
+
return {
|
|
1099
|
+
type: "nextQuestion",
|
|
1100
|
+
questionSlug: step.slug,
|
|
1101
|
+
question: step.question[ctx.language],
|
|
1102
|
+
questionType: "text"
|
|
1103
|
+
};
|
|
1104
|
+
}
|
|
1105
|
+
const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
|
|
1106
|
+
if (options.length === 0) {
|
|
1107
|
+
continue;
|
|
1108
|
+
}
|
|
1109
|
+
return {
|
|
1110
|
+
type: "nextQuestion",
|
|
1111
|
+
questionSlug: step.slug,
|
|
1112
|
+
question: step.question[ctx.language],
|
|
1113
|
+
questionType: step.type,
|
|
1114
|
+
options
|
|
1115
|
+
};
|
|
1116
|
+
}
|
|
1117
|
+
const dataInvestigationResult = await flow.finalize(state, runtime);
|
|
1118
|
+
return { type: "fulfilled", dataInvestigationResult };
|
|
1119
|
+
}
|
|
1120
|
+
async function resolveSetupSelection(params) {
|
|
1121
|
+
const { selected, allSentinel, fetchAll, limit } = params;
|
|
1122
|
+
const resolved = selected.includes(allSentinel) ? await fetchAll() : selected.filter((v) => v !== allSentinel);
|
|
1123
|
+
return resolved.slice(0, limit);
|
|
1124
|
+
}
|
|
1125
|
+
|
|
855
1126
|
// ../connectors/src/auth-types.ts
|
|
856
1127
|
var AUTH_TYPES = {
|
|
857
1128
|
OAUTH: "oauth",
|
|
@@ -862,6 +1133,14 @@ var AUTH_TYPES = {
|
|
|
862
1133
|
USER_PASSWORD: "user-password"
|
|
863
1134
|
};
|
|
864
1135
|
|
|
1136
|
+
// ../connectors/src/connectors/jdbc/index.ts
|
|
1137
|
+
init_pg_pool();
|
|
1138
|
+
init_ssh_tunnel();
|
|
1139
|
+
init_mssql_runner();
|
|
1140
|
+
init_oracle_runner();
|
|
1141
|
+
init_utils();
|
|
1142
|
+
init_utils2();
|
|
1143
|
+
|
|
865
1144
|
// ../connectors/src/connectors/jdbc/setup.ts
|
|
866
1145
|
var jdbcOnboarding = new ConnectorOnboarding({
|
|
867
1146
|
dataOverviewInstructions: {
|
|
@@ -880,8 +1159,326 @@ var jdbcOnboarding = new ConnectorOnboarding({
|
|
|
880
1159
|
}
|
|
881
1160
|
});
|
|
882
1161
|
|
|
1162
|
+
// ../connectors/src/connectors/jdbc/setup-flow.ts
|
|
1163
|
+
var ALL_TABLES = "__ALL_TABLES__";
|
|
1164
|
+
var JDBC_SETUP_MAX_TABLES = 20;
|
|
1165
|
+
function quoteLiteral(value) {
|
|
1166
|
+
return "'" + value.replace(/'/g, "''") + "'";
|
|
1167
|
+
}
|
|
1168
|
+
var PG_INTERNAL_SCHEMAS = /* @__PURE__ */ new Set([
|
|
1169
|
+
"information_schema",
|
|
1170
|
+
"pg_catalog",
|
|
1171
|
+
"pg_toast"
|
|
1172
|
+
]);
|
|
1173
|
+
var MYSQL_INTERNAL_DATABASES = /* @__PURE__ */ new Set([
|
|
1174
|
+
"mysql",
|
|
1175
|
+
"information_schema",
|
|
1176
|
+
"performance_schema",
|
|
1177
|
+
"sys"
|
|
1178
|
+
]);
|
|
1179
|
+
var SQLSERVER_INTERNAL_SCHEMAS = /* @__PURE__ */ new Set([
|
|
1180
|
+
"sys",
|
|
1181
|
+
"information_schema",
|
|
1182
|
+
"guest",
|
|
1183
|
+
"db_owner",
|
|
1184
|
+
"db_accessadmin",
|
|
1185
|
+
"db_securityadmin",
|
|
1186
|
+
"db_ddladmin",
|
|
1187
|
+
"db_backupoperator",
|
|
1188
|
+
"db_datareader",
|
|
1189
|
+
"db_datawriter",
|
|
1190
|
+
"db_denydatareader",
|
|
1191
|
+
"db_denydatawriter"
|
|
1192
|
+
]);
|
|
1193
|
+
var ORACLE_INTERNAL_OWNERS = /* @__PURE__ */ new Set([
|
|
1194
|
+
"SYS",
|
|
1195
|
+
"SYSTEM",
|
|
1196
|
+
"XDB",
|
|
1197
|
+
"OUTLN",
|
|
1198
|
+
"ANONYMOUS",
|
|
1199
|
+
"APEX_PUBLIC_USER",
|
|
1200
|
+
"APPQOSSYS",
|
|
1201
|
+
"AUDSYS",
|
|
1202
|
+
"CTXSYS",
|
|
1203
|
+
"DBSFWUSER",
|
|
1204
|
+
"DBSNMP",
|
|
1205
|
+
"DIP",
|
|
1206
|
+
"DVF",
|
|
1207
|
+
"DVSYS",
|
|
1208
|
+
"GGSYS",
|
|
1209
|
+
"GSMADMIN_INTERNAL",
|
|
1210
|
+
"GSMCATUSER",
|
|
1211
|
+
"GSMUSER",
|
|
1212
|
+
"LBACSYS",
|
|
1213
|
+
"MDDATA",
|
|
1214
|
+
"MDSYS",
|
|
1215
|
+
"OJVMSYS",
|
|
1216
|
+
"OLAPSYS",
|
|
1217
|
+
"ORACLE_OCM",
|
|
1218
|
+
"ORDDATA",
|
|
1219
|
+
"ORDPLUGINS",
|
|
1220
|
+
"ORDSYS",
|
|
1221
|
+
"PDBADMIN",
|
|
1222
|
+
"REMOTE_SCHEDULER_AGENT",
|
|
1223
|
+
"SI_INFORMTN_SCHEMA",
|
|
1224
|
+
"SPATIAL_CSW_ADMIN_USR",
|
|
1225
|
+
"SPATIAL_WFS_ADMIN_USR",
|
|
1226
|
+
"SQLTXADMIN",
|
|
1227
|
+
"SQLTXPLAIN",
|
|
1228
|
+
"SYSBACKUP",
|
|
1229
|
+
"SYSDG",
|
|
1230
|
+
"SYSKM",
|
|
1231
|
+
"SYSRAC",
|
|
1232
|
+
"TSMSYS",
|
|
1233
|
+
"WMSYS",
|
|
1234
|
+
"XS$NULL"
|
|
1235
|
+
]);
|
|
1236
|
+
async function listNamespaces(params) {
|
|
1237
|
+
const dialect = getJdbcDialect(params);
|
|
1238
|
+
if (dialect === "postgresql") {
|
|
1239
|
+
const rows = await runJdbcSetupQuery(
|
|
1240
|
+
params,
|
|
1241
|
+
`SELECT schema_name FROM information_schema.schemata ORDER BY schema_name`
|
|
1242
|
+
);
|
|
1243
|
+
return rows.map((r) => String(r["schema_name"] ?? "")).filter(
|
|
1244
|
+
(name) => name && !PG_INTERNAL_SCHEMAS.has(name.toLowerCase()) && !name.toLowerCase().startsWith("pg_")
|
|
1245
|
+
);
|
|
1246
|
+
}
|
|
1247
|
+
if (dialect === "mysql") {
|
|
1248
|
+
const rows = await runJdbcSetupQuery(params, "SHOW DATABASES");
|
|
1249
|
+
return rows.map(
|
|
1250
|
+
(r) => String(r["Database"] ?? r["database"] ?? r["SCHEMA_NAME"] ?? "")
|
|
1251
|
+
).filter(
|
|
1252
|
+
(name) => name && !MYSQL_INTERNAL_DATABASES.has(name.toLowerCase())
|
|
1253
|
+
);
|
|
1254
|
+
}
|
|
1255
|
+
if (dialect === "sqlserver") {
|
|
1256
|
+
const rows = await runJdbcSetupQuery(
|
|
1257
|
+
params,
|
|
1258
|
+
`SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA ORDER BY SCHEMA_NAME`
|
|
1259
|
+
);
|
|
1260
|
+
return rows.map((r) => String(r["SCHEMA_NAME"] ?? "")).filter(
|
|
1261
|
+
(name) => name && !SQLSERVER_INTERNAL_SCHEMAS.has(name.toLowerCase())
|
|
1262
|
+
);
|
|
1263
|
+
}
|
|
1264
|
+
if (dialect === "oracle") {
|
|
1265
|
+
const rows = await runJdbcSetupQuery(
|
|
1266
|
+
params,
|
|
1267
|
+
`SELECT USERNAME FROM ALL_USERS ORDER BY USERNAME`
|
|
1268
|
+
);
|
|
1269
|
+
return rows.map((r) => String(r["USERNAME"] ?? "")).filter((name) => {
|
|
1270
|
+
if (!name) return false;
|
|
1271
|
+
const upper = name.toUpperCase();
|
|
1272
|
+
return !ORACLE_INTERNAL_OWNERS.has(upper) && !upper.startsWith("APEX_");
|
|
1273
|
+
});
|
|
1274
|
+
}
|
|
1275
|
+
return [];
|
|
1276
|
+
}
|
|
1277
|
+
async function listTables(params, namespace) {
|
|
1278
|
+
const dialect = getJdbcDialect(params);
|
|
1279
|
+
if (dialect === "postgresql") {
|
|
1280
|
+
const rows = await runJdbcSetupQuery(
|
|
1281
|
+
params,
|
|
1282
|
+
`SELECT table_name FROM information_schema.tables
|
|
1283
|
+
WHERE table_schema = $1 AND table_type IN ('BASE TABLE', 'VIEW')
|
|
1284
|
+
ORDER BY table_name`,
|
|
1285
|
+
[namespace]
|
|
1286
|
+
);
|
|
1287
|
+
return rows.map((r) => String(r["table_name"] ?? "")).filter((name) => name);
|
|
1288
|
+
}
|
|
1289
|
+
if (dialect === "mysql") {
|
|
1290
|
+
const rows = await runJdbcSetupQuery(
|
|
1291
|
+
params,
|
|
1292
|
+
`SELECT TABLE_NAME FROM information_schema.TABLES
|
|
1293
|
+
WHERE TABLE_SCHEMA = ? AND TABLE_TYPE IN ('BASE TABLE', 'VIEW')
|
|
1294
|
+
ORDER BY TABLE_NAME`,
|
|
1295
|
+
[namespace]
|
|
1296
|
+
);
|
|
1297
|
+
return rows.map((r) => String(r["TABLE_NAME"] ?? r["table_name"] ?? "")).filter((name) => name);
|
|
1298
|
+
}
|
|
1299
|
+
if (dialect === "sqlserver") {
|
|
1300
|
+
const rows = await runJdbcSetupQuery(
|
|
1301
|
+
params,
|
|
1302
|
+
`SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
|
|
1303
|
+
WHERE TABLE_TYPE IN ('BASE TABLE', 'VIEW')
|
|
1304
|
+
AND TABLE_SCHEMA = ${quoteLiteral(namespace)}
|
|
1305
|
+
ORDER BY TABLE_NAME`
|
|
1306
|
+
);
|
|
1307
|
+
return rows.map((r) => String(r["TABLE_NAME"] ?? "")).filter((name) => name);
|
|
1308
|
+
}
|
|
1309
|
+
if (dialect === "oracle") {
|
|
1310
|
+
const rows = await runJdbcSetupQuery(
|
|
1311
|
+
params,
|
|
1312
|
+
`SELECT TABLE_NAME FROM ALL_TABLES
|
|
1313
|
+
WHERE OWNER = ${quoteLiteral(namespace)}
|
|
1314
|
+
ORDER BY TABLE_NAME`
|
|
1315
|
+
);
|
|
1316
|
+
return rows.map((r) => String(r["TABLE_NAME"] ?? "")).filter((name) => name);
|
|
1317
|
+
}
|
|
1318
|
+
return [];
|
|
1319
|
+
}
|
|
1320
|
+
async function describeTable(params, namespace, table) {
|
|
1321
|
+
const dialect = getJdbcDialect(params);
|
|
1322
|
+
if (dialect === "postgresql") {
|
|
1323
|
+
const rows = await runJdbcSetupQuery(
|
|
1324
|
+
params,
|
|
1325
|
+
`SELECT column_name, data_type, is_nullable, column_default
|
|
1326
|
+
FROM information_schema.columns
|
|
1327
|
+
WHERE table_schema = $1 AND table_name = $2
|
|
1328
|
+
ORDER BY ordinal_position`,
|
|
1329
|
+
[namespace, table]
|
|
1330
|
+
);
|
|
1331
|
+
return rows.map((c) => ({
|
|
1332
|
+
name: String(c["column_name"] ?? ""),
|
|
1333
|
+
type: String(c["data_type"] ?? ""),
|
|
1334
|
+
nullable: String(c["is_nullable"] ?? ""),
|
|
1335
|
+
default: c["column_default"] == null ? "-" : String(c["column_default"])
|
|
1336
|
+
}));
|
|
1337
|
+
}
|
|
1338
|
+
if (dialect === "mysql") {
|
|
1339
|
+
const rows = await runJdbcSetupQuery(
|
|
1340
|
+
params,
|
|
1341
|
+
`SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_DEFAULT
|
|
1342
|
+
FROM information_schema.COLUMNS
|
|
1343
|
+
WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ?
|
|
1344
|
+
ORDER BY ORDINAL_POSITION`,
|
|
1345
|
+
[namespace, table]
|
|
1346
|
+
);
|
|
1347
|
+
return rows.map((c) => ({
|
|
1348
|
+
name: String(c["COLUMN_NAME"] ?? c["column_name"] ?? ""),
|
|
1349
|
+
type: String(c["DATA_TYPE"] ?? c["data_type"] ?? ""),
|
|
1350
|
+
nullable: String(c["IS_NULLABLE"] ?? c["is_nullable"] ?? ""),
|
|
1351
|
+
default: (c["COLUMN_DEFAULT"] ?? c["column_default"]) == null ? "-" : String(c["COLUMN_DEFAULT"] ?? c["column_default"])
|
|
1352
|
+
}));
|
|
1353
|
+
}
|
|
1354
|
+
if (dialect === "sqlserver") {
|
|
1355
|
+
const rows = await runJdbcSetupQuery(
|
|
1356
|
+
params,
|
|
1357
|
+
`SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_DEFAULT
|
|
1358
|
+
FROM INFORMATION_SCHEMA.COLUMNS
|
|
1359
|
+
WHERE TABLE_SCHEMA = ${quoteLiteral(namespace)}
|
|
1360
|
+
AND TABLE_NAME = ${quoteLiteral(table)}
|
|
1361
|
+
ORDER BY ORDINAL_POSITION`
|
|
1362
|
+
);
|
|
1363
|
+
return rows.map((c) => ({
|
|
1364
|
+
name: String(c["COLUMN_NAME"] ?? ""),
|
|
1365
|
+
type: String(c["DATA_TYPE"] ?? ""),
|
|
1366
|
+
nullable: String(c["IS_NULLABLE"] ?? ""),
|
|
1367
|
+
default: c["COLUMN_DEFAULT"] == null ? "-" : String(c["COLUMN_DEFAULT"])
|
|
1368
|
+
}));
|
|
1369
|
+
}
|
|
1370
|
+
if (dialect === "oracle") {
|
|
1371
|
+
const rows = await runJdbcSetupQuery(
|
|
1372
|
+
params,
|
|
1373
|
+
`SELECT COLUMN_NAME, DATA_TYPE, NULLABLE, DATA_DEFAULT
|
|
1374
|
+
FROM ALL_TAB_COLUMNS
|
|
1375
|
+
WHERE OWNER = ${quoteLiteral(namespace)}
|
|
1376
|
+
AND TABLE_NAME = ${quoteLiteral(table)}
|
|
1377
|
+
ORDER BY COLUMN_ID`
|
|
1378
|
+
);
|
|
1379
|
+
return rows.map((c) => {
|
|
1380
|
+
const defaultRaw = c["DATA_DEFAULT"];
|
|
1381
|
+
return {
|
|
1382
|
+
name: String(c["COLUMN_NAME"] ?? ""),
|
|
1383
|
+
type: String(c["DATA_TYPE"] ?? ""),
|
|
1384
|
+
nullable: String(c["NULLABLE"] ?? ""),
|
|
1385
|
+
default: defaultRaw == null ? "-" : String(defaultRaw).trim() || "-"
|
|
1386
|
+
};
|
|
1387
|
+
});
|
|
1388
|
+
}
|
|
1389
|
+
return [];
|
|
1390
|
+
}
|
|
1391
|
+
function namespaceLabel(dialect, language) {
|
|
1392
|
+
if (dialect === "mysql") {
|
|
1393
|
+
return language === "ja" ? "\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9" : "Database";
|
|
1394
|
+
}
|
|
1395
|
+
if (dialect === "oracle") {
|
|
1396
|
+
return language === "ja" ? "\u30AA\u30FC\u30CA\u30FC\uFF08\u30B9\u30AD\u30FC\u30DE\uFF09" : "Schema (owner)";
|
|
1397
|
+
}
|
|
1398
|
+
return language === "ja" ? "\u30B9\u30AD\u30FC\u30DE" : "Schema";
|
|
1399
|
+
}
|
|
1400
|
+
var jdbcSetupFlow = {
|
|
1401
|
+
initialState: () => ({}),
|
|
1402
|
+
steps: [
|
|
1403
|
+
{
|
|
1404
|
+
slug: "namespace",
|
|
1405
|
+
type: "select",
|
|
1406
|
+
question: {
|
|
1407
|
+
ja: "\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u306B\u4F7F\u3046\u30B9\u30AD\u30FC\u30DE\u307E\u305F\u306F\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044",
|
|
1408
|
+
en: "Select the schema or database to use for setup"
|
|
1409
|
+
},
|
|
1410
|
+
async fetchOptions(_state, rt) {
|
|
1411
|
+
const names = await listNamespaces(rt.params);
|
|
1412
|
+
return names.map((value) => ({ value }));
|
|
1413
|
+
},
|
|
1414
|
+
applyAnswer: (state, answer) => ({ ...state, namespace: answer[0] })
|
|
1415
|
+
},
|
|
1416
|
+
{
|
|
1417
|
+
slug: "tables",
|
|
1418
|
+
type: "multiSelect",
|
|
1419
|
+
question: {
|
|
1420
|
+
ja: "\u5BFE\u8C61\u30C6\u30FC\u30D6\u30EB\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
|
|
1421
|
+
en: "Select target tables (multi-select allowed)"
|
|
1422
|
+
},
|
|
1423
|
+
async fetchOptions(state, rt) {
|
|
1424
|
+
if (!state.namespace) return [];
|
|
1425
|
+
const names = await listTables(rt.params, state.namespace);
|
|
1426
|
+
const tableOptions = names.map((value) => ({ value }));
|
|
1427
|
+
return [
|
|
1428
|
+
{
|
|
1429
|
+
value: ALL_TABLES,
|
|
1430
|
+
label: rt.language === "ja" ? "\u3059\u3079\u3066\u306E\u30C6\u30FC\u30D6\u30EB" : "All tables"
|
|
1431
|
+
},
|
|
1432
|
+
...tableOptions
|
|
1433
|
+
];
|
|
1434
|
+
},
|
|
1435
|
+
applyAnswer: (state, answer) => ({ ...state, tables: answer })
|
|
1436
|
+
}
|
|
1437
|
+
],
|
|
1438
|
+
async finalize(state, rt) {
|
|
1439
|
+
if (!state.namespace || !state.tables) {
|
|
1440
|
+
throw new Error("JDBC setup: incomplete state on finalize");
|
|
1441
|
+
}
|
|
1442
|
+
const namespace = state.namespace;
|
|
1443
|
+
const dialect = getJdbcDialect(rt.params);
|
|
1444
|
+
const targetTables = await resolveSetupSelection({
|
|
1445
|
+
selected: state.tables,
|
|
1446
|
+
allSentinel: ALL_TABLES,
|
|
1447
|
+
fetchAll: () => listTables(rt.params, namespace),
|
|
1448
|
+
limit: JDBC_SETUP_MAX_TABLES
|
|
1449
|
+
});
|
|
1450
|
+
const label = namespaceLabel(dialect, rt.language);
|
|
1451
|
+
const sections = [
|
|
1452
|
+
"## JDBC",
|
|
1453
|
+
"",
|
|
1454
|
+
`### Dialect: ${dialect ?? "unknown"}`,
|
|
1455
|
+
`### ${label}: ${namespace}`,
|
|
1456
|
+
""
|
|
1457
|
+
];
|
|
1458
|
+
for (const table of targetTables) {
|
|
1459
|
+
const cols = await describeTable(rt.params, namespace, table);
|
|
1460
|
+
sections.push(`#### Table: ${table}`, "");
|
|
1461
|
+
sections.push("| Column | Type | Nullable | Default |");
|
|
1462
|
+
sections.push("|--------|------|----------|---------|");
|
|
1463
|
+
for (const c of cols) {
|
|
1464
|
+
sections.push(
|
|
1465
|
+
`| ${c.name} | ${c.type} | ${c.nullable} | ${c.default} |`
|
|
1466
|
+
);
|
|
1467
|
+
}
|
|
1468
|
+
sections.push("");
|
|
1469
|
+
}
|
|
1470
|
+
return sections.join("\n");
|
|
1471
|
+
}
|
|
1472
|
+
};
|
|
1473
|
+
|
|
883
1474
|
// ../connectors/src/connectors/jdbc/tools/execute-query.ts
|
|
884
1475
|
import { z } from "zod";
|
|
1476
|
+
init_pg_pool();
|
|
1477
|
+
init_ssh_tunnel();
|
|
1478
|
+
init_mssql_runner();
|
|
1479
|
+
init_oracle_runner();
|
|
1480
|
+
init_utils();
|
|
1481
|
+
init_utils2();
|
|
885
1482
|
var MAX_ROWS = 500;
|
|
886
1483
|
var CONNECT_TIMEOUT_MS = 1e4;
|
|
887
1484
|
var STATEMENT_TIMEOUT_MS = 6e4;
|
|
@@ -1137,6 +1734,7 @@ JDBC URL \u306E\u30D7\u30EC\u30D5\u30A3\u30C3\u30AF\u30B9\u306B\u3088\u308A\u65B
|
|
|
1137
1734
|
\u30D7\u30E9\u30C3\u30C8\u30D5\u30A9\u30FC\u30E0\u306E server-logic \u30B9\u30AD\u30FC\u30DE\u63A8\u8AD6\u306F\u3001\u30AF\u30A8\u30EA\u3092 \`SELECT * FROM (<inner>) AS _sq LIMIT N\`\uFF08PostgreSQL/MySQL \u69CB\u6587\uFF09\u306E\u5F62\u3067\u30E9\u30C3\u30D7\u3057\u3066\u304F\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002PostgreSQL / Redshift / MySQL \u30EB\u30FC\u30C8\u3067\u306F\u305D\u306E\u307E\u307E\u5B9F\u884C\u3055\u308C\u307E\u3059\u3002\`jdbc:sqlserver://\` \u304A\u3088\u3073 \`jdbc:oracle:thin:\` \u30EB\u30FC\u30C8\u3067\u306F\u3001\u30B3\u30CD\u30AF\u30BF\u304C \`query()\` \u5185\u3067\u3053\u306E\u30E9\u30C3\u30D1\u3092\u691C\u51FA\u3057\u3001\`<inner>\` \u3092\u65B9\u8A00\u56FA\u6709\u306E\u30C9\u30E9\u30A4\u30D0\u3067\u76F4\u63A5\u5B9F\u884C\u3057\u3066 JS \u5074\u3067\u5148\u982D N \u884C\u306B\u5207\u308A\u8A70\u3081\u307E\u3059\u3002\u5229\u7528\u8005\u5074\u3067\u5BFE\u51E6\u3059\u308B\u5FC5\u8981\u306F\u3042\u308A\u307E\u305B\u3093\u304C\u3001**\u81EA\u5206\u3067\u66F8\u304F SQL** \u3067\u306F SQL Server / Oracle \u30EB\u30FC\u30C8\u3067 \`LIMIT\` \u3092\u4F7F\u308F\u305A\u3001\u4E0A\u8A18\u306E \`TOP\` / \`FETCH FIRST\` \u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044\u3002`
|
|
1138
1735
|
},
|
|
1139
1736
|
tools,
|
|
1737
|
+
setup: (params, ctx, config) => runSetupFlow(jdbcSetupFlow, params, ctx, config),
|
|
1140
1738
|
async checkConnection(params, _config) {
|
|
1141
1739
|
const jdbcUrl = params[parameters.jdbcUrl.slug];
|
|
1142
1740
|
const username = params[parameters.username.slug];
|
|
@@ -1316,6 +1914,7 @@ function resolveEnvVarOptional(entry, key) {
|
|
|
1316
1914
|
import { getContext } from "hono/context-storage";
|
|
1317
1915
|
import { getCookie } from "hono/cookie";
|
|
1318
1916
|
var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
|
|
1917
|
+
var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
|
|
1319
1918
|
function normalizeHeaders(input) {
|
|
1320
1919
|
const out = {};
|
|
1321
1920
|
if (!input) return out;
|
|
@@ -1324,6 +1923,11 @@ function normalizeHeaders(input) {
|
|
|
1324
1923
|
});
|
|
1325
1924
|
return out;
|
|
1326
1925
|
}
|
|
1926
|
+
function extractInputUrl(input) {
|
|
1927
|
+
if (typeof input === "string") return input;
|
|
1928
|
+
if (input instanceof URL) return input.href;
|
|
1929
|
+
return input.url;
|
|
1930
|
+
}
|
|
1327
1931
|
function createSandboxProxyFetch(connectionId) {
|
|
1328
1932
|
return async (input, init) => {
|
|
1329
1933
|
const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
|
|
@@ -1333,10 +1937,17 @@ function createSandboxProxyFetch(connectionId) {
|
|
|
1333
1937
|
"Connection proxy is not configured. Please check your deployment settings."
|
|
1334
1938
|
);
|
|
1335
1939
|
}
|
|
1336
|
-
const originalUrl =
|
|
1940
|
+
const originalUrl = extractInputUrl(input);
|
|
1941
|
+
const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
|
|
1942
|
+
if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
|
|
1943
|
+
const sessionUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
|
|
1944
|
+
return fetch(sessionUrl, {
|
|
1945
|
+
method: "POST",
|
|
1946
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
1947
|
+
});
|
|
1948
|
+
}
|
|
1337
1949
|
const originalMethod = init?.method ?? "GET";
|
|
1338
1950
|
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
1339
|
-
const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
|
|
1340
1951
|
const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
1341
1952
|
return fetch(proxyUrl, {
|
|
1342
1953
|
method: "POST",
|
|
@@ -1362,10 +1973,9 @@ function createDeployedAppProxyFetch(connectionId) {
|
|
|
1362
1973
|
}
|
|
1363
1974
|
const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
|
|
1364
1975
|
const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
1976
|
+
const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
|
|
1365
1977
|
return async (input, init) => {
|
|
1366
|
-
const originalUrl =
|
|
1367
|
-
const originalMethod = init?.method ?? "GET";
|
|
1368
|
-
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
1978
|
+
const originalUrl = extractInputUrl(input);
|
|
1369
1979
|
const c = getContext();
|
|
1370
1980
|
const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
|
|
1371
1981
|
if (!appSession) {
|
|
@@ -1373,6 +1983,14 @@ function createDeployedAppProxyFetch(connectionId) {
|
|
|
1373
1983
|
"No authentication method available for connection proxy."
|
|
1374
1984
|
);
|
|
1375
1985
|
}
|
|
1986
|
+
if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
|
|
1987
|
+
return fetch(sessionUrl, {
|
|
1988
|
+
method: "POST",
|
|
1989
|
+
headers: { Authorization: `Bearer ${appSession}` }
|
|
1990
|
+
});
|
|
1991
|
+
}
|
|
1992
|
+
const originalMethod = init?.method ?? "GET";
|
|
1993
|
+
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
1376
1994
|
return fetch(proxyUrl, {
|
|
1377
1995
|
method: "POST",
|
|
1378
1996
|
headers: {
|