@squadbase/connectors 0.0.4 → 0.0.5
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/index.d.ts +13 -1
- package/dist/index.js +318 -28
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -52,6 +52,12 @@ interface ProxyPolicyRule {
|
|
|
52
52
|
interface ProxyPolicy {
|
|
53
53
|
allowlist: ProxyPolicyRule[];
|
|
54
54
|
}
|
|
55
|
+
type ConnectionCheckResult = {
|
|
56
|
+
success: true;
|
|
57
|
+
} | {
|
|
58
|
+
success: false;
|
|
59
|
+
error: string;
|
|
60
|
+
};
|
|
55
61
|
interface ConnectorToolsConfig {
|
|
56
62
|
oauthProxy: {
|
|
57
63
|
appApiKey: string;
|
|
@@ -97,6 +103,9 @@ declare class ConnectorPlugin<P extends Record<string, ParameterDefinition> = Re
|
|
|
97
103
|
}) => Promise<{
|
|
98
104
|
rows: Record<string, unknown>[];
|
|
99
105
|
}>;
|
|
106
|
+
readonly checkConnection?: (params: Record<string, string>, config: {
|
|
107
|
+
proxyFetch: typeof fetch;
|
|
108
|
+
}) => Promise<ConnectionCheckResult>;
|
|
100
109
|
constructor(config: {
|
|
101
110
|
slug: string;
|
|
102
111
|
authType: string | null;
|
|
@@ -115,6 +124,9 @@ declare class ConnectorPlugin<P extends Record<string, ParameterDefinition> = Re
|
|
|
115
124
|
}) => Promise<{
|
|
116
125
|
rows: Record<string, unknown>[];
|
|
117
126
|
}>;
|
|
127
|
+
checkConnection?: (params: Record<string, string>, config: {
|
|
128
|
+
proxyFetch: typeof fetch;
|
|
129
|
+
}) => Promise<ConnectionCheckResult>;
|
|
118
130
|
});
|
|
119
131
|
get connectorKey(): string;
|
|
120
132
|
/**
|
|
@@ -790,4 +802,4 @@ declare const squadbaseDbConnector: ConnectorPlugin<{
|
|
|
790
802
|
}>;
|
|
791
803
|
}>;
|
|
792
804
|
|
|
793
|
-
export { AUTH_TYPES, ConnectorPlugin, ConnectorSetup, ConnectorTool, type ConnectorToolsConfig, ParameterDefinition, type ProxyPolicy, type ProxyPolicyRule, type ReleaseFlag, type SetupLanguage, airtableConnector, awsAthenaConnector, bigqueryConnector, bigqueryOauthConnector, connectors, databricksConnector, dbtConnector, googleAnalyticsConnector, kintoneConnector, mysqlConnector, postgresqlConnector, redshiftConnector, snowflakeConnector, snowflakePatConnector, squadbaseDbConnector, wixStoreConnector };
|
|
805
|
+
export { AUTH_TYPES, type ConnectionCheckResult, ConnectorPlugin, ConnectorSetup, ConnectorTool, type ConnectorToolsConfig, ParameterDefinition, type ProxyPolicy, type ProxyPolicyRule, type ReleaseFlag, type SetupLanguage, airtableConnector, awsAthenaConnector, bigqueryConnector, bigqueryOauthConnector, connectors, databricksConnector, dbtConnector, googleAnalyticsConnector, kintoneConnector, mysqlConnector, postgresqlConnector, redshiftConnector, snowflakeConnector, snowflakePatConnector, squadbaseDbConnector, wixStoreConnector };
|
package/dist/index.js
CHANGED
|
@@ -92,6 +92,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
92
92
|
systemPrompt;
|
|
93
93
|
tools;
|
|
94
94
|
query;
|
|
95
|
+
checkConnection;
|
|
95
96
|
constructor(config) {
|
|
96
97
|
this.slug = config.slug;
|
|
97
98
|
this.authType = config.authType;
|
|
@@ -106,6 +107,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
106
107
|
this.systemPrompt = config.systemPrompt;
|
|
107
108
|
this.tools = config.tools;
|
|
108
109
|
this.query = config.query;
|
|
110
|
+
this.checkConnection = config.checkConnection;
|
|
109
111
|
}
|
|
110
112
|
get connectorKey() {
|
|
111
113
|
return _ConnectorPlugin.deriveKey(this.slug, this.authType);
|
|
@@ -439,6 +441,45 @@ var snowflakeConnector = new ConnectorPlugin({
|
|
|
439
441
|
- List columns: \`DESCRIBE TABLE db_name.schema_name.table_name\`
|
|
440
442
|
- INFORMATION_SCHEMA is also available: \`SELECT * FROM db_name.INFORMATION_SCHEMA.TABLES\``,
|
|
441
443
|
tools,
|
|
444
|
+
async checkConnection(params, _config) {
|
|
445
|
+
try {
|
|
446
|
+
const snowflake = (await import("snowflake-sdk")).default;
|
|
447
|
+
snowflake.configure({ logLevel: "ERROR" });
|
|
448
|
+
const privateKey = Buffer.from(
|
|
449
|
+
params[parameters.privateKeyBase64.slug],
|
|
450
|
+
"base64"
|
|
451
|
+
).toString("utf-8");
|
|
452
|
+
const conn = snowflake.createConnection({
|
|
453
|
+
account: params[parameters.account.slug],
|
|
454
|
+
username: params[parameters.user.slug],
|
|
455
|
+
role: params[parameters.role.slug],
|
|
456
|
+
warehouse: params[parameters.warehouse.slug],
|
|
457
|
+
authenticator: "SNOWFLAKE_JWT",
|
|
458
|
+
privateKey
|
|
459
|
+
});
|
|
460
|
+
await new Promise((resolve, reject) => {
|
|
461
|
+
conn.connect((err) => {
|
|
462
|
+
if (err) reject(new Error(`Snowflake connect failed: ${err.message}`));
|
|
463
|
+
else resolve();
|
|
464
|
+
});
|
|
465
|
+
});
|
|
466
|
+
await new Promise((resolve, reject) => {
|
|
467
|
+
conn.execute({
|
|
468
|
+
sqlText: "SELECT 1",
|
|
469
|
+
complete: (err) => {
|
|
470
|
+
if (err) reject(new Error(`Snowflake query failed: ${err.message}`));
|
|
471
|
+
else resolve();
|
|
472
|
+
}
|
|
473
|
+
});
|
|
474
|
+
});
|
|
475
|
+
conn.destroy((err) => {
|
|
476
|
+
if (err) console.warn(`[connector-client] Snowflake destroy error: ${err.message}`);
|
|
477
|
+
});
|
|
478
|
+
return { success: true };
|
|
479
|
+
} catch (e) {
|
|
480
|
+
return { success: false, error: e instanceof Error ? e.message : String(e) };
|
|
481
|
+
}
|
|
482
|
+
},
|
|
442
483
|
async query(params, sql, namedParams) {
|
|
443
484
|
const resolvedSql = replaceLiteralParams(sql, namedParams);
|
|
444
485
|
const snowflake = (await import("snowflake-sdk")).default;
|
|
@@ -653,6 +694,45 @@ var snowflakePatConnector = new ConnectorPlugin({
|
|
|
653
694
|
- List columns: \`DESCRIBE TABLE db_name.schema_name.table_name\`
|
|
654
695
|
- INFORMATION_SCHEMA is also available: \`SELECT * FROM db_name.INFORMATION_SCHEMA.TABLES\``,
|
|
655
696
|
tools: tools2,
|
|
697
|
+
async checkConnection(params, _config) {
|
|
698
|
+
try {
|
|
699
|
+
const snowflake = (await import("snowflake-sdk")).default;
|
|
700
|
+
snowflake.configure({ logLevel: "ERROR" });
|
|
701
|
+
const conn = snowflake.createConnection({
|
|
702
|
+
account: params[parameters2.account.slug],
|
|
703
|
+
username: params[parameters2.user.slug],
|
|
704
|
+
role: params[parameters2.role.slug],
|
|
705
|
+
warehouse: params[parameters2.warehouse.slug],
|
|
706
|
+
password: params[parameters2.pat.slug]
|
|
707
|
+
});
|
|
708
|
+
await new Promise((resolve, reject) => {
|
|
709
|
+
conn.connect((err) => {
|
|
710
|
+
if (err)
|
|
711
|
+
reject(new Error(`Snowflake connect failed: ${err.message}`));
|
|
712
|
+
else resolve();
|
|
713
|
+
});
|
|
714
|
+
});
|
|
715
|
+
await new Promise((resolve, reject) => {
|
|
716
|
+
conn.execute({
|
|
717
|
+
sqlText: "SELECT 1",
|
|
718
|
+
complete: (err) => {
|
|
719
|
+
if (err)
|
|
720
|
+
reject(new Error(`Snowflake query failed: ${err.message}`));
|
|
721
|
+
else resolve();
|
|
722
|
+
}
|
|
723
|
+
});
|
|
724
|
+
});
|
|
725
|
+
conn.destroy((err) => {
|
|
726
|
+
if (err)
|
|
727
|
+
console.warn(
|
|
728
|
+
`[connector-client] Snowflake destroy error: ${err.message}`
|
|
729
|
+
);
|
|
730
|
+
});
|
|
731
|
+
return { success: true };
|
|
732
|
+
} catch (e) {
|
|
733
|
+
return { success: false, error: e instanceof Error ? e.message : String(e) };
|
|
734
|
+
}
|
|
735
|
+
},
|
|
656
736
|
async query(params, sql, namedParams) {
|
|
657
737
|
const resolvedSql = replaceLiteralParams(sql, namedParams);
|
|
658
738
|
const snowflake = (await import("snowflake-sdk")).default;
|
|
@@ -797,6 +877,22 @@ var postgresqlConnector = new ConnectorPlugin({
|
|
|
797
877
|
- List columns: \`SELECT column_name, data_type FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'xxx'\`
|
|
798
878
|
- Always include LIMIT in queries`,
|
|
799
879
|
tools: tools3,
|
|
880
|
+
async checkConnection(params, _config) {
|
|
881
|
+
const { Pool } = await import("pg");
|
|
882
|
+
const pool = new Pool({
|
|
883
|
+
connectionString: params[parameters3.connectionUrl.slug],
|
|
884
|
+
ssl: { rejectUnauthorized: false },
|
|
885
|
+
connectionTimeoutMillis: 1e4
|
|
886
|
+
});
|
|
887
|
+
try {
|
|
888
|
+
await pool.query("SELECT 1");
|
|
889
|
+
return { success: true };
|
|
890
|
+
} catch (error) {
|
|
891
|
+
return { success: false, error: error instanceof Error ? error.message : String(error) };
|
|
892
|
+
} finally {
|
|
893
|
+
await pool.end();
|
|
894
|
+
}
|
|
895
|
+
},
|
|
800
896
|
async query(params, sql, namedParams) {
|
|
801
897
|
const { Pool } = await import("pg");
|
|
802
898
|
const { text, values } = buildPositionalParams(sql, namedParams);
|
|
@@ -921,6 +1017,21 @@ var mysqlConnector = new ConnectorPlugin({
|
|
|
921
1017
|
- List columns: \`SELECT COLUMN_NAME, DATA_TYPE FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'xxx'\`
|
|
922
1018
|
- Always include LIMIT in queries`,
|
|
923
1019
|
tools: tools4,
|
|
1020
|
+
async checkConnection(params, _config) {
|
|
1021
|
+
const mysql = await import("mysql2/promise");
|
|
1022
|
+
const pool = mysql.createPool({
|
|
1023
|
+
uri: params[parameters4.connectionUrl.slug],
|
|
1024
|
+
connectTimeout: 1e4
|
|
1025
|
+
});
|
|
1026
|
+
try {
|
|
1027
|
+
await pool.query("SELECT 1");
|
|
1028
|
+
return { success: true };
|
|
1029
|
+
} catch (e) {
|
|
1030
|
+
return { success: false, error: e instanceof Error ? e.message : String(e) };
|
|
1031
|
+
} finally {
|
|
1032
|
+
await pool.end();
|
|
1033
|
+
}
|
|
1034
|
+
},
|
|
924
1035
|
async query(params, sql, namedParams) {
|
|
925
1036
|
const mysql = await import("mysql2/promise");
|
|
926
1037
|
const { text, values } = buildQuestionmarkParams(sql, namedParams);
|
|
@@ -1039,14 +1150,10 @@ var bigquerySetup = new ConnectorSetup({
|
|
|
1039
1150
|
|
|
1040
1151
|
#### \u30B9\u30C6\u30C3\u30D71: \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u9078\u629E
|
|
1041
1152
|
1. \`${listProjectsToolName}\` \u3092\u547C\u3073\u51FA\u3057\u3066\u3001\u30B5\u30FC\u30D3\u30B9\u30A2\u30AB\u30A6\u30F3\u30C8\u304C\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306AGCP\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u4E00\u89A7\u3092\u53D6\u5F97\u3059\u308B
|
|
1042
|
-
2. \
|
|
1043
|
-
- **\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u304C2\u3064\u4EE5\u4E0A**: \`askUserQuestion\`\uFF08multiSelect: false\uFF09\u3067\u30E6\u30FC\u30B6\u30FC\u306B\u63D0\u793A\u3057\u3001\u4F7F\u7528\u3059\u308B\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u3092\u9078\u629E\u3055\u305B\u308B\u3002\u9078\u629E\u80A2\u306E label \u306F \`\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u540D (id: \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8ID)\` \u306E\u5F62\u5F0F\u306B\u3059\u308B
|
|
1044
|
-
- **\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u304C1\u3064\u3060\u3051**: askUserQuestion \u306F\u4F7F\u308F\u305A\u81EA\u52D5\u63A1\u7528\u3002\u300C\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8 X \u3092\u81EA\u52D5\u9078\u629E\u3057\u307E\u3057\u305F\u300D\u30681\u6587\u3060\u3051\u66F8\u304F
|
|
1045
|
-
3. \`updateConnectionParameters\` \u3067\u9078\u629E\u3055\u308C\u305F\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u3092\u4FDD\u5B58\u3059\u308B:
|
|
1153
|
+
2. \`updateConnectionParameters\` \u3092\u547C\u3073\u51FA\u3057\u3066\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u3092\u4FDD\u5B58\u3059\u308B:
|
|
1046
1154
|
- \`parameterSlug\`: \`"project-id"\`
|
|
1047
|
-
- \`
|
|
1048
|
-
|
|
1049
|
-
4. \u7D9A\u884C\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u53D7\u3051\u53D6\u3063\u305F\u3089\u3001\u30B9\u30C6\u30C3\u30D72\u306B\u9032\u3080
|
|
1155
|
+
- \`options\`: \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u4E00\u89A7\u3002\u5404 option \u306E \`label\` \u306F \`\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u540D (id: \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8ID)\` \u306E\u5F62\u5F0F\u3001\`value\` \u306F\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8ID
|
|
1156
|
+
3. \u7D9A\u884C\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u53D7\u3051\u53D6\u3063\u305F\u3089\u3001\u30B9\u30C6\u30C3\u30D72\u306B\u9032\u3080
|
|
1050
1157
|
|
|
1051
1158
|
#### \u30B9\u30C6\u30C3\u30D72: \u30C7\u30FC\u30BF\u30BB\u30C3\u30C8\u9078\u629E
|
|
1052
1159
|
1. \`SELECT schema_name FROM INFORMATION_SCHEMA.SCHEMATA\` \u3092\u5B9F\u884C\u3057\u3066\u30C7\u30FC\u30BF\u30BB\u30C3\u30C8\u4E00\u89A7\u3092\u53D6\u5F97\u3059\u308B
|
|
@@ -1081,14 +1188,10 @@ Follow these steps to set up the BigQuery connection.
|
|
|
1081
1188
|
|
|
1082
1189
|
#### Step 1: Project Selection
|
|
1083
1190
|
1. Call \`${listProjectsToolName}\` to get the list of GCP projects accessible with the service account credentials
|
|
1084
|
-
2.
|
|
1085
|
-
- **2 or more projects**: Present them to the user via \`askUserQuestion\` (multiSelect: false) and let them select a project. Format option labels as \`Project Name (id: project-id)\`
|
|
1086
|
-
- **Exactly 1 project**: Do NOT call askUserQuestion. Auto-select it. Just write "Auto-selected project X" in one sentence
|
|
1087
|
-
3. Call \`updateConnectionParameters\` to save the selected project:
|
|
1191
|
+
2. Call \`updateConnectionParameters\` to save the project:
|
|
1088
1192
|
- \`parameterSlug\`: \`"project-id"\`
|
|
1089
|
-
- \`
|
|
1090
|
-
|
|
1091
|
-
4. After receiving the continuation message, proceed to Step 2
|
|
1193
|
+
- \`options\`: The project list. Each option's \`label\` should be \`Project Name (id: project-id)\`, \`value\` should be the project ID
|
|
1194
|
+
3. After receiving the continuation message, proceed to Step 2
|
|
1092
1195
|
|
|
1093
1196
|
#### Step 2: Dataset Selection
|
|
1094
1197
|
1. Run \`SELECT schema_name FROM INFORMATION_SCHEMA.SCHEMATA\` to get the list of datasets
|
|
@@ -1203,6 +1306,23 @@ var bigqueryConnector = new ConnectorPlugin({
|
|
|
1203
1306
|
- List columns: \`SELECT column_name, data_type FROM \\\`project_id.dataset\\\`.INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'xxx'\`
|
|
1204
1307
|
- Always specify project_id explicitly in queries`,
|
|
1205
1308
|
tools: tools5,
|
|
1309
|
+
async checkConnection(params, _config) {
|
|
1310
|
+
const { BigQuery } = await import("@google-cloud/bigquery");
|
|
1311
|
+
const credentials = JSON.parse(
|
|
1312
|
+
Buffer.from(params[parameters5.serviceAccountKeyJsonBase64.slug], "base64").toString("utf-8")
|
|
1313
|
+
);
|
|
1314
|
+
const bq = new BigQuery({
|
|
1315
|
+
projectId: params[parameters5.projectId.slug],
|
|
1316
|
+
credentials
|
|
1317
|
+
});
|
|
1318
|
+
try {
|
|
1319
|
+
const [job] = await bq.createQueryJob({ query: "SELECT 1" });
|
|
1320
|
+
await job.getQueryResults();
|
|
1321
|
+
return { success: true };
|
|
1322
|
+
} catch (error) {
|
|
1323
|
+
return { success: false, error: error instanceof Error ? error.message : String(error) };
|
|
1324
|
+
}
|
|
1325
|
+
},
|
|
1206
1326
|
async query(params, sql, namedParams) {
|
|
1207
1327
|
const { BigQuery } = await import("@google-cloud/bigquery");
|
|
1208
1328
|
const resolvedSql = replaceLiteralParams(sql, namedParams);
|
|
@@ -1337,14 +1457,10 @@ var bigquerySetup2 = new ConnectorSetup({
|
|
|
1337
1457
|
|
|
1338
1458
|
#### \u30B9\u30C6\u30C3\u30D71: \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u9078\u629E
|
|
1339
1459
|
1. \`${listProjectsToolName2}\` \u3092\u547C\u3073\u51FA\u3057\u3066\u3001OAuth\u3067\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306AGCP\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u4E00\u89A7\u3092\u53D6\u5F97\u3059\u308B
|
|
1340
|
-
2. \
|
|
1341
|
-
- **\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u304C2\u3064\u4EE5\u4E0A**: \`askUserQuestion\`\uFF08multiSelect: false\uFF09\u3067\u30E6\u30FC\u30B6\u30FC\u306B\u63D0\u793A\u3057\u3001\u4F7F\u7528\u3059\u308B\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u3092\u9078\u629E\u3055\u305B\u308B\u3002\u9078\u629E\u80A2\u306E label \u306F \`\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u540D (id: \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8ID)\` \u306E\u5F62\u5F0F\u306B\u3059\u308B
|
|
1342
|
-
- **\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u304C1\u3064\u3060\u3051**: askUserQuestion \u306F\u4F7F\u308F\u305A\u81EA\u52D5\u63A1\u7528\u3002\u300C\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8 X \u3092\u81EA\u52D5\u9078\u629E\u3057\u307E\u3057\u305F\u300D\u30681\u6587\u3060\u3051\u66F8\u304F
|
|
1343
|
-
3. \`updateConnectionParameters\` \u3067\u9078\u629E\u3055\u308C\u305F\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u3092\u4FDD\u5B58\u3059\u308B:
|
|
1460
|
+
2. \`updateConnectionParameters\` \u3092\u547C\u3073\u51FA\u3057\u3066\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u3092\u4FDD\u5B58\u3059\u308B:
|
|
1344
1461
|
- \`parameterSlug\`: \`"project-id"\`
|
|
1345
|
-
- \`
|
|
1346
|
-
|
|
1347
|
-
4. \u7D9A\u884C\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u53D7\u3051\u53D6\u3063\u305F\u3089\u3001\u30B9\u30C6\u30C3\u30D72\u306B\u9032\u3080
|
|
1462
|
+
- \`options\`: \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u4E00\u89A7\u3002\u5404 option \u306E \`label\` \u306F \`\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u540D (id: \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8ID)\` \u306E\u5F62\u5F0F\u3001\`value\` \u306F\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8ID
|
|
1463
|
+
3. \u7D9A\u884C\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u53D7\u3051\u53D6\u3063\u305F\u3089\u3001\u30B9\u30C6\u30C3\u30D72\u306B\u9032\u3080
|
|
1348
1464
|
|
|
1349
1465
|
#### \u30B9\u30C6\u30C3\u30D72: \u30C7\u30FC\u30BF\u30BB\u30C3\u30C8\u9078\u629E
|
|
1350
1466
|
1. \`SELECT schema_name FROM INFORMATION_SCHEMA.SCHEMATA\` \u3092\u5B9F\u884C\u3057\u3066\u30C7\u30FC\u30BF\u30BB\u30C3\u30C8\u4E00\u89A7\u3092\u53D6\u5F97\u3059\u308B
|
|
@@ -1379,14 +1495,10 @@ Follow these steps to set up the BigQuery connection.
|
|
|
1379
1495
|
|
|
1380
1496
|
#### Step 1: Project Selection
|
|
1381
1497
|
1. Call \`${listProjectsToolName2}\` to get the list of GCP projects accessible with the OAuth credentials
|
|
1382
|
-
2.
|
|
1383
|
-
- **2 or more projects**: Present them to the user via \`askUserQuestion\` (multiSelect: false) and let them select a project. Format option labels as \`Project Name (id: project-id)\`
|
|
1384
|
-
- **Exactly 1 project**: Do NOT call askUserQuestion. Auto-select it. Just write "Auto-selected project X" in one sentence
|
|
1385
|
-
3. Call \`updateConnectionParameters\` to save the selected project:
|
|
1498
|
+
2. Call \`updateConnectionParameters\` to save the project:
|
|
1386
1499
|
- \`parameterSlug\`: \`"project-id"\`
|
|
1387
|
-
- \`
|
|
1388
|
-
|
|
1389
|
-
4. After receiving the continuation message, proceed to Step 2
|
|
1500
|
+
- \`options\`: The project list. Each option's \`label\` should be \`Project Name (id: project-id)\`, \`value\` should be the project ID
|
|
1501
|
+
3. After receiving the continuation message, proceed to Step 2
|
|
1390
1502
|
|
|
1391
1503
|
#### Step 2: Dataset Selection
|
|
1392
1504
|
1. Run \`SELECT schema_name FROM INFORMATION_SCHEMA.SCHEMATA\` to get the list of datasets
|
|
@@ -1594,6 +1706,25 @@ var bigqueryOauthConnector = new ConnectorPlugin({
|
|
|
1594
1706
|
- List columns: \`SELECT column_name, data_type FROM \\\`project_id.dataset\\\`.INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'xxx'\`
|
|
1595
1707
|
- Always specify project_id explicitly in queries`,
|
|
1596
1708
|
tools: tools6,
|
|
1709
|
+
async checkConnection(params, config) {
|
|
1710
|
+
const { proxyFetch } = config;
|
|
1711
|
+
const projectId = params[parameters6.projectId.slug];
|
|
1712
|
+
const url = `https://bigquery.googleapis.com/bigquery/v2/projects/${projectId}/queries`;
|
|
1713
|
+
try {
|
|
1714
|
+
const res = await proxyFetch(url, {
|
|
1715
|
+
method: "POST",
|
|
1716
|
+
headers: { "Content-Type": "application/json" },
|
|
1717
|
+
body: JSON.stringify({ query: "SELECT 1", useLegacySql: false })
|
|
1718
|
+
});
|
|
1719
|
+
if (!res.ok) {
|
|
1720
|
+
const errorText = await res.text().catch(() => res.statusText);
|
|
1721
|
+
return { success: false, error: `BigQuery query failed: HTTP ${res.status} ${errorText}` };
|
|
1722
|
+
}
|
|
1723
|
+
return { success: true };
|
|
1724
|
+
} catch (error) {
|
|
1725
|
+
return { success: false, error: error instanceof Error ? error.message : String(error) };
|
|
1726
|
+
}
|
|
1727
|
+
},
|
|
1597
1728
|
async query(params, sql, namedParams, context) {
|
|
1598
1729
|
const { proxyFetch } = context;
|
|
1599
1730
|
const projectId = params[parameters6.projectId.slug];
|
|
@@ -1798,6 +1929,62 @@ var awsAthenaConnector = new ConnectorPlugin({
|
|
|
1798
1929
|
- Always include LIMIT in queries
|
|
1799
1930
|
- Query execution is asynchronous and results may take time to retrieve`,
|
|
1800
1931
|
tools: tools7,
|
|
1932
|
+
async checkConnection(params, _config) {
|
|
1933
|
+
try {
|
|
1934
|
+
const {
|
|
1935
|
+
AthenaClient,
|
|
1936
|
+
StartQueryExecutionCommand,
|
|
1937
|
+
GetQueryExecutionCommand
|
|
1938
|
+
} = await import("@aws-sdk/client-athena");
|
|
1939
|
+
const workgroup = params[parameters7.workgroup.slug];
|
|
1940
|
+
const outputLocation = params[parameters7.outputLocation.slug];
|
|
1941
|
+
if (!workgroup && !outputLocation) {
|
|
1942
|
+
return {
|
|
1943
|
+
success: false,
|
|
1944
|
+
error: "Either workgroup or output-location is required"
|
|
1945
|
+
};
|
|
1946
|
+
}
|
|
1947
|
+
const client = new AthenaClient({
|
|
1948
|
+
region: params[parameters7.awsRegion.slug],
|
|
1949
|
+
credentials: {
|
|
1950
|
+
accessKeyId: params[parameters7.awsAccessKeyId.slug],
|
|
1951
|
+
secretAccessKey: params[parameters7.awsSecretAccessKey.slug]
|
|
1952
|
+
}
|
|
1953
|
+
});
|
|
1954
|
+
const startParams = { QueryString: "SELECT 1" };
|
|
1955
|
+
if (workgroup) startParams.WorkGroup = workgroup;
|
|
1956
|
+
if (outputLocation) {
|
|
1957
|
+
startParams.ResultConfiguration = { OutputLocation: outputLocation };
|
|
1958
|
+
}
|
|
1959
|
+
const { QueryExecutionId } = await client.send(
|
|
1960
|
+
new StartQueryExecutionCommand(startParams)
|
|
1961
|
+
);
|
|
1962
|
+
const startTime = Date.now();
|
|
1963
|
+
while (true) {
|
|
1964
|
+
const exec = await client.send(
|
|
1965
|
+
new GetQueryExecutionCommand({ QueryExecutionId })
|
|
1966
|
+
);
|
|
1967
|
+
const state = exec.QueryExecution?.Status?.State;
|
|
1968
|
+
if (state === "SUCCEEDED") break;
|
|
1969
|
+
if (state === "FAILED" || state === "CANCELLED") {
|
|
1970
|
+
return {
|
|
1971
|
+
success: false,
|
|
1972
|
+
error: exec.QueryExecution?.Status?.StateChangeReason || `Query ${state}`
|
|
1973
|
+
};
|
|
1974
|
+
}
|
|
1975
|
+
if (Date.now() - startTime > 12e4) {
|
|
1976
|
+
return { success: false, error: "Query timed out after 120 seconds" };
|
|
1977
|
+
}
|
|
1978
|
+
await new Promise((r) => setTimeout(r, 1e3));
|
|
1979
|
+
}
|
|
1980
|
+
return { success: true };
|
|
1981
|
+
} catch (error) {
|
|
1982
|
+
return {
|
|
1983
|
+
success: false,
|
|
1984
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1985
|
+
};
|
|
1986
|
+
}
|
|
1987
|
+
},
|
|
1801
1988
|
async query(params, sql, namedParams) {
|
|
1802
1989
|
const {
|
|
1803
1990
|
AthenaClient,
|
|
@@ -2075,6 +2262,65 @@ var redshiftConnector = new ConnectorPlugin({
|
|
|
2075
2262
|
- Always include LIMIT in queries
|
|
2076
2263
|
- Query execution is asynchronous and results may take time to retrieve`,
|
|
2077
2264
|
tools: tools8,
|
|
2265
|
+
async checkConnection(params, _config) {
|
|
2266
|
+
try {
|
|
2267
|
+
const {
|
|
2268
|
+
RedshiftDataClient,
|
|
2269
|
+
ExecuteStatementCommand,
|
|
2270
|
+
DescribeStatementCommand
|
|
2271
|
+
} = await import("@aws-sdk/client-redshift-data");
|
|
2272
|
+
const clusterIdentifier = params[parameters8.clusterIdentifier.slug];
|
|
2273
|
+
const workgroupName = params[parameters8.workgroupName.slug];
|
|
2274
|
+
const secretArn = params[parameters8.secretArn.slug];
|
|
2275
|
+
const dbUser = params[parameters8.dbUser.slug];
|
|
2276
|
+
if (!clusterIdentifier && !workgroupName) {
|
|
2277
|
+
return {
|
|
2278
|
+
success: false,
|
|
2279
|
+
error: "Either cluster-identifier or workgroup-name is required"
|
|
2280
|
+
};
|
|
2281
|
+
}
|
|
2282
|
+
const client = new RedshiftDataClient({
|
|
2283
|
+
region: params[parameters8.awsRegion.slug],
|
|
2284
|
+
credentials: {
|
|
2285
|
+
accessKeyId: params[parameters8.awsAccessKeyId.slug],
|
|
2286
|
+
secretAccessKey: params[parameters8.awsSecretAccessKey.slug]
|
|
2287
|
+
}
|
|
2288
|
+
});
|
|
2289
|
+
const { Id: statementId } = await client.send(
|
|
2290
|
+
new ExecuteStatementCommand({
|
|
2291
|
+
Database: params[parameters8.database.slug],
|
|
2292
|
+
Sql: "SELECT 1",
|
|
2293
|
+
...clusterIdentifier && { ClusterIdentifier: clusterIdentifier },
|
|
2294
|
+
...workgroupName && { WorkgroupName: workgroupName },
|
|
2295
|
+
...secretArn && { SecretArn: secretArn },
|
|
2296
|
+
...dbUser && { DbUser: dbUser }
|
|
2297
|
+
})
|
|
2298
|
+
);
|
|
2299
|
+
const startTime = Date.now();
|
|
2300
|
+
while (true) {
|
|
2301
|
+
const desc = await client.send(
|
|
2302
|
+
new DescribeStatementCommand({ Id: statementId })
|
|
2303
|
+
);
|
|
2304
|
+
if (desc.Status === "FINISHED") break;
|
|
2305
|
+
if (desc.Status === "FAILED" || desc.Status === "ABORTED") {
|
|
2306
|
+
return {
|
|
2307
|
+
success: false,
|
|
2308
|
+
error: desc.Error || `Statement ${desc.Status}`
|
|
2309
|
+
};
|
|
2310
|
+
}
|
|
2311
|
+
if (Date.now() - startTime > 12e4) {
|
|
2312
|
+
return { success: false, error: "Query timed out after 120 seconds" };
|
|
2313
|
+
}
|
|
2314
|
+
await new Promise((r) => setTimeout(r, 1e3));
|
|
2315
|
+
}
|
|
2316
|
+
return { success: true };
|
|
2317
|
+
} catch (error) {
|
|
2318
|
+
return {
|
|
2319
|
+
success: false,
|
|
2320
|
+
error: error instanceof Error ? error.message : String(error)
|
|
2321
|
+
};
|
|
2322
|
+
}
|
|
2323
|
+
},
|
|
2078
2324
|
async query(params, sql, namedParams) {
|
|
2079
2325
|
const {
|
|
2080
2326
|
RedshiftDataClient,
|
|
@@ -2263,6 +2509,34 @@ var databricksConnector = new ConnectorPlugin({
|
|
|
2263
2509
|
- List columns: \`DESCRIBE TABLE table_name\`
|
|
2264
2510
|
- Always include LIMIT in queries`,
|
|
2265
2511
|
tools: tools9,
|
|
2512
|
+
async checkConnection(params, _config) {
|
|
2513
|
+
const { DBSQLClient } = await import("@databricks/sql");
|
|
2514
|
+
const client = new DBSQLClient();
|
|
2515
|
+
await client.connect({
|
|
2516
|
+
host: params[parameters9.host.slug],
|
|
2517
|
+
path: params[parameters9.httpPath.slug],
|
|
2518
|
+
token: params[parameters9.token.slug]
|
|
2519
|
+
});
|
|
2520
|
+
let session;
|
|
2521
|
+
let operation;
|
|
2522
|
+
try {
|
|
2523
|
+
session = await client.openSession();
|
|
2524
|
+
operation = await session.executeStatement("SELECT 1", {
|
|
2525
|
+
runAsync: true
|
|
2526
|
+
});
|
|
2527
|
+
await operation.fetchAll();
|
|
2528
|
+
return { success: true };
|
|
2529
|
+
} catch (e) {
|
|
2530
|
+
return { success: false, error: e instanceof Error ? e.message : String(e) };
|
|
2531
|
+
} finally {
|
|
2532
|
+
if (operation) await operation.close().catch(() => {
|
|
2533
|
+
});
|
|
2534
|
+
if (session) await session.close().catch(() => {
|
|
2535
|
+
});
|
|
2536
|
+
await client.close().catch(() => {
|
|
2537
|
+
});
|
|
2538
|
+
}
|
|
2539
|
+
},
|
|
2266
2540
|
async query(params, sql, namedParams) {
|
|
2267
2541
|
const { DBSQLClient } = await import("@databricks/sql");
|
|
2268
2542
|
const resolvedSql = replaceLiteralParams(sql, namedParams);
|
|
@@ -3124,6 +3398,22 @@ var squadbaseDbConnector = new ConnectorPlugin({
|
|
|
3124
3398
|
- List columns: \`SELECT column_name, data_type FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'xxx'\`
|
|
3125
3399
|
- Always include LIMIT in queries`,
|
|
3126
3400
|
tools: tools15,
|
|
3401
|
+
async checkConnection(params, _config) {
|
|
3402
|
+
const { Pool } = await import("pg");
|
|
3403
|
+
const pool = new Pool({
|
|
3404
|
+
connectionString: params[parameters15.connectionUrl.slug],
|
|
3405
|
+
ssl: { rejectUnauthorized: false },
|
|
3406
|
+
connectionTimeoutMillis: 1e4
|
|
3407
|
+
});
|
|
3408
|
+
try {
|
|
3409
|
+
await pool.query("SELECT 1");
|
|
3410
|
+
return { success: true };
|
|
3411
|
+
} catch (error) {
|
|
3412
|
+
return { success: false, error: error instanceof Error ? error.message : String(error) };
|
|
3413
|
+
} finally {
|
|
3414
|
+
await pool.end();
|
|
3415
|
+
}
|
|
3416
|
+
},
|
|
3127
3417
|
async query(params, sql, namedParams) {
|
|
3128
3418
|
const { Pool } = await import("pg");
|
|
3129
3419
|
const { text, values } = buildPositionalParams(sql, namedParams);
|