@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/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-LB7J6VXK.js";
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 parameters10 = {
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 = parameters10.account.getValue(connection);
355
- const user = parameters10.user.getValue(connection);
356
- const role = parameters10.role.getValue(connection);
357
- const warehouse = parameters10.warehouse.getValue(connection);
358
- const privateKeyBase64 = parameters10.privateKeyBase64.getValue(connection);
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 = parameters10.privateKeyPassphrase.tryGetValue(connection);
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: parameters10,
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[parameters10.privateKeyBase64.slug],
453
+ params[parameters19.privateKeyBase64.slug],
445
454
  "base64"
446
455
  ).toString("utf-8");
447
- const privateKeyPass = params[parameters10.privateKeyPassphrase.slug] || void 0;
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[parameters10.account.slug],
451
- username: params[parameters10.user.slug],
452
- role: params[parameters10.role.slug],
453
- warehouse: params[parameters10.warehouse.slug],
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[parameters10.privateKeyBase64.slug],
494
+ params[parameters19.privateKeyBase64.slug],
486
495
  "base64"
487
496
  ).toString("utf-8");
488
- const privateKeyPass = params[parameters10.privateKeyPassphrase.slug] || void 0;
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[parameters10.account.slug],
492
- username: params[parameters10.user.slug],
493
- role: params[parameters10.role.slug],
494
- warehouse: params[parameters10.warehouse.slug],
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 parameters11 = {
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 = parameters11.account.getValue(connection);
618
- const user = parameters11.user.getValue(connection);
619
- const role = parameters11.role.getValue(connection);
620
- const warehouse = parameters11.warehouse.getValue(connection);
621
- const password = parameters11.pat.getValue(connection);
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: parameters11,
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[parameters11.account.slug],
702
- username: params[parameters11.user.slug],
703
- role: params[parameters11.role.slug],
704
- warehouse: params[parameters11.warehouse.slug],
705
- password: params[parameters11.pat.slug]
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[parameters11.account.slug],
741
- username: params[parameters11.user.slug],
742
- role: params[parameters11.role.slug],
743
- warehouse: params[parameters11.warehouse.slug],
744
- password: params[parameters11.pat.slug]
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 parameters12 = {
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 = parameters12.connectionUrl.getValue(connection);
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: parameters12,
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[parameters12.connectionUrl.slug],
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[parameters12.connectionUrl.slug],
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 parameters13 = {
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 = parameters13.connectionUrl.getValue(connection);
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: parameters13,
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[parameters13.connectionUrl.slug],
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[parameters13.connectionUrl.slug],
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 parameters14 = {
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 = parameters14.serviceAccountKeyJsonBase64.getValue(connection);
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 = parameters14.projectId.getValue(connection);
1181
- const serviceAccountJsonBase64 = parameters14.serviceAccountKeyJsonBase64.getValue(connection);
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 = parameters14.projectId.getValue(connection);
1343
- const serviceAccountJsonBase64 = parameters14.serviceAccountKeyJsonBase64.getValue(connection);
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: parameters14,
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[parameters14.serviceAccountKeyJsonBase64.slug], "base64").toString("utf-8")
1396
+ Buffer.from(params[parameters23.serviceAccountKeyJsonBase64.slug], "base64").toString("utf-8")
1388
1397
  );
1389
1398
  const bq = new BigQuery({
1390
- projectId: params[parameters14.projectId.slug],
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[parameters14.serviceAccountKeyJsonBase64.slug], "base64").toString("utf-8")
1414
+ Buffer.from(params[parameters23.serviceAccountKeyJsonBase64.slug], "base64").toString("utf-8")
1406
1415
  );
1407
1416
  const bq = new BigQuery({
1408
- projectId: params[parameters14.projectId.slug],
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 parameters15 = {
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 = parameters15.projectId.getValue(connection);
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 = parameters15.projectId.getValue(connection);
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: parameters15,
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[parameters15.projectId.slug];
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[parameters15.projectId.slug];
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 parameters16 = {
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 = parameters16.workgroup.tryGetValue(connection);
2050
- const outputLocation = parameters16.outputLocation.tryGetValue(connection);
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: parameters16.awsRegion.getValue(connection),
2067
+ region: parameters25.awsRegion.getValue(connection),
2059
2068
  credentials: {
2060
- accessKeyId: parameters16.awsAccessKeyId.getValue(connection),
2061
- secretAccessKey: parameters16.awsSecretAccessKey.getValue(connection)
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: parameters16,
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[parameters16.workgroup.slug];
2144
- const outputLocation = params[parameters16.outputLocation.slug];
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[parameters16.awsRegion.slug],
2161
+ region: params[parameters25.awsRegion.slug],
2153
2162
  credentials: {
2154
- accessKeyId: params[parameters16.awsAccessKeyId.slug],
2155
- secretAccessKey: params[parameters16.awsSecretAccessKey.slug]
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[parameters16.workgroup.slug];
2201
- const outputLocation = params[parameters16.outputLocation.slug];
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[parameters16.awsRegion.slug],
2215
+ region: params[parameters25.awsRegion.slug],
2207
2216
  credentials: {
2208
- accessKeyId: params[parameters16.awsAccessKeyId.slug],
2209
- secretAccessKey: params[parameters16.awsSecretAccessKey.slug]
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 parameters17 = {
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 = parameters17.awsAccessKeyId.getValue(connection);
2381
- const awsSecretAccessKey = parameters17.awsSecretAccessKey.getValue(connection);
2382
- const awsRegion = parameters17.awsRegion.getValue(connection);
2383
- const database = parameters17.database.getValue(connection);
2384
- const clusterIdentifier = parameters17.clusterIdentifier.tryGetValue(connection);
2385
- const workgroupName = parameters17.workgroupName.tryGetValue(connection);
2386
- const secretArn = parameters17.secretArn.tryGetValue(connection);
2387
- const dbUser = parameters17.dbUser.tryGetValue(connection);
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: parameters17,
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[parameters17.clusterIdentifier.slug];
2477
- const workgroupName = params[parameters17.workgroupName.slug];
2478
- const secretArn = params[parameters17.secretArn.slug];
2479
- const dbUser = params[parameters17.dbUser.slug];
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[parameters17.awsRegion.slug],
2496
+ region: params[parameters26.awsRegion.slug],
2488
2497
  credentials: {
2489
- accessKeyId: params[parameters17.awsAccessKeyId.slug],
2490
- secretAccessKey: params[parameters17.awsSecretAccessKey.slug]
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[parameters17.database.slug],
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[parameters17.clusterIdentifier.slug];
2537
- const workgroupName = params[parameters17.workgroupName.slug];
2538
- const secretArn = params[parameters17.secretArn.slug];
2539
- const dbUser = params[parameters17.dbUser.slug];
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[parameters17.awsRegion.slug],
2553
+ region: params[parameters26.awsRegion.slug],
2545
2554
  credentials: {
2546
- accessKeyId: params[parameters17.awsAccessKeyId.slug],
2547
- secretAccessKey: params[parameters17.awsSecretAccessKey.slug]
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[parameters17.database.slug],
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 parameters18 = {
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 = parameters18.host.getValue(connection);
2663
- const token = parameters18.token.getValue(connection);
2664
- const httpPath = parameters18.httpPath.getValue(connection);
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: parameters18,
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[parameters18.host.slug],
2721
- path: params[parameters18.httpPath.slug],
2722
- token: params[parameters18.token.slug]
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[parameters18.host.slug],
2750
- path: params[parameters18.httpPath.slug],
2751
- token: params[parameters18.token.slug]
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/kintone/tools/request.ts
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("Brief description of what you intend to accomplish with this tool call"),
4310
- connectionId: z22.string().describe("ID of the kintone connection to use"),
4311
- method: z22.enum(["GET", "POST", "PUT", "DELETE"]).describe("HTTP method"),
4312
- path: z22.string().describe("API path (e.g., 'apps.json', 'records.json?app=1&query=...')"),
4313
- body: z22.record(z22.string(), z22.unknown()).optional().describe("Request body (JSON)")
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 kintone REST API.
4329
- Authentication is handled automatically using username and password.`,
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 { success: false, error: `Connection ${connectionId} not found` };
4381
+ return {
4382
+ success: false,
4383
+ error: `Connection ${connectionId} not found`
4384
+ };
4336
4385
  }
4337
- console.log(`[connector-request] kintone/${connection.name}: ${method} ${path}`);
4386
+ console.log(
4387
+ `[connector-request] hubspot-oauth/${connection.name}: ${method} ${path}`
4388
+ );
4338
4389
  try {
4339
- const baseUrl = parameters6.baseUrl.getValue(connection);
4340
- const username = parameters6.username.getValue(connection);
4341
- const password = parameters6.password.getValue(connection);
4342
- const authToken = Buffer.from(`${username}:${password}`).toString("base64");
4343
- const url = `${baseUrl.replace(/\/+$/, "")}/k/v1/${path}`;
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 headers = {
4348
- "X-Cybozu-Authorization": authToken
4349
- };
4350
- if (body) {
4351
- headers["Content-Type"] = "application/json";
4352
- }
4353
- const response = await fetch(url, {
4354
- method,
4355
- headers,
4356
- body: body ? JSON.stringify(body) : void 0,
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
- return {
4362
- success: false,
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/kintone/index.ts
4378
- var tools15 = { request: requestTool6 };
4379
- var kintoneConnector = new ConnectorPlugin({
4380
- slug: "kintone",
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
- ### List Apps
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
- ### Get Field Definitions
4395
- - GET app/form/fields.json?app={appId}
4436
+ ### \u624B\u9806
4396
4437
 
4397
- ### Get Records
4398
- - GET records.json?app={appId}&query={query}
4399
- - Query example: records.json?app=1&query=updatedTime > "2024-01-01" order by recordNumber asc limit 100
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
- ### Add Record
4402
- - POST record.json
4403
- - Body: { "app": 1, "record": { "fieldName": { "value": "value" } } }
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
- ### kintone Query Syntax
4406
- - Comparison: fieldName = "value", fieldName > 100
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
- ## kintone SDK (TypeScript handler)
4413
- Non-SQL connectors like kintone can also be used via the SDK in TypeScript handlers:
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
- \`\`\`ts
4416
- import { connection } from "@squadbase/vite-server/connectors/kintone";
4457
+ Follow these steps to set up the HubSpot connection.
4417
4458
 
4418
- const kintone = connection("<connectionId>");
4459
+ ### Steps
4419
4460
 
4420
- // Authenticated fetch (returns standard Response)
4421
- const res = await kintone.request("/k/v1/records.json?app=1&query=limit 10");
4422
- const data = await res.json();
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
- await kintone.request("/k/v1/record.json", {
4425
- method: "POST",
4426
- body: JSON.stringify({ app: 1, record: { title: { value: "Hello" } } }),
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
- // Convenience methods (uses @kintone/rest-api-client)
4430
- const { records, totalCount } = await kintone.getRecords(1, {
4431
- query: 'status = "Active"',
4432
- fields: ["name", "email"],
4433
- totalCount: true,
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
- const { record } = await kintone.getRecord(1, 100);
4436
- const { apps } = await kintone.listApps();
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/wix-store/tools/request.ts
4564
+ // src/connectors/stripe-oauth/tools/request.ts
4442
4565
  import { z as z23 } from "zod";
4443
- var BASE_URL7 = "https://www.wixapis.com/";
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("Brief description of what you intend to accomplish with this tool call"),
4447
- connectionId: z23.string().describe("ID of the Wix Store connection to use"),
4448
- method: z23.enum(["GET", "POST"]).describe("HTTP method"),
4449
- path: z23.string().describe("API path (e.g., 'stores/v1/products/query', 'stores/v2/orders/query')"),
4450
- body: z23.record(z23.string(), z23.unknown()).optional().describe("Request body (JSON)")
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 Wix Store API.
4466
- Authentication is handled automatically using the API Key and Site ID.`,
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 { success: false, error: `Connection ${connectionId} not found` };
4631
+ return {
4632
+ success: false,
4633
+ error: `Connection ${connectionId} not found`
4634
+ };
4473
4635
  }
4474
- console.log(`[connector-request] wix-store/${connection.name}: ${method} ${path}`);
4636
+ console.log(
4637
+ `[connector-request] stripe-oauth/${connection.name}: ${method} ${path}`
4638
+ );
4475
4639
  try {
4476
- const apiKey = parameters7.apiKey.getValue(connection);
4477
- const siteId = parameters7.siteId.getValue(connection);
4478
- const url = `${BASE_URL7}${path}`;
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(url, {
4483
- method,
4650
+ const response = await fetch(proxyUrl, {
4651
+ method: "POST",
4484
4652
  headers: {
4485
- Authorization: apiKey,
4486
- "wix-site-id": siteId,
4487
- "Content-Type": "application/json"
4653
+ "Content-Type": "application/json",
4654
+ Authorization: `Bearer ${token}`
4488
4655
  },
4489
- body: body ? JSON.stringify(body) : void 0,
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 errorObj = data?.message;
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/wix-store/index.ts
4512
- var tools16 = { request: requestTool7 };
4513
- var wixStoreConnector = new ConnectorPlugin({
4514
- slug: "wix-store",
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
- ### List Products
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
- ### Search Products (with filter)
4533
- - POST stores/v1/products/query
4534
- - Body: { "query": { "filter": { "name": { "$contains": "keyword" } }, "paging": { "limit": 50 } } }
4686
+ ### \u624B\u9806
4535
4687
 
4536
- ### Search Orders (eCommerce Orders V1)
4537
- - POST ecom/v1/orders/search
4538
- - Body: { "search": { "cursorPaging": { "limit": 50 } } }
4539
- - Uses cursor-based pagination (cursorPaging, not paging)
4540
- - Response includes pagingMetadata.cursors.next for pagination
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
- ### List Collections (Categories)
4543
- - POST stores/v1/collections/query
4544
- - Body: { "query": { "paging": { "limit": 50 } } }
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
- ### List Inventory Items
4547
- - POST stores/v2/inventoryItems/query
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
- ## Wix Store SDK (TypeScript handler)
4551
- Non-SQL connectors like Wix Store can also be used via the SDK in TypeScript handlers:
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/wix-store";
4785
+ import { connection } from "@squadbase/vite-server/connectors/stripe-oauth";
4555
4786
 
4556
- const wix = connection("<connectionId>");
4787
+ const stripe = connection("<connectionId>");
4557
4788
 
4558
4789
  // Authenticated fetch (returns standard Response)
4559
- const res = await wix.request("/stores/v1/products/query", {
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/dbt/tools/request.ts
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
- function resolveGraphqlEndpoint(host) {
4581
- if (host.includes("emea")) return "https://metadata.emea.dbt.com/graphql";
4582
- if (host.includes(".au.")) return "https://metadata.au.dbt.com/graphql";
4583
- return "https://metadata.cloud.getdbt.com/graphql";
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("Brief description of what you intend to accomplish with this tool call"),
4587
- connectionId: z24.string().describe("ID of the dbt Cloud connection to use"),
4588
- query: z24.string().describe("GraphQL query"),
4589
- variables: z24.record(z24.string(), z24.unknown()).optional().describe("GraphQL variables (JSON)")
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 dbt Cloud Discovery API (GraphQL).
4604
- Authentication is handled automatically using the API token.
4605
- {environmentId} in GraphQL variables is automatically replaced with the prod-env-id.`,
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, query, variables }, connections) {
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 { success: false, error: `Connection ${connectionId} not found` };
4885
+ return {
4886
+ success: false,
4887
+ error: `Connection ${connectionId} not found`
4888
+ };
4612
4889
  }
4613
- console.log(`[connector-request] dbt/${connection.name}: GraphQL query`);
4890
+ console.log(
4891
+ `[connector-request] airtable-oauth/${connection.name}: ${method} ${path}`
4892
+ );
4614
4893
  try {
4615
- const host = parameters8.host.getValue(connection);
4616
- const token = parameters8.token.getValue(connection);
4617
- const environmentId = parameters8.prodEnvId.getValue(connection);
4618
- const resolvedVariables = variables ? JSON.parse(
4619
- JSON.stringify(variables).replace(/\{environmentId\}/g, environmentId)
4620
- ) : void 0;
4621
- const endpoint = resolveGraphqlEndpoint(host);
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(endpoint, {
4906
+ const response = await fetch(proxyUrl, {
4626
4907
  method: "POST",
4627
4908
  headers: {
4628
- Authorization: `Bearer ${token}`,
4629
- "Content-Type": "application/json"
4909
+ "Content-Type": "application/json",
4910
+ Authorization: `Bearer ${token}`
4630
4911
  },
4631
- body: JSON.stringify({ query, variables: resolvedVariables }),
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
- return {
4637
- success: false,
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/dbt/index.ts
4660
- var tools17 = { request: requestTool8 };
4661
- var dbtConnector = new ConnectorPlugin({
4662
- slug: "dbt",
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
- ### List Models
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
- ### List Sources
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
- ### Model Column Information
4704
- query:
4705
- query($environmentId: BigInt!, $uniqueId: String!) {
4706
- environment(id: $environmentId) {
4707
- applied {
4708
- models(filter: { uniqueId: { eq: $uniqueId } }) {
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
- ### Lineage (Dependencies)
4718
- - Traverse relationships using ancestors / children fields
4719
- - Get ancestors { uniqueId name } or children { uniqueId name } within node
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
- ## dbt SDK (TypeScript handler)
4722
- Non-SQL connectors like dbt can also be used via the SDK in TypeScript handlers:
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
- \`\`\`ts
4725
- import { connection } from "@squadbase/vite-server/connectors/dbt";
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
- const dbt = connection("<connectionId>");
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
- // Authenticated fetch (returns standard Response)
4730
- const res = await dbt.request("/graphql", {
4731
- method: "POST",
4732
- headers: { "Content-Type": "application/json" },
4733
- body: JSON.stringify({ query: "{ ... }", variables: {} }),
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
- // Convenience methods
4738
- const result = await dbt.query(\`
4739
- query($environmentId: BigInt!) {
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/squadbase-db/parameters.ts
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 MAX_ROWS10 = 500;
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
- "Brief description of what you intend to accomplish with this tool call"
4773
- ),
4774
- connectionId: z25.string().describe("ID of the Squadbase DB connection to use"),
4775
- sql: z25.string().describe("PostgreSQL SQL query. Always include LIMIT in queries.")
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
- rowCount: z25.number(),
4781
- truncated: z25.boolean(),
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 executeQueryTool10 = new ConnectorTool({
4790
- name: "executeQuery",
4791
- description: `Execute SQL against Squadbase DB (PostgreSQL). Returns up to ${MAX_ROWS10} rows.
4792
- Use for: schema exploration (information_schema), data sampling, analytical queries.
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, sql }, connections) {
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 { Pool } = await import("pg");
4810
- connectionUrl = parameters19.connectionUrl.getValue(connection);
4811
- const pool = new Pool({
4812
- connectionString: connectionUrl,
4813
- ssl: { rejectUnauthorized: false },
4814
- connectionTimeoutMillis: CONNECT_TIMEOUT_MS3,
4815
- statement_timeout: STATEMENT_TIMEOUT_MS2
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 result = await pool.query(sql);
4819
- const rows = result.rows;
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
- await pool.end();
5153
+ clearTimeout(timeout);
4829
5154
  }
4830
5155
  } catch (err) {
4831
- let msg = err instanceof Error ? err.message : String(err);
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/squadbase-db/index.ts
4841
- var tools18 = { executeQuery: executeQueryTool10 };
4842
- var squadbaseDbConnector = new ConnectorPlugin({
4843
- slug: "squadbase-db",
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: "Squadbase DB",
4846
- description: "Connect to Squadbase DB (PostgreSQL).",
4847
- iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/25y0XqMxIufeD3egWH3bEl/659b4ade405890654cfaf91c03a4b458/icon.svg",
4848
- parameters: parameters19,
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: `## Squadbase DB SQL Notes
4851
- - Uses PostgreSQL based SQL syntax
4852
- - Schema exploration:
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
- // src/connectors/openai/index.ts
4892
- var tools19 = {};
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
- \`\`\`ts
4905
- import { connection } from "@squadbase/vite-server/connectors/openai";
4906
- import OpenAI from "openai";
5179
+ ### Get Field Definitions
5180
+ - GET app/form/fields.json?app={appId}
4907
5181
 
4908
- const { apiKey } = connection("<connectionId>");
4909
- const client = new OpenAI({ apiKey });
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
- const response = await client.chat.completions.create({
4912
- model: "gpt-4o",
4913
- messages: [{ role: "user", content: "Hello" }],
4914
- });
4915
- \`\`\``,
4916
- tools: tools19
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,