@squadbase/connectors 0.1.2-dev.1 → 0.1.2-dev.2
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/{chunk-LB7J6VXK.js → chunk-HHVJKPCD.js} +176 -5
- package/dist/index.d.ts +174 -1
- package/dist/index.js +2256 -524
- package/dist/sdk.d.ts +196 -10
- package/dist/sdk.js +231 -37
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ParameterDefinition,
|
|
3
3
|
parameters,
|
|
4
|
+
parameters10,
|
|
5
|
+
parameters11,
|
|
6
|
+
parameters12,
|
|
7
|
+
parameters13,
|
|
8
|
+
parameters14,
|
|
9
|
+
parameters15,
|
|
10
|
+
parameters16,
|
|
11
|
+
parameters17,
|
|
12
|
+
parameters18,
|
|
4
13
|
parameters2,
|
|
5
14
|
parameters3,
|
|
6
15
|
parameters4,
|
|
@@ -9,7 +18,7 @@ import {
|
|
|
9
18
|
parameters7,
|
|
10
19
|
parameters8,
|
|
11
20
|
parameters9
|
|
12
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-HHVJKPCD.js";
|
|
13
22
|
|
|
14
23
|
// src/connector-setup.ts
|
|
15
24
|
var ConnectorSetup = class {
|
|
@@ -235,7 +244,7 @@ Follow these steps to set up the Snowflake connection.
|
|
|
235
244
|
});
|
|
236
245
|
|
|
237
246
|
// src/connectors/snowflake/parameters.ts
|
|
238
|
-
var
|
|
247
|
+
var parameters19 = {
|
|
239
248
|
account: new ParameterDefinition({
|
|
240
249
|
slug: "account",
|
|
241
250
|
name: "Snowflake Account",
|
|
@@ -351,15 +360,15 @@ Avoid loading large amounts of data; always include LIMIT in queries.`,
|
|
|
351
360
|
try {
|
|
352
361
|
const snowflake = (await import("snowflake-sdk")).default;
|
|
353
362
|
snowflake.configure({ logLevel: "ERROR" });
|
|
354
|
-
const account =
|
|
355
|
-
const user =
|
|
356
|
-
const role =
|
|
357
|
-
const warehouse =
|
|
358
|
-
const privateKeyBase64 =
|
|
363
|
+
const account = parameters19.account.getValue(connection);
|
|
364
|
+
const user = parameters19.user.getValue(connection);
|
|
365
|
+
const role = parameters19.role.getValue(connection);
|
|
366
|
+
const warehouse = parameters19.warehouse.getValue(connection);
|
|
367
|
+
const privateKeyBase64 = parameters19.privateKeyBase64.getValue(connection);
|
|
359
368
|
const privateKeyPem = Buffer.from(privateKeyBase64, "base64").toString(
|
|
360
369
|
"utf-8"
|
|
361
370
|
);
|
|
362
|
-
const privateKeyPass =
|
|
371
|
+
const privateKeyPass = parameters19.privateKeyPassphrase.tryGetValue(connection);
|
|
363
372
|
const privateKey = decryptPrivateKey(privateKeyPem, privateKeyPass ?? void 0);
|
|
364
373
|
const conn = snowflake.createConnection({
|
|
365
374
|
account,
|
|
@@ -424,7 +433,7 @@ var snowflakeConnector = new ConnectorPlugin({
|
|
|
424
433
|
name: "Snowflake",
|
|
425
434
|
description: "Connect to Snowflake for cloud data warehousing and analytics.",
|
|
426
435
|
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/6oyVtAcP3pMlXaOrts9unk/b7a9dc25d15c388b66e983041b855447/snowflake.svg",
|
|
427
|
-
parameters:
|
|
436
|
+
parameters: parameters19,
|
|
428
437
|
releaseFlag: { dev1: true, dev2: true, prod: true },
|
|
429
438
|
setup: snowflakeSetup,
|
|
430
439
|
systemPrompt: `## Snowflake SQL Notes
|
|
@@ -441,16 +450,16 @@ var snowflakeConnector = new ConnectorPlugin({
|
|
|
441
450
|
const snowflake = (await import("snowflake-sdk")).default;
|
|
442
451
|
snowflake.configure({ logLevel: "ERROR" });
|
|
443
452
|
const privateKeyPem = Buffer.from(
|
|
444
|
-
params[
|
|
453
|
+
params[parameters19.privateKeyBase64.slug],
|
|
445
454
|
"base64"
|
|
446
455
|
).toString("utf-8");
|
|
447
|
-
const privateKeyPass = params[
|
|
456
|
+
const privateKeyPass = params[parameters19.privateKeyPassphrase.slug] || void 0;
|
|
448
457
|
const privateKey = decryptPrivateKey(privateKeyPem, privateKeyPass);
|
|
449
458
|
const conn = snowflake.createConnection({
|
|
450
|
-
account: params[
|
|
451
|
-
username: params[
|
|
452
|
-
role: params[
|
|
453
|
-
warehouse: params[
|
|
459
|
+
account: params[parameters19.account.slug],
|
|
460
|
+
username: params[parameters19.user.slug],
|
|
461
|
+
role: params[parameters19.role.slug],
|
|
462
|
+
warehouse: params[parameters19.warehouse.slug],
|
|
454
463
|
authenticator: "SNOWFLAKE_JWT",
|
|
455
464
|
privateKey
|
|
456
465
|
});
|
|
@@ -482,16 +491,16 @@ var snowflakeConnector = new ConnectorPlugin({
|
|
|
482
491
|
const snowflake = (await import("snowflake-sdk")).default;
|
|
483
492
|
snowflake.configure({ logLevel: "ERROR" });
|
|
484
493
|
const privateKeyPem = Buffer.from(
|
|
485
|
-
params[
|
|
494
|
+
params[parameters19.privateKeyBase64.slug],
|
|
486
495
|
"base64"
|
|
487
496
|
).toString("utf-8");
|
|
488
|
-
const privateKeyPass = params[
|
|
497
|
+
const privateKeyPass = params[parameters19.privateKeyPassphrase.slug] || void 0;
|
|
489
498
|
const privateKey = decryptPrivateKey(privateKeyPem, privateKeyPass);
|
|
490
499
|
const conn = snowflake.createConnection({
|
|
491
|
-
account: params[
|
|
492
|
-
username: params[
|
|
493
|
-
role: params[
|
|
494
|
-
warehouse: params[
|
|
500
|
+
account: params[parameters19.account.slug],
|
|
501
|
+
username: params[parameters19.user.slug],
|
|
502
|
+
role: params[parameters19.role.slug],
|
|
503
|
+
warehouse: params[parameters19.warehouse.slug],
|
|
495
504
|
authenticator: "SNOWFLAKE_JWT",
|
|
496
505
|
privateKey
|
|
497
506
|
});
|
|
@@ -520,7 +529,7 @@ var snowflakeConnector = new ConnectorPlugin({
|
|
|
520
529
|
});
|
|
521
530
|
|
|
522
531
|
// src/connectors/snowflake-pat/parameters.ts
|
|
523
|
-
var
|
|
532
|
+
var parameters20 = {
|
|
524
533
|
account: new ParameterDefinition({
|
|
525
534
|
slug: "account",
|
|
526
535
|
name: "Snowflake Account",
|
|
@@ -614,11 +623,11 @@ Avoid loading large amounts of data; always include LIMIT in queries.`,
|
|
|
614
623
|
try {
|
|
615
624
|
const snowflake = (await import("snowflake-sdk")).default;
|
|
616
625
|
snowflake.configure({ logLevel: "ERROR" });
|
|
617
|
-
const account =
|
|
618
|
-
const user =
|
|
619
|
-
const role =
|
|
620
|
-
const warehouse =
|
|
621
|
-
const password =
|
|
626
|
+
const account = parameters20.account.getValue(connection);
|
|
627
|
+
const user = parameters20.user.getValue(connection);
|
|
628
|
+
const role = parameters20.role.getValue(connection);
|
|
629
|
+
const warehouse = parameters20.warehouse.getValue(connection);
|
|
630
|
+
const password = parameters20.pat.getValue(connection);
|
|
622
631
|
const conn = snowflake.createConnection({
|
|
623
632
|
account,
|
|
624
633
|
username: user,
|
|
@@ -681,7 +690,7 @@ var snowflakePatConnector = new ConnectorPlugin({
|
|
|
681
690
|
name: "Snowflake (PAT)",
|
|
682
691
|
description: "Connect to Snowflake using a Personal Access Token (PAT).",
|
|
683
692
|
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/6oyVtAcP3pMlXaOrts9unk/b7a9dc25d15c388b66e983041b855447/snowflake.svg",
|
|
684
|
-
parameters:
|
|
693
|
+
parameters: parameters20,
|
|
685
694
|
releaseFlag: { dev1: true, dev2: true, prod: true },
|
|
686
695
|
setup: snowflakeSetup,
|
|
687
696
|
systemPrompt: `## Snowflake SQL Notes
|
|
@@ -698,11 +707,11 @@ var snowflakePatConnector = new ConnectorPlugin({
|
|
|
698
707
|
const snowflake = (await import("snowflake-sdk")).default;
|
|
699
708
|
snowflake.configure({ logLevel: "ERROR" });
|
|
700
709
|
const conn = snowflake.createConnection({
|
|
701
|
-
account: params[
|
|
702
|
-
username: params[
|
|
703
|
-
role: params[
|
|
704
|
-
warehouse: params[
|
|
705
|
-
password: params[
|
|
710
|
+
account: params[parameters20.account.slug],
|
|
711
|
+
username: params[parameters20.user.slug],
|
|
712
|
+
role: params[parameters20.role.slug],
|
|
713
|
+
warehouse: params[parameters20.warehouse.slug],
|
|
714
|
+
password: params[parameters20.pat.slug]
|
|
706
715
|
});
|
|
707
716
|
await new Promise((resolve, reject) => {
|
|
708
717
|
conn.connect((err) => {
|
|
@@ -737,11 +746,11 @@ var snowflakePatConnector = new ConnectorPlugin({
|
|
|
737
746
|
const snowflake = (await import("snowflake-sdk")).default;
|
|
738
747
|
snowflake.configure({ logLevel: "ERROR" });
|
|
739
748
|
const conn = snowflake.createConnection({
|
|
740
|
-
account: params[
|
|
741
|
-
username: params[
|
|
742
|
-
role: params[
|
|
743
|
-
warehouse: params[
|
|
744
|
-
password: params[
|
|
749
|
+
account: params[parameters20.account.slug],
|
|
750
|
+
username: params[parameters20.user.slug],
|
|
751
|
+
role: params[parameters20.role.slug],
|
|
752
|
+
warehouse: params[parameters20.warehouse.slug],
|
|
753
|
+
password: params[parameters20.pat.slug]
|
|
745
754
|
});
|
|
746
755
|
await new Promise((resolve, reject) => {
|
|
747
756
|
conn.connect((err) => {
|
|
@@ -773,7 +782,7 @@ var snowflakePatConnector = new ConnectorPlugin({
|
|
|
773
782
|
});
|
|
774
783
|
|
|
775
784
|
// src/connectors/postgresql/parameters.ts
|
|
776
|
-
var
|
|
785
|
+
var parameters21 = {
|
|
777
786
|
connectionUrl: new ParameterDefinition({
|
|
778
787
|
slug: "connection-url",
|
|
779
788
|
name: "PostgreSQL Connection URL",
|
|
@@ -830,7 +839,7 @@ Avoid loading large amounts of data; always include LIMIT in queries.`,
|
|
|
830
839
|
let connectionUrl;
|
|
831
840
|
try {
|
|
832
841
|
const { Pool } = await import("pg");
|
|
833
|
-
connectionUrl =
|
|
842
|
+
connectionUrl = parameters21.connectionUrl.getValue(connection);
|
|
834
843
|
const pool = new Pool({
|
|
835
844
|
connectionString: connectionUrl,
|
|
836
845
|
ssl: { rejectUnauthorized: false },
|
|
@@ -868,7 +877,7 @@ var postgresqlConnector = new ConnectorPlugin({
|
|
|
868
877
|
name: "PostgreSQL",
|
|
869
878
|
description: "Connect to PostgreSQL databases for relational data storage and querying.",
|
|
870
879
|
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/42AHi2uqteUn65MyqdN6V7/a0f68f12af6aac96bbcda5980f43de07/elephant.png",
|
|
871
|
-
parameters:
|
|
880
|
+
parameters: parameters21,
|
|
872
881
|
releaseFlag: { dev1: true, dev2: true, prod: true },
|
|
873
882
|
systemPrompt: `## PostgreSQL SQL Notes
|
|
874
883
|
- Schema exploration:
|
|
@@ -879,7 +888,7 @@ var postgresqlConnector = new ConnectorPlugin({
|
|
|
879
888
|
async checkConnection(params, _config) {
|
|
880
889
|
const { Pool } = await import("pg");
|
|
881
890
|
const pool = new Pool({
|
|
882
|
-
connectionString: params[
|
|
891
|
+
connectionString: params[parameters21.connectionUrl.slug],
|
|
883
892
|
ssl: { rejectUnauthorized: false },
|
|
884
893
|
connectionTimeoutMillis: 1e4
|
|
885
894
|
});
|
|
@@ -896,7 +905,7 @@ var postgresqlConnector = new ConnectorPlugin({
|
|
|
896
905
|
const { Pool } = await import("pg");
|
|
897
906
|
const { text, values } = buildPositionalParams(sql, namedParams);
|
|
898
907
|
const pool = new Pool({
|
|
899
|
-
connectionString: params[
|
|
908
|
+
connectionString: params[parameters21.connectionUrl.slug],
|
|
900
909
|
ssl: { rejectUnauthorized: false },
|
|
901
910
|
connectionTimeoutMillis: 1e4,
|
|
902
911
|
statement_timeout: 6e4
|
|
@@ -911,7 +920,7 @@ var postgresqlConnector = new ConnectorPlugin({
|
|
|
911
920
|
});
|
|
912
921
|
|
|
913
922
|
// src/connectors/mysql/parameters.ts
|
|
914
|
-
var
|
|
923
|
+
var parameters22 = {
|
|
915
924
|
connectionUrl: new ParameterDefinition({
|
|
916
925
|
slug: "connection-url",
|
|
917
926
|
name: "MySQL Connection URL",
|
|
@@ -968,7 +977,7 @@ Avoid loading large amounts of data; always include LIMIT in queries.`,
|
|
|
968
977
|
let connectionUrl;
|
|
969
978
|
try {
|
|
970
979
|
const mysql = await import("mysql2/promise");
|
|
971
|
-
connectionUrl =
|
|
980
|
+
connectionUrl = parameters22.connectionUrl.getValue(connection);
|
|
972
981
|
const pool = mysql.createPool({
|
|
973
982
|
uri: connectionUrl,
|
|
974
983
|
connectTimeout: CONNECT_TIMEOUT_MS2
|
|
@@ -1008,7 +1017,7 @@ var mysqlConnector = new ConnectorPlugin({
|
|
|
1008
1017
|
name: "MySQL",
|
|
1009
1018
|
description: "Connect to MySQL databases for relational data storage and querying.",
|
|
1010
1019
|
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/6ghPFeGgl7uBs5NHH1a4L/512c9433beec5b595caa41f04921c1f9/logo-mysql-170x115.png",
|
|
1011
|
-
parameters:
|
|
1020
|
+
parameters: parameters22,
|
|
1012
1021
|
releaseFlag: { dev1: true, dev2: true, prod: true },
|
|
1013
1022
|
systemPrompt: `## MySQL SQL Notes
|
|
1014
1023
|
- Schema exploration:
|
|
@@ -1019,7 +1028,7 @@ var mysqlConnector = new ConnectorPlugin({
|
|
|
1019
1028
|
async checkConnection(params, _config) {
|
|
1020
1029
|
const mysql = await import("mysql2/promise");
|
|
1021
1030
|
const pool = mysql.createPool({
|
|
1022
|
-
uri: params[
|
|
1031
|
+
uri: params[parameters22.connectionUrl.slug],
|
|
1023
1032
|
connectTimeout: 1e4
|
|
1024
1033
|
});
|
|
1025
1034
|
try {
|
|
@@ -1035,7 +1044,7 @@ var mysqlConnector = new ConnectorPlugin({
|
|
|
1035
1044
|
const mysql = await import("mysql2/promise");
|
|
1036
1045
|
const { text, values } = buildQuestionmarkParams(sql, namedParams);
|
|
1037
1046
|
const pool = mysql.createPool({
|
|
1038
|
-
uri: params[
|
|
1047
|
+
uri: params[parameters22.connectionUrl.slug],
|
|
1039
1048
|
connectTimeout: 1e4
|
|
1040
1049
|
});
|
|
1041
1050
|
try {
|
|
@@ -1056,7 +1065,7 @@ var mysqlConnector = new ConnectorPlugin({
|
|
|
1056
1065
|
import { z as z5 } from "zod";
|
|
1057
1066
|
|
|
1058
1067
|
// src/connectors/bigquery/parameters.ts
|
|
1059
|
-
var
|
|
1068
|
+
var parameters23 = {
|
|
1060
1069
|
serviceAccountKeyJsonBase64: new ParameterDefinition({
|
|
1061
1070
|
slug: "service-account-key-json-base64",
|
|
1062
1071
|
name: "Google Cloud Service Account JSON",
|
|
@@ -1113,7 +1122,7 @@ var listProjectsTool = new ConnectorTool({
|
|
|
1113
1122
|
};
|
|
1114
1123
|
}
|
|
1115
1124
|
try {
|
|
1116
|
-
const serviceAccountJsonBase64 =
|
|
1125
|
+
const serviceAccountJsonBase64 = parameters23.serviceAccountKeyJsonBase64.getValue(connection);
|
|
1117
1126
|
const credentials = JSON.parse(
|
|
1118
1127
|
Buffer.from(serviceAccountJsonBase64, "base64").toString("utf-8")
|
|
1119
1128
|
);
|
|
@@ -1177,8 +1186,8 @@ var listDatasetsTool = new ConnectorTool({
|
|
|
1177
1186
|
}
|
|
1178
1187
|
try {
|
|
1179
1188
|
const { BigQuery } = await import("@google-cloud/bigquery");
|
|
1180
|
-
const projectId =
|
|
1181
|
-
const serviceAccountJsonBase64 =
|
|
1189
|
+
const projectId = parameters23.projectId.getValue(connection);
|
|
1190
|
+
const serviceAccountJsonBase64 = parameters23.serviceAccountKeyJsonBase64.getValue(connection);
|
|
1182
1191
|
const credentials = JSON.parse(
|
|
1183
1192
|
Buffer.from(serviceAccountJsonBase64, "base64").toString("utf-8")
|
|
1184
1193
|
);
|
|
@@ -1339,8 +1348,8 @@ Avoid loading large amounts of data; always include LIMIT in queries.`,
|
|
|
1339
1348
|
);
|
|
1340
1349
|
try {
|
|
1341
1350
|
const { BigQuery } = await import("@google-cloud/bigquery");
|
|
1342
|
-
const projectId =
|
|
1343
|
-
const serviceAccountJsonBase64 =
|
|
1351
|
+
const projectId = parameters23.projectId.getValue(connection);
|
|
1352
|
+
const serviceAccountJsonBase64 = parameters23.serviceAccountKeyJsonBase64.getValue(connection);
|
|
1344
1353
|
const credentials = JSON.parse(
|
|
1345
1354
|
Buffer.from(serviceAccountJsonBase64, "base64").toString("utf-8")
|
|
1346
1355
|
);
|
|
@@ -1370,7 +1379,7 @@ var bigqueryConnector = new ConnectorPlugin({
|
|
|
1370
1379
|
name: "BigQuery",
|
|
1371
1380
|
description: "Connect to Google BigQuery for data warehouse and analytics.",
|
|
1372
1381
|
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/6nlehQyOmdbktG5hOYkYMr/6ca559140d5ddc7dadc5eac88858a563/bigquery.svg",
|
|
1373
|
-
parameters:
|
|
1382
|
+
parameters: parameters23,
|
|
1374
1383
|
releaseFlag: { dev1: true, dev2: true, prod: true },
|
|
1375
1384
|
setup: bigquerySetup,
|
|
1376
1385
|
systemPrompt: `## BigQuery SQL Notes
|
|
@@ -1384,10 +1393,10 @@ var bigqueryConnector = new ConnectorPlugin({
|
|
|
1384
1393
|
async checkConnection(params, _config) {
|
|
1385
1394
|
const { BigQuery } = await import("@google-cloud/bigquery");
|
|
1386
1395
|
const credentials = JSON.parse(
|
|
1387
|
-
Buffer.from(params[
|
|
1396
|
+
Buffer.from(params[parameters23.serviceAccountKeyJsonBase64.slug], "base64").toString("utf-8")
|
|
1388
1397
|
);
|
|
1389
1398
|
const bq = new BigQuery({
|
|
1390
|
-
projectId: params[
|
|
1399
|
+
projectId: params[parameters23.projectId.slug],
|
|
1391
1400
|
credentials
|
|
1392
1401
|
});
|
|
1393
1402
|
try {
|
|
@@ -1402,10 +1411,10 @@ var bigqueryConnector = new ConnectorPlugin({
|
|
|
1402
1411
|
const { BigQuery } = await import("@google-cloud/bigquery");
|
|
1403
1412
|
const resolvedSql = replaceLiteralParams(sql, namedParams);
|
|
1404
1413
|
const credentials = JSON.parse(
|
|
1405
|
-
Buffer.from(params[
|
|
1414
|
+
Buffer.from(params[parameters23.serviceAccountKeyJsonBase64.slug], "base64").toString("utf-8")
|
|
1406
1415
|
);
|
|
1407
1416
|
const bq = new BigQuery({
|
|
1408
|
-
projectId: params[
|
|
1417
|
+
projectId: params[parameters23.projectId.slug],
|
|
1409
1418
|
credentials
|
|
1410
1419
|
});
|
|
1411
1420
|
const [job] = await bq.createQueryJob({ query: resolvedSql });
|
|
@@ -1525,7 +1534,7 @@ var listProjectsTool2 = new ConnectorTool({
|
|
|
1525
1534
|
import { z as z9 } from "zod";
|
|
1526
1535
|
|
|
1527
1536
|
// src/connectors/bigquery-oauth/parameters.ts
|
|
1528
|
-
var
|
|
1537
|
+
var parameters24 = {
|
|
1529
1538
|
projectId: new ParameterDefinition({
|
|
1530
1539
|
slug: "project-id",
|
|
1531
1540
|
name: "Google Cloud Project ID",
|
|
@@ -1603,7 +1612,7 @@ var listDatasetsTool2 = new ConnectorTool({
|
|
|
1603
1612
|
error: `Connection ${connectionId} not found`
|
|
1604
1613
|
};
|
|
1605
1614
|
}
|
|
1606
|
-
const gcpProjectId =
|
|
1615
|
+
const gcpProjectId = parameters24.projectId.getValue(connection);
|
|
1607
1616
|
console.log(
|
|
1608
1617
|
`[connector-query] bigquery-oauth/${connection.name}: listDatasets`
|
|
1609
1618
|
);
|
|
@@ -1826,7 +1835,7 @@ Avoid loading large amounts of data; always include LIMIT in queries.`,
|
|
|
1826
1835
|
error: `Connection ${connectionId} not found`
|
|
1827
1836
|
};
|
|
1828
1837
|
}
|
|
1829
|
-
const gcpProjectId =
|
|
1838
|
+
const gcpProjectId = parameters24.projectId.getValue(connection);
|
|
1830
1839
|
console.log(
|
|
1831
1840
|
`[connector-query] bigquery-oauth/${connection.name}: ${sql}`
|
|
1832
1841
|
);
|
|
@@ -1893,7 +1902,7 @@ var bigqueryOauthConnector = new ConnectorPlugin({
|
|
|
1893
1902
|
name: "BigQuery (OAuth)",
|
|
1894
1903
|
description: "Connect to Google BigQuery for data warehouse and analytics using OAuth.",
|
|
1895
1904
|
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/6nlehQyOmdbktG5hOYkYMr/6ca559140d5ddc7dadc5eac88858a563/bigquery.svg",
|
|
1896
|
-
parameters:
|
|
1905
|
+
parameters: parameters24,
|
|
1897
1906
|
releaseFlag: { dev1: true, dev2: true, prod: true },
|
|
1898
1907
|
setup: bigquerySetup2,
|
|
1899
1908
|
proxyPolicy: {
|
|
@@ -1912,7 +1921,7 @@ var bigqueryOauthConnector = new ConnectorPlugin({
|
|
|
1912
1921
|
tools: tools6,
|
|
1913
1922
|
async checkConnection(params, config) {
|
|
1914
1923
|
const { proxyFetch } = config;
|
|
1915
|
-
const projectId = params[
|
|
1924
|
+
const projectId = params[parameters24.projectId.slug];
|
|
1916
1925
|
const url = `https://bigquery.googleapis.com/bigquery/v2/projects/${projectId}/queries`;
|
|
1917
1926
|
try {
|
|
1918
1927
|
const res = await proxyFetch(url, {
|
|
@@ -1931,7 +1940,7 @@ var bigqueryOauthConnector = new ConnectorPlugin({
|
|
|
1931
1940
|
},
|
|
1932
1941
|
async query(params, sql, namedParams, context) {
|
|
1933
1942
|
const { proxyFetch } = context;
|
|
1934
|
-
const projectId = params[
|
|
1943
|
+
const projectId = params[parameters24.projectId.slug];
|
|
1935
1944
|
const resolvedSql = replaceLiteralParams(sql, namedParams);
|
|
1936
1945
|
const url = `https://bigquery.googleapis.com/bigquery/v2/projects/${projectId}/queries`;
|
|
1937
1946
|
const res = await proxyFetch(url, {
|
|
@@ -1949,7 +1958,7 @@ var bigqueryOauthConnector = new ConnectorPlugin({
|
|
|
1949
1958
|
});
|
|
1950
1959
|
|
|
1951
1960
|
// src/connectors/aws-athena/parameters.ts
|
|
1952
|
-
var
|
|
1961
|
+
var parameters25 = {
|
|
1953
1962
|
awsAccessKeyId: new ParameterDefinition({
|
|
1954
1963
|
slug: "aws-access-key-id",
|
|
1955
1964
|
name: "AWS Access Key ID",
|
|
@@ -2046,8 +2055,8 @@ Avoid loading large amounts of data; always include LIMIT in queries.`,
|
|
|
2046
2055
|
GetQueryExecutionCommand,
|
|
2047
2056
|
GetQueryResultsCommand
|
|
2048
2057
|
} = await import("@aws-sdk/client-athena");
|
|
2049
|
-
const workgroup =
|
|
2050
|
-
const outputLocation =
|
|
2058
|
+
const workgroup = parameters25.workgroup.tryGetValue(connection);
|
|
2059
|
+
const outputLocation = parameters25.outputLocation.tryGetValue(connection);
|
|
2051
2060
|
if (!workgroup && !outputLocation) {
|
|
2052
2061
|
return {
|
|
2053
2062
|
success: false,
|
|
@@ -2055,10 +2064,10 @@ Avoid loading large amounts of data; always include LIMIT in queries.`,
|
|
|
2055
2064
|
};
|
|
2056
2065
|
}
|
|
2057
2066
|
const client = new AthenaClient({
|
|
2058
|
-
region:
|
|
2067
|
+
region: parameters25.awsRegion.getValue(connection),
|
|
2059
2068
|
credentials: {
|
|
2060
|
-
accessKeyId:
|
|
2061
|
-
secretAccessKey:
|
|
2069
|
+
accessKeyId: parameters25.awsAccessKeyId.getValue(connection),
|
|
2070
|
+
secretAccessKey: parameters25.awsSecretAccessKey.getValue(connection)
|
|
2062
2071
|
}
|
|
2063
2072
|
});
|
|
2064
2073
|
const startParams = { QueryString: sql };
|
|
@@ -2122,7 +2131,7 @@ var awsAthenaConnector = new ConnectorPlugin({
|
|
|
2122
2131
|
name: "AWS Athena",
|
|
2123
2132
|
description: "Connect to AWS Athena for serverless SQL queries on S3 data.",
|
|
2124
2133
|
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/5x0vIHtUHfJJMZUv4RFOYZ/5059bac389f0169542f39cdb4b387d2c/Athena.svg",
|
|
2125
|
-
parameters:
|
|
2134
|
+
parameters: parameters25,
|
|
2126
2135
|
releaseFlag: { dev1: true, dev2: true, prod: true },
|
|
2127
2136
|
systemPrompt: `## AWS Athena SQL Notes
|
|
2128
2137
|
- Uses Presto/Trino based SQL syntax
|
|
@@ -2140,8 +2149,8 @@ var awsAthenaConnector = new ConnectorPlugin({
|
|
|
2140
2149
|
StartQueryExecutionCommand,
|
|
2141
2150
|
GetQueryExecutionCommand
|
|
2142
2151
|
} = await import("@aws-sdk/client-athena");
|
|
2143
|
-
const workgroup = params[
|
|
2144
|
-
const outputLocation = params[
|
|
2152
|
+
const workgroup = params[parameters25.workgroup.slug];
|
|
2153
|
+
const outputLocation = params[parameters25.outputLocation.slug];
|
|
2145
2154
|
if (!workgroup && !outputLocation) {
|
|
2146
2155
|
return {
|
|
2147
2156
|
success: false,
|
|
@@ -2149,10 +2158,10 @@ var awsAthenaConnector = new ConnectorPlugin({
|
|
|
2149
2158
|
};
|
|
2150
2159
|
}
|
|
2151
2160
|
const client = new AthenaClient({
|
|
2152
|
-
region: params[
|
|
2161
|
+
region: params[parameters25.awsRegion.slug],
|
|
2153
2162
|
credentials: {
|
|
2154
|
-
accessKeyId: params[
|
|
2155
|
-
secretAccessKey: params[
|
|
2163
|
+
accessKeyId: params[parameters25.awsAccessKeyId.slug],
|
|
2164
|
+
secretAccessKey: params[parameters25.awsSecretAccessKey.slug]
|
|
2156
2165
|
}
|
|
2157
2166
|
});
|
|
2158
2167
|
const startParams = { QueryString: "SELECT 1" };
|
|
@@ -2197,16 +2206,16 @@ var awsAthenaConnector = new ConnectorPlugin({
|
|
|
2197
2206
|
GetQueryResultsCommand
|
|
2198
2207
|
} = await import("@aws-sdk/client-athena");
|
|
2199
2208
|
const resolvedSql = replaceLiteralParams(sql, namedParams);
|
|
2200
|
-
const workgroup = params[
|
|
2201
|
-
const outputLocation = params[
|
|
2209
|
+
const workgroup = params[parameters25.workgroup.slug];
|
|
2210
|
+
const outputLocation = params[parameters25.outputLocation.slug];
|
|
2202
2211
|
if (!workgroup && !outputLocation) {
|
|
2203
2212
|
throw new Error("Either workgroup or output-location is required");
|
|
2204
2213
|
}
|
|
2205
2214
|
const client = new AthenaClient({
|
|
2206
|
-
region: params[
|
|
2215
|
+
region: params[parameters25.awsRegion.slug],
|
|
2207
2216
|
credentials: {
|
|
2208
|
-
accessKeyId: params[
|
|
2209
|
-
secretAccessKey: params[
|
|
2217
|
+
accessKeyId: params[parameters25.awsAccessKeyId.slug],
|
|
2218
|
+
secretAccessKey: params[parameters25.awsSecretAccessKey.slug]
|
|
2210
2219
|
}
|
|
2211
2220
|
});
|
|
2212
2221
|
const startParams = { QueryString: resolvedSql };
|
|
@@ -2251,7 +2260,7 @@ var awsAthenaConnector = new ConnectorPlugin({
|
|
|
2251
2260
|
});
|
|
2252
2261
|
|
|
2253
2262
|
// src/connectors/redshift/parameters.ts
|
|
2254
|
-
var
|
|
2263
|
+
var parameters26 = {
|
|
2255
2264
|
awsAccessKeyId: new ParameterDefinition({
|
|
2256
2265
|
slug: "aws-access-key-id",
|
|
2257
2266
|
name: "AWS Access Key ID",
|
|
@@ -2377,14 +2386,14 @@ Avoid loading large amounts of data; always include LIMIT in queries.`,
|
|
|
2377
2386
|
DescribeStatementCommand,
|
|
2378
2387
|
GetStatementResultCommand
|
|
2379
2388
|
} = await import("@aws-sdk/client-redshift-data");
|
|
2380
|
-
const awsAccessKeyId =
|
|
2381
|
-
const awsSecretAccessKey =
|
|
2382
|
-
const awsRegion =
|
|
2383
|
-
const database =
|
|
2384
|
-
const clusterIdentifier =
|
|
2385
|
-
const workgroupName =
|
|
2386
|
-
const secretArn =
|
|
2387
|
-
const dbUser =
|
|
2389
|
+
const awsAccessKeyId = parameters26.awsAccessKeyId.getValue(connection);
|
|
2390
|
+
const awsSecretAccessKey = parameters26.awsSecretAccessKey.getValue(connection);
|
|
2391
|
+
const awsRegion = parameters26.awsRegion.getValue(connection);
|
|
2392
|
+
const database = parameters26.database.getValue(connection);
|
|
2393
|
+
const clusterIdentifier = parameters26.clusterIdentifier.tryGetValue(connection);
|
|
2394
|
+
const workgroupName = parameters26.workgroupName.tryGetValue(connection);
|
|
2395
|
+
const secretArn = parameters26.secretArn.tryGetValue(connection);
|
|
2396
|
+
const dbUser = parameters26.dbUser.tryGetValue(connection);
|
|
2388
2397
|
if (!clusterIdentifier && !workgroupName) {
|
|
2389
2398
|
return {
|
|
2390
2399
|
success: false,
|
|
@@ -2455,7 +2464,7 @@ var redshiftConnector = new ConnectorPlugin({
|
|
|
2455
2464
|
name: "Redshift",
|
|
2456
2465
|
description: "Connect to Amazon Redshift for data warehouse analytics.",
|
|
2457
2466
|
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/AEwW2psmrnZ7htTVsgA9t/a637e31707c5d760be73ce1d8ec75580/aws-redshift-logo.svg",
|
|
2458
|
-
parameters:
|
|
2467
|
+
parameters: parameters26,
|
|
2459
2468
|
releaseFlag: { dev1: true, dev2: true, prod: true },
|
|
2460
2469
|
systemPrompt: `## Redshift SQL Notes
|
|
2461
2470
|
- Uses PostgreSQL based SQL syntax
|
|
@@ -2473,10 +2482,10 @@ var redshiftConnector = new ConnectorPlugin({
|
|
|
2473
2482
|
ExecuteStatementCommand,
|
|
2474
2483
|
DescribeStatementCommand
|
|
2475
2484
|
} = await import("@aws-sdk/client-redshift-data");
|
|
2476
|
-
const clusterIdentifier = params[
|
|
2477
|
-
const workgroupName = params[
|
|
2478
|
-
const secretArn = params[
|
|
2479
|
-
const dbUser = params[
|
|
2485
|
+
const clusterIdentifier = params[parameters26.clusterIdentifier.slug];
|
|
2486
|
+
const workgroupName = params[parameters26.workgroupName.slug];
|
|
2487
|
+
const secretArn = params[parameters26.secretArn.slug];
|
|
2488
|
+
const dbUser = params[parameters26.dbUser.slug];
|
|
2480
2489
|
if (!clusterIdentifier && !workgroupName) {
|
|
2481
2490
|
return {
|
|
2482
2491
|
success: false,
|
|
@@ -2484,15 +2493,15 @@ var redshiftConnector = new ConnectorPlugin({
|
|
|
2484
2493
|
};
|
|
2485
2494
|
}
|
|
2486
2495
|
const client = new RedshiftDataClient({
|
|
2487
|
-
region: params[
|
|
2496
|
+
region: params[parameters26.awsRegion.slug],
|
|
2488
2497
|
credentials: {
|
|
2489
|
-
accessKeyId: params[
|
|
2490
|
-
secretAccessKey: params[
|
|
2498
|
+
accessKeyId: params[parameters26.awsAccessKeyId.slug],
|
|
2499
|
+
secretAccessKey: params[parameters26.awsSecretAccessKey.slug]
|
|
2491
2500
|
}
|
|
2492
2501
|
});
|
|
2493
2502
|
const { Id: statementId } = await client.send(
|
|
2494
2503
|
new ExecuteStatementCommand({
|
|
2495
|
-
Database: params[
|
|
2504
|
+
Database: params[parameters26.database.slug],
|
|
2496
2505
|
Sql: "SELECT 1",
|
|
2497
2506
|
...clusterIdentifier && { ClusterIdentifier: clusterIdentifier },
|
|
2498
2507
|
...workgroupName && { WorkgroupName: workgroupName },
|
|
@@ -2533,23 +2542,23 @@ var redshiftConnector = new ConnectorPlugin({
|
|
|
2533
2542
|
GetStatementResultCommand
|
|
2534
2543
|
} = await import("@aws-sdk/client-redshift-data");
|
|
2535
2544
|
const resolvedSql = replaceLiteralParams(sql, namedParams);
|
|
2536
|
-
const clusterIdentifier = params[
|
|
2537
|
-
const workgroupName = params[
|
|
2538
|
-
const secretArn = params[
|
|
2539
|
-
const dbUser = params[
|
|
2545
|
+
const clusterIdentifier = params[parameters26.clusterIdentifier.slug];
|
|
2546
|
+
const workgroupName = params[parameters26.workgroupName.slug];
|
|
2547
|
+
const secretArn = params[parameters26.secretArn.slug];
|
|
2548
|
+
const dbUser = params[parameters26.dbUser.slug];
|
|
2540
2549
|
if (!clusterIdentifier && !workgroupName) {
|
|
2541
2550
|
throw new Error("Either cluster-identifier or workgroup-name is required");
|
|
2542
2551
|
}
|
|
2543
2552
|
const client = new RedshiftDataClient({
|
|
2544
|
-
region: params[
|
|
2553
|
+
region: params[parameters26.awsRegion.slug],
|
|
2545
2554
|
credentials: {
|
|
2546
|
-
accessKeyId: params[
|
|
2547
|
-
secretAccessKey: params[
|
|
2555
|
+
accessKeyId: params[parameters26.awsAccessKeyId.slug],
|
|
2556
|
+
secretAccessKey: params[parameters26.awsSecretAccessKey.slug]
|
|
2548
2557
|
}
|
|
2549
2558
|
});
|
|
2550
2559
|
const { Id: statementId } = await client.send(
|
|
2551
2560
|
new ExecuteStatementCommand({
|
|
2552
|
-
Database: params[
|
|
2561
|
+
Database: params[parameters26.database.slug],
|
|
2553
2562
|
Sql: resolvedSql,
|
|
2554
2563
|
...clusterIdentifier && { ClusterIdentifier: clusterIdentifier },
|
|
2555
2564
|
...workgroupName && { WorkgroupName: workgroupName },
|
|
@@ -2587,7 +2596,7 @@ var redshiftConnector = new ConnectorPlugin({
|
|
|
2587
2596
|
});
|
|
2588
2597
|
|
|
2589
2598
|
// src/connectors/databricks/parameters.ts
|
|
2590
|
-
var
|
|
2599
|
+
var parameters27 = {
|
|
2591
2600
|
host: new ParameterDefinition({
|
|
2592
2601
|
slug: "host",
|
|
2593
2602
|
name: "Databricks Workspace Host",
|
|
@@ -2659,9 +2668,9 @@ Avoid loading large amounts of data; always include LIMIT in queries.`,
|
|
|
2659
2668
|
);
|
|
2660
2669
|
try {
|
|
2661
2670
|
const { DBSQLClient } = await import("@databricks/sql");
|
|
2662
|
-
const host =
|
|
2663
|
-
const token =
|
|
2664
|
-
const httpPath =
|
|
2671
|
+
const host = parameters27.host.getValue(connection);
|
|
2672
|
+
const token = parameters27.token.getValue(connection);
|
|
2673
|
+
const httpPath = parameters27.httpPath.getValue(connection);
|
|
2665
2674
|
const client = new DBSQLClient();
|
|
2666
2675
|
await client.connect({ host, path: httpPath, token });
|
|
2667
2676
|
let session;
|
|
@@ -2702,7 +2711,7 @@ var databricksConnector = new ConnectorPlugin({
|
|
|
2702
2711
|
name: "Databricks",
|
|
2703
2712
|
description: "Connect to Databricks for data lakehouse and SQL analytics.",
|
|
2704
2713
|
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/6QgcrfpQOKg18P7DdgKerd/af55bf0d871339049824dd167b97a29f/databricks-icon.svg",
|
|
2705
|
-
parameters:
|
|
2714
|
+
parameters: parameters27,
|
|
2706
2715
|
releaseFlag: { dev1: true, dev2: true, prod: true },
|
|
2707
2716
|
systemPrompt: `## Databricks SQL Notes
|
|
2708
2717
|
- Uses Spark SQL / Databricks SQL syntax
|
|
@@ -2717,9 +2726,9 @@ var databricksConnector = new ConnectorPlugin({
|
|
|
2717
2726
|
const { DBSQLClient } = await import("@databricks/sql");
|
|
2718
2727
|
const client = new DBSQLClient();
|
|
2719
2728
|
await client.connect({
|
|
2720
|
-
host: params[
|
|
2721
|
-
path: params[
|
|
2722
|
-
token: params[
|
|
2729
|
+
host: params[parameters27.host.slug],
|
|
2730
|
+
path: params[parameters27.httpPath.slug],
|
|
2731
|
+
token: params[parameters27.token.slug]
|
|
2723
2732
|
});
|
|
2724
2733
|
let session;
|
|
2725
2734
|
let operation;
|
|
@@ -2746,9 +2755,9 @@ var databricksConnector = new ConnectorPlugin({
|
|
|
2746
2755
|
const resolvedSql = replaceLiteralParams(sql, namedParams);
|
|
2747
2756
|
const client = new DBSQLClient();
|
|
2748
2757
|
await client.connect({
|
|
2749
|
-
host: params[
|
|
2750
|
-
path: params[
|
|
2751
|
-
token: params[
|
|
2758
|
+
host: params[parameters27.host.slug],
|
|
2759
|
+
path: params[parameters27.httpPath.slug],
|
|
2760
|
+
token: params[parameters27.token.slug]
|
|
2752
2761
|
});
|
|
2753
2762
|
let session;
|
|
2754
2763
|
let operation;
|
|
@@ -4302,15 +4311,52 @@ batch.valueRanges.forEach(vr => console.log(vr.range, vr.values));
|
|
|
4302
4311
|
}
|
|
4303
4312
|
});
|
|
4304
4313
|
|
|
4305
|
-
// src/connectors/
|
|
4314
|
+
// src/connectors/hubspot-oauth/tools/request.ts
|
|
4306
4315
|
import { z as z22 } from "zod";
|
|
4316
|
+
var BASE_URL7 = "https://api.hubapi.com";
|
|
4307
4317
|
var REQUEST_TIMEOUT_MS12 = 6e4;
|
|
4318
|
+
var cachedToken10 = null;
|
|
4319
|
+
async function getProxyToken10(config) {
|
|
4320
|
+
if (cachedToken10 && cachedToken10.expiresAt > Date.now() + 6e4) {
|
|
4321
|
+
return cachedToken10.token;
|
|
4322
|
+
}
|
|
4323
|
+
const url = `${config.appApiBaseUrl}/v0/database/${config.projectId}/environment/${config.environmentId}/oauth-request-proxy-token`;
|
|
4324
|
+
const res = await fetch(url, {
|
|
4325
|
+
method: "POST",
|
|
4326
|
+
headers: {
|
|
4327
|
+
"Content-Type": "application/json",
|
|
4328
|
+
"x-api-key": config.appApiKey,
|
|
4329
|
+
"project-id": config.projectId
|
|
4330
|
+
},
|
|
4331
|
+
body: JSON.stringify({
|
|
4332
|
+
sandboxId: config.sandboxId,
|
|
4333
|
+
issuedBy: "coding-agent"
|
|
4334
|
+
})
|
|
4335
|
+
});
|
|
4336
|
+
if (!res.ok) {
|
|
4337
|
+
const errorText = await res.text().catch(() => res.statusText);
|
|
4338
|
+
throw new Error(
|
|
4339
|
+
`Failed to get proxy token: HTTP ${res.status} ${errorText}`
|
|
4340
|
+
);
|
|
4341
|
+
}
|
|
4342
|
+
const data = await res.json();
|
|
4343
|
+
cachedToken10 = {
|
|
4344
|
+
token: data.token,
|
|
4345
|
+
expiresAt: new Date(data.expiresAt).getTime()
|
|
4346
|
+
};
|
|
4347
|
+
return data.token;
|
|
4348
|
+
}
|
|
4308
4349
|
var inputSchema22 = z22.object({
|
|
4309
|
-
toolUseIntent: z22.string().optional().describe(
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
|
|
4313
|
-
|
|
4350
|
+
toolUseIntent: z22.string().optional().describe(
|
|
4351
|
+
"Brief description of what you intend to accomplish with this tool call"
|
|
4352
|
+
),
|
|
4353
|
+
connectionId: z22.string().describe("ID of the HubSpot OAuth connection to use"),
|
|
4354
|
+
method: z22.enum(["GET", "POST", "PATCH", "DELETE"]).describe("HTTP method"),
|
|
4355
|
+
path: z22.string().describe(
|
|
4356
|
+
"API path appended to https://api.hubapi.com (e.g., '/crm/v3/objects/contacts', '/crm/v3/objects/deals')"
|
|
4357
|
+
),
|
|
4358
|
+
queryParams: z22.record(z22.string(), z22.string()).optional().describe("Query parameters to append to the URL"),
|
|
4359
|
+
body: z22.record(z22.string(), z22.unknown()).optional().describe("Request body (JSON) for POST/PATCH requests")
|
|
4314
4360
|
});
|
|
4315
4361
|
var outputSchema22 = z22.discriminatedUnion("success", [
|
|
4316
4362
|
z22.object({
|
|
@@ -4325,43 +4371,49 @@ var outputSchema22 = z22.discriminatedUnion("success", [
|
|
|
4325
4371
|
]);
|
|
4326
4372
|
var requestTool6 = new ConnectorTool({
|
|
4327
4373
|
name: "request",
|
|
4328
|
-
description: `Send authenticated requests to the
|
|
4329
|
-
Authentication is handled automatically
|
|
4374
|
+
description: `Send authenticated requests to the HubSpot API.
|
|
4375
|
+
Authentication is handled automatically via OAuth proxy.`,
|
|
4330
4376
|
inputSchema: inputSchema22,
|
|
4331
4377
|
outputSchema: outputSchema22,
|
|
4332
|
-
async execute({ connectionId, method, path, body }, connections) {
|
|
4378
|
+
async execute({ connectionId, method, path, queryParams, body }, connections, config) {
|
|
4333
4379
|
const connection = connections.find((c) => c.id === connectionId);
|
|
4334
4380
|
if (!connection) {
|
|
4335
|
-
return {
|
|
4381
|
+
return {
|
|
4382
|
+
success: false,
|
|
4383
|
+
error: `Connection ${connectionId} not found`
|
|
4384
|
+
};
|
|
4336
4385
|
}
|
|
4337
|
-
console.log(
|
|
4386
|
+
console.log(
|
|
4387
|
+
`[connector-request] hubspot-oauth/${connection.name}: ${method} ${path}`
|
|
4388
|
+
);
|
|
4338
4389
|
try {
|
|
4339
|
-
|
|
4340
|
-
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4390
|
+
let url = `${BASE_URL7}${path.startsWith("/") ? "" : "/"}${path}`;
|
|
4391
|
+
if (queryParams) {
|
|
4392
|
+
const searchParams = new URLSearchParams(queryParams);
|
|
4393
|
+
url += `?${searchParams.toString()}`;
|
|
4394
|
+
}
|
|
4395
|
+
const token = await getProxyToken10(config.oauthProxy);
|
|
4396
|
+
const proxyUrl = `https://${config.oauthProxy.sandboxId}.${config.oauthProxy.previewBaseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
4344
4397
|
const controller = new AbortController();
|
|
4345
4398
|
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS12);
|
|
4346
4399
|
try {
|
|
4347
|
-
const
|
|
4348
|
-
"
|
|
4349
|
-
|
|
4350
|
-
|
|
4351
|
-
|
|
4352
|
-
|
|
4353
|
-
|
|
4354
|
-
|
|
4355
|
-
|
|
4356
|
-
|
|
4400
|
+
const response = await fetch(proxyUrl, {
|
|
4401
|
+
method: "POST",
|
|
4402
|
+
headers: {
|
|
4403
|
+
"Content-Type": "application/json",
|
|
4404
|
+
Authorization: `Bearer ${token}`
|
|
4405
|
+
},
|
|
4406
|
+
body: JSON.stringify({
|
|
4407
|
+
url,
|
|
4408
|
+
method,
|
|
4409
|
+
body: body ? JSON.stringify(body) : void 0
|
|
4410
|
+
}),
|
|
4357
4411
|
signal: controller.signal
|
|
4358
4412
|
});
|
|
4359
4413
|
const data = await response.json();
|
|
4360
4414
|
if (!response.ok) {
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
error: data?.message ?? `HTTP ${response.status} ${response.statusText}`
|
|
4364
|
-
};
|
|
4415
|
+
const errorMessage = typeof data?.error === "string" ? data.error : typeof data?.message === "string" ? data.message : `HTTP ${response.status} ${response.statusText}`;
|
|
4416
|
+
return { success: false, error: errorMessage };
|
|
4365
4417
|
}
|
|
4366
4418
|
return { success: true, status: response.status, data };
|
|
4367
4419
|
} finally {
|
|
@@ -4374,80 +4426,187 @@ Authentication is handled automatically using username and password.`,
|
|
|
4374
4426
|
}
|
|
4375
4427
|
});
|
|
4376
4428
|
|
|
4377
|
-
// src/connectors/
|
|
4378
|
-
var
|
|
4379
|
-
var
|
|
4380
|
-
|
|
4381
|
-
authType: null,
|
|
4382
|
-
name: "kintone",
|
|
4383
|
-
description: "Connect to kintone for business application data retrieval and analytics.",
|
|
4384
|
-
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/76nPGMJFZkMFE3UQNo2JFy/e71dc5f5d5cec1306ce0e17aafbfd9f0/kintone.png",
|
|
4385
|
-
parameters: parameters6,
|
|
4386
|
-
releaseFlag: { dev1: true, dev2: true, prod: true },
|
|
4387
|
-
systemPrompt: `## kintone REST API
|
|
4388
|
-
- Call the kintone REST API using the authenticated request tool
|
|
4389
|
-
- The base URL (e.g., https://example.cybozu.com) is automatically resolved
|
|
4429
|
+
// src/connectors/hubspot-oauth/setup.ts
|
|
4430
|
+
var requestToolName2 = `hubspot-oauth_${requestTool6.name}`;
|
|
4431
|
+
var hubspotSetup = new ConnectorSetup({
|
|
4432
|
+
ja: `## HubSpot \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u624B\u9806
|
|
4390
4433
|
|
|
4391
|
-
|
|
4392
|
-
- GET apps.json
|
|
4434
|
+
\u4EE5\u4E0B\u306E\u624B\u9806\u3067HubSpot\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3092\u884C\u3063\u3066\u304F\u3060\u3055\u3044\u3002
|
|
4393
4435
|
|
|
4394
|
-
###
|
|
4395
|
-
- GET app/form/fields.json?app={appId}
|
|
4436
|
+
### \u624B\u9806
|
|
4396
4437
|
|
|
4397
|
-
|
|
4398
|
-
|
|
4399
|
-
-
|
|
4438
|
+
#### \u30B9\u30C6\u30C3\u30D71: \u63A5\u7D9A\u78BA\u8A8D
|
|
4439
|
+
1. \`${requestToolName2}\` \u3092\u547C\u3073\u51FA\u3057\u3066\u3001\u30A2\u30AB\u30A6\u30F3\u30C8\u60C5\u5831\u3092\u53D6\u5F97\u3059\u308B:
|
|
4440
|
+
- \`method\`: \`"GET"\`
|
|
4441
|
+
- \`path\`: \`"/account-info/v3/details"\`
|
|
4442
|
+
2. \u30A8\u30E9\u30FC\u304C\u8FD4\u3055\u308C\u305F\u5834\u5408\u3001\u30E6\u30FC\u30B6\u30FC\u306BOAuth\u63A5\u7D9A\u306E\u8A2D\u5B9A\u3092\u78BA\u8A8D\u3059\u308B\u3088\u3046\u4F1D\u3048\u308B
|
|
4400
4443
|
|
|
4401
|
-
|
|
4402
|
-
|
|
4403
|
-
-
|
|
4444
|
+
#### \u30B9\u30C6\u30C3\u30D72: \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u5B8C\u4E86
|
|
4445
|
+
1. \`updateConnectionContext\` \u3092\u547C\u3073\u51FA\u3059:
|
|
4446
|
+
- \`account\`: HubSpot\u30A2\u30AB\u30A6\u30F3\u30C8\u540D\u307E\u305F\u306FID
|
|
4447
|
+
- \`note\`: \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u5185\u5BB9\u306E\u7C21\u5358\u306A\u8AAC\u660E
|
|
4404
4448
|
|
|
4405
|
-
###
|
|
4406
|
-
-
|
|
4407
|
-
- Operators: and, or, not
|
|
4408
|
-
- Sort: order by fieldName asc/desc
|
|
4409
|
-
- Limit: limit 100 offset 0
|
|
4410
|
-
- String: like "partial match"
|
|
4449
|
+
### \u91CD\u8981\u306A\u5236\u7D04
|
|
4450
|
+
- **\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u4E2D\u306B\u30D3\u30B8\u30CD\u30B9\u30C7\u30FC\u30BF\u3092\u8AAD\u307F\u53D6\u3089\u306A\u3044\u3053\u3068**\u3002\u5B9F\u884C\u3057\u3066\u3088\u3044\u306E\u306F\u4E0A\u8A18\u624B\u9806\u3067\u6307\u5B9A\u3055\u308C\u305F\u30E1\u30BF\u30C7\u30FC\u30BF\u53D6\u5F97\u30EA\u30AF\u30A8\u30B9\u30C8\u306E\u307F
|
|
4411
4451
|
|
|
4412
|
-
|
|
4413
|
-
|
|
4452
|
+
### \u5B9F\u884C\u65B9\u91DD
|
|
4453
|
+
- \u30C4\u30FC\u30EB\u9593\u306F1\u6587\u3060\u3051\u66F8\u3044\u3066\u5373\u6B21\u306E\u30C4\u30FC\u30EB\u547C\u3073\u51FA\u3057
|
|
4454
|
+
- \u4E0D\u8981\u306A\u8AAC\u660E\u306F\u7701\u7565\u3057\u3001\u52B9\u7387\u7684\u306B\u9032\u3081\u308B`,
|
|
4455
|
+
en: `## HubSpot Setup Instructions
|
|
4414
4456
|
|
|
4415
|
-
|
|
4416
|
-
import { connection } from "@squadbase/vite-server/connectors/kintone";
|
|
4457
|
+
Follow these steps to set up the HubSpot connection.
|
|
4417
4458
|
|
|
4418
|
-
|
|
4459
|
+
### Steps
|
|
4419
4460
|
|
|
4420
|
-
|
|
4421
|
-
|
|
4422
|
-
|
|
4461
|
+
#### Step 1: Verify Connection
|
|
4462
|
+
1. Call \`${requestToolName2}\` to fetch account info:
|
|
4463
|
+
- \`method\`: \`"GET"\`
|
|
4464
|
+
- \`path\`: \`"/account-info/v3/details"\`
|
|
4465
|
+
2. If an error is returned, ask the user to check the OAuth connection settings
|
|
4423
4466
|
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
|
|
4467
|
+
#### Step 2: Complete Setup
|
|
4468
|
+
1. Call \`updateConnectionContext\`:
|
|
4469
|
+
- \`account\`: HubSpot account name or ID
|
|
4470
|
+
- \`note\`: Brief description of the setup
|
|
4428
4471
|
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
|
|
4432
|
-
|
|
4433
|
-
|
|
4472
|
+
### Important Constraints
|
|
4473
|
+
- **Do NOT read business data during setup**. Only the metadata request specified in the steps above is allowed
|
|
4474
|
+
|
|
4475
|
+
### Execution Policy
|
|
4476
|
+
- Write only 1 sentence between tool calls, then immediately call the next tool
|
|
4477
|
+
- Skip unnecessary explanations and proceed efficiently`
|
|
4434
4478
|
});
|
|
4435
|
-
|
|
4436
|
-
|
|
4479
|
+
|
|
4480
|
+
// src/connectors/hubspot-oauth/parameters.ts
|
|
4481
|
+
var parameters28 = {};
|
|
4482
|
+
|
|
4483
|
+
// src/connectors/hubspot-oauth/index.ts
|
|
4484
|
+
var tools15 = { request: requestTool6 };
|
|
4485
|
+
var hubspotOauthConnector = new ConnectorPlugin({
|
|
4486
|
+
slug: "hubspot",
|
|
4487
|
+
authType: AUTH_TYPES.OAUTH,
|
|
4488
|
+
name: "HubSpot (OAuth)",
|
|
4489
|
+
description: "Connect to HubSpot CRM for contacts, deals, companies, and marketing data using OAuth.",
|
|
4490
|
+
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/5UcSkKkzhUMA4RsM45ynuo/43b967e36915ca0fc5d277684b204320/hubspot.svg",
|
|
4491
|
+
parameters: parameters28,
|
|
4492
|
+
releaseFlag: { dev1: true, dev2: false, prod: false },
|
|
4493
|
+
setup: hubspotSetup,
|
|
4494
|
+
proxyPolicy: {
|
|
4495
|
+
allowlist: [
|
|
4496
|
+
{
|
|
4497
|
+
host: "api.hubapi.com",
|
|
4498
|
+
methods: ["GET", "POST", "PATCH", "DELETE"]
|
|
4499
|
+
}
|
|
4500
|
+
]
|
|
4501
|
+
},
|
|
4502
|
+
systemPrompt: `## HubSpot API (OAuth)
|
|
4503
|
+
|
|
4504
|
+
### Available Endpoints
|
|
4505
|
+
- GET \`/crm/v3/objects/contacts\` \u2014 List contacts
|
|
4506
|
+
- GET \`/crm/v3/objects/contacts/{contactId}\` \u2014 Get a contact
|
|
4507
|
+
- GET \`/crm/v3/objects/deals\` \u2014 List deals
|
|
4508
|
+
- GET \`/crm/v3/objects/deals/{dealId}\` \u2014 Get a deal
|
|
4509
|
+
- GET \`/crm/v3/objects/companies\` \u2014 List companies
|
|
4510
|
+
- GET \`/crm/v3/objects/companies/{companyId}\` \u2014 Get a company
|
|
4511
|
+
- POST \`/crm/v3/objects/contacts\` \u2014 Create a contact
|
|
4512
|
+
- POST \`/crm/v3/objects/deals\` \u2014 Create a deal
|
|
4513
|
+
- PATCH \`/crm/v3/objects/contacts/{contactId}\` \u2014 Update a contact
|
|
4514
|
+
- PATCH \`/crm/v3/objects/deals/{dealId}\` \u2014 Update a deal
|
|
4515
|
+
- POST \`/crm/v3/objects/{objectType}/search\` \u2014 Search objects
|
|
4516
|
+
|
|
4517
|
+
### Query Parameters
|
|
4518
|
+
- \`limit\` \u2014 Number of results per page (max 100)
|
|
4519
|
+
- \`after\` \u2014 Pagination cursor
|
|
4520
|
+
- \`properties\` \u2014 Comma-separated list of properties to return
|
|
4521
|
+
- \`associations\` \u2014 Comma-separated list of association types to include
|
|
4522
|
+
|
|
4523
|
+
### Tips
|
|
4524
|
+
- Use the search endpoint with filters for complex queries
|
|
4525
|
+
- Properties are returned in a \`properties\` object on each record
|
|
4526
|
+
- Pagination uses cursor-based \`after\` parameter from \`paging.next.after\` in the response
|
|
4527
|
+
|
|
4528
|
+
## HubSpot SDK (TypeScript handler)
|
|
4529
|
+
|
|
4530
|
+
\`\`\`ts
|
|
4531
|
+
import { connection } from "@squadbase/vite-server/connectors/hubspot-oauth";
|
|
4532
|
+
|
|
4533
|
+
const hubspot = connection("<connectionId>");
|
|
4534
|
+
|
|
4535
|
+
// Authenticated fetch (returns standard Response)
|
|
4536
|
+
const res = await hubspot.request("/crm/v3/objects/contacts?limit=10");
|
|
4537
|
+
const data = await res.json();
|
|
4437
4538
|
\`\`\``,
|
|
4438
|
-
tools: tools15
|
|
4539
|
+
tools: tools15,
|
|
4540
|
+
async checkConnection(_params, config) {
|
|
4541
|
+
const { proxyFetch } = config;
|
|
4542
|
+
try {
|
|
4543
|
+
const res = await proxyFetch(
|
|
4544
|
+
"https://api.hubapi.com/account-info/v3/details",
|
|
4545
|
+
{ method: "GET" }
|
|
4546
|
+
);
|
|
4547
|
+
if (!res.ok) {
|
|
4548
|
+
const errorText = await res.text().catch(() => res.statusText);
|
|
4549
|
+
return {
|
|
4550
|
+
success: false,
|
|
4551
|
+
error: `HubSpot API failed: HTTP ${res.status} ${errorText}`
|
|
4552
|
+
};
|
|
4553
|
+
}
|
|
4554
|
+
return { success: true };
|
|
4555
|
+
} catch (error) {
|
|
4556
|
+
return {
|
|
4557
|
+
success: false,
|
|
4558
|
+
error: error instanceof Error ? error.message : String(error)
|
|
4559
|
+
};
|
|
4560
|
+
}
|
|
4561
|
+
}
|
|
4439
4562
|
});
|
|
4440
4563
|
|
|
4441
|
-
// src/connectors/
|
|
4564
|
+
// src/connectors/stripe-oauth/tools/request.ts
|
|
4442
4565
|
import { z as z23 } from "zod";
|
|
4443
|
-
var
|
|
4566
|
+
var BASE_URL8 = "https://api.stripe.com";
|
|
4444
4567
|
var REQUEST_TIMEOUT_MS13 = 6e4;
|
|
4568
|
+
var cachedToken11 = null;
|
|
4569
|
+
async function getProxyToken11(config) {
|
|
4570
|
+
if (cachedToken11 && cachedToken11.expiresAt > Date.now() + 6e4) {
|
|
4571
|
+
return cachedToken11.token;
|
|
4572
|
+
}
|
|
4573
|
+
const url = `${config.appApiBaseUrl}/v0/database/${config.projectId}/environment/${config.environmentId}/oauth-request-proxy-token`;
|
|
4574
|
+
const res = await fetch(url, {
|
|
4575
|
+
method: "POST",
|
|
4576
|
+
headers: {
|
|
4577
|
+
"Content-Type": "application/json",
|
|
4578
|
+
"x-api-key": config.appApiKey,
|
|
4579
|
+
"project-id": config.projectId
|
|
4580
|
+
},
|
|
4581
|
+
body: JSON.stringify({
|
|
4582
|
+
sandboxId: config.sandboxId,
|
|
4583
|
+
issuedBy: "coding-agent"
|
|
4584
|
+
})
|
|
4585
|
+
});
|
|
4586
|
+
if (!res.ok) {
|
|
4587
|
+
const errorText = await res.text().catch(() => res.statusText);
|
|
4588
|
+
throw new Error(
|
|
4589
|
+
`Failed to get proxy token: HTTP ${res.status} ${errorText}`
|
|
4590
|
+
);
|
|
4591
|
+
}
|
|
4592
|
+
const data = await res.json();
|
|
4593
|
+
cachedToken11 = {
|
|
4594
|
+
token: data.token,
|
|
4595
|
+
expiresAt: new Date(data.expiresAt).getTime()
|
|
4596
|
+
};
|
|
4597
|
+
return data.token;
|
|
4598
|
+
}
|
|
4445
4599
|
var inputSchema23 = z23.object({
|
|
4446
|
-
toolUseIntent: z23.string().optional().describe(
|
|
4447
|
-
|
|
4448
|
-
|
|
4449
|
-
|
|
4450
|
-
|
|
4600
|
+
toolUseIntent: z23.string().optional().describe(
|
|
4601
|
+
"Brief description of what you intend to accomplish with this tool call"
|
|
4602
|
+
),
|
|
4603
|
+
connectionId: z23.string().describe("ID of the Stripe OAuth connection to use"),
|
|
4604
|
+
method: z23.enum(["GET", "POST", "DELETE"]).describe("HTTP method"),
|
|
4605
|
+
path: z23.string().describe(
|
|
4606
|
+
"API path appended to https://api.stripe.com (e.g., '/v1/charges', '/v1/customers', '/v1/invoices')"
|
|
4607
|
+
),
|
|
4608
|
+
queryParams: z23.record(z23.string(), z23.string()).optional().describe("Query parameters to append to the URL"),
|
|
4609
|
+
body: z23.record(z23.string(), z23.unknown()).optional().describe("Request body (JSON) for POST requests")
|
|
4451
4610
|
});
|
|
4452
4611
|
var outputSchema23 = z23.discriminatedUnion("success", [
|
|
4453
4612
|
z23.object({
|
|
@@ -4462,40 +4621,49 @@ var outputSchema23 = z23.discriminatedUnion("success", [
|
|
|
4462
4621
|
]);
|
|
4463
4622
|
var requestTool7 = new ConnectorTool({
|
|
4464
4623
|
name: "request",
|
|
4465
|
-
description: `Send authenticated requests to the
|
|
4466
|
-
Authentication is handled automatically
|
|
4624
|
+
description: `Send authenticated requests to the Stripe API.
|
|
4625
|
+
Authentication is handled automatically via OAuth proxy.`,
|
|
4467
4626
|
inputSchema: inputSchema23,
|
|
4468
4627
|
outputSchema: outputSchema23,
|
|
4469
|
-
async execute({ connectionId, method, path, body }, connections) {
|
|
4628
|
+
async execute({ connectionId, method, path, queryParams, body }, connections, config) {
|
|
4470
4629
|
const connection = connections.find((c) => c.id === connectionId);
|
|
4471
4630
|
if (!connection) {
|
|
4472
|
-
return {
|
|
4631
|
+
return {
|
|
4632
|
+
success: false,
|
|
4633
|
+
error: `Connection ${connectionId} not found`
|
|
4634
|
+
};
|
|
4473
4635
|
}
|
|
4474
|
-
console.log(
|
|
4636
|
+
console.log(
|
|
4637
|
+
`[connector-request] stripe-oauth/${connection.name}: ${method} ${path}`
|
|
4638
|
+
);
|
|
4475
4639
|
try {
|
|
4476
|
-
|
|
4477
|
-
|
|
4478
|
-
|
|
4640
|
+
let url = `${BASE_URL8}${path.startsWith("/") ? "" : "/"}${path}`;
|
|
4641
|
+
if (queryParams) {
|
|
4642
|
+
const searchParams = new URLSearchParams(queryParams);
|
|
4643
|
+
url += `?${searchParams.toString()}`;
|
|
4644
|
+
}
|
|
4645
|
+
const token = await getProxyToken11(config.oauthProxy);
|
|
4646
|
+
const proxyUrl = `https://${config.oauthProxy.sandboxId}.${config.oauthProxy.previewBaseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
4479
4647
|
const controller = new AbortController();
|
|
4480
4648
|
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS13);
|
|
4481
4649
|
try {
|
|
4482
|
-
const response = await fetch(
|
|
4483
|
-
method,
|
|
4650
|
+
const response = await fetch(proxyUrl, {
|
|
4651
|
+
method: "POST",
|
|
4484
4652
|
headers: {
|
|
4485
|
-
|
|
4486
|
-
|
|
4487
|
-
"Content-Type": "application/json"
|
|
4653
|
+
"Content-Type": "application/json",
|
|
4654
|
+
Authorization: `Bearer ${token}`
|
|
4488
4655
|
},
|
|
4489
|
-
body:
|
|
4656
|
+
body: JSON.stringify({
|
|
4657
|
+
url,
|
|
4658
|
+
method,
|
|
4659
|
+
body: body ? JSON.stringify(body) : void 0
|
|
4660
|
+
}),
|
|
4490
4661
|
signal: controller.signal
|
|
4491
4662
|
});
|
|
4492
4663
|
const data = await response.json();
|
|
4493
4664
|
if (!response.ok) {
|
|
4494
|
-
const
|
|
4495
|
-
return {
|
|
4496
|
-
success: false,
|
|
4497
|
-
error: errorObj ?? `HTTP ${response.status} ${response.statusText}`
|
|
4498
|
-
};
|
|
4665
|
+
const errorMessage = typeof data?.error === "string" ? data.error : typeof data?.message === "string" ? data.message : `HTTP ${response.status} ${response.statusText}`;
|
|
4666
|
+
return { success: false, error: errorMessage };
|
|
4499
4667
|
}
|
|
4500
4668
|
return { success: true, status: response.status, data };
|
|
4501
4669
|
} finally {
|
|
@@ -4508,89 +4676,195 @@ Authentication is handled automatically using the API Key and Site ID.`,
|
|
|
4508
4676
|
}
|
|
4509
4677
|
});
|
|
4510
4678
|
|
|
4511
|
-
// src/connectors/
|
|
4512
|
-
var
|
|
4513
|
-
var
|
|
4514
|
-
|
|
4515
|
-
authType: null,
|
|
4516
|
-
name: "Wix Store",
|
|
4517
|
-
description: "Connect to Wix Store.",
|
|
4518
|
-
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/YyFxclQFzROIYpFam6vRK/e7e75d3feac49a1cc5e433c147216d23/Wix_logo_black.svg",
|
|
4519
|
-
parameters: parameters7,
|
|
4520
|
-
releaseFlag: { dev1: true, dev2: true, prod: true },
|
|
4521
|
-
systemPrompt: `## Wix Store API
|
|
4522
|
-
- Call the Wix Store REST API using the authenticated request tool
|
|
4523
|
-
- Authentication (API Key, Site ID) is automatically configured
|
|
4524
|
-
- Wix API uses POST for query endpoints as well
|
|
4525
|
-
- Wix uses WQL (Wix Query Language) for filters
|
|
4526
|
-
- Max 100 items per page
|
|
4679
|
+
// src/connectors/stripe-oauth/setup.ts
|
|
4680
|
+
var requestToolName3 = `stripe-oauth_${requestTool7.name}`;
|
|
4681
|
+
var stripeSetup = new ConnectorSetup({
|
|
4682
|
+
ja: `## Stripe \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u624B\u9806
|
|
4527
4683
|
|
|
4528
|
-
|
|
4529
|
-
- POST stores/v1/products/query
|
|
4530
|
-
- Body: { "query": { "paging": { "limit": 50, "offset": 0 } } }
|
|
4684
|
+
\u4EE5\u4E0B\u306E\u624B\u9806\u3067Stripe\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3092\u884C\u3063\u3066\u304F\u3060\u3055\u3044\u3002
|
|
4531
4685
|
|
|
4532
|
-
###
|
|
4533
|
-
- POST stores/v1/products/query
|
|
4534
|
-
- Body: { "query": { "filter": { "name": { "$contains": "keyword" } }, "paging": { "limit": 50 } } }
|
|
4686
|
+
### \u624B\u9806
|
|
4535
4687
|
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
-
|
|
4539
|
-
-
|
|
4540
|
-
|
|
4688
|
+
#### \u30B9\u30C6\u30C3\u30D71: \u63A5\u7D9A\u78BA\u8A8D
|
|
4689
|
+
1. \`${requestToolName3}\` \u3092\u547C\u3073\u51FA\u3057\u3066\u3001\u30A2\u30AB\u30A6\u30F3\u30C8\u60C5\u5831\u3092\u53D6\u5F97\u3059\u308B:
|
|
4690
|
+
- \`method\`: \`"GET"\`
|
|
4691
|
+
- \`path\`: \`"/v1/accounts"\`
|
|
4692
|
+
2. \u30A8\u30E9\u30FC\u304C\u8FD4\u3055\u308C\u305F\u5834\u5408\u3001\u30E6\u30FC\u30B6\u30FC\u306BOAuth\u63A5\u7D9A\u306E\u8A2D\u5B9A\u3092\u78BA\u8A8D\u3059\u308B\u3088\u3046\u4F1D\u3048\u308B
|
|
4541
4693
|
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
-
|
|
4694
|
+
#### \u30B9\u30C6\u30C3\u30D72: \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u5B8C\u4E86
|
|
4695
|
+
1. \`updateConnectionContext\` \u3092\u547C\u3073\u51FA\u3059:
|
|
4696
|
+
- \`account\`: Stripe\u30A2\u30AB\u30A6\u30F3\u30C8\u60C5\u5831
|
|
4697
|
+
- \`note\`: \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u5185\u5BB9\u306E\u7C21\u5358\u306A\u8AAC\u660E
|
|
4545
4698
|
|
|
4546
|
-
###
|
|
4547
|
-
-
|
|
4548
|
-
- Body: { "query": { "paging": { "limit": 50 } } }
|
|
4699
|
+
### \u91CD\u8981\u306A\u5236\u7D04
|
|
4700
|
+
- **\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u4E2D\u306B\u6C7A\u6E08\u30C7\u30FC\u30BF\u3092\u8AAD\u307F\u53D6\u3089\u306A\u3044\u3053\u3068**\u3002\u5B9F\u884C\u3057\u3066\u3088\u3044\u306E\u306F\u4E0A\u8A18\u624B\u9806\u3067\u6307\u5B9A\u3055\u308C\u305F\u30E1\u30BF\u30C7\u30FC\u30BF\u53D6\u5F97\u30EA\u30AF\u30A8\u30B9\u30C8\u306E\u307F
|
|
4549
4701
|
|
|
4550
|
-
|
|
4551
|
-
|
|
4702
|
+
### \u5B9F\u884C\u65B9\u91DD
|
|
4703
|
+
- \u30C4\u30FC\u30EB\u9593\u306F1\u6587\u3060\u3051\u66F8\u3044\u3066\u5373\u6B21\u306E\u30C4\u30FC\u30EB\u547C\u3073\u51FA\u3057
|
|
4704
|
+
- \u4E0D\u8981\u306A\u8AAC\u660E\u306F\u7701\u7565\u3057\u3001\u52B9\u7387\u7684\u306B\u9032\u3081\u308B`,
|
|
4705
|
+
en: `## Stripe Setup Instructions
|
|
4706
|
+
|
|
4707
|
+
Follow these steps to set up the Stripe connection.
|
|
4708
|
+
|
|
4709
|
+
### Steps
|
|
4710
|
+
|
|
4711
|
+
#### Step 1: Verify Connection
|
|
4712
|
+
1. Call \`${requestToolName3}\` to fetch account info:
|
|
4713
|
+
- \`method\`: \`"GET"\`
|
|
4714
|
+
- \`path\`: \`"/v1/accounts"\`
|
|
4715
|
+
2. If an error is returned, ask the user to check the OAuth connection settings
|
|
4716
|
+
|
|
4717
|
+
#### Step 2: Complete Setup
|
|
4718
|
+
1. Call \`updateConnectionContext\`:
|
|
4719
|
+
- \`account\`: Stripe account info
|
|
4720
|
+
- \`note\`: Brief description of the setup
|
|
4721
|
+
|
|
4722
|
+
### Important Constraints
|
|
4723
|
+
- **Do NOT read payment data during setup**. Only the metadata request specified in the steps above is allowed
|
|
4724
|
+
|
|
4725
|
+
### Execution Policy
|
|
4726
|
+
- Write only 1 sentence between tool calls, then immediately call the next tool
|
|
4727
|
+
- Skip unnecessary explanations and proceed efficiently`
|
|
4728
|
+
});
|
|
4729
|
+
|
|
4730
|
+
// src/connectors/stripe-oauth/parameters.ts
|
|
4731
|
+
var parameters29 = {};
|
|
4732
|
+
|
|
4733
|
+
// src/connectors/stripe-oauth/index.ts
|
|
4734
|
+
var tools16 = { request: requestTool7 };
|
|
4735
|
+
var stripeOauthConnector = new ConnectorPlugin({
|
|
4736
|
+
slug: "stripe",
|
|
4737
|
+
authType: AUTH_TYPES.OAUTH,
|
|
4738
|
+
name: "Stripe (OAuth)",
|
|
4739
|
+
description: "Connect to Stripe for payment, customer, and subscription data using OAuth.",
|
|
4740
|
+
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/2QNK0u2doqp41uL0POS4Ks/7a92367e2388ec77c7f4ada143606f9a/stripe.jpeg",
|
|
4741
|
+
parameters: parameters29,
|
|
4742
|
+
releaseFlag: { dev1: true, dev2: false, prod: false },
|
|
4743
|
+
setup: stripeSetup,
|
|
4744
|
+
proxyPolicy: {
|
|
4745
|
+
allowlist: [
|
|
4746
|
+
{
|
|
4747
|
+
host: "api.stripe.com",
|
|
4748
|
+
methods: ["GET", "POST", "DELETE"]
|
|
4749
|
+
}
|
|
4750
|
+
]
|
|
4751
|
+
},
|
|
4752
|
+
systemPrompt: `## Stripe API (OAuth)
|
|
4753
|
+
|
|
4754
|
+
### Available Endpoints
|
|
4755
|
+
- GET \`/v1/charges\` \u2014 List charges
|
|
4756
|
+
- GET \`/v1/charges/{chargeId}\` \u2014 Get a charge
|
|
4757
|
+
- GET \`/v1/customers\` \u2014 List customers
|
|
4758
|
+
- GET \`/v1/customers/{customerId}\` \u2014 Get a customer
|
|
4759
|
+
- GET \`/v1/invoices\` \u2014 List invoices
|
|
4760
|
+
- GET \`/v1/invoices/{invoiceId}\` \u2014 Get an invoice
|
|
4761
|
+
- GET \`/v1/subscriptions\` \u2014 List subscriptions
|
|
4762
|
+
- GET \`/v1/subscriptions/{subscriptionId}\` \u2014 Get a subscription
|
|
4763
|
+
- GET \`/v1/products\` \u2014 List products
|
|
4764
|
+
- GET \`/v1/prices\` \u2014 List prices
|
|
4765
|
+
- GET \`/v1/payment_intents\` \u2014 List payment intents
|
|
4766
|
+
- GET \`/v1/balance\` \u2014 Get account balance
|
|
4767
|
+
- GET \`/v1/balance_transactions\` \u2014 List balance transactions
|
|
4768
|
+
|
|
4769
|
+
### Query Parameters
|
|
4770
|
+
- \`limit\` \u2014 Number of results per page (max 100, default 10)
|
|
4771
|
+
- \`starting_after\` \u2014 Pagination cursor (object ID)
|
|
4772
|
+
- \`ending_before\` \u2014 Reverse pagination cursor
|
|
4773
|
+
- \`created[gte]\`, \`created[lte]\` \u2014 Filter by creation date (Unix timestamp)
|
|
4774
|
+
- \`status\` \u2014 Filter by status (varies by resource)
|
|
4775
|
+
|
|
4776
|
+
### Tips
|
|
4777
|
+
- Stripe uses cursor-based pagination with \`starting_after\` and \`has_more\`
|
|
4778
|
+
- All timestamps are Unix timestamps in seconds
|
|
4779
|
+
- Use \`expand[]\` query parameter to include related objects inline
|
|
4780
|
+
- List responses have \`data\` array and \`has_more\` boolean
|
|
4781
|
+
|
|
4782
|
+
## Stripe SDK (TypeScript handler)
|
|
4552
4783
|
|
|
4553
4784
|
\`\`\`ts
|
|
4554
|
-
import { connection } from "@squadbase/vite-server/connectors/
|
|
4785
|
+
import { connection } from "@squadbase/vite-server/connectors/stripe-oauth";
|
|
4555
4786
|
|
|
4556
|
-
const
|
|
4787
|
+
const stripe = connection("<connectionId>");
|
|
4557
4788
|
|
|
4558
4789
|
// Authenticated fetch (returns standard Response)
|
|
4559
|
-
const res = await
|
|
4560
|
-
method: "POST",
|
|
4561
|
-
headers: { "Content-Type": "application/json" },
|
|
4562
|
-
body: JSON.stringify({ query: { paging: { limit: 10 } } }),
|
|
4563
|
-
});
|
|
4790
|
+
const res = await stripe.request("/v1/customers?limit=10");
|
|
4564
4791
|
const data = await res.json();
|
|
4565
|
-
|
|
4566
|
-
// Convenience methods
|
|
4567
|
-
const { products, totalResults } = await wix.queryProducts({ paging: { limit: 50 } });
|
|
4568
|
-
const { product } = await wix.getProduct("product-id");
|
|
4569
|
-
const { orders, pagingMetadata } = await wix.queryOrders({ cursorPaging: { limit: 50 } });
|
|
4570
|
-
const { order } = await wix.getOrder("order-id");
|
|
4571
|
-
const { inventoryItems } = await wix.queryInventory({ paging: { limit: 50 } });
|
|
4572
|
-
const { collections } = await wix.queryCollections({ paging: { limit: 50 } });
|
|
4573
4792
|
\`\`\``,
|
|
4574
|
-
tools: tools16
|
|
4793
|
+
tools: tools16,
|
|
4794
|
+
async checkConnection(_params, config) {
|
|
4795
|
+
const { proxyFetch } = config;
|
|
4796
|
+
try {
|
|
4797
|
+
const res = await proxyFetch("https://api.stripe.com/v1/balance", {
|
|
4798
|
+
method: "GET"
|
|
4799
|
+
});
|
|
4800
|
+
if (!res.ok) {
|
|
4801
|
+
const errorText = await res.text().catch(() => res.statusText);
|
|
4802
|
+
return {
|
|
4803
|
+
success: false,
|
|
4804
|
+
error: `Stripe API failed: HTTP ${res.status} ${errorText}`
|
|
4805
|
+
};
|
|
4806
|
+
}
|
|
4807
|
+
return { success: true };
|
|
4808
|
+
} catch (error) {
|
|
4809
|
+
return {
|
|
4810
|
+
success: false,
|
|
4811
|
+
error: error instanceof Error ? error.message : String(error)
|
|
4812
|
+
};
|
|
4813
|
+
}
|
|
4814
|
+
}
|
|
4575
4815
|
});
|
|
4576
4816
|
|
|
4577
|
-
// src/connectors/
|
|
4817
|
+
// src/connectors/airtable-oauth/tools/request.ts
|
|
4578
4818
|
import { z as z24 } from "zod";
|
|
4819
|
+
var BASE_URL9 = "https://api.airtable.com/v0";
|
|
4579
4820
|
var REQUEST_TIMEOUT_MS14 = 6e4;
|
|
4580
|
-
|
|
4581
|
-
|
|
4582
|
-
if (
|
|
4583
|
-
|
|
4821
|
+
var cachedToken12 = null;
|
|
4822
|
+
async function getProxyToken12(config) {
|
|
4823
|
+
if (cachedToken12 && cachedToken12.expiresAt > Date.now() + 6e4) {
|
|
4824
|
+
return cachedToken12.token;
|
|
4825
|
+
}
|
|
4826
|
+
const url = `${config.appApiBaseUrl}/v0/database/${config.projectId}/environment/${config.environmentId}/oauth-request-proxy-token`;
|
|
4827
|
+
const res = await fetch(url, {
|
|
4828
|
+
method: "POST",
|
|
4829
|
+
headers: {
|
|
4830
|
+
"Content-Type": "application/json",
|
|
4831
|
+
"x-api-key": config.appApiKey,
|
|
4832
|
+
"project-id": config.projectId
|
|
4833
|
+
},
|
|
4834
|
+
body: JSON.stringify({
|
|
4835
|
+
sandboxId: config.sandboxId,
|
|
4836
|
+
issuedBy: "coding-agent"
|
|
4837
|
+
})
|
|
4838
|
+
});
|
|
4839
|
+
if (!res.ok) {
|
|
4840
|
+
const errorText = await res.text().catch(() => res.statusText);
|
|
4841
|
+
throw new Error(
|
|
4842
|
+
`Failed to get proxy token: HTTP ${res.status} ${errorText}`
|
|
4843
|
+
);
|
|
4844
|
+
}
|
|
4845
|
+
const data = await res.json();
|
|
4846
|
+
cachedToken12 = {
|
|
4847
|
+
token: data.token,
|
|
4848
|
+
expiresAt: new Date(data.expiresAt).getTime()
|
|
4849
|
+
};
|
|
4850
|
+
return data.token;
|
|
4584
4851
|
}
|
|
4585
4852
|
var inputSchema24 = z24.object({
|
|
4586
|
-
toolUseIntent: z24.string().optional().describe(
|
|
4587
|
-
|
|
4588
|
-
|
|
4589
|
-
|
|
4853
|
+
toolUseIntent: z24.string().optional().describe(
|
|
4854
|
+
"Brief description of what you intend to accomplish with this tool call"
|
|
4855
|
+
),
|
|
4856
|
+
connectionId: z24.string().describe("ID of the Airtable OAuth connection to use"),
|
|
4857
|
+
method: z24.enum(["GET", "POST", "PATCH", "DELETE"]).describe("HTTP method"),
|
|
4858
|
+
path: z24.string().describe(
|
|
4859
|
+
"API path appended to https://api.airtable.com/v0 (e.g., '/{baseId}/{tableIdOrName}', '/meta/bases/{baseId}/tables'). {baseId} is automatically replaced if a default is configured."
|
|
4860
|
+
),
|
|
4861
|
+
queryParams: z24.record(z24.string(), z24.string()).optional().describe("Query parameters to append to the URL"),
|
|
4862
|
+
body: z24.record(z24.string(), z24.unknown()).optional().describe("Request body (JSON) for POST/PATCH requests")
|
|
4590
4863
|
});
|
|
4591
4864
|
var outputSchema24 = z24.discriminatedUnion("success", [
|
|
4592
4865
|
z24.object({
|
|
4593
4866
|
success: z24.literal(true),
|
|
4867
|
+
status: z24.number(),
|
|
4594
4868
|
data: z24.record(z24.string(), z24.unknown())
|
|
4595
4869
|
}),
|
|
4596
4870
|
z24.object({
|
|
@@ -4600,52 +4874,54 @@ var outputSchema24 = z24.discriminatedUnion("success", [
|
|
|
4600
4874
|
]);
|
|
4601
4875
|
var requestTool8 = new ConnectorTool({
|
|
4602
4876
|
name: "request",
|
|
4603
|
-
description: `Send authenticated requests to the
|
|
4604
|
-
Authentication is handled automatically
|
|
4605
|
-
{
|
|
4877
|
+
description: `Send authenticated requests to the Airtable API.
|
|
4878
|
+
Authentication is handled automatically via OAuth proxy.
|
|
4879
|
+
{baseId} in the path is automatically replaced with the connection's default base ID if configured.`,
|
|
4606
4880
|
inputSchema: inputSchema24,
|
|
4607
4881
|
outputSchema: outputSchema24,
|
|
4608
|
-
async execute({ connectionId,
|
|
4882
|
+
async execute({ connectionId, method, path, queryParams, body }, connections, config) {
|
|
4609
4883
|
const connection = connections.find((c) => c.id === connectionId);
|
|
4610
4884
|
if (!connection) {
|
|
4611
|
-
return {
|
|
4885
|
+
return {
|
|
4886
|
+
success: false,
|
|
4887
|
+
error: `Connection ${connectionId} not found`
|
|
4888
|
+
};
|
|
4612
4889
|
}
|
|
4613
|
-
console.log(
|
|
4890
|
+
console.log(
|
|
4891
|
+
`[connector-request] airtable-oauth/${connection.name}: ${method} ${path}`
|
|
4892
|
+
);
|
|
4614
4893
|
try {
|
|
4615
|
-
const
|
|
4616
|
-
const
|
|
4617
|
-
|
|
4618
|
-
|
|
4619
|
-
|
|
4620
|
-
|
|
4621
|
-
|
|
4894
|
+
const baseId = parameters6.baseId.tryGetValue(connection);
|
|
4895
|
+
const resolvedPath = baseId ? path.replace(/\{baseId\}/g, baseId) : path;
|
|
4896
|
+
let url = `${BASE_URL9}${resolvedPath.startsWith("/") ? "" : "/"}${resolvedPath}`;
|
|
4897
|
+
if (queryParams) {
|
|
4898
|
+
const searchParams = new URLSearchParams(queryParams);
|
|
4899
|
+
url += `?${searchParams.toString()}`;
|
|
4900
|
+
}
|
|
4901
|
+
const token = await getProxyToken12(config.oauthProxy);
|
|
4902
|
+
const proxyUrl = `https://${config.oauthProxy.sandboxId}.${config.oauthProxy.previewBaseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
4622
4903
|
const controller = new AbortController();
|
|
4623
4904
|
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS14);
|
|
4624
4905
|
try {
|
|
4625
|
-
const response = await fetch(
|
|
4906
|
+
const response = await fetch(proxyUrl, {
|
|
4626
4907
|
method: "POST",
|
|
4627
4908
|
headers: {
|
|
4628
|
-
|
|
4629
|
-
|
|
4909
|
+
"Content-Type": "application/json",
|
|
4910
|
+
Authorization: `Bearer ${token}`
|
|
4630
4911
|
},
|
|
4631
|
-
body: JSON.stringify({
|
|
4912
|
+
body: JSON.stringify({
|
|
4913
|
+
url,
|
|
4914
|
+
method,
|
|
4915
|
+
body: body ? JSON.stringify(body) : void 0
|
|
4916
|
+
}),
|
|
4632
4917
|
signal: controller.signal
|
|
4633
4918
|
});
|
|
4634
4919
|
const data = await response.json();
|
|
4635
4920
|
if (!response.ok) {
|
|
4636
|
-
|
|
4637
|
-
|
|
4638
|
-
error: data?.message ?? `HTTP ${response.status} ${response.statusText}`
|
|
4639
|
-
};
|
|
4640
|
-
}
|
|
4641
|
-
if (Array.isArray(data?.errors) && data.errors.length > 0) {
|
|
4642
|
-
const errors = data.errors;
|
|
4643
|
-
return {
|
|
4644
|
-
success: false,
|
|
4645
|
-
error: errors.map((e) => e.message).join("; ")
|
|
4646
|
-
};
|
|
4921
|
+
const errorMessage = typeof data?.error === "string" ? data.error : typeof data?.message === "string" ? data.message : `HTTP ${response.status} ${response.statusText}`;
|
|
4922
|
+
return { success: false, error: errorMessage };
|
|
4647
4923
|
}
|
|
4648
|
-
return { success: true, data };
|
|
4924
|
+
return { success: true, status: response.status, data };
|
|
4649
4925
|
} finally {
|
|
4650
4926
|
clearTimeout(timeout);
|
|
4651
4927
|
}
|
|
@@ -4656,264 +4932,1704 @@ Authentication is handled automatically using the API token.
|
|
|
4656
4932
|
}
|
|
4657
4933
|
});
|
|
4658
4934
|
|
|
4659
|
-
// src/connectors/
|
|
4660
|
-
var
|
|
4661
|
-
var
|
|
4662
|
-
|
|
4663
|
-
authType: null,
|
|
4664
|
-
name: "dbt",
|
|
4665
|
-
description: "Connect to dbt Cloud for data transformation and analytics engineering.",
|
|
4666
|
-
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/4iT6ncXtdtHdkXexU0WgfZ/0367a38d245f2568eab5eb511f9ee692/dbt.png",
|
|
4667
|
-
parameters: parameters8,
|
|
4668
|
-
releaseFlag: { dev1: true, dev2: true, prod: true },
|
|
4669
|
-
systemPrompt: `## dbt Cloud Discovery API (GraphQL)
|
|
4670
|
-
- Call the dbt Cloud Discovery API using the authenticated request tool
|
|
4671
|
-
- {environmentId} in GraphQL variables is automatically replaced with the prod-env-id
|
|
4935
|
+
// src/connectors/airtable-oauth/setup.ts
|
|
4936
|
+
var requestToolName4 = `airtable-oauth_${requestTool8.name}`;
|
|
4937
|
+
var airtableOauthSetup = new ConnectorSetup({
|
|
4938
|
+
ja: `## Airtable (OAuth) \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u624B\u9806
|
|
4672
4939
|
|
|
4673
|
-
|
|
4674
|
-
query:
|
|
4675
|
-
query($environmentId: BigInt!) {
|
|
4676
|
-
environment(id: $environmentId) {
|
|
4677
|
-
applied {
|
|
4678
|
-
models(first: 100) {
|
|
4679
|
-
edges {
|
|
4680
|
-
node { uniqueId name description database schema alias materializedType }
|
|
4681
|
-
}
|
|
4682
|
-
}
|
|
4683
|
-
}
|
|
4684
|
-
}
|
|
4685
|
-
}
|
|
4686
|
-
variables: { "environmentId": "{environmentId}" }
|
|
4940
|
+
\u4EE5\u4E0B\u306E\u624B\u9806\u3067Airtable OAuth\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3092\u884C\u3063\u3066\u304F\u3060\u3055\u3044\u3002
|
|
4687
4941
|
|
|
4688
|
-
###
|
|
4689
|
-
query:
|
|
4690
|
-
query($environmentId: BigInt!) {
|
|
4691
|
-
environment(id: $environmentId) {
|
|
4692
|
-
applied {
|
|
4693
|
-
sources(first: 100) {
|
|
4694
|
-
edges {
|
|
4695
|
-
node { uniqueId name description database schema identifier }
|
|
4696
|
-
}
|
|
4697
|
-
}
|
|
4698
|
-
}
|
|
4699
|
-
}
|
|
4700
|
-
}
|
|
4701
|
-
variables: { "environmentId": "{environmentId}" }
|
|
4942
|
+
### \u624B\u9806
|
|
4702
4943
|
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
|
|
4707
|
-
|
|
4708
|
-
|
|
4709
|
-
edges {
|
|
4710
|
-
node { uniqueId name columns { name description type } }
|
|
4711
|
-
}
|
|
4712
|
-
}
|
|
4713
|
-
}
|
|
4714
|
-
}
|
|
4715
|
-
}
|
|
4944
|
+
#### \u30B9\u30C6\u30C3\u30D71: \u30D9\u30FC\u30B9\u9078\u629E
|
|
4945
|
+
1. \u30E6\u30FC\u30B6\u30FC\u306B\u300C\u4F7F\u7528\u3059\u308BAirtable\u306E\u30D9\u30FC\u30B9URL\u3092\u8CBC\u308A\u4ED8\u3051\u3066\u304F\u3060\u3055\u3044\uFF08\u4F8B: https://airtable.com/appXXXXXXXXXXXXXX/...\uFF09\u300D\u3068\u4F1D\u3048\u308B
|
|
4946
|
+
2. \u30E6\u30FC\u30B6\u30FC\u304CURL\u307E\u305F\u306F\u30D9\u30FC\u30B9ID\u3092\u63D0\u4F9B\u3057\u305F\u3089\u3001URL\u304B\u3089ID\u3092\u62BD\u51FA\u3059\u308B\uFF08\`airtable.com/\` \u76F4\u5F8C\u306E \`app\` \u3067\u59CB\u307E\u308B\u6587\u5B57\u5217\uFF09
|
|
4947
|
+
3. \`updateConnectionParameters\` \u3092\u547C\u3073\u51FA\u3059:
|
|
4948
|
+
- \`parameterSlug\`: \`"base-id"\`
|
|
4949
|
+
- \`value\`: \u62BD\u51FA\u3057\u305F\u30D9\u30FC\u30B9ID
|
|
4716
4950
|
|
|
4717
|
-
|
|
4718
|
-
|
|
4719
|
-
-
|
|
4951
|
+
#### \u30B9\u30C6\u30C3\u30D72: \u30D9\u30FC\u30B9\u691C\u8A3C
|
|
4952
|
+
1. \`${requestToolName4}\` \u3092\u547C\u3073\u51FA\u3057\u3066\u3001\u30D9\u30FC\u30B9\u306E\u30C6\u30FC\u30D6\u30EB\u4E00\u89A7\u3092\u53D6\u5F97\u3059\u308B:
|
|
4953
|
+
- \`method\`: \`"GET"\`
|
|
4954
|
+
- \`path\`: \`"/meta/bases/{baseId}/tables"\`
|
|
4955
|
+
2. \u30A8\u30E9\u30FC\u304C\u8FD4\u3055\u308C\u305F\u5834\u5408\u3001\u30E6\u30FC\u30B6\u30FC\u306B\u30D9\u30FC\u30B9\u306E\u5171\u6709\u8A2D\u5B9A\u3092\u78BA\u8A8D\u3059\u308B\u3088\u3046\u4F1D\u3048\u308B
|
|
4720
4956
|
|
|
4721
|
-
|
|
4722
|
-
|
|
4957
|
+
#### \u30B9\u30C6\u30C3\u30D73: \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u5B8C\u4E86
|
|
4958
|
+
1. \`updateConnectionContext\` \u3092\u547C\u3073\u51FA\u3059:
|
|
4959
|
+
- \`base\`: \u30D9\u30FC\u30B9ID
|
|
4960
|
+
- \`tables\`: \u30C6\u30FC\u30D6\u30EB\u540D\u4E00\u89A7\uFF08\u30AB\u30F3\u30DE\u533A\u5207\u308A\uFF09
|
|
4961
|
+
- \`note\`: \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u5185\u5BB9\u306E\u7C21\u5358\u306A\u8AAC\u660E
|
|
4723
4962
|
|
|
4724
|
-
|
|
4725
|
-
|
|
4963
|
+
### \u91CD\u8981\u306A\u5236\u7D04
|
|
4964
|
+
- **\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u4E2D\u306B\u30C6\u30FC\u30D6\u30EB\u306E\u30EC\u30B3\u30FC\u30C9\u30C7\u30FC\u30BF\u3092\u8AAD\u307F\u53D6\u3089\u306A\u3044\u3053\u3068**\u3002\u5B9F\u884C\u3057\u3066\u3088\u3044\u306E\u306F\u4E0A\u8A18\u624B\u9806\u3067\u6307\u5B9A\u3055\u308C\u305F\u30E1\u30BF\u30C7\u30FC\u30BF\u53D6\u5F97\u30EA\u30AF\u30A8\u30B9\u30C8\u306E\u307F
|
|
4726
4965
|
|
|
4727
|
-
|
|
4966
|
+
### \u5B9F\u884C\u65B9\u91DD
|
|
4967
|
+
- \u30C4\u30FC\u30EB\u9593\u306F1\u6587\u3060\u3051\u66F8\u3044\u3066\u5373\u6B21\u306E\u30C4\u30FC\u30EB\u547C\u3073\u51FA\u3057
|
|
4968
|
+
- \u4E0D\u8981\u306A\u8AAC\u660E\u306F\u7701\u7565\u3057\u3001\u52B9\u7387\u7684\u306B\u9032\u3081\u308B`,
|
|
4969
|
+
en: `## Airtable (OAuth) Setup Instructions
|
|
4728
4970
|
|
|
4729
|
-
|
|
4730
|
-
|
|
4731
|
-
|
|
4732
|
-
|
|
4733
|
-
|
|
4971
|
+
Follow these steps to set up the Airtable OAuth connection.
|
|
4972
|
+
|
|
4973
|
+
### Steps
|
|
4974
|
+
|
|
4975
|
+
#### Step 1: Base Selection
|
|
4976
|
+
1. Ask the user to paste the Airtable base URL (e.g., https://airtable.com/appXXXXXXXXXXXXXX/...)
|
|
4977
|
+
2. When the user provides a URL or base ID, extract the ID from the URL (the string starting with \`app\` after \`airtable.com/\`)
|
|
4978
|
+
3. Call \`updateConnectionParameters\`:
|
|
4979
|
+
- \`parameterSlug\`: \`"base-id"\`
|
|
4980
|
+
- \`value\`: The extracted base ID
|
|
4981
|
+
|
|
4982
|
+
#### Step 2: Base Validation
|
|
4983
|
+
1. Call \`${requestToolName4}\` to fetch the base's table list:
|
|
4984
|
+
- \`method\`: \`"GET"\`
|
|
4985
|
+
- \`path\`: \`"/meta/bases/{baseId}/tables"\`
|
|
4986
|
+
2. If an error is returned, ask the user to check the base sharing settings
|
|
4987
|
+
|
|
4988
|
+
#### Step 3: Complete Setup
|
|
4989
|
+
1. Call \`updateConnectionContext\`:
|
|
4990
|
+
- \`base\`: The base ID
|
|
4991
|
+
- \`tables\`: Table names (comma-separated)
|
|
4992
|
+
- \`note\`: Brief description of the setup
|
|
4993
|
+
|
|
4994
|
+
### Important Constraints
|
|
4995
|
+
- **Do NOT read table record data during setup**. Only the metadata request specified in the steps above is allowed
|
|
4996
|
+
|
|
4997
|
+
### Execution Policy
|
|
4998
|
+
- Write only 1 sentence between tool calls, then immediately call the next tool
|
|
4999
|
+
- Skip unnecessary explanations and proceed efficiently`
|
|
4734
5000
|
});
|
|
5001
|
+
|
|
5002
|
+
// src/connectors/airtable-oauth/index.ts
|
|
5003
|
+
var tools17 = { request: requestTool8 };
|
|
5004
|
+
var airtableOauthConnector = new ConnectorPlugin({
|
|
5005
|
+
slug: "airtable",
|
|
5006
|
+
authType: AUTH_TYPES.OAUTH,
|
|
5007
|
+
name: "Airtable (OAuth)",
|
|
5008
|
+
description: "Connect to Airtable for spreadsheet-database hybrid data management using OAuth.",
|
|
5009
|
+
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/19JUphfOZjyjTK6Zg4NGCf/8c56227b088cada52d3a2d9385a3be97/airtable.svg",
|
|
5010
|
+
parameters: parameters6,
|
|
5011
|
+
releaseFlag: { dev1: true, dev2: false, prod: false },
|
|
5012
|
+
setup: airtableOauthSetup,
|
|
5013
|
+
proxyPolicy: {
|
|
5014
|
+
allowlist: [
|
|
5015
|
+
{
|
|
5016
|
+
host: "api.airtable.com",
|
|
5017
|
+
methods: ["GET", "POST", "PATCH", "DELETE"]
|
|
5018
|
+
}
|
|
5019
|
+
]
|
|
5020
|
+
},
|
|
5021
|
+
systemPrompt: `## Airtable API (OAuth)
|
|
5022
|
+
|
|
5023
|
+
### Available Endpoints
|
|
5024
|
+
- GET \`/meta/bases/{baseId}/tables\` \u2014 List tables in a base
|
|
5025
|
+
- GET \`/{baseId}/{tableIdOrName}\` \u2014 List records in a table
|
|
5026
|
+
- GET \`/{baseId}/{tableIdOrName}/{recordId}\` \u2014 Get a single record
|
|
5027
|
+
- POST \`/{baseId}/{tableIdOrName}\` \u2014 Create records
|
|
5028
|
+
- PATCH \`/{baseId}/{tableIdOrName}\` \u2014 Update records
|
|
5029
|
+
- DELETE \`/{baseId}/{tableIdOrName}?records[]={recordId}\` \u2014 Delete records
|
|
5030
|
+
|
|
5031
|
+
### Query Parameters (List Records)
|
|
5032
|
+
- \`maxRecords\` \u2014 Max number of records to return
|
|
5033
|
+
- \`pageSize\` \u2014 Number of records per page (max 100)
|
|
5034
|
+
- \`offset\` \u2014 Pagination cursor from previous response
|
|
5035
|
+
- \`filterByFormula\` \u2014 Airtable formula to filter records
|
|
5036
|
+
- \`sort[0][field]\`, \`sort[0][direction]\` \u2014 Sort by field (asc/desc)
|
|
5037
|
+
- \`fields[]\` \u2014 Select specific fields to return
|
|
5038
|
+
- \`view\` \u2014 Filter by a specific view
|
|
5039
|
+
|
|
5040
|
+
### Tips
|
|
5041
|
+
- {baseId} in the path is automatically replaced with the configured default base ID
|
|
5042
|
+
- Pagination: if the response contains an \`offset\`, append \`?offset={offset}\` to the next request
|
|
5043
|
+
- Create/Update body format: \`{ "records": [{ "fields": { "Name": "value" } }] }\`
|
|
5044
|
+
- Update uses PATCH for partial updates
|
|
5045
|
+
|
|
5046
|
+
## Airtable SDK (TypeScript handler)
|
|
5047
|
+
|
|
5048
|
+
\`\`\`ts
|
|
5049
|
+
import { connection } from "@squadbase/vite-server/connectors/airtable-oauth";
|
|
5050
|
+
|
|
5051
|
+
const airtable = connection("<connectionId>");
|
|
5052
|
+
|
|
5053
|
+
// Authenticated fetch (returns standard Response)
|
|
5054
|
+
const res = await airtable.request("/meta/bases/{baseId}/tables");
|
|
4735
5055
|
const data = await res.json();
|
|
4736
5056
|
|
|
4737
|
-
//
|
|
4738
|
-
const
|
|
4739
|
-
|
|
4740
|
-
environment(id: $environmentId) { applied { models(first: 10) { edges { node { name } } } } }
|
|
4741
|
-
}
|
|
4742
|
-
\`);
|
|
4743
|
-
const models = await dbt.getModels({ limit: 100 });
|
|
4744
|
-
const model = await dbt.getModelByUniqueId("model.project.my_model");
|
|
4745
|
-
const sources = await dbt.getSources({ limit: 100 });
|
|
4746
|
-
const tests = await dbt.getTests({ limit: 100 });
|
|
4747
|
-
const metrics = await dbt.getMetrics({ limit: 100 });
|
|
5057
|
+
// List records
|
|
5058
|
+
const records = await airtable.request("/{baseId}/Tasks?maxRecords=100");
|
|
5059
|
+
const recordsData = await records.json();
|
|
4748
5060
|
\`\`\``,
|
|
4749
|
-
tools: tools17
|
|
5061
|
+
tools: tools17,
|
|
5062
|
+
async checkConnection(params, config) {
|
|
5063
|
+
const { proxyFetch } = config;
|
|
5064
|
+
const baseId = params[parameters6.baseId.slug];
|
|
5065
|
+
if (!baseId) {
|
|
5066
|
+
return { success: true };
|
|
5067
|
+
}
|
|
5068
|
+
try {
|
|
5069
|
+
const res = await proxyFetch(
|
|
5070
|
+
`https://api.airtable.com/v0/meta/bases/${baseId}/tables`,
|
|
5071
|
+
{ method: "GET" }
|
|
5072
|
+
);
|
|
5073
|
+
if (!res.ok) {
|
|
5074
|
+
const errorText = await res.text().catch(() => res.statusText);
|
|
5075
|
+
return {
|
|
5076
|
+
success: false,
|
|
5077
|
+
error: `Airtable API failed: HTTP ${res.status} ${errorText}`
|
|
5078
|
+
};
|
|
5079
|
+
}
|
|
5080
|
+
return { success: true };
|
|
5081
|
+
} catch (error) {
|
|
5082
|
+
return {
|
|
5083
|
+
success: false,
|
|
5084
|
+
error: error instanceof Error ? error.message : String(error)
|
|
5085
|
+
};
|
|
5086
|
+
}
|
|
5087
|
+
}
|
|
4750
5088
|
});
|
|
4751
5089
|
|
|
4752
|
-
// src/connectors/
|
|
4753
|
-
var parameters19 = {
|
|
4754
|
-
connectionUrl: new ParameterDefinition({
|
|
4755
|
-
slug: "connection-url",
|
|
4756
|
-
name: "Connection URL",
|
|
4757
|
-
description: "PostgreSQL connection URL for Squadbase DB.",
|
|
4758
|
-
envVarBaseKey: "SQUADBASE_DB_CONNECTION_URL",
|
|
4759
|
-
type: "text",
|
|
4760
|
-
secret: true,
|
|
4761
|
-
required: true
|
|
4762
|
-
})
|
|
4763
|
-
};
|
|
4764
|
-
|
|
4765
|
-
// src/connectors/squadbase-db/tools/execute-query.ts
|
|
5090
|
+
// src/connectors/kintone/tools/request.ts
|
|
4766
5091
|
import { z as z25 } from "zod";
|
|
4767
|
-
var
|
|
4768
|
-
var CONNECT_TIMEOUT_MS3 = 1e4;
|
|
4769
|
-
var STATEMENT_TIMEOUT_MS2 = 6e4;
|
|
5092
|
+
var REQUEST_TIMEOUT_MS15 = 6e4;
|
|
4770
5093
|
var inputSchema25 = z25.object({
|
|
4771
|
-
toolUseIntent: z25.string().optional().describe(
|
|
4772
|
-
|
|
4773
|
-
),
|
|
4774
|
-
|
|
4775
|
-
|
|
5094
|
+
toolUseIntent: z25.string().optional().describe("Brief description of what you intend to accomplish with this tool call"),
|
|
5095
|
+
connectionId: z25.string().describe("ID of the kintone connection to use"),
|
|
5096
|
+
method: z25.enum(["GET", "POST", "PUT", "DELETE"]).describe("HTTP method"),
|
|
5097
|
+
path: z25.string().describe("API path (e.g., 'apps.json', 'records.json?app=1&query=...')"),
|
|
5098
|
+
body: z25.record(z25.string(), z25.unknown()).optional().describe("Request body (JSON)")
|
|
4776
5099
|
});
|
|
4777
5100
|
var outputSchema25 = z25.discriminatedUnion("success", [
|
|
4778
5101
|
z25.object({
|
|
4779
5102
|
success: z25.literal(true),
|
|
4780
|
-
|
|
4781
|
-
|
|
4782
|
-
rows: z25.array(z25.record(z25.string(), z25.unknown()))
|
|
5103
|
+
status: z25.number(),
|
|
5104
|
+
data: z25.record(z25.string(), z25.unknown())
|
|
4783
5105
|
}),
|
|
4784
5106
|
z25.object({
|
|
4785
5107
|
success: z25.literal(false),
|
|
4786
5108
|
error: z25.string()
|
|
4787
5109
|
})
|
|
4788
5110
|
]);
|
|
4789
|
-
var
|
|
4790
|
-
name: "
|
|
4791
|
-
description: `
|
|
4792
|
-
|
|
4793
|
-
Avoid loading large amounts of data; always include LIMIT in queries.`,
|
|
5111
|
+
var requestTool9 = new ConnectorTool({
|
|
5112
|
+
name: "request",
|
|
5113
|
+
description: `Send authenticated requests to the kintone REST API.
|
|
5114
|
+
Authentication is handled automatically using username and password.`,
|
|
4794
5115
|
inputSchema: inputSchema25,
|
|
4795
5116
|
outputSchema: outputSchema25,
|
|
4796
|
-
async execute({ connectionId,
|
|
5117
|
+
async execute({ connectionId, method, path, body }, connections) {
|
|
4797
5118
|
const connection = connections.find((c) => c.id === connectionId);
|
|
4798
5119
|
if (!connection) {
|
|
4799
|
-
return {
|
|
4800
|
-
success: false,
|
|
4801
|
-
error: `Connection ${connectionId} not found`
|
|
4802
|
-
};
|
|
5120
|
+
return { success: false, error: `Connection ${connectionId} not found` };
|
|
4803
5121
|
}
|
|
4804
|
-
console.log(
|
|
4805
|
-
`[connector-query] squadbase-db/${connection.name}: ${sql}`
|
|
4806
|
-
);
|
|
4807
|
-
let connectionUrl;
|
|
5122
|
+
console.log(`[connector-request] kintone/${connection.name}: ${method} ${path}`);
|
|
4808
5123
|
try {
|
|
4809
|
-
const
|
|
4810
|
-
|
|
4811
|
-
const
|
|
4812
|
-
|
|
4813
|
-
|
|
4814
|
-
|
|
4815
|
-
|
|
4816
|
-
});
|
|
5124
|
+
const baseUrl = parameters7.baseUrl.getValue(connection);
|
|
5125
|
+
const username = parameters7.username.getValue(connection);
|
|
5126
|
+
const password = parameters7.password.getValue(connection);
|
|
5127
|
+
const authToken = Buffer.from(`${username}:${password}`).toString("base64");
|
|
5128
|
+
const url = `${baseUrl.replace(/\/+$/, "")}/k/v1/${path}`;
|
|
5129
|
+
const controller = new AbortController();
|
|
5130
|
+
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS15);
|
|
4817
5131
|
try {
|
|
4818
|
-
const
|
|
4819
|
-
|
|
4820
|
-
const truncated = rows.length > MAX_ROWS10;
|
|
4821
|
-
return {
|
|
4822
|
-
success: true,
|
|
4823
|
-
rowCount: Math.min(rows.length, MAX_ROWS10),
|
|
4824
|
-
truncated,
|
|
4825
|
-
rows: rows.slice(0, MAX_ROWS10)
|
|
5132
|
+
const headers = {
|
|
5133
|
+
"X-Cybozu-Authorization": authToken
|
|
4826
5134
|
};
|
|
5135
|
+
if (body) {
|
|
5136
|
+
headers["Content-Type"] = "application/json";
|
|
5137
|
+
}
|
|
5138
|
+
const response = await fetch(url, {
|
|
5139
|
+
method,
|
|
5140
|
+
headers,
|
|
5141
|
+
body: body ? JSON.stringify(body) : void 0,
|
|
5142
|
+
signal: controller.signal
|
|
5143
|
+
});
|
|
5144
|
+
const data = await response.json();
|
|
5145
|
+
if (!response.ok) {
|
|
5146
|
+
return {
|
|
5147
|
+
success: false,
|
|
5148
|
+
error: data?.message ?? `HTTP ${response.status} ${response.statusText}`
|
|
5149
|
+
};
|
|
5150
|
+
}
|
|
5151
|
+
return { success: true, status: response.status, data };
|
|
4827
5152
|
} finally {
|
|
4828
|
-
|
|
5153
|
+
clearTimeout(timeout);
|
|
4829
5154
|
}
|
|
4830
5155
|
} catch (err) {
|
|
4831
|
-
|
|
4832
|
-
if (connectionUrl) {
|
|
4833
|
-
msg = msg.replaceAll(connectionUrl, "***");
|
|
4834
|
-
}
|
|
5156
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
4835
5157
|
return { success: false, error: msg };
|
|
4836
5158
|
}
|
|
4837
5159
|
}
|
|
4838
5160
|
});
|
|
4839
5161
|
|
|
4840
|
-
// src/connectors/
|
|
4841
|
-
var tools18 = {
|
|
4842
|
-
var
|
|
4843
|
-
slug: "
|
|
5162
|
+
// src/connectors/kintone/index.ts
|
|
5163
|
+
var tools18 = { request: requestTool9 };
|
|
5164
|
+
var kintoneConnector = new ConnectorPlugin({
|
|
5165
|
+
slug: "kintone",
|
|
4844
5166
|
authType: null,
|
|
4845
|
-
name: "
|
|
4846
|
-
description: "Connect to
|
|
4847
|
-
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/
|
|
4848
|
-
parameters:
|
|
5167
|
+
name: "kintone (Password)",
|
|
5168
|
+
description: "Connect to kintone for business application data retrieval and analytics.",
|
|
5169
|
+
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/76nPGMJFZkMFE3UQNo2JFy/e71dc5f5d5cec1306ce0e17aafbfd9f0/kintone.png",
|
|
5170
|
+
parameters: parameters7,
|
|
4849
5171
|
releaseFlag: { dev1: true, dev2: true, prod: true },
|
|
4850
|
-
systemPrompt: `##
|
|
4851
|
-
-
|
|
4852
|
-
-
|
|
4853
|
-
- List tables: \`SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'\`
|
|
4854
|
-
- List columns: \`SELECT column_name, data_type FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'xxx'\`
|
|
4855
|
-
- Always include LIMIT in queries`,
|
|
4856
|
-
tools: tools18,
|
|
4857
|
-
async checkConnection(params, _config) {
|
|
4858
|
-
const { Pool } = await import("pg");
|
|
4859
|
-
const pool = new Pool({
|
|
4860
|
-
connectionString: params[parameters19.connectionUrl.slug],
|
|
4861
|
-
ssl: { rejectUnauthorized: false },
|
|
4862
|
-
connectionTimeoutMillis: 1e4
|
|
4863
|
-
});
|
|
4864
|
-
try {
|
|
4865
|
-
await pool.query("SELECT 1");
|
|
4866
|
-
return { success: true };
|
|
4867
|
-
} catch (error) {
|
|
4868
|
-
return { success: false, error: error instanceof Error ? error.message : String(error) };
|
|
4869
|
-
} finally {
|
|
4870
|
-
await pool.end();
|
|
4871
|
-
}
|
|
4872
|
-
},
|
|
4873
|
-
async query(params, sql, namedParams) {
|
|
4874
|
-
const { Pool } = await import("pg");
|
|
4875
|
-
const { text, values } = buildPositionalParams(sql, namedParams);
|
|
4876
|
-
const pool = new Pool({
|
|
4877
|
-
connectionString: params[parameters19.connectionUrl.slug],
|
|
4878
|
-
ssl: { rejectUnauthorized: false },
|
|
4879
|
-
connectionTimeoutMillis: 1e4,
|
|
4880
|
-
statement_timeout: 6e4
|
|
4881
|
-
});
|
|
4882
|
-
try {
|
|
4883
|
-
const result = await pool.query(text, values);
|
|
4884
|
-
return { rows: result.rows };
|
|
4885
|
-
} finally {
|
|
4886
|
-
await pool.end();
|
|
4887
|
-
}
|
|
4888
|
-
}
|
|
4889
|
-
});
|
|
5172
|
+
systemPrompt: `## kintone REST API
|
|
5173
|
+
- Call the kintone REST API using the authenticated request tool
|
|
5174
|
+
- The base URL (e.g., https://example.cybozu.com) is automatically resolved
|
|
4890
5175
|
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
var openaiConnector = new ConnectorPlugin({
|
|
4894
|
-
slug: "openai",
|
|
4895
|
-
authType: null,
|
|
4896
|
-
name: "OpenAI",
|
|
4897
|
-
description: "Connect to OpenAI for AI model inference, embeddings, and image generation.",
|
|
4898
|
-
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/53XJtCgUlW10x6i1X8xpxM/0bfd634069f1d74241296543cb20427a/openai.svg",
|
|
4899
|
-
parameters: parameters9,
|
|
4900
|
-
releaseFlag: { dev1: true, dev2: true, prod: true },
|
|
4901
|
-
systemPrompt: `## OpenAI SDK (TypeScript handler)
|
|
4902
|
-
Use the OpenAI connector via the SDK in TypeScript handlers:
|
|
5176
|
+
### List Apps
|
|
5177
|
+
- GET apps.json
|
|
4903
5178
|
|
|
4904
|
-
|
|
4905
|
-
|
|
4906
|
-
import OpenAI from "openai";
|
|
5179
|
+
### Get Field Definitions
|
|
5180
|
+
- GET app/form/fields.json?app={appId}
|
|
4907
5181
|
|
|
4908
|
-
|
|
4909
|
-
|
|
5182
|
+
### Get Records
|
|
5183
|
+
- GET records.json?app={appId}&query={query}
|
|
5184
|
+
- Query example: records.json?app=1&query=updatedTime > "2024-01-01" order by recordNumber asc limit 100
|
|
4910
5185
|
|
|
4911
|
-
|
|
4912
|
-
|
|
4913
|
-
|
|
4914
|
-
|
|
4915
|
-
|
|
4916
|
-
|
|
5186
|
+
### Add Record
|
|
5187
|
+
- POST record.json
|
|
5188
|
+
- Body: { "app": 1, "record": { "fieldName": { "value": "value" } } }
|
|
5189
|
+
|
|
5190
|
+
### kintone Query Syntax
|
|
5191
|
+
- Comparison: fieldName = "value", fieldName > 100
|
|
5192
|
+
- Operators: and, or, not
|
|
5193
|
+
- Sort: order by fieldName asc/desc
|
|
5194
|
+
- Limit: limit 100 offset 0
|
|
5195
|
+
- String: like "partial match"
|
|
5196
|
+
|
|
5197
|
+
## kintone SDK (TypeScript handler)
|
|
5198
|
+
Non-SQL connectors like kintone can also be used via the SDK in TypeScript handlers:
|
|
5199
|
+
|
|
5200
|
+
\`\`\`ts
|
|
5201
|
+
import { connection } from "@squadbase/vite-server/connectors/kintone";
|
|
5202
|
+
|
|
5203
|
+
const kintone = connection("<connectionId>");
|
|
5204
|
+
|
|
5205
|
+
// Authenticated fetch (returns standard Response)
|
|
5206
|
+
const res = await kintone.request("/k/v1/records.json?app=1&query=limit 10");
|
|
5207
|
+
const data = await res.json();
|
|
5208
|
+
|
|
5209
|
+
await kintone.request("/k/v1/record.json", {
|
|
5210
|
+
method: "POST",
|
|
5211
|
+
body: JSON.stringify({ app: 1, record: { title: { value: "Hello" } } }),
|
|
5212
|
+
});
|
|
5213
|
+
|
|
5214
|
+
// Convenience methods (uses @kintone/rest-api-client)
|
|
5215
|
+
const { records, totalCount } = await kintone.getRecords(1, {
|
|
5216
|
+
query: 'status = "Active"',
|
|
5217
|
+
fields: ["name", "email"],
|
|
5218
|
+
totalCount: true,
|
|
5219
|
+
});
|
|
5220
|
+
const { record } = await kintone.getRecord(1, 100);
|
|
5221
|
+
const { apps } = await kintone.listApps();
|
|
5222
|
+
\`\`\``,
|
|
5223
|
+
tools: tools18
|
|
5224
|
+
});
|
|
5225
|
+
|
|
5226
|
+
// src/connectors/kintone-api-token/tools/request.ts
|
|
5227
|
+
import { z as z26 } from "zod";
|
|
5228
|
+
var REQUEST_TIMEOUT_MS16 = 6e4;
|
|
5229
|
+
var inputSchema26 = z26.object({
|
|
5230
|
+
toolUseIntent: z26.string().optional().describe("Brief description of what you intend to accomplish with this tool call"),
|
|
5231
|
+
connectionId: z26.string().describe("ID of the kintone connection to use"),
|
|
5232
|
+
method: z26.enum(["GET", "POST", "PUT", "DELETE"]).describe("HTTP method"),
|
|
5233
|
+
path: z26.string().describe("API path (e.g., 'apps.json', 'records.json?app=1&query=...')"),
|
|
5234
|
+
body: z26.record(z26.string(), z26.unknown()).optional().describe("Request body (JSON)")
|
|
5235
|
+
});
|
|
5236
|
+
var outputSchema26 = z26.discriminatedUnion("success", [
|
|
5237
|
+
z26.object({
|
|
5238
|
+
success: z26.literal(true),
|
|
5239
|
+
status: z26.number(),
|
|
5240
|
+
data: z26.record(z26.string(), z26.unknown())
|
|
5241
|
+
}),
|
|
5242
|
+
z26.object({
|
|
5243
|
+
success: z26.literal(false),
|
|
5244
|
+
error: z26.string()
|
|
5245
|
+
})
|
|
5246
|
+
]);
|
|
5247
|
+
var requestTool10 = new ConnectorTool({
|
|
5248
|
+
name: "request",
|
|
5249
|
+
description: `Send authenticated requests to the kintone REST API.
|
|
5250
|
+
Authentication is handled automatically using the API token.`,
|
|
5251
|
+
inputSchema: inputSchema26,
|
|
5252
|
+
outputSchema: outputSchema26,
|
|
5253
|
+
async execute({ connectionId, method, path, body }, connections) {
|
|
5254
|
+
const connection = connections.find((c) => c.id === connectionId);
|
|
5255
|
+
if (!connection) {
|
|
5256
|
+
return { success: false, error: `Connection ${connectionId} not found` };
|
|
5257
|
+
}
|
|
5258
|
+
console.log(`[connector-request] kintone-api-token/${connection.name}: ${method} ${path}`);
|
|
5259
|
+
try {
|
|
5260
|
+
const baseUrl = parameters8.baseUrl.getValue(connection);
|
|
5261
|
+
const apiToken = parameters8.apiToken.getValue(connection);
|
|
5262
|
+
const url = `${baseUrl.replace(/\/+$/, "")}/k/v1/${path}`;
|
|
5263
|
+
const controller = new AbortController();
|
|
5264
|
+
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS16);
|
|
5265
|
+
try {
|
|
5266
|
+
const headers = {
|
|
5267
|
+
"X-Cybozu-API-Token": apiToken
|
|
5268
|
+
};
|
|
5269
|
+
if (body) {
|
|
5270
|
+
headers["Content-Type"] = "application/json";
|
|
5271
|
+
}
|
|
5272
|
+
const response = await fetch(url, {
|
|
5273
|
+
method,
|
|
5274
|
+
headers,
|
|
5275
|
+
body: body ? JSON.stringify(body) : void 0,
|
|
5276
|
+
signal: controller.signal
|
|
5277
|
+
});
|
|
5278
|
+
const data = await response.json();
|
|
5279
|
+
if (!response.ok) {
|
|
5280
|
+
return {
|
|
5281
|
+
success: false,
|
|
5282
|
+
error: data?.message ?? `HTTP ${response.status} ${response.statusText}`
|
|
5283
|
+
};
|
|
5284
|
+
}
|
|
5285
|
+
return { success: true, status: response.status, data };
|
|
5286
|
+
} finally {
|
|
5287
|
+
clearTimeout(timeout);
|
|
5288
|
+
}
|
|
5289
|
+
} catch (err) {
|
|
5290
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
5291
|
+
return { success: false, error: msg };
|
|
5292
|
+
}
|
|
5293
|
+
}
|
|
5294
|
+
});
|
|
5295
|
+
|
|
5296
|
+
// src/connectors/kintone-api-token/index.ts
|
|
5297
|
+
var tools19 = { request: requestTool10 };
|
|
5298
|
+
var kintoneApiTokenConnector = new ConnectorPlugin({
|
|
5299
|
+
slug: "kintone",
|
|
5300
|
+
authType: AUTH_TYPES.API_KEY,
|
|
5301
|
+
name: "kintone (API Token)",
|
|
5302
|
+
description: "Connect to kintone for business application data retrieval and analytics using API token authentication.",
|
|
5303
|
+
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/76nPGMJFZkMFE3UQNo2JFy/e71dc5f5d5cec1306ce0e17aafbfd9f0/kintone.png",
|
|
5304
|
+
parameters: parameters8,
|
|
5305
|
+
releaseFlag: { dev1: true, dev2: false, prod: false },
|
|
5306
|
+
systemPrompt: `## kintone REST API (API Token)
|
|
5307
|
+
- Call the kintone REST API using the authenticated request tool
|
|
5308
|
+
- The base URL (e.g., https://example.cybozu.com) is automatically resolved
|
|
5309
|
+
- Authentication uses the kintone API token (scoped to specific apps)
|
|
5310
|
+
|
|
5311
|
+
### List Apps
|
|
5312
|
+
- GET apps.json
|
|
5313
|
+
|
|
5314
|
+
### Get Field Definitions
|
|
5315
|
+
- GET app/form/fields.json?app={appId}
|
|
5316
|
+
|
|
5317
|
+
### Get Records
|
|
5318
|
+
- GET records.json?app={appId}&query={query}
|
|
5319
|
+
- Query example: records.json?app=1&query=updatedTime > "2024-01-01" order by recordNumber asc limit 100
|
|
5320
|
+
|
|
5321
|
+
### Add Record
|
|
5322
|
+
- POST record.json
|
|
5323
|
+
- Body: { "app": 1, "record": { "fieldName": { "value": "value" } } }
|
|
5324
|
+
|
|
5325
|
+
### kintone Query Syntax
|
|
5326
|
+
- Comparison: fieldName = "value", fieldName > 100
|
|
5327
|
+
- Operators: and, or, not
|
|
5328
|
+
- Sort: order by fieldName asc/desc
|
|
5329
|
+
- Limit: limit 100 offset 0
|
|
5330
|
+
- String: like "partial match"
|
|
5331
|
+
|
|
5332
|
+
### Tips
|
|
5333
|
+
- API tokens are scoped per app. If you need to access multiple apps, you can combine multiple tokens separated by commas.
|
|
5334
|
+
|
|
5335
|
+
## kintone SDK (TypeScript handler)
|
|
5336
|
+
|
|
5337
|
+
\`\`\`ts
|
|
5338
|
+
import { connection } from "@squadbase/vite-server/connectors/kintone-api-key";
|
|
5339
|
+
|
|
5340
|
+
const kintone = connection("<connectionId>");
|
|
5341
|
+
|
|
5342
|
+
// Authenticated fetch (returns standard Response)
|
|
5343
|
+
const res = await kintone.request("/k/v1/records.json?app=1&query=limit 10");
|
|
5344
|
+
const data = await res.json();
|
|
5345
|
+
|
|
5346
|
+
await kintone.request("/k/v1/record.json", {
|
|
5347
|
+
method: "POST",
|
|
5348
|
+
body: JSON.stringify({ app: 1, record: { title: { value: "Hello" } } }),
|
|
5349
|
+
});
|
|
5350
|
+
\`\`\``,
|
|
5351
|
+
tools: tools19
|
|
5352
|
+
});
|
|
5353
|
+
|
|
5354
|
+
// src/connectors/wix-store/tools/request.ts
|
|
5355
|
+
import { z as z27 } from "zod";
|
|
5356
|
+
var BASE_URL10 = "https://www.wixapis.com/";
|
|
5357
|
+
var REQUEST_TIMEOUT_MS17 = 6e4;
|
|
5358
|
+
var inputSchema27 = z27.object({
|
|
5359
|
+
toolUseIntent: z27.string().optional().describe("Brief description of what you intend to accomplish with this tool call"),
|
|
5360
|
+
connectionId: z27.string().describe("ID of the Wix Store connection to use"),
|
|
5361
|
+
method: z27.enum(["GET", "POST"]).describe("HTTP method"),
|
|
5362
|
+
path: z27.string().describe("API path (e.g., 'stores/v1/products/query', 'stores/v2/orders/query')"),
|
|
5363
|
+
body: z27.record(z27.string(), z27.unknown()).optional().describe("Request body (JSON)")
|
|
5364
|
+
});
|
|
5365
|
+
var outputSchema27 = z27.discriminatedUnion("success", [
|
|
5366
|
+
z27.object({
|
|
5367
|
+
success: z27.literal(true),
|
|
5368
|
+
status: z27.number(),
|
|
5369
|
+
data: z27.record(z27.string(), z27.unknown())
|
|
5370
|
+
}),
|
|
5371
|
+
z27.object({
|
|
5372
|
+
success: z27.literal(false),
|
|
5373
|
+
error: z27.string()
|
|
5374
|
+
})
|
|
5375
|
+
]);
|
|
5376
|
+
var requestTool11 = new ConnectorTool({
|
|
5377
|
+
name: "request",
|
|
5378
|
+
description: `Send authenticated requests to the Wix Store API.
|
|
5379
|
+
Authentication is handled automatically using the API Key and Site ID.`,
|
|
5380
|
+
inputSchema: inputSchema27,
|
|
5381
|
+
outputSchema: outputSchema27,
|
|
5382
|
+
async execute({ connectionId, method, path, body }, connections) {
|
|
5383
|
+
const connection = connections.find((c) => c.id === connectionId);
|
|
5384
|
+
if (!connection) {
|
|
5385
|
+
return { success: false, error: `Connection ${connectionId} not found` };
|
|
5386
|
+
}
|
|
5387
|
+
console.log(`[connector-request] wix-store/${connection.name}: ${method} ${path}`);
|
|
5388
|
+
try {
|
|
5389
|
+
const apiKey = parameters9.apiKey.getValue(connection);
|
|
5390
|
+
const siteId = parameters9.siteId.getValue(connection);
|
|
5391
|
+
const url = `${BASE_URL10}${path}`;
|
|
5392
|
+
const controller = new AbortController();
|
|
5393
|
+
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS17);
|
|
5394
|
+
try {
|
|
5395
|
+
const response = await fetch(url, {
|
|
5396
|
+
method,
|
|
5397
|
+
headers: {
|
|
5398
|
+
Authorization: apiKey,
|
|
5399
|
+
"wix-site-id": siteId,
|
|
5400
|
+
"Content-Type": "application/json"
|
|
5401
|
+
},
|
|
5402
|
+
body: body ? JSON.stringify(body) : void 0,
|
|
5403
|
+
signal: controller.signal
|
|
5404
|
+
});
|
|
5405
|
+
const data = await response.json();
|
|
5406
|
+
if (!response.ok) {
|
|
5407
|
+
const errorObj = data?.message;
|
|
5408
|
+
return {
|
|
5409
|
+
success: false,
|
|
5410
|
+
error: errorObj ?? `HTTP ${response.status} ${response.statusText}`
|
|
5411
|
+
};
|
|
5412
|
+
}
|
|
5413
|
+
return { success: true, status: response.status, data };
|
|
5414
|
+
} finally {
|
|
5415
|
+
clearTimeout(timeout);
|
|
5416
|
+
}
|
|
5417
|
+
} catch (err) {
|
|
5418
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
5419
|
+
return { success: false, error: msg };
|
|
5420
|
+
}
|
|
5421
|
+
}
|
|
5422
|
+
});
|
|
5423
|
+
|
|
5424
|
+
// src/connectors/wix-store/index.ts
|
|
5425
|
+
var tools20 = { request: requestTool11 };
|
|
5426
|
+
var wixStoreConnector = new ConnectorPlugin({
|
|
5427
|
+
slug: "wix-store",
|
|
5428
|
+
authType: null,
|
|
5429
|
+
name: "Wix Store",
|
|
5430
|
+
description: "Connect to Wix Store.",
|
|
5431
|
+
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/YyFxclQFzROIYpFam6vRK/e7e75d3feac49a1cc5e433c147216d23/Wix_logo_black.svg",
|
|
5432
|
+
parameters: parameters9,
|
|
5433
|
+
releaseFlag: { dev1: true, dev2: true, prod: true },
|
|
5434
|
+
systemPrompt: `## Wix Store API
|
|
5435
|
+
- Call the Wix Store REST API using the authenticated request tool
|
|
5436
|
+
- Authentication (API Key, Site ID) is automatically configured
|
|
5437
|
+
- Wix API uses POST for query endpoints as well
|
|
5438
|
+
- Wix uses WQL (Wix Query Language) for filters
|
|
5439
|
+
- Max 100 items per page
|
|
5440
|
+
|
|
5441
|
+
### List Products
|
|
5442
|
+
- POST stores/v1/products/query
|
|
5443
|
+
- Body: { "query": { "paging": { "limit": 50, "offset": 0 } } }
|
|
5444
|
+
|
|
5445
|
+
### Search Products (with filter)
|
|
5446
|
+
- POST stores/v1/products/query
|
|
5447
|
+
- Body: { "query": { "filter": { "name": { "$contains": "keyword" } }, "paging": { "limit": 50 } } }
|
|
5448
|
+
|
|
5449
|
+
### Search Orders (eCommerce Orders V1)
|
|
5450
|
+
- POST ecom/v1/orders/search
|
|
5451
|
+
- Body: { "search": { "cursorPaging": { "limit": 50 } } }
|
|
5452
|
+
- Uses cursor-based pagination (cursorPaging, not paging)
|
|
5453
|
+
- Response includes pagingMetadata.cursors.next for pagination
|
|
5454
|
+
|
|
5455
|
+
### List Collections (Categories)
|
|
5456
|
+
- POST stores/v1/collections/query
|
|
5457
|
+
- Body: { "query": { "paging": { "limit": 50 } } }
|
|
5458
|
+
|
|
5459
|
+
### List Inventory Items
|
|
5460
|
+
- POST stores/v2/inventoryItems/query
|
|
5461
|
+
- Body: { "query": { "paging": { "limit": 50 } } }
|
|
5462
|
+
|
|
5463
|
+
## Wix Store SDK (TypeScript handler)
|
|
5464
|
+
Non-SQL connectors like Wix Store can also be used via the SDK in TypeScript handlers:
|
|
5465
|
+
|
|
5466
|
+
\`\`\`ts
|
|
5467
|
+
import { connection } from "@squadbase/vite-server/connectors/wix-store";
|
|
5468
|
+
|
|
5469
|
+
const wix = connection("<connectionId>");
|
|
5470
|
+
|
|
5471
|
+
// Authenticated fetch (returns standard Response)
|
|
5472
|
+
const res = await wix.request("/stores/v1/products/query", {
|
|
5473
|
+
method: "POST",
|
|
5474
|
+
headers: { "Content-Type": "application/json" },
|
|
5475
|
+
body: JSON.stringify({ query: { paging: { limit: 10 } } }),
|
|
5476
|
+
});
|
|
5477
|
+
const data = await res.json();
|
|
5478
|
+
|
|
5479
|
+
// Convenience methods
|
|
5480
|
+
const { products, totalResults } = await wix.queryProducts({ paging: { limit: 50 } });
|
|
5481
|
+
const { product } = await wix.getProduct("product-id");
|
|
5482
|
+
const { orders, pagingMetadata } = await wix.queryOrders({ cursorPaging: { limit: 50 } });
|
|
5483
|
+
const { order } = await wix.getOrder("order-id");
|
|
5484
|
+
const { inventoryItems } = await wix.queryInventory({ paging: { limit: 50 } });
|
|
5485
|
+
const { collections } = await wix.queryCollections({ paging: { limit: 50 } });
|
|
5486
|
+
\`\`\``,
|
|
5487
|
+
tools: tools20
|
|
5488
|
+
});
|
|
5489
|
+
|
|
5490
|
+
// src/connectors/dbt/tools/request.ts
|
|
5491
|
+
import { z as z28 } from "zod";
|
|
5492
|
+
var REQUEST_TIMEOUT_MS18 = 6e4;
|
|
5493
|
+
function resolveGraphqlEndpoint(host) {
|
|
5494
|
+
if (host.includes("emea")) return "https://metadata.emea.dbt.com/graphql";
|
|
5495
|
+
if (host.includes(".au.")) return "https://metadata.au.dbt.com/graphql";
|
|
5496
|
+
return "https://metadata.cloud.getdbt.com/graphql";
|
|
5497
|
+
}
|
|
5498
|
+
var inputSchema28 = z28.object({
|
|
5499
|
+
toolUseIntent: z28.string().optional().describe("Brief description of what you intend to accomplish with this tool call"),
|
|
5500
|
+
connectionId: z28.string().describe("ID of the dbt Cloud connection to use"),
|
|
5501
|
+
query: z28.string().describe("GraphQL query"),
|
|
5502
|
+
variables: z28.record(z28.string(), z28.unknown()).optional().describe("GraphQL variables (JSON)")
|
|
5503
|
+
});
|
|
5504
|
+
var outputSchema28 = z28.discriminatedUnion("success", [
|
|
5505
|
+
z28.object({
|
|
5506
|
+
success: z28.literal(true),
|
|
5507
|
+
data: z28.record(z28.string(), z28.unknown())
|
|
5508
|
+
}),
|
|
5509
|
+
z28.object({
|
|
5510
|
+
success: z28.literal(false),
|
|
5511
|
+
error: z28.string()
|
|
5512
|
+
})
|
|
5513
|
+
]);
|
|
5514
|
+
var requestTool12 = new ConnectorTool({
|
|
5515
|
+
name: "request",
|
|
5516
|
+
description: `Send authenticated requests to the dbt Cloud Discovery API (GraphQL).
|
|
5517
|
+
Authentication is handled automatically using the API token.
|
|
5518
|
+
{environmentId} in GraphQL variables is automatically replaced with the prod-env-id.`,
|
|
5519
|
+
inputSchema: inputSchema28,
|
|
5520
|
+
outputSchema: outputSchema28,
|
|
5521
|
+
async execute({ connectionId, query, variables }, connections) {
|
|
5522
|
+
const connection = connections.find((c) => c.id === connectionId);
|
|
5523
|
+
if (!connection) {
|
|
5524
|
+
return { success: false, error: `Connection ${connectionId} not found` };
|
|
5525
|
+
}
|
|
5526
|
+
console.log(`[connector-request] dbt/${connection.name}: GraphQL query`);
|
|
5527
|
+
try {
|
|
5528
|
+
const host = parameters10.host.getValue(connection);
|
|
5529
|
+
const token = parameters10.token.getValue(connection);
|
|
5530
|
+
const environmentId = parameters10.prodEnvId.getValue(connection);
|
|
5531
|
+
const resolvedVariables = variables ? JSON.parse(
|
|
5532
|
+
JSON.stringify(variables).replace(/\{environmentId\}/g, environmentId)
|
|
5533
|
+
) : void 0;
|
|
5534
|
+
const endpoint = resolveGraphqlEndpoint(host);
|
|
5535
|
+
const controller = new AbortController();
|
|
5536
|
+
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS18);
|
|
5537
|
+
try {
|
|
5538
|
+
const response = await fetch(endpoint, {
|
|
5539
|
+
method: "POST",
|
|
5540
|
+
headers: {
|
|
5541
|
+
Authorization: `Bearer ${token}`,
|
|
5542
|
+
"Content-Type": "application/json"
|
|
5543
|
+
},
|
|
5544
|
+
body: JSON.stringify({ query, variables: resolvedVariables }),
|
|
5545
|
+
signal: controller.signal
|
|
5546
|
+
});
|
|
5547
|
+
const data = await response.json();
|
|
5548
|
+
if (!response.ok) {
|
|
5549
|
+
return {
|
|
5550
|
+
success: false,
|
|
5551
|
+
error: data?.message ?? `HTTP ${response.status} ${response.statusText}`
|
|
5552
|
+
};
|
|
5553
|
+
}
|
|
5554
|
+
if (Array.isArray(data?.errors) && data.errors.length > 0) {
|
|
5555
|
+
const errors = data.errors;
|
|
5556
|
+
return {
|
|
5557
|
+
success: false,
|
|
5558
|
+
error: errors.map((e) => e.message).join("; ")
|
|
5559
|
+
};
|
|
5560
|
+
}
|
|
5561
|
+
return { success: true, data };
|
|
5562
|
+
} finally {
|
|
5563
|
+
clearTimeout(timeout);
|
|
5564
|
+
}
|
|
5565
|
+
} catch (err) {
|
|
5566
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
5567
|
+
return { success: false, error: msg };
|
|
5568
|
+
}
|
|
5569
|
+
}
|
|
5570
|
+
});
|
|
5571
|
+
|
|
5572
|
+
// src/connectors/dbt/index.ts
|
|
5573
|
+
var tools21 = { request: requestTool12 };
|
|
5574
|
+
var dbtConnector = new ConnectorPlugin({
|
|
5575
|
+
slug: "dbt",
|
|
5576
|
+
authType: null,
|
|
5577
|
+
name: "dbt",
|
|
5578
|
+
description: "Connect to dbt Cloud for data transformation and analytics engineering.",
|
|
5579
|
+
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/4iT6ncXtdtHdkXexU0WgfZ/0367a38d245f2568eab5eb511f9ee692/dbt.png",
|
|
5580
|
+
parameters: parameters10,
|
|
5581
|
+
releaseFlag: { dev1: true, dev2: true, prod: true },
|
|
5582
|
+
systemPrompt: `## dbt Cloud Discovery API (GraphQL)
|
|
5583
|
+
- Call the dbt Cloud Discovery API using the authenticated request tool
|
|
5584
|
+
- {environmentId} in GraphQL variables is automatically replaced with the prod-env-id
|
|
5585
|
+
|
|
5586
|
+
### List Models
|
|
5587
|
+
query:
|
|
5588
|
+
query($environmentId: BigInt!) {
|
|
5589
|
+
environment(id: $environmentId) {
|
|
5590
|
+
applied {
|
|
5591
|
+
models(first: 100) {
|
|
5592
|
+
edges {
|
|
5593
|
+
node { uniqueId name description database schema alias materializedType }
|
|
5594
|
+
}
|
|
5595
|
+
}
|
|
5596
|
+
}
|
|
5597
|
+
}
|
|
5598
|
+
}
|
|
5599
|
+
variables: { "environmentId": "{environmentId}" }
|
|
5600
|
+
|
|
5601
|
+
### List Sources
|
|
5602
|
+
query:
|
|
5603
|
+
query($environmentId: BigInt!) {
|
|
5604
|
+
environment(id: $environmentId) {
|
|
5605
|
+
applied {
|
|
5606
|
+
sources(first: 100) {
|
|
5607
|
+
edges {
|
|
5608
|
+
node { uniqueId name description database schema identifier }
|
|
5609
|
+
}
|
|
5610
|
+
}
|
|
5611
|
+
}
|
|
5612
|
+
}
|
|
5613
|
+
}
|
|
5614
|
+
variables: { "environmentId": "{environmentId}" }
|
|
5615
|
+
|
|
5616
|
+
### Model Column Information
|
|
5617
|
+
query:
|
|
5618
|
+
query($environmentId: BigInt!, $uniqueId: String!) {
|
|
5619
|
+
environment(id: $environmentId) {
|
|
5620
|
+
applied {
|
|
5621
|
+
models(filter: { uniqueId: { eq: $uniqueId } }) {
|
|
5622
|
+
edges {
|
|
5623
|
+
node { uniqueId name columns { name description type } }
|
|
5624
|
+
}
|
|
5625
|
+
}
|
|
5626
|
+
}
|
|
5627
|
+
}
|
|
5628
|
+
}
|
|
5629
|
+
|
|
5630
|
+
### Lineage (Dependencies)
|
|
5631
|
+
- Traverse relationships using ancestors / children fields
|
|
5632
|
+
- Get ancestors { uniqueId name } or children { uniqueId name } within node
|
|
5633
|
+
|
|
5634
|
+
## dbt SDK (TypeScript handler)
|
|
5635
|
+
Non-SQL connectors like dbt can also be used via the SDK in TypeScript handlers:
|
|
5636
|
+
|
|
5637
|
+
\`\`\`ts
|
|
5638
|
+
import { connection } from "@squadbase/vite-server/connectors/dbt";
|
|
5639
|
+
|
|
5640
|
+
const dbt = connection("<connectionId>");
|
|
5641
|
+
|
|
5642
|
+
// Authenticated fetch (returns standard Response)
|
|
5643
|
+
const res = await dbt.request("/graphql", {
|
|
5644
|
+
method: "POST",
|
|
5645
|
+
headers: { "Content-Type": "application/json" },
|
|
5646
|
+
body: JSON.stringify({ query: "{ ... }", variables: {} }),
|
|
5647
|
+
});
|
|
5648
|
+
const data = await res.json();
|
|
5649
|
+
|
|
5650
|
+
// Convenience methods
|
|
5651
|
+
const result = await dbt.query(\`
|
|
5652
|
+
query($environmentId: BigInt!) {
|
|
5653
|
+
environment(id: $environmentId) { applied { models(first: 10) { edges { node { name } } } } }
|
|
5654
|
+
}
|
|
5655
|
+
\`);
|
|
5656
|
+
const models = await dbt.getModels({ limit: 100 });
|
|
5657
|
+
const model = await dbt.getModelByUniqueId("model.project.my_model");
|
|
5658
|
+
const sources = await dbt.getSources({ limit: 100 });
|
|
5659
|
+
const tests = await dbt.getTests({ limit: 100 });
|
|
5660
|
+
const metrics = await dbt.getMetrics({ limit: 100 });
|
|
5661
|
+
\`\`\``,
|
|
5662
|
+
tools: tools21
|
|
5663
|
+
});
|
|
5664
|
+
|
|
5665
|
+
// src/connectors/squadbase-db/parameters.ts
|
|
5666
|
+
var parameters30 = {
|
|
5667
|
+
connectionUrl: new ParameterDefinition({
|
|
5668
|
+
slug: "connection-url",
|
|
5669
|
+
name: "Connection URL",
|
|
5670
|
+
description: "PostgreSQL connection URL for Squadbase DB.",
|
|
5671
|
+
envVarBaseKey: "SQUADBASE_DB_CONNECTION_URL",
|
|
5672
|
+
type: "text",
|
|
5673
|
+
secret: true,
|
|
5674
|
+
required: true
|
|
5675
|
+
})
|
|
5676
|
+
};
|
|
5677
|
+
|
|
5678
|
+
// src/connectors/squadbase-db/tools/execute-query.ts
|
|
5679
|
+
import { z as z29 } from "zod";
|
|
5680
|
+
var MAX_ROWS10 = 500;
|
|
5681
|
+
var CONNECT_TIMEOUT_MS3 = 1e4;
|
|
5682
|
+
var STATEMENT_TIMEOUT_MS2 = 6e4;
|
|
5683
|
+
var inputSchema29 = z29.object({
|
|
5684
|
+
toolUseIntent: z29.string().optional().describe(
|
|
5685
|
+
"Brief description of what you intend to accomplish with this tool call"
|
|
5686
|
+
),
|
|
5687
|
+
connectionId: z29.string().describe("ID of the Squadbase DB connection to use"),
|
|
5688
|
+
sql: z29.string().describe("PostgreSQL SQL query. Always include LIMIT in queries.")
|
|
5689
|
+
});
|
|
5690
|
+
var outputSchema29 = z29.discriminatedUnion("success", [
|
|
5691
|
+
z29.object({
|
|
5692
|
+
success: z29.literal(true),
|
|
5693
|
+
rowCount: z29.number(),
|
|
5694
|
+
truncated: z29.boolean(),
|
|
5695
|
+
rows: z29.array(z29.record(z29.string(), z29.unknown()))
|
|
5696
|
+
}),
|
|
5697
|
+
z29.object({
|
|
5698
|
+
success: z29.literal(false),
|
|
5699
|
+
error: z29.string()
|
|
5700
|
+
})
|
|
5701
|
+
]);
|
|
5702
|
+
var executeQueryTool10 = new ConnectorTool({
|
|
5703
|
+
name: "executeQuery",
|
|
5704
|
+
description: `Execute SQL against Squadbase DB (PostgreSQL). Returns up to ${MAX_ROWS10} rows.
|
|
5705
|
+
Use for: schema exploration (information_schema), data sampling, analytical queries.
|
|
5706
|
+
Avoid loading large amounts of data; always include LIMIT in queries.`,
|
|
5707
|
+
inputSchema: inputSchema29,
|
|
5708
|
+
outputSchema: outputSchema29,
|
|
5709
|
+
async execute({ connectionId, sql }, connections) {
|
|
5710
|
+
const connection = connections.find((c) => c.id === connectionId);
|
|
5711
|
+
if (!connection) {
|
|
5712
|
+
return {
|
|
5713
|
+
success: false,
|
|
5714
|
+
error: `Connection ${connectionId} not found`
|
|
5715
|
+
};
|
|
5716
|
+
}
|
|
5717
|
+
console.log(
|
|
5718
|
+
`[connector-query] squadbase-db/${connection.name}: ${sql}`
|
|
5719
|
+
);
|
|
5720
|
+
let connectionUrl;
|
|
5721
|
+
try {
|
|
5722
|
+
const { Pool } = await import("pg");
|
|
5723
|
+
connectionUrl = parameters30.connectionUrl.getValue(connection);
|
|
5724
|
+
const pool = new Pool({
|
|
5725
|
+
connectionString: connectionUrl,
|
|
5726
|
+
ssl: { rejectUnauthorized: false },
|
|
5727
|
+
connectionTimeoutMillis: CONNECT_TIMEOUT_MS3,
|
|
5728
|
+
statement_timeout: STATEMENT_TIMEOUT_MS2
|
|
5729
|
+
});
|
|
5730
|
+
try {
|
|
5731
|
+
const result = await pool.query(sql);
|
|
5732
|
+
const rows = result.rows;
|
|
5733
|
+
const truncated = rows.length > MAX_ROWS10;
|
|
5734
|
+
return {
|
|
5735
|
+
success: true,
|
|
5736
|
+
rowCount: Math.min(rows.length, MAX_ROWS10),
|
|
5737
|
+
truncated,
|
|
5738
|
+
rows: rows.slice(0, MAX_ROWS10)
|
|
5739
|
+
};
|
|
5740
|
+
} finally {
|
|
5741
|
+
await pool.end();
|
|
5742
|
+
}
|
|
5743
|
+
} catch (err) {
|
|
5744
|
+
let msg = err instanceof Error ? err.message : String(err);
|
|
5745
|
+
if (connectionUrl) {
|
|
5746
|
+
msg = msg.replaceAll(connectionUrl, "***");
|
|
5747
|
+
}
|
|
5748
|
+
return { success: false, error: msg };
|
|
5749
|
+
}
|
|
5750
|
+
}
|
|
5751
|
+
});
|
|
5752
|
+
|
|
5753
|
+
// src/connectors/squadbase-db/index.ts
|
|
5754
|
+
var tools22 = { executeQuery: executeQueryTool10 };
|
|
5755
|
+
var squadbaseDbConnector = new ConnectorPlugin({
|
|
5756
|
+
slug: "squadbase-db",
|
|
5757
|
+
authType: null,
|
|
5758
|
+
name: "Squadbase DB",
|
|
5759
|
+
description: "Connect to Squadbase DB (PostgreSQL).",
|
|
5760
|
+
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/25y0XqMxIufeD3egWH3bEl/659b4ade405890654cfaf91c03a4b458/icon.svg",
|
|
5761
|
+
parameters: parameters30,
|
|
5762
|
+
releaseFlag: { dev1: true, dev2: true, prod: true },
|
|
5763
|
+
systemPrompt: `## Squadbase DB SQL Notes
|
|
5764
|
+
- Uses PostgreSQL based SQL syntax
|
|
5765
|
+
- Schema exploration:
|
|
5766
|
+
- List tables: \`SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'\`
|
|
5767
|
+
- List columns: \`SELECT column_name, data_type FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'xxx'\`
|
|
5768
|
+
- Always include LIMIT in queries`,
|
|
5769
|
+
tools: tools22,
|
|
5770
|
+
async checkConnection(params, _config) {
|
|
5771
|
+
const { Pool } = await import("pg");
|
|
5772
|
+
const pool = new Pool({
|
|
5773
|
+
connectionString: params[parameters30.connectionUrl.slug],
|
|
5774
|
+
ssl: { rejectUnauthorized: false },
|
|
5775
|
+
connectionTimeoutMillis: 1e4
|
|
5776
|
+
});
|
|
5777
|
+
try {
|
|
5778
|
+
await pool.query("SELECT 1");
|
|
5779
|
+
return { success: true };
|
|
5780
|
+
} catch (error) {
|
|
5781
|
+
return { success: false, error: error instanceof Error ? error.message : String(error) };
|
|
5782
|
+
} finally {
|
|
5783
|
+
await pool.end();
|
|
5784
|
+
}
|
|
5785
|
+
},
|
|
5786
|
+
async query(params, sql, namedParams) {
|
|
5787
|
+
const { Pool } = await import("pg");
|
|
5788
|
+
const { text, values } = buildPositionalParams(sql, namedParams);
|
|
5789
|
+
const pool = new Pool({
|
|
5790
|
+
connectionString: params[parameters30.connectionUrl.slug],
|
|
5791
|
+
ssl: { rejectUnauthorized: false },
|
|
5792
|
+
connectionTimeoutMillis: 1e4,
|
|
5793
|
+
statement_timeout: 6e4
|
|
5794
|
+
});
|
|
5795
|
+
try {
|
|
5796
|
+
const result = await pool.query(text, values);
|
|
5797
|
+
return { rows: result.rows };
|
|
5798
|
+
} finally {
|
|
5799
|
+
await pool.end();
|
|
5800
|
+
}
|
|
5801
|
+
}
|
|
5802
|
+
});
|
|
5803
|
+
|
|
5804
|
+
// src/connectors/openai/index.ts
|
|
5805
|
+
var tools23 = {};
|
|
5806
|
+
var openaiConnector = new ConnectorPlugin({
|
|
5807
|
+
slug: "openai",
|
|
5808
|
+
authType: null,
|
|
5809
|
+
name: "OpenAI",
|
|
5810
|
+
description: "Connect to OpenAI for AI model inference, embeddings, and image generation.",
|
|
5811
|
+
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/53XJtCgUlW10x6i1X8xpxM/0bfd634069f1d74241296543cb20427a/openai.svg",
|
|
5812
|
+
parameters: parameters11,
|
|
5813
|
+
releaseFlag: { dev1: true, dev2: true, prod: true },
|
|
5814
|
+
systemPrompt: `## OpenAI SDK (TypeScript handler)
|
|
5815
|
+
Use the OpenAI connector via the SDK in TypeScript handlers:
|
|
5816
|
+
|
|
5817
|
+
\`\`\`ts
|
|
5818
|
+
import { connection } from "@squadbase/vite-server/connectors/openai";
|
|
5819
|
+
import OpenAI from "openai";
|
|
5820
|
+
|
|
5821
|
+
const { apiKey } = connection("<connectionId>");
|
|
5822
|
+
const client = new OpenAI({ apiKey });
|
|
5823
|
+
|
|
5824
|
+
const response = await client.chat.completions.create({
|
|
5825
|
+
model: "gpt-4o",
|
|
5826
|
+
messages: [{ role: "user", content: "Hello" }],
|
|
5827
|
+
});
|
|
5828
|
+
\`\`\``,
|
|
5829
|
+
tools: tools23
|
|
5830
|
+
});
|
|
5831
|
+
|
|
5832
|
+
// src/connectors/gemini/index.ts
|
|
5833
|
+
var tools24 = {};
|
|
5834
|
+
var geminiConnector = new ConnectorPlugin({
|
|
5835
|
+
slug: "gemini",
|
|
5836
|
+
authType: null,
|
|
5837
|
+
name: "Gemini",
|
|
5838
|
+
description: "Connect to Google Gemini for AI model inference, embeddings, and multimodal generation.",
|
|
5839
|
+
iconUrl: "https://www.gstatic.com/lamda/images/gemini_sparkle_v002_d4735304ff6292a690b6.svg",
|
|
5840
|
+
parameters: parameters12,
|
|
5841
|
+
releaseFlag: { dev1: true, dev2: true, prod: true },
|
|
5842
|
+
systemPrompt: `## Gemini SDK (TypeScript handler)
|
|
5843
|
+
Use the Gemini connector via the SDK in TypeScript handlers:
|
|
5844
|
+
|
|
5845
|
+
\`\`\`ts
|
|
5846
|
+
import { connection } from "@squadbase/vite-server/connectors/gemini";
|
|
5847
|
+
import { GoogleGenerativeAI } from "@google/generative-ai";
|
|
5848
|
+
|
|
5849
|
+
const { apiKey } = connection("<connectionId>");
|
|
5850
|
+
const genAI = new GoogleGenerativeAI(apiKey);
|
|
5851
|
+
const model = genAI.getGenerativeModel({ model: "gemini-2.0-flash" });
|
|
5852
|
+
|
|
5853
|
+
const result = await model.generateContent("Hello");
|
|
5854
|
+
const text = result.response.text();
|
|
5855
|
+
\`\`\``,
|
|
5856
|
+
tools: tools24
|
|
5857
|
+
});
|
|
5858
|
+
|
|
5859
|
+
// src/connectors/anthropic/index.ts
|
|
5860
|
+
var tools25 = {};
|
|
5861
|
+
var anthropicConnector = new ConnectorPlugin({
|
|
5862
|
+
slug: "anthropic",
|
|
5863
|
+
authType: null,
|
|
5864
|
+
name: "Anthropic",
|
|
5865
|
+
description: "Connect to Anthropic for AI model inference and text generation with Claude.",
|
|
5866
|
+
iconUrl: "https://www.anthropic.com/images/icons/safari-pinned-tab.svg",
|
|
5867
|
+
parameters: parameters13,
|
|
5868
|
+
releaseFlag: { dev1: true, dev2: true, prod: true },
|
|
5869
|
+
systemPrompt: `## Anthropic SDK (TypeScript handler)
|
|
5870
|
+
Use the Anthropic connector via the SDK in TypeScript handlers:
|
|
5871
|
+
|
|
5872
|
+
\`\`\`ts
|
|
5873
|
+
import { connection } from "@squadbase/vite-server/connectors/anthropic";
|
|
5874
|
+
import Anthropic from "@anthropic-ai/sdk";
|
|
5875
|
+
|
|
5876
|
+
const { apiKey } = connection("<connectionId>");
|
|
5877
|
+
const client = new Anthropic({ apiKey });
|
|
5878
|
+
|
|
5879
|
+
const message = await client.messages.create({
|
|
5880
|
+
model: "claude-sonnet-4-20250514",
|
|
5881
|
+
max_tokens: 1024,
|
|
5882
|
+
messages: [{ role: "user", content: "Hello" }],
|
|
5883
|
+
});
|
|
5884
|
+
\`\`\``,
|
|
5885
|
+
tools: tools25
|
|
5886
|
+
});
|
|
5887
|
+
|
|
5888
|
+
// src/connectors/amplitude/index.ts
|
|
5889
|
+
var tools26 = {};
|
|
5890
|
+
var amplitudeConnector = new ConnectorPlugin({
|
|
5891
|
+
slug: "amplitude",
|
|
5892
|
+
authType: null,
|
|
5893
|
+
name: "Amplitude",
|
|
5894
|
+
description: "Connect to Amplitude for product analytics and user behavior data.",
|
|
5895
|
+
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/2UBJSdRlFJaLq52WUCTBEB/308b59b374cf6c662ac70989860bffd7/amplitude-icon.svg",
|
|
5896
|
+
parameters: parameters14,
|
|
5897
|
+
releaseFlag: { dev1: true, dev2: false, prod: false },
|
|
5898
|
+
systemPrompt: `## Amplitude SDK (TypeScript handler)
|
|
5899
|
+
Use the Amplitude connector via the SDK in TypeScript handlers:
|
|
5900
|
+
|
|
5901
|
+
\`\`\`ts
|
|
5902
|
+
import { connection } from "@squadbase/vite-server/connectors/amplitude";
|
|
5903
|
+
|
|
5904
|
+
const { apiKey, secretKey } = connection("<connectionId>");
|
|
5905
|
+
|
|
5906
|
+
// Use the Amplitude REST API with Basic auth (apiKey:secretKey)
|
|
5907
|
+
const res = await fetch("https://amplitude.com/api/2/events/segmentation", {
|
|
5908
|
+
headers: {
|
|
5909
|
+
Authorization: "Basic " + btoa(apiKey + ":" + secretKey),
|
|
5910
|
+
},
|
|
5911
|
+
});
|
|
5912
|
+
const data = await res.json();
|
|
5913
|
+
\`\`\`
|
|
5914
|
+
|
|
5915
|
+
### Common Endpoints
|
|
5916
|
+
- GET \`https://amplitude.com/api/2/events/segmentation\` \u2014 Event segmentation
|
|
5917
|
+
- GET \`https://amplitude.com/api/2/events/list\` \u2014 List event types
|
|
5918
|
+
- GET \`https://amplitude.com/api/2/usersearch\` \u2014 Search users
|
|
5919
|
+
- GET \`https://amplitude.com/api/2/useractivity\` \u2014 User activity
|
|
5920
|
+
- POST \`https://amplitude.com/api/2/export\` \u2014 Export raw events`,
|
|
5921
|
+
tools: tools26
|
|
5922
|
+
});
|
|
5923
|
+
|
|
5924
|
+
// src/connectors/attio/index.ts
|
|
5925
|
+
var tools27 = {};
|
|
5926
|
+
var attioConnector = new ConnectorPlugin({
|
|
5927
|
+
slug: "attio",
|
|
5928
|
+
authType: null,
|
|
5929
|
+
name: "Attio",
|
|
5930
|
+
description: "Connect to Attio for CRM data and relationship intelligence.",
|
|
5931
|
+
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/2qqx99vvXJojUM3tSrSWPX/1e7c35e13da6b365b8b475c1effe568f/attio.svg",
|
|
5932
|
+
parameters: parameters15,
|
|
5933
|
+
releaseFlag: { dev1: true, dev2: false, prod: false },
|
|
5934
|
+
systemPrompt: `## Attio SDK (TypeScript handler)
|
|
5935
|
+
Use the Attio connector via the SDK in TypeScript handlers:
|
|
5936
|
+
|
|
5937
|
+
\`\`\`ts
|
|
5938
|
+
import { connection } from "@squadbase/vite-server/connectors/attio";
|
|
5939
|
+
|
|
5940
|
+
const { apiKey } = connection("<connectionId>");
|
|
5941
|
+
|
|
5942
|
+
// Use the Attio REST API
|
|
5943
|
+
const res = await fetch("https://api.attio.com/v2/objects/people/records/query", {
|
|
5944
|
+
method: "POST",
|
|
5945
|
+
headers: {
|
|
5946
|
+
Authorization: "Bearer " + apiKey,
|
|
5947
|
+
"Content-Type": "application/json",
|
|
5948
|
+
},
|
|
5949
|
+
body: JSON.stringify({ limit: 25 }),
|
|
5950
|
+
});
|
|
5951
|
+
const data = await res.json();
|
|
5952
|
+
\`\`\`
|
|
5953
|
+
|
|
5954
|
+
### Common Endpoints (Base URL: https://api.attio.com/v2)
|
|
5955
|
+
- POST \`/objects/{object}/records/query\` \u2014 Query records (people, companies, deals, etc.)
|
|
5956
|
+
- GET \`/objects/{object}/records/{record_id}\` \u2014 Get a record
|
|
5957
|
+
- POST \`/objects/{object}/records\` \u2014 Create a record
|
|
5958
|
+
- PATCH \`/objects/{object}/records/{record_id}\` \u2014 Update a record
|
|
5959
|
+
- DELETE \`/objects/{object}/records/{record_id}\` \u2014 Delete a record
|
|
5960
|
+
- GET \`/objects\` \u2014 List all objects
|
|
5961
|
+
- GET \`/objects/{object}/attributes\` \u2014 List attributes of an object
|
|
5962
|
+
- POST \`/lists/{list_id}/entries/query\` \u2014 Query list entries
|
|
5963
|
+
- POST \`/notes\` \u2014 Create a note
|
|
5964
|
+
- GET \`/notes?parent_object={object}&parent_record_id={id}\` \u2014 Get notes for a record`,
|
|
5965
|
+
tools: tools27
|
|
5966
|
+
});
|
|
5967
|
+
|
|
5968
|
+
// src/connectors/shopify/index.ts
|
|
5969
|
+
var tools28 = {};
|
|
5970
|
+
var shopifyConnector = new ConnectorPlugin({
|
|
5971
|
+
slug: "shopify",
|
|
5972
|
+
authType: null,
|
|
5973
|
+
name: "Shopify",
|
|
5974
|
+
description: "Connect to Shopify for e-commerce data including products, orders, and customers.",
|
|
5975
|
+
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/57KEjZCBskKgSxgKyU4Sm0/117d681a410f48dc36f97cdd9c0593c5/shopify-icon.svg",
|
|
5976
|
+
parameters: parameters16,
|
|
5977
|
+
releaseFlag: { dev1: true, dev2: false, prod: false },
|
|
5978
|
+
systemPrompt: `## Shopify SDK (TypeScript handler)
|
|
5979
|
+
Use the Shopify connector via the SDK in TypeScript handlers:
|
|
5980
|
+
|
|
5981
|
+
\`\`\`ts
|
|
5982
|
+
import { connection } from "@squadbase/vite-server/connectors/shopify";
|
|
5983
|
+
|
|
5984
|
+
const { accessToken, storeDomain } = connection("<connectionId>");
|
|
5985
|
+
|
|
5986
|
+
// Use the Shopify Admin REST API
|
|
5987
|
+
const res = await fetch(
|
|
5988
|
+
\`https://\${storeDomain}/admin/api/2024-10/products.json\`,
|
|
5989
|
+
{
|
|
5990
|
+
headers: {
|
|
5991
|
+
"X-Shopify-Access-Token": accessToken,
|
|
5992
|
+
"Content-Type": "application/json",
|
|
5993
|
+
},
|
|
5994
|
+
},
|
|
5995
|
+
);
|
|
5996
|
+
const data = await res.json();
|
|
5997
|
+
\`\`\`
|
|
5998
|
+
|
|
5999
|
+
### Common Endpoints (Base URL: https://{storeDomain}/admin/api/2024-10)
|
|
6000
|
+
- GET \`/products.json\` \u2014 List products
|
|
6001
|
+
- GET \`/products/{id}.json\` \u2014 Get a product
|
|
6002
|
+
- GET \`/orders.json\` \u2014 List orders
|
|
6003
|
+
- GET \`/orders/{id}.json\` \u2014 Get an order
|
|
6004
|
+
- GET \`/customers.json\` \u2014 List customers
|
|
6005
|
+
- GET \`/customers/{id}.json\` \u2014 Get a customer
|
|
6006
|
+
- GET \`/inventory_items.json?ids={ids}\` \u2014 List inventory items
|
|
6007
|
+
- GET \`/locations.json\` \u2014 List locations
|
|
6008
|
+
- GET \`/collects.json\` \u2014 List collects
|
|
6009
|
+
- GET \`/custom_collections.json\` \u2014 List custom collections
|
|
6010
|
+
- GET \`/smart_collections.json\` \u2014 List smart collections
|
|
6011
|
+
|
|
6012
|
+
### Query Parameters
|
|
6013
|
+
- \`limit\` \u2014 Max records per page (max 250)
|
|
6014
|
+
- \`page_info\` \u2014 Cursor for pagination (from Link header)
|
|
6015
|
+
- \`fields\` \u2014 Comma-separated list of fields to return
|
|
6016
|
+
- \`created_at_min\`, \`created_at_max\` \u2014 Date filters
|
|
6017
|
+
- \`updated_at_min\`, \`updated_at_max\` \u2014 Date filters
|
|
6018
|
+
- \`status\` \u2014 Filter by status (e.g., active, draft, archived for products)`,
|
|
6019
|
+
tools: tools28
|
|
6020
|
+
});
|
|
6021
|
+
|
|
6022
|
+
// src/connectors/slack/index.ts
|
|
6023
|
+
var tools29 = {};
|
|
6024
|
+
var slackConnector = new ConnectorPlugin({
|
|
6025
|
+
slug: "slack",
|
|
6026
|
+
authType: null,
|
|
6027
|
+
name: "Slack",
|
|
6028
|
+
description: "Connect to Slack for messaging and workspace data retrieval.",
|
|
6029
|
+
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/7zTp67vMTvAV1wPftt6Z9R/f859e25c223d9fe4c3fd4f83895acbf6/slack.svg",
|
|
6030
|
+
parameters: parameters17,
|
|
6031
|
+
releaseFlag: { dev1: true, dev2: false, prod: false },
|
|
6032
|
+
systemPrompt: `## Slack SDK (TypeScript handler)
|
|
6033
|
+
Use the Slack connector via the SDK in TypeScript handlers:
|
|
6034
|
+
|
|
6035
|
+
\`\`\`ts
|
|
6036
|
+
import { connection } from "@squadbase/vite-server/connectors/slack";
|
|
6037
|
+
import { WebClient } from "@slack/web-api";
|
|
6038
|
+
|
|
6039
|
+
const { botToken } = connection("<connectionId>");
|
|
6040
|
+
const client = new WebClient(botToken);
|
|
6041
|
+
|
|
6042
|
+
const result = await client.conversations.list({ limit: 100 });
|
|
6043
|
+
\`\`\`
|
|
6044
|
+
|
|
6045
|
+
### Common Web API Methods (Base URL: https://slack.com/api)
|
|
6046
|
+
- \`conversations.list\` \u2014 List channels
|
|
6047
|
+
- \`conversations.history\` \u2014 Get channel messages
|
|
6048
|
+
- \`conversations.info\` \u2014 Get channel info
|
|
6049
|
+
- \`conversations.members\` \u2014 List channel members
|
|
6050
|
+
- \`users.list\` \u2014 List users
|
|
6051
|
+
- \`users.info\` \u2014 Get user info
|
|
6052
|
+
- \`chat.postMessage\` \u2014 Send a message
|
|
6053
|
+
- \`reactions.list\` \u2014 List reactions
|
|
6054
|
+
- \`search.messages\` \u2014 Search messages
|
|
6055
|
+
- \`team.info\` \u2014 Get team info
|
|
6056
|
+
|
|
6057
|
+
### Tips
|
|
6058
|
+
- Use the \`@slack/web-api\` package for type-safe API calls
|
|
6059
|
+
- Pagination: use \`cursor\` parameter with \`response_metadata.next_cursor\`
|
|
6060
|
+
- Rate limits: Tier 1-4, most methods are Tier 3 (50+ per minute)`,
|
|
6061
|
+
tools: tools29
|
|
6062
|
+
});
|
|
6063
|
+
|
|
6064
|
+
// src/connectors/shopify-oauth/tools/request.ts
|
|
6065
|
+
import { z as z30 } from "zod";
|
|
6066
|
+
var REQUEST_TIMEOUT_MS19 = 6e4;
|
|
6067
|
+
var cachedToken13 = null;
|
|
6068
|
+
async function getProxyToken13(config) {
|
|
6069
|
+
if (cachedToken13 && cachedToken13.expiresAt > Date.now() + 6e4) {
|
|
6070
|
+
return cachedToken13.token;
|
|
6071
|
+
}
|
|
6072
|
+
const url = `${config.appApiBaseUrl}/v0/database/${config.projectId}/environment/${config.environmentId}/oauth-request-proxy-token`;
|
|
6073
|
+
const res = await fetch(url, {
|
|
6074
|
+
method: "POST",
|
|
6075
|
+
headers: {
|
|
6076
|
+
"Content-Type": "application/json",
|
|
6077
|
+
"x-api-key": config.appApiKey,
|
|
6078
|
+
"project-id": config.projectId
|
|
6079
|
+
},
|
|
6080
|
+
body: JSON.stringify({
|
|
6081
|
+
sandboxId: config.sandboxId,
|
|
6082
|
+
issuedBy: "coding-agent"
|
|
6083
|
+
})
|
|
6084
|
+
});
|
|
6085
|
+
if (!res.ok) {
|
|
6086
|
+
const errorText = await res.text().catch(() => res.statusText);
|
|
6087
|
+
throw new Error(
|
|
6088
|
+
`Failed to get proxy token: HTTP ${res.status} ${errorText}`
|
|
6089
|
+
);
|
|
6090
|
+
}
|
|
6091
|
+
const data = await res.json();
|
|
6092
|
+
cachedToken13 = {
|
|
6093
|
+
token: data.token,
|
|
6094
|
+
expiresAt: new Date(data.expiresAt).getTime()
|
|
6095
|
+
};
|
|
6096
|
+
return data.token;
|
|
6097
|
+
}
|
|
6098
|
+
var inputSchema30 = z30.object({
|
|
6099
|
+
toolUseIntent: z30.string().optional().describe(
|
|
6100
|
+
"Brief description of what you intend to accomplish with this tool call"
|
|
6101
|
+
),
|
|
6102
|
+
connectionId: z30.string().describe("ID of the Shopify OAuth connection to use"),
|
|
6103
|
+
method: z30.enum(["GET", "POST", "PUT", "DELETE"]).describe("HTTP method"),
|
|
6104
|
+
path: z30.string().describe(
|
|
6105
|
+
"API path (e.g., '/admin/api/2024-10/products.json', '/admin/api/2024-10/orders.json')"
|
|
6106
|
+
),
|
|
6107
|
+
queryParams: z30.record(z30.string(), z30.string()).optional().describe("Query parameters to append to the URL"),
|
|
6108
|
+
body: z30.record(z30.string(), z30.unknown()).optional().describe("Request body (JSON) for POST/PUT requests")
|
|
6109
|
+
});
|
|
6110
|
+
var outputSchema30 = z30.discriminatedUnion("success", [
|
|
6111
|
+
z30.object({
|
|
6112
|
+
success: z30.literal(true),
|
|
6113
|
+
status: z30.number(),
|
|
6114
|
+
data: z30.record(z30.string(), z30.unknown())
|
|
6115
|
+
}),
|
|
6116
|
+
z30.object({
|
|
6117
|
+
success: z30.literal(false),
|
|
6118
|
+
error: z30.string()
|
|
6119
|
+
})
|
|
6120
|
+
]);
|
|
6121
|
+
var requestTool13 = new ConnectorTool({
|
|
6122
|
+
name: "request",
|
|
6123
|
+
description: `Send authenticated requests to the Shopify Admin API.
|
|
6124
|
+
Authentication is handled automatically via OAuth proxy.`,
|
|
6125
|
+
inputSchema: inputSchema30,
|
|
6126
|
+
outputSchema: outputSchema30,
|
|
6127
|
+
async execute({ connectionId, method, path, queryParams, body }, connections, config) {
|
|
6128
|
+
const connection = connections.find((c) => c.id === connectionId);
|
|
6129
|
+
if (!connection) {
|
|
6130
|
+
return {
|
|
6131
|
+
success: false,
|
|
6132
|
+
error: `Connection ${connectionId} not found`
|
|
6133
|
+
};
|
|
6134
|
+
}
|
|
6135
|
+
console.log(
|
|
6136
|
+
`[connector-request] shopify-oauth/${connection.name}: ${method} ${path}`
|
|
6137
|
+
);
|
|
6138
|
+
try {
|
|
6139
|
+
let url = path;
|
|
6140
|
+
if (queryParams) {
|
|
6141
|
+
const searchParams = new URLSearchParams(queryParams);
|
|
6142
|
+
url += `${url.includes("?") ? "&" : "?"}${searchParams.toString()}`;
|
|
6143
|
+
}
|
|
6144
|
+
const token = await getProxyToken13(config.oauthProxy);
|
|
6145
|
+
const proxyUrl = `https://${config.oauthProxy.sandboxId}.${config.oauthProxy.previewBaseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
6146
|
+
const controller = new AbortController();
|
|
6147
|
+
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS19);
|
|
6148
|
+
try {
|
|
6149
|
+
const response = await fetch(proxyUrl, {
|
|
6150
|
+
method: "POST",
|
|
6151
|
+
headers: {
|
|
6152
|
+
"Content-Type": "application/json",
|
|
6153
|
+
Authorization: `Bearer ${token}`
|
|
6154
|
+
},
|
|
6155
|
+
body: JSON.stringify({
|
|
6156
|
+
url,
|
|
6157
|
+
method,
|
|
6158
|
+
body: body ? JSON.stringify(body) : void 0
|
|
6159
|
+
}),
|
|
6160
|
+
signal: controller.signal
|
|
6161
|
+
});
|
|
6162
|
+
const data = await response.json();
|
|
6163
|
+
if (!response.ok) {
|
|
6164
|
+
const errorMessage = typeof data?.error === "string" ? data.error : typeof data?.message === "string" ? data.message : `HTTP ${response.status} ${response.statusText}`;
|
|
6165
|
+
return { success: false, error: errorMessage };
|
|
6166
|
+
}
|
|
6167
|
+
return { success: true, status: response.status, data };
|
|
6168
|
+
} finally {
|
|
6169
|
+
clearTimeout(timeout);
|
|
6170
|
+
}
|
|
6171
|
+
} catch (err) {
|
|
6172
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6173
|
+
return { success: false, error: msg };
|
|
6174
|
+
}
|
|
6175
|
+
}
|
|
6176
|
+
});
|
|
6177
|
+
|
|
6178
|
+
// src/connectors/shopify-oauth/setup.ts
|
|
6179
|
+
var requestToolName5 = `shopify-oauth_${requestTool13.name}`;
|
|
6180
|
+
var shopifyOauthSetup = new ConnectorSetup({
|
|
6181
|
+
ja: `## Shopify \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u624B\u9806
|
|
6182
|
+
|
|
6183
|
+
\u4EE5\u4E0B\u306E\u624B\u9806\u3067Shopify\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3092\u884C\u3063\u3066\u304F\u3060\u3055\u3044\u3002
|
|
6184
|
+
|
|
6185
|
+
### \u624B\u9806
|
|
6186
|
+
|
|
6187
|
+
#### \u30B9\u30C6\u30C3\u30D71: \u63A5\u7D9A\u78BA\u8A8D
|
|
6188
|
+
1. \`${requestToolName5}\` \u3092\u547C\u3073\u51FA\u3057\u3066\u3001\u30B7\u30E7\u30C3\u30D7\u60C5\u5831\u3092\u53D6\u5F97\u3059\u308B:
|
|
6189
|
+
- \`method\`: \`"GET"\`
|
|
6190
|
+
- \`path\`: \`"/admin/api/2024-10/shop.json"\`
|
|
6191
|
+
2. \u30A8\u30E9\u30FC\u304C\u8FD4\u3055\u308C\u305F\u5834\u5408\u3001\u30E6\u30FC\u30B6\u30FC\u306BOAuth\u63A5\u7D9A\u306E\u8A2D\u5B9A\u3092\u78BA\u8A8D\u3059\u308B\u3088\u3046\u4F1D\u3048\u308B
|
|
6192
|
+
|
|
6193
|
+
#### \u30B9\u30C6\u30C3\u30D72: \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u5B8C\u4E86
|
|
6194
|
+
1. \`updateConnectionContext\` \u3092\u547C\u3073\u51FA\u3059:
|
|
6195
|
+
- \`shop\`: Shopify\u30B7\u30E7\u30C3\u30D7\u60C5\u5831
|
|
6196
|
+
- \`note\`: \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u5185\u5BB9\u306E\u7C21\u5358\u306A\u8AAC\u660E
|
|
6197
|
+
|
|
6198
|
+
### \u91CD\u8981\u306A\u5236\u7D04
|
|
6199
|
+
- **\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u4E2D\u306B\u30D3\u30B8\u30CD\u30B9\u30C7\u30FC\u30BF\uFF08\u6CE8\u6587\u3001\u9867\u5BA2\u306A\u3069\uFF09\u3092\u8AAD\u307F\u53D6\u3089\u306A\u3044\u3053\u3068**\u3002\u5B9F\u884C\u3057\u3066\u3088\u3044\u306E\u306F\u4E0A\u8A18\u624B\u9806\u3067\u6307\u5B9A\u3055\u308C\u305F\u30E1\u30BF\u30C7\u30FC\u30BF\u53D6\u5F97\u30EA\u30AF\u30A8\u30B9\u30C8\u306E\u307F
|
|
6200
|
+
|
|
6201
|
+
### \u5B9F\u884C\u65B9\u91DD
|
|
6202
|
+
- \u30C4\u30FC\u30EB\u9593\u306F1\u6587\u3060\u3051\u66F8\u3044\u3066\u5373\u6B21\u306E\u30C4\u30FC\u30EB\u547C\u3073\u51FA\u3057
|
|
6203
|
+
- \u4E0D\u8981\u306A\u8AAC\u660E\u306F\u7701\u7565\u3057\u3001\u52B9\u7387\u7684\u306B\u9032\u3081\u308B`,
|
|
6204
|
+
en: `## Shopify Setup Instructions
|
|
6205
|
+
|
|
6206
|
+
Follow these steps to set up the Shopify connection.
|
|
6207
|
+
|
|
6208
|
+
### Steps
|
|
6209
|
+
|
|
6210
|
+
#### Step 1: Verify Connection
|
|
6211
|
+
1. Call \`${requestToolName5}\` to fetch shop info:
|
|
6212
|
+
- \`method\`: \`"GET"\`
|
|
6213
|
+
- \`path\`: \`"/admin/api/2024-10/shop.json"\`
|
|
6214
|
+
2. If an error is returned, ask the user to check the OAuth connection settings
|
|
6215
|
+
|
|
6216
|
+
#### Step 2: Complete Setup
|
|
6217
|
+
1. Call \`updateConnectionContext\`:
|
|
6218
|
+
- \`shop\`: Shopify shop info
|
|
6219
|
+
- \`note\`: Brief description of the setup
|
|
6220
|
+
|
|
6221
|
+
### Important Constraints
|
|
6222
|
+
- **Do NOT read business data (orders, customers, etc.) during setup**. Only the metadata request specified in the steps above is allowed
|
|
6223
|
+
|
|
6224
|
+
### Execution Policy
|
|
6225
|
+
- Write only 1 sentence between tool calls, then immediately call the next tool
|
|
6226
|
+
- Skip unnecessary explanations and proceed efficiently`
|
|
6227
|
+
});
|
|
6228
|
+
|
|
6229
|
+
// src/connectors/shopify-oauth/parameters.ts
|
|
6230
|
+
var parameters31 = {};
|
|
6231
|
+
|
|
6232
|
+
// src/connectors/shopify-oauth/index.ts
|
|
6233
|
+
var tools30 = { request: requestTool13 };
|
|
6234
|
+
var shopifyOauthConnector = new ConnectorPlugin({
|
|
6235
|
+
slug: "shopify",
|
|
6236
|
+
authType: AUTH_TYPES.OAUTH,
|
|
6237
|
+
name: "Shopify (OAuth)",
|
|
6238
|
+
description: "Connect to Shopify for e-commerce data including products, orders, and customers using OAuth.",
|
|
6239
|
+
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/57KEjZCBskKgSxgKyU4Sm0/117d681a410f48dc36f97cdd9c0593c5/shopify-icon.svg",
|
|
6240
|
+
parameters: parameters31,
|
|
6241
|
+
releaseFlag: { dev1: true, dev2: false, prod: false },
|
|
6242
|
+
setup: shopifyOauthSetup,
|
|
6243
|
+
proxyPolicy: {
|
|
6244
|
+
allowlist: [
|
|
6245
|
+
{
|
|
6246
|
+
host: "*.myshopify.com",
|
|
6247
|
+
methods: ["GET", "POST", "PUT", "DELETE"]
|
|
6248
|
+
}
|
|
6249
|
+
]
|
|
6250
|
+
},
|
|
6251
|
+
systemPrompt: `## Shopify API (OAuth)
|
|
6252
|
+
|
|
6253
|
+
### Available Endpoints (API version: 2024-10)
|
|
6254
|
+
- GET \`/admin/api/2024-10/shop.json\` \u2014 Get shop info
|
|
6255
|
+
- GET \`/admin/api/2024-10/products.json\` \u2014 List products
|
|
6256
|
+
- GET \`/admin/api/2024-10/products/{id}.json\` \u2014 Get a product
|
|
6257
|
+
- GET \`/admin/api/2024-10/orders.json\` \u2014 List orders
|
|
6258
|
+
- GET \`/admin/api/2024-10/orders/{id}.json\` \u2014 Get an order
|
|
6259
|
+
- GET \`/admin/api/2024-10/customers.json\` \u2014 List customers
|
|
6260
|
+
- GET \`/admin/api/2024-10/customers/{id}.json\` \u2014 Get a customer
|
|
6261
|
+
- GET \`/admin/api/2024-10/inventory_items.json?ids={ids}\` \u2014 List inventory items
|
|
6262
|
+
- GET \`/admin/api/2024-10/locations.json\` \u2014 List locations
|
|
6263
|
+
- GET \`/admin/api/2024-10/collects.json\` \u2014 List collects
|
|
6264
|
+
- GET \`/admin/api/2024-10/custom_collections.json\` \u2014 List custom collections
|
|
6265
|
+
- GET \`/admin/api/2024-10/smart_collections.json\` \u2014 List smart collections
|
|
6266
|
+
|
|
6267
|
+
### Query Parameters
|
|
6268
|
+
- \`limit\` \u2014 Max records per page (max 250)
|
|
6269
|
+
- \`page_info\` \u2014 Cursor for pagination (from Link header)
|
|
6270
|
+
- \`fields\` \u2014 Comma-separated list of fields to return
|
|
6271
|
+
- \`created_at_min\`, \`created_at_max\` \u2014 Date filters
|
|
6272
|
+
- \`updated_at_min\`, \`updated_at_max\` \u2014 Date filters
|
|
6273
|
+
- \`status\` \u2014 Filter by status (e.g., active, draft, archived for products)
|
|
6274
|
+
|
|
6275
|
+
### Tips
|
|
6276
|
+
- Pagination uses cursor-based \`page_info\` parameter from the Link header
|
|
6277
|
+
- Use \`fields\` parameter to limit response size
|
|
6278
|
+
|
|
6279
|
+
## Shopify SDK (TypeScript handler)
|
|
6280
|
+
|
|
6281
|
+
\`\`\`ts
|
|
6282
|
+
import { connection } from "@squadbase/vite-server/connectors/shopify-oauth";
|
|
6283
|
+
|
|
6284
|
+
const shopify = connection("<connectionId>");
|
|
6285
|
+
|
|
6286
|
+
// Authenticated fetch (returns standard Response)
|
|
6287
|
+
const res = await shopify.request("/admin/api/2024-10/products.json?limit=10");
|
|
6288
|
+
const data = await res.json();
|
|
6289
|
+
\`\`\``,
|
|
6290
|
+
tools: tools30,
|
|
6291
|
+
async checkConnection(_params, config) {
|
|
6292
|
+
const { proxyFetch } = config;
|
|
6293
|
+
try {
|
|
6294
|
+
const res = await proxyFetch("/admin/api/2024-10/shop.json", {
|
|
6295
|
+
method: "GET"
|
|
6296
|
+
});
|
|
6297
|
+
if (!res.ok) {
|
|
6298
|
+
const errorText = await res.text().catch(() => res.statusText);
|
|
6299
|
+
return {
|
|
6300
|
+
success: false,
|
|
6301
|
+
error: `Shopify API failed: HTTP ${res.status} ${errorText}`
|
|
6302
|
+
};
|
|
6303
|
+
}
|
|
6304
|
+
return { success: true };
|
|
6305
|
+
} catch (error) {
|
|
6306
|
+
return {
|
|
6307
|
+
success: false,
|
|
6308
|
+
error: error instanceof Error ? error.message : String(error)
|
|
6309
|
+
};
|
|
6310
|
+
}
|
|
6311
|
+
}
|
|
6312
|
+
});
|
|
6313
|
+
|
|
6314
|
+
// src/connectors/ms-teams/index.ts
|
|
6315
|
+
var tools31 = {};
|
|
6316
|
+
var msTeamsConnector = new ConnectorPlugin({
|
|
6317
|
+
slug: "ms-teams",
|
|
6318
|
+
authType: null,
|
|
6319
|
+
name: "Microsoft Teams",
|
|
6320
|
+
description: "Connect to Microsoft Teams for messaging, channels, and team data.",
|
|
6321
|
+
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/6QM1sVuqarTJAB2UihVNQ9/12b8353c9b022916d72ef0f53349bae2/microsoft-teams-icon.svg",
|
|
6322
|
+
parameters: parameters18,
|
|
6323
|
+
releaseFlag: { dev1: true, dev2: false, prod: false },
|
|
6324
|
+
systemPrompt: `## Microsoft Teams SDK (TypeScript handler)
|
|
6325
|
+
Use the Microsoft Teams connector via the SDK in TypeScript handlers:
|
|
6326
|
+
|
|
6327
|
+
\`\`\`ts
|
|
6328
|
+
import { connection } from "@squadbase/vite-server/connectors/ms-teams";
|
|
6329
|
+
|
|
6330
|
+
const { clientId, clientSecret, tenantId } = connection("<connectionId>");
|
|
6331
|
+
|
|
6332
|
+
// 1. Get an access token using client credentials flow
|
|
6333
|
+
const tokenRes = await fetch(
|
|
6334
|
+
\`https://login.microsoftonline.com/\${tenantId}/oauth2/v2.0/token\`,
|
|
6335
|
+
{
|
|
6336
|
+
method: "POST",
|
|
6337
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
6338
|
+
body: new URLSearchParams({
|
|
6339
|
+
client_id: clientId,
|
|
6340
|
+
client_secret: clientSecret,
|
|
6341
|
+
scope: "https://graph.microsoft.com/.default",
|
|
6342
|
+
grant_type: "client_credentials",
|
|
6343
|
+
}),
|
|
6344
|
+
},
|
|
6345
|
+
);
|
|
6346
|
+
const { access_token } = await tokenRes.json();
|
|
6347
|
+
|
|
6348
|
+
// 2. Call the Microsoft Graph API
|
|
6349
|
+
const res = await fetch("https://graph.microsoft.com/v1.0/teams", {
|
|
6350
|
+
headers: { Authorization: \`Bearer \${access_token}\` },
|
|
6351
|
+
});
|
|
6352
|
+
const data = await res.json();
|
|
6353
|
+
\`\`\`
|
|
6354
|
+
|
|
6355
|
+
### Common Endpoints (Base URL: https://graph.microsoft.com/v1.0)
|
|
6356
|
+
- GET \`/teams\` \u2014 List all teams
|
|
6357
|
+
- GET \`/teams/{id}\` \u2014 Get a team
|
|
6358
|
+
- GET \`/teams/{id}/channels\` \u2014 List channels
|
|
6359
|
+
- GET \`/teams/{id}/channels/{id}/messages\` \u2014 List channel messages
|
|
6360
|
+
- POST \`/teams/{id}/channels/{id}/messages\` \u2014 Send a channel message
|
|
6361
|
+
- GET \`/teams/{id}/members\` \u2014 List team members
|
|
6362
|
+
- GET \`/chats\` \u2014 List chats
|
|
6363
|
+
- GET \`/chats/{id}/messages\` \u2014 List chat messages
|
|
6364
|
+
- POST \`/chats/{id}/messages\` \u2014 Send a chat message
|
|
6365
|
+
- GET \`/users\` \u2014 List users
|
|
6366
|
+
|
|
6367
|
+
### Query Parameters
|
|
6368
|
+
- \`$top\` \u2014 Number of results per page
|
|
6369
|
+
- \`$skip\` \u2014 Number of results to skip
|
|
6370
|
+
- \`$filter\` \u2014 OData filter expression
|
|
6371
|
+
- \`$select\` \u2014 Comma-separated list of properties to return
|
|
6372
|
+
- \`$orderby\` \u2014 Sort order
|
|
6373
|
+
|
|
6374
|
+
### Tips
|
|
6375
|
+
- Use the client credentials flow to get an access token
|
|
6376
|
+
- Application permissions require admin consent in Azure AD
|
|
6377
|
+
- Pagination uses \`@odata.nextLink\` URL in the response
|
|
6378
|
+
- Required API permissions: Team.ReadBasic.All, Channel.ReadBasic.All, ChannelMessage.Read.All, Chat.Read.All, User.Read.All`,
|
|
6379
|
+
tools: tools31
|
|
6380
|
+
});
|
|
6381
|
+
|
|
6382
|
+
// src/connectors/ms-teams-oauth/tools/request.ts
|
|
6383
|
+
import { z as z31 } from "zod";
|
|
6384
|
+
var BASE_URL11 = "https://graph.microsoft.com";
|
|
6385
|
+
var REQUEST_TIMEOUT_MS20 = 6e4;
|
|
6386
|
+
var cachedToken14 = null;
|
|
6387
|
+
async function getProxyToken14(config) {
|
|
6388
|
+
if (cachedToken14 && cachedToken14.expiresAt > Date.now() + 6e4) {
|
|
6389
|
+
return cachedToken14.token;
|
|
6390
|
+
}
|
|
6391
|
+
const url = `${config.appApiBaseUrl}/v0/database/${config.projectId}/environment/${config.environmentId}/oauth-request-proxy-token`;
|
|
6392
|
+
const res = await fetch(url, {
|
|
6393
|
+
method: "POST",
|
|
6394
|
+
headers: {
|
|
6395
|
+
"Content-Type": "application/json",
|
|
6396
|
+
"x-api-key": config.appApiKey,
|
|
6397
|
+
"project-id": config.projectId
|
|
6398
|
+
},
|
|
6399
|
+
body: JSON.stringify({
|
|
6400
|
+
sandboxId: config.sandboxId,
|
|
6401
|
+
issuedBy: "coding-agent"
|
|
6402
|
+
})
|
|
6403
|
+
});
|
|
6404
|
+
if (!res.ok) {
|
|
6405
|
+
const errorText = await res.text().catch(() => res.statusText);
|
|
6406
|
+
throw new Error(
|
|
6407
|
+
`Failed to get proxy token: HTTP ${res.status} ${errorText}`
|
|
6408
|
+
);
|
|
6409
|
+
}
|
|
6410
|
+
const data = await res.json();
|
|
6411
|
+
cachedToken14 = {
|
|
6412
|
+
token: data.token,
|
|
6413
|
+
expiresAt: new Date(data.expiresAt).getTime()
|
|
6414
|
+
};
|
|
6415
|
+
return data.token;
|
|
6416
|
+
}
|
|
6417
|
+
var inputSchema31 = z31.object({
|
|
6418
|
+
toolUseIntent: z31.string().optional().describe(
|
|
6419
|
+
"Brief description of what you intend to accomplish with this tool call"
|
|
6420
|
+
),
|
|
6421
|
+
connectionId: z31.string().describe("ID of the Microsoft Teams OAuth connection to use"),
|
|
6422
|
+
method: z31.enum(["GET", "POST", "PATCH", "DELETE"]).describe("HTTP method"),
|
|
6423
|
+
path: z31.string().describe(
|
|
6424
|
+
"API path appended to https://graph.microsoft.com (e.g., '/v1.0/me/joinedTeams', '/v1.0/teams/{id}/channels')"
|
|
6425
|
+
),
|
|
6426
|
+
queryParams: z31.record(z31.string(), z31.string()).optional().describe("Query parameters to append to the URL"),
|
|
6427
|
+
body: z31.record(z31.string(), z31.unknown()).optional().describe("Request body (JSON) for POST/PATCH requests")
|
|
6428
|
+
});
|
|
6429
|
+
var outputSchema31 = z31.discriminatedUnion("success", [
|
|
6430
|
+
z31.object({
|
|
6431
|
+
success: z31.literal(true),
|
|
6432
|
+
status: z31.number(),
|
|
6433
|
+
data: z31.record(z31.string(), z31.unknown())
|
|
6434
|
+
}),
|
|
6435
|
+
z31.object({
|
|
6436
|
+
success: z31.literal(false),
|
|
6437
|
+
error: z31.string()
|
|
6438
|
+
})
|
|
6439
|
+
]);
|
|
6440
|
+
var requestTool14 = new ConnectorTool({
|
|
6441
|
+
name: "request",
|
|
6442
|
+
description: `Send authenticated requests to the Microsoft Graph API.
|
|
6443
|
+
Authentication is handled automatically via OAuth proxy.`,
|
|
6444
|
+
inputSchema: inputSchema31,
|
|
6445
|
+
outputSchema: outputSchema31,
|
|
6446
|
+
async execute({ connectionId, method, path, queryParams, body }, connections, config) {
|
|
6447
|
+
const connection = connections.find((c) => c.id === connectionId);
|
|
6448
|
+
if (!connection) {
|
|
6449
|
+
return {
|
|
6450
|
+
success: false,
|
|
6451
|
+
error: `Connection ${connectionId} not found`
|
|
6452
|
+
};
|
|
6453
|
+
}
|
|
6454
|
+
console.log(
|
|
6455
|
+
`[connector-request] ms-teams-oauth/${connection.name}: ${method} ${path}`
|
|
6456
|
+
);
|
|
6457
|
+
try {
|
|
6458
|
+
let url = `${BASE_URL11}${path.startsWith("/") ? "" : "/"}${path}`;
|
|
6459
|
+
if (queryParams) {
|
|
6460
|
+
const searchParams = new URLSearchParams(queryParams);
|
|
6461
|
+
url += `?${searchParams.toString()}`;
|
|
6462
|
+
}
|
|
6463
|
+
const token = await getProxyToken14(config.oauthProxy);
|
|
6464
|
+
const proxyUrl = `https://${config.oauthProxy.sandboxId}.${config.oauthProxy.previewBaseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
6465
|
+
const controller = new AbortController();
|
|
6466
|
+
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS20);
|
|
6467
|
+
try {
|
|
6468
|
+
const response = await fetch(proxyUrl, {
|
|
6469
|
+
method: "POST",
|
|
6470
|
+
headers: {
|
|
6471
|
+
"Content-Type": "application/json",
|
|
6472
|
+
Authorization: `Bearer ${token}`
|
|
6473
|
+
},
|
|
6474
|
+
body: JSON.stringify({
|
|
6475
|
+
url,
|
|
6476
|
+
method,
|
|
6477
|
+
body: body ? JSON.stringify(body) : void 0
|
|
6478
|
+
}),
|
|
6479
|
+
signal: controller.signal
|
|
6480
|
+
});
|
|
6481
|
+
const data = await response.json();
|
|
6482
|
+
if (!response.ok) {
|
|
6483
|
+
const errorMessage = typeof data?.error === "string" ? data.error : typeof data?.message === "string" ? data.message : `HTTP ${response.status} ${response.statusText}`;
|
|
6484
|
+
return { success: false, error: errorMessage };
|
|
6485
|
+
}
|
|
6486
|
+
return { success: true, status: response.status, data };
|
|
6487
|
+
} finally {
|
|
6488
|
+
clearTimeout(timeout);
|
|
6489
|
+
}
|
|
6490
|
+
} catch (err) {
|
|
6491
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6492
|
+
return { success: false, error: msg };
|
|
6493
|
+
}
|
|
6494
|
+
}
|
|
6495
|
+
});
|
|
6496
|
+
|
|
6497
|
+
// src/connectors/ms-teams-oauth/setup.ts
|
|
6498
|
+
var requestToolName6 = `ms-teams-oauth_${requestTool14.name}`;
|
|
6499
|
+
var msTeamsOauthSetup = new ConnectorSetup({
|
|
6500
|
+
ja: `## Microsoft Teams \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u624B\u9806
|
|
6501
|
+
|
|
6502
|
+
\u4EE5\u4E0B\u306E\u624B\u9806\u3067Microsoft Teams\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3092\u884C\u3063\u3066\u304F\u3060\u3055\u3044\u3002
|
|
6503
|
+
|
|
6504
|
+
### \u624B\u9806
|
|
6505
|
+
|
|
6506
|
+
#### \u30B9\u30C6\u30C3\u30D71: \u63A5\u7D9A\u78BA\u8A8D
|
|
6507
|
+
1. \`${requestToolName6}\` \u3092\u547C\u3073\u51FA\u3057\u3066\u3001\u30E6\u30FC\u30B6\u30FC\u60C5\u5831\u3092\u53D6\u5F97\u3059\u308B:
|
|
6508
|
+
- \`method\`: \`"GET"\`
|
|
6509
|
+
- \`path\`: \`"/v1.0/me"\`
|
|
6510
|
+
2. \u30A8\u30E9\u30FC\u304C\u8FD4\u3055\u308C\u305F\u5834\u5408\u3001\u30E6\u30FC\u30B6\u30FC\u306BOAuth\u63A5\u7D9A\u306E\u8A2D\u5B9A\u3092\u78BA\u8A8D\u3059\u308B\u3088\u3046\u4F1D\u3048\u308B
|
|
6511
|
+
|
|
6512
|
+
#### \u30B9\u30C6\u30C3\u30D72: \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u5B8C\u4E86
|
|
6513
|
+
1. \`updateConnectionContext\` \u3092\u547C\u3073\u51FA\u3059:
|
|
6514
|
+
- \`user\`: Microsoft \u30E6\u30FC\u30B6\u30FC\u60C5\u5831
|
|
6515
|
+
- \`note\`: \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u5185\u5BB9\u306E\u7C21\u5358\u306A\u8AAC\u660E
|
|
6516
|
+
|
|
6517
|
+
### \u91CD\u8981\u306A\u5236\u7D04
|
|
6518
|
+
- **\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u4E2D\u306B\u30E1\u30C3\u30BB\u30FC\u30B8\u3084\u30C1\u30E3\u30C3\u30C8\u306E\u5185\u5BB9\u3092\u8AAD\u307F\u53D6\u3089\u306A\u3044\u3053\u3068**\u3002\u5B9F\u884C\u3057\u3066\u3088\u3044\u306E\u306F\u4E0A\u8A18\u624B\u9806\u3067\u6307\u5B9A\u3055\u308C\u305F\u30E1\u30BF\u30C7\u30FC\u30BF\u53D6\u5F97\u30EA\u30AF\u30A8\u30B9\u30C8\u306E\u307F
|
|
6519
|
+
|
|
6520
|
+
### \u5B9F\u884C\u65B9\u91DD
|
|
6521
|
+
- \u30C4\u30FC\u30EB\u9593\u306F1\u6587\u3060\u3051\u66F8\u3044\u3066\u5373\u6B21\u306E\u30C4\u30FC\u30EB\u547C\u3073\u51FA\u3057
|
|
6522
|
+
- \u4E0D\u8981\u306A\u8AAC\u660E\u306F\u7701\u7565\u3057\u3001\u52B9\u7387\u7684\u306B\u9032\u3081\u308B`,
|
|
6523
|
+
en: `## Microsoft Teams Setup Instructions
|
|
6524
|
+
|
|
6525
|
+
Follow these steps to set up the Microsoft Teams connection.
|
|
6526
|
+
|
|
6527
|
+
### Steps
|
|
6528
|
+
|
|
6529
|
+
#### Step 1: Verify Connection
|
|
6530
|
+
1. Call \`${requestToolName6}\` to fetch user info:
|
|
6531
|
+
- \`method\`: \`"GET"\`
|
|
6532
|
+
- \`path\`: \`"/v1.0/me"\`
|
|
6533
|
+
2. If an error is returned, ask the user to check the OAuth connection settings
|
|
6534
|
+
|
|
6535
|
+
#### Step 2: Complete Setup
|
|
6536
|
+
1. Call \`updateConnectionContext\`:
|
|
6537
|
+
- \`user\`: Microsoft user info
|
|
6538
|
+
- \`note\`: Brief description of the setup
|
|
6539
|
+
|
|
6540
|
+
### Important Constraints
|
|
6541
|
+
- **Do NOT read messages or chat content during setup**. Only the metadata request specified in the steps above is allowed
|
|
6542
|
+
|
|
6543
|
+
### Execution Policy
|
|
6544
|
+
- Write only 1 sentence between tool calls, then immediately call the next tool
|
|
6545
|
+
- Skip unnecessary explanations and proceed efficiently`
|
|
6546
|
+
});
|
|
6547
|
+
|
|
6548
|
+
// src/connectors/ms-teams-oauth/parameters.ts
|
|
6549
|
+
var parameters32 = {};
|
|
6550
|
+
|
|
6551
|
+
// src/connectors/ms-teams-oauth/index.ts
|
|
6552
|
+
var tools32 = { request: requestTool14 };
|
|
6553
|
+
var msTeamsOauthConnector = new ConnectorPlugin({
|
|
6554
|
+
slug: "ms-teams",
|
|
6555
|
+
authType: AUTH_TYPES.OAUTH,
|
|
6556
|
+
name: "Microsoft Teams (OAuth)",
|
|
6557
|
+
description: "Connect to Microsoft Teams for messaging, channels, and team data using OAuth.",
|
|
6558
|
+
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/6QM1sVuqarTJAB2UihVNQ9/12b8353c9b022916d72ef0f53349bae2/microsoft-teams-icon.svg",
|
|
6559
|
+
parameters: parameters32,
|
|
6560
|
+
releaseFlag: { dev1: true, dev2: false, prod: false },
|
|
6561
|
+
setup: msTeamsOauthSetup,
|
|
6562
|
+
proxyPolicy: {
|
|
6563
|
+
allowlist: [
|
|
6564
|
+
{
|
|
6565
|
+
host: "graph.microsoft.com",
|
|
6566
|
+
methods: ["GET", "POST", "PATCH", "DELETE"]
|
|
6567
|
+
}
|
|
6568
|
+
]
|
|
6569
|
+
},
|
|
6570
|
+
systemPrompt: `## Microsoft Teams API (OAuth)
|
|
6571
|
+
|
|
6572
|
+
### Available Endpoints (Microsoft Graph API v1.0)
|
|
6573
|
+
- GET \`/v1.0/me\` \u2014 Get current user info
|
|
6574
|
+
- GET \`/v1.0/me/joinedTeams\` \u2014 List joined teams
|
|
6575
|
+
- GET \`/v1.0/teams/{teamId}\` \u2014 Get a team
|
|
6576
|
+
- GET \`/v1.0/teams/{teamId}/channels\` \u2014 List channels
|
|
6577
|
+
- GET \`/v1.0/teams/{teamId}/channels/{channelId}\` \u2014 Get a channel
|
|
6578
|
+
- GET \`/v1.0/teams/{teamId}/channels/{channelId}/messages\` \u2014 List channel messages
|
|
6579
|
+
- POST \`/v1.0/teams/{teamId}/channels/{channelId}/messages\` \u2014 Send a channel message
|
|
6580
|
+
- GET \`/v1.0/teams/{teamId}/members\` \u2014 List team members
|
|
6581
|
+
- GET \`/v1.0/chats\` \u2014 List chats
|
|
6582
|
+
- GET \`/v1.0/chats/{chatId}/messages\` \u2014 List chat messages
|
|
6583
|
+
- POST \`/v1.0/chats/{chatId}/messages\` \u2014 Send a chat message
|
|
6584
|
+
- GET \`/v1.0/users\` \u2014 List users
|
|
6585
|
+
|
|
6586
|
+
### Query Parameters
|
|
6587
|
+
- \`$top\` \u2014 Number of results per page (max varies by endpoint)
|
|
6588
|
+
- \`$skip\` \u2014 Number of results to skip
|
|
6589
|
+
- \`$filter\` \u2014 OData filter expression
|
|
6590
|
+
- \`$select\` \u2014 Comma-separated list of properties to return
|
|
6591
|
+
- \`$orderby\` \u2014 Sort order
|
|
6592
|
+
- \`$expand\` \u2014 Related resources to include
|
|
6593
|
+
|
|
6594
|
+
### Tips
|
|
6595
|
+
- Pagination uses \`@odata.nextLink\` URL in the response
|
|
6596
|
+
- Use \`$select\` to limit response size
|
|
6597
|
+
- Channel messages require \`ChannelMessage.Read.All\` permission
|
|
6598
|
+
- Chat messages require \`Chat.Read\` permission
|
|
6599
|
+
|
|
6600
|
+
## Microsoft Teams SDK (TypeScript handler)
|
|
6601
|
+
|
|
6602
|
+
\`\`\`ts
|
|
6603
|
+
import { connection } from "@squadbase/vite-server/connectors/ms-teams-oauth";
|
|
6604
|
+
|
|
6605
|
+
const teams = connection("<connectionId>");
|
|
6606
|
+
|
|
6607
|
+
// Authenticated fetch (returns standard Response)
|
|
6608
|
+
const res = await teams.request("/v1.0/me/joinedTeams");
|
|
6609
|
+
const data = await res.json();
|
|
6610
|
+
\`\`\``,
|
|
6611
|
+
tools: tools32,
|
|
6612
|
+
async checkConnection(_params, config) {
|
|
6613
|
+
const { proxyFetch } = config;
|
|
6614
|
+
try {
|
|
6615
|
+
const res = await proxyFetch("https://graph.microsoft.com/v1.0/me", {
|
|
6616
|
+
method: "GET"
|
|
6617
|
+
});
|
|
6618
|
+
if (!res.ok) {
|
|
6619
|
+
const errorText = await res.text().catch(() => res.statusText);
|
|
6620
|
+
return {
|
|
6621
|
+
success: false,
|
|
6622
|
+
error: `Microsoft Graph API failed: HTTP ${res.status} ${errorText}`
|
|
6623
|
+
};
|
|
6624
|
+
}
|
|
6625
|
+
return { success: true };
|
|
6626
|
+
} catch (error) {
|
|
6627
|
+
return {
|
|
6628
|
+
success: false,
|
|
6629
|
+
error: error instanceof Error ? error.message : String(error)
|
|
6630
|
+
};
|
|
6631
|
+
}
|
|
6632
|
+
}
|
|
4917
6633
|
});
|
|
4918
6634
|
|
|
4919
6635
|
// src/connectors/registry.ts
|
|
@@ -4932,11 +6648,24 @@ var plugins = {
|
|
|
4932
6648
|
googleAnalytics: googleAnalyticsConnector,
|
|
4933
6649
|
googleAnalyticsOauth: googleAnalyticsOauthConnector,
|
|
4934
6650
|
googleSheetsOauth: googleSheetsOauthConnector,
|
|
6651
|
+
hubspotOauth: hubspotOauthConnector,
|
|
6652
|
+
stripeOauth: stripeOauthConnector,
|
|
4935
6653
|
airtable: airtableConnector,
|
|
6654
|
+
airtableOauth: airtableOauthConnector,
|
|
4936
6655
|
squadbaseDb: squadbaseDbConnector,
|
|
4937
6656
|
kintone: kintoneConnector,
|
|
6657
|
+
kintoneApiToken: kintoneApiTokenConnector,
|
|
4938
6658
|
wixStore: wixStoreConnector,
|
|
4939
|
-
openai: openaiConnector
|
|
6659
|
+
openai: openaiConnector,
|
|
6660
|
+
gemini: geminiConnector,
|
|
6661
|
+
anthropic: anthropicConnector,
|
|
6662
|
+
amplitude: amplitudeConnector,
|
|
6663
|
+
attio: attioConnector,
|
|
6664
|
+
shopify: shopifyConnector,
|
|
6665
|
+
slack: slackConnector,
|
|
6666
|
+
shopifyOauth: shopifyOauthConnector,
|
|
6667
|
+
msTeams: msTeamsConnector,
|
|
6668
|
+
msTeamsOauth: msTeamsOauthConnector
|
|
4940
6669
|
};
|
|
4941
6670
|
var connectors = {
|
|
4942
6671
|
...plugins,
|
|
@@ -4977,10 +6706,13 @@ export {
|
|
|
4977
6706
|
googleAnalyticsOauthConnector,
|
|
4978
6707
|
googleSheetsOauthConnector,
|
|
4979
6708
|
kintoneConnector,
|
|
6709
|
+
msTeamsConnector,
|
|
6710
|
+
msTeamsOauthConnector,
|
|
4980
6711
|
mysqlConnector,
|
|
4981
6712
|
openaiConnector,
|
|
4982
6713
|
postgresqlConnector,
|
|
4983
6714
|
redshiftConnector,
|
|
6715
|
+
shopifyOauthConnector,
|
|
4984
6716
|
snowflakeConnector,
|
|
4985
6717
|
snowflakePatConnector,
|
|
4986
6718
|
squadbaseDbConnector,
|