@squadbase/vite-server 0.1.12-dev.8860f37 → 0.1.12-dev.93b8799

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.
Files changed (78) hide show
  1. package/dist/cli/index.js +482 -573
  2. package/dist/connectors/airtable-oauth.js +9 -0
  3. package/dist/connectors/airtable.js +9 -0
  4. package/dist/connectors/amplitude.js +9 -0
  5. package/dist/connectors/anthropic.js +9 -0
  6. package/dist/connectors/asana.js +9 -0
  7. package/dist/connectors/attio.js +9 -0
  8. package/dist/connectors/aws-billing.js +9 -0
  9. package/dist/connectors/azure-sql.js +9 -0
  10. package/dist/connectors/backlog-api-key.js +9 -0
  11. package/dist/connectors/clickup.js +9 -0
  12. package/dist/connectors/cosmosdb.js +9 -0
  13. package/dist/connectors/customerio.js +9 -0
  14. package/dist/connectors/dbt.js +9 -0
  15. package/dist/connectors/freshdesk.js +9 -0
  16. package/dist/connectors/freshsales.js +9 -0
  17. package/dist/connectors/freshservice.js +9 -0
  18. package/dist/connectors/gamma.js +9 -0
  19. package/dist/connectors/gemini.js +9 -0
  20. package/dist/connectors/github.js +9 -0
  21. package/dist/connectors/gmail-oauth.js +9 -0
  22. package/dist/connectors/gmail.js +9 -0
  23. package/dist/connectors/google-ads.js +9 -0
  24. package/dist/connectors/google-analytics-oauth.js +9 -0
  25. package/dist/connectors/google-analytics.js +9 -0
  26. package/dist/connectors/google-audit-log.js +9 -0
  27. package/dist/connectors/google-calendar-oauth.js +9 -0
  28. package/dist/connectors/google-calendar.js +9 -0
  29. package/dist/connectors/google-docs.js +9 -0
  30. package/dist/connectors/google-drive.js +9 -0
  31. package/dist/connectors/google-search-console-oauth.js +9 -0
  32. package/dist/connectors/google-sheets.js +9 -0
  33. package/dist/connectors/google-slides.js +9 -0
  34. package/dist/connectors/grafana.js +9 -0
  35. package/dist/connectors/hubspot-oauth.js +9 -0
  36. package/dist/connectors/hubspot.js +9 -0
  37. package/dist/connectors/influxdb.js +9 -0
  38. package/dist/connectors/intercom-oauth.js +9 -0
  39. package/dist/connectors/intercom.js +9 -0
  40. package/dist/connectors/jdbc.js +9 -0
  41. package/dist/connectors/jira-api-key.js +9 -0
  42. package/dist/connectors/kintone-api-token.js +9 -0
  43. package/dist/connectors/kintone.js +9 -0
  44. package/dist/connectors/linear.js +9 -0
  45. package/dist/connectors/linkedin-ads.js +9 -0
  46. package/dist/connectors/mailchimp-oauth.js +9 -0
  47. package/dist/connectors/mailchimp.js +9 -0
  48. package/dist/connectors/meta-ads-oauth.js +9 -0
  49. package/dist/connectors/meta-ads.js +9 -0
  50. package/dist/connectors/mixpanel.js +9 -0
  51. package/dist/connectors/monday.js +9 -0
  52. package/dist/connectors/mongodb.js +9 -0
  53. package/dist/connectors/notion-oauth.js +9 -0
  54. package/dist/connectors/notion.js +9 -0
  55. package/dist/connectors/openai.js +9 -0
  56. package/dist/connectors/oracle.js +9 -0
  57. package/dist/connectors/outlook-oauth.js +10 -1
  58. package/dist/connectors/powerbi-oauth.js +11 -2
  59. package/dist/connectors/salesforce.js +9 -0
  60. package/dist/connectors/semrush.js +9 -0
  61. package/dist/connectors/sentry.js +9 -0
  62. package/dist/connectors/shopify-oauth.js +9 -0
  63. package/dist/connectors/shopify.js +9 -0
  64. package/dist/connectors/sqlserver.js +9 -0
  65. package/dist/connectors/stripe-api-key.js +9 -0
  66. package/dist/connectors/stripe-oauth.js +9 -0
  67. package/dist/connectors/supabase.js +9 -0
  68. package/dist/connectors/tableau.js +131 -57
  69. package/dist/connectors/tiktok-ads.js +9 -0
  70. package/dist/connectors/wix-store.js +9 -0
  71. package/dist/connectors/zendesk-oauth.js +9 -0
  72. package/dist/connectors/zendesk.js +9 -0
  73. package/dist/index.js +482 -573
  74. package/dist/main.js +482 -573
  75. package/dist/vite-plugin.js +482 -573
  76. package/package.json +1 -5
  77. package/dist/connectors/powerbi.d.ts +0 -5
  78. package/dist/connectors/powerbi.js +0 -869
@@ -118,6 +118,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
118
118
  tools;
119
119
  query;
120
120
  checkConnection;
121
+ /**
122
+ * SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
123
+ * implement this expose a step-by-step exploration flow (database/schema/
124
+ * table/etc. discovery) that the dashboard backend drives via the
125
+ * `/connections/:connectionId/setup` endpoint. Implement by delegating to
126
+ * `runSetupFlow` from `setup-flow.ts`.
127
+ */
128
+ setup;
121
129
  constructor(config) {
122
130
  this.slug = config.slug;
123
131
  this.authType = config.authType;
@@ -134,6 +142,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
134
142
  this.tools = config.tools;
135
143
  this.query = config.query;
136
144
  this.checkConnection = config.checkConnection;
145
+ this.setup = config.setup;
137
146
  }
138
147
  get connectorKey() {
139
148
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -198,6 +207,50 @@ var ConnectorPlugin = class _ConnectorPlugin {
198
207
  }
199
208
  };
200
209
 
210
+ // ../connectors/src/setup-flow.ts
211
+ async function runSetupFlow(flow, params, ctx, config) {
212
+ const runtime = {
213
+ params,
214
+ language: ctx.language,
215
+ config
216
+ };
217
+ let state = flow.initialState();
218
+ let answerIdx = 0;
219
+ for (const step of flow.steps) {
220
+ const ans = ctx.answers[answerIdx];
221
+ if (ans && ans.questionSlug === step.slug) {
222
+ state = step.applyAnswer(state, ans.answer);
223
+ answerIdx += 1;
224
+ continue;
225
+ }
226
+ if (step.type === "text") {
227
+ return {
228
+ type: "nextQuestion",
229
+ questionSlug: step.slug,
230
+ question: step.question[ctx.language],
231
+ questionType: "text"
232
+ };
233
+ }
234
+ const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
235
+ if (options.length === 0) {
236
+ continue;
237
+ }
238
+ if (step.autoSelectIfSingle && options.length === 1) {
239
+ state = step.applyAnswer(state, [options[0].value]);
240
+ continue;
241
+ }
242
+ return {
243
+ type: "nextQuestion",
244
+ questionSlug: step.slug,
245
+ question: step.question[ctx.language],
246
+ questionType: "multiSelect",
247
+ options
248
+ };
249
+ }
250
+ const dataInvestigationResult = await flow.finalize(state, runtime);
251
+ return { type: "fulfilled", dataInvestigationResult };
252
+ }
253
+
201
254
  // ../connectors/src/auth-types.ts
202
255
  var AUTH_TYPES = {
203
256
  OAUTH: "oauth",
@@ -359,6 +412,125 @@ var parameters = {
359
412
  })
360
413
  };
361
414
 
415
+ // ../connectors/src/connectors/snowflake/setup-flow.ts
416
+ var ALL_TABLES = "__ALL_TABLES__";
417
+ var INTERNAL_SCHEMAS = /* @__PURE__ */ new Set([
418
+ "INFORMATION_SCHEMA",
419
+ "ACCOUNT_USAGE",
420
+ "READER_ACCOUNT_USAGE",
421
+ "DATA_SHARING_USAGE"
422
+ ]);
423
+ function createSnowflakeSetupFlow(runQuery3) {
424
+ return {
425
+ initialState: () => ({}),
426
+ steps: [
427
+ {
428
+ slug: "database",
429
+ type: "multiSelect",
430
+ autoSelectIfSingle: true,
431
+ question: {
432
+ ja: "\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u306B\u4F7F\u3046\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF081 \u4EF6\u306E\u307F\uFF09",
433
+ en: "Select the database to use for setup (pick one)"
434
+ },
435
+ async fetchOptions(_state, rt) {
436
+ const rows = await runQuery3(rt.params, "SHOW DATABASES");
437
+ return rows.map((r) => String(r["name"] ?? "")).filter((name) => name && !name.endsWith("_SHARE")).map((value) => ({ value }));
438
+ },
439
+ applyAnswer: (state, answer) => ({ ...state, database: answer[0] })
440
+ },
441
+ {
442
+ slug: "schema",
443
+ type: "multiSelect",
444
+ autoSelectIfSingle: true,
445
+ question: {
446
+ ja: "\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u306B\u4F7F\u3046\u30B9\u30AD\u30FC\u30DE\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF081 \u4EF6\u306E\u307F\uFF09",
447
+ en: "Select the schema to use for setup (pick one)"
448
+ },
449
+ async fetchOptions(state, rt) {
450
+ if (!state.database) return [];
451
+ const rows = await runQuery3(
452
+ rt.params,
453
+ `SHOW SCHEMAS IN DATABASE "${state.database}"`
454
+ );
455
+ return rows.map((r) => String(r["name"] ?? "")).filter(
456
+ (name) => name && !INTERNAL_SCHEMAS.has(name.toUpperCase())
457
+ ).map((value) => ({ value }));
458
+ },
459
+ applyAnswer: (state, answer) => ({ ...state, schema: answer[0] })
460
+ },
461
+ {
462
+ slug: "tables",
463
+ type: "multiSelect",
464
+ question: {
465
+ ja: "\u5BFE\u8C61\u30C6\u30FC\u30D6\u30EB\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
466
+ en: "Select target tables (multi-select allowed)"
467
+ },
468
+ async fetchOptions(state, rt) {
469
+ if (!state.database || !state.schema) return [];
470
+ const rows = await runQuery3(
471
+ rt.params,
472
+ `SHOW TABLES IN SCHEMA "${state.database}"."${state.schema}"`
473
+ );
474
+ const tableOptions = rows.map((r) => String(r["name"] ?? "")).filter((name) => name).map((value) => ({ value }));
475
+ return [
476
+ {
477
+ value: ALL_TABLES,
478
+ label: rt.language === "ja" ? "\u3059\u3079\u3066\u306E\u30C6\u30FC\u30D6\u30EB" : "All tables"
479
+ },
480
+ ...tableOptions
481
+ ];
482
+ },
483
+ applyAnswer: (state, answer) => ({ ...state, tables: answer })
484
+ }
485
+ ],
486
+ async finalize(state, rt) {
487
+ if (!state.database || !state.schema || !state.tables) {
488
+ throw new Error("Snowflake setup: incomplete state on finalize");
489
+ }
490
+ const db = state.database;
491
+ const schema = state.schema;
492
+ let targetTables;
493
+ if (state.tables.includes(ALL_TABLES)) {
494
+ const rows = await runQuery3(
495
+ rt.params,
496
+ `SHOW TABLES IN SCHEMA "${db}"."${schema}"`
497
+ );
498
+ targetTables = rows.map((r) => String(r["name"] ?? "")).filter((name) => name);
499
+ } else {
500
+ targetTables = state.tables.filter((t) => t !== ALL_TABLES);
501
+ }
502
+ const sections = [
503
+ "## Snowflake",
504
+ "",
505
+ `### Database: ${db}`,
506
+ "",
507
+ `#### Schema: ${schema}`,
508
+ ""
509
+ ];
510
+ for (const table of targetTables) {
511
+ const cols = await runQuery3(
512
+ rt.params,
513
+ `DESCRIBE TABLE "${db}"."${schema}"."${table}"`
514
+ );
515
+ sections.push(`##### Table: ${table}`, "");
516
+ sections.push("| Column | Type | Nullable | Default |");
517
+ sections.push("|--------|------|----------|---------|");
518
+ for (const c of cols) {
519
+ const name = String(c["name"] ?? "");
520
+ const type = String(c["type"] ?? "");
521
+ const nullable = String(c["null?"] ?? "");
522
+ const defaultValue = c["default"] == null ? "-" : String(c["default"]);
523
+ sections.push(
524
+ `| ${name} | ${type} | ${nullable} | ${defaultValue} |`
525
+ );
526
+ }
527
+ sections.push("");
528
+ }
529
+ return sections.join("\n");
530
+ }
531
+ };
532
+ }
533
+
362
534
  // ../connectors/src/connectors/snowflake/tools/execute-query.ts
363
535
  import { z } from "zod";
364
536
 
@@ -403,6 +575,49 @@ function decryptPrivateKey(pem, passphrase) {
403
575
  passphrase
404
576
  }).export({ type: "pkcs8", format: "pem" });
405
577
  }
578
+ async function runQuery(params, sql) {
579
+ const snowflake = (await import("snowflake-sdk")).default;
580
+ snowflake.configure({ logLevel: "ERROR" });
581
+ const privateKeyPem = Buffer.from(
582
+ params[parameters.privateKeyBase64.slug],
583
+ "base64"
584
+ ).toString("utf-8");
585
+ const privateKeyPass = params[parameters.privateKeyPassphrase.slug] || void 0;
586
+ const privateKey = decryptPrivateKey(privateKeyPem, privateKeyPass);
587
+ const conn = snowflake.createConnection({
588
+ account: params[parameters.account.slug],
589
+ username: params[parameters.user.slug],
590
+ role: params[parameters.role.slug],
591
+ warehouse: params[parameters.warehouse.slug],
592
+ authenticator: "SNOWFLAKE_JWT",
593
+ privateKey
594
+ });
595
+ await new Promise((resolve, reject) => {
596
+ conn.connect((err) => {
597
+ if (err) reject(new Error(`Snowflake connect failed: ${err.message}`));
598
+ else resolve();
599
+ });
600
+ });
601
+ try {
602
+ return await new Promise((resolve, reject) => {
603
+ conn.execute({
604
+ sqlText: sql,
605
+ complete: (err, _stmt, rows) => {
606
+ if (err) reject(new Error(`Snowflake query failed: ${err.message}`));
607
+ else resolve(rows ?? []);
608
+ }
609
+ });
610
+ });
611
+ } finally {
612
+ conn.destroy((err) => {
613
+ if (err) {
614
+ console.warn(
615
+ `[connector-query] Snowflake destroy error: ${err.message}`
616
+ );
617
+ }
618
+ });
619
+ }
620
+ }
406
621
  async function executeWithSizeLimit(conn, sql, options) {
407
622
  const rows = [];
408
623
  let acc = 0;
@@ -557,6 +772,7 @@ Memory guidance:
557
772
  });
558
773
 
559
774
  // ../connectors/src/connectors/snowflake/index.ts
775
+ var snowflakeSetupFlow = createSnowflakeSetupFlow(runQuery);
560
776
  var tools = { executeQuery: executeQueryTool };
561
777
  var snowflakeConnector = new ConnectorPlugin({
562
778
  slug: "snowflake",
@@ -603,6 +819,7 @@ The business logic type for this connector is "sql".
603
819
  - INFORMATION_SCHEMA \u3082\u5229\u7528\u53EF\u80FD: \`SELECT * FROM db_name.INFORMATION_SCHEMA.TABLES\``
604
820
  },
605
821
  tools,
822
+ setup: (params, ctx, config) => runSetupFlow(snowflakeSetupFlow, params, ctx, config),
606
823
  async checkConnection(params, _config) {
607
824
  try {
608
825
  const snowflake = (await import("snowflake-sdk")).default;
@@ -735,6 +952,47 @@ var parameters2 = {
735
952
  })
736
953
  };
737
954
 
955
+ // ../connectors/src/connectors/snowflake-pat/utils.ts
956
+ async function runQuery2(params, sql) {
957
+ const snowflake = (await import("snowflake-sdk")).default;
958
+ snowflake.configure({ logLevel: "ERROR" });
959
+ const conn = snowflake.createConnection({
960
+ account: params[parameters2.account.slug],
961
+ username: params[parameters2.user.slug],
962
+ role: params[parameters2.role.slug],
963
+ warehouse: params[parameters2.warehouse.slug],
964
+ password: params[parameters2.pat.slug]
965
+ });
966
+ await new Promise((resolve, reject) => {
967
+ conn.connect((err) => {
968
+ if (err) reject(new Error(`Snowflake connect failed: ${err.message}`));
969
+ else resolve();
970
+ });
971
+ });
972
+ try {
973
+ return await new Promise((resolve, reject) => {
974
+ conn.execute({
975
+ sqlText: sql,
976
+ complete: (err, _stmt, rows) => {
977
+ if (err) reject(new Error(`Snowflake query failed: ${err.message}`));
978
+ else resolve(rows ?? []);
979
+ }
980
+ });
981
+ });
982
+ } finally {
983
+ conn.destroy((err) => {
984
+ if (err) {
985
+ console.warn(
986
+ `[connector-query] Snowflake destroy error: ${err.message}`
987
+ );
988
+ }
989
+ });
990
+ }
991
+ }
992
+
993
+ // ../connectors/src/connectors/snowflake-pat/setup-flow.ts
994
+ var snowflakePatSetupFlow = createSnowflakeSetupFlow(runQuery2);
995
+
738
996
  // ../connectors/src/connectors/snowflake-pat/tools/execute-query.ts
739
997
  import { z as z2 } from "zod";
740
998
  var MAX_ROWS = 500;
@@ -887,6 +1145,7 @@ The business logic type for this connector is "sql".
887
1145
  - INFORMATION_SCHEMA \u3082\u5229\u7528\u53EF\u80FD: \`SELECT * FROM db_name.INFORMATION_SCHEMA.TABLES\``
888
1146
  },
889
1147
  tools: tools2,
1148
+ setup: (params, ctx, config) => runSetupFlow(snowflakePatSetupFlow, params, ctx, config),
890
1149
  async checkConnection(params, _config) {
891
1150
  try {
892
1151
  const snowflake = (await import("snowflake-sdk")).default;
@@ -27551,399 +27810,12 @@ export default async function handler(c: Context) {
27551
27810
  tools: tools79
27552
27811
  });
27553
27812
 
27554
- // ../connectors/src/connectors/powerbi/setup.ts
27555
- var powerbiOnboarding = new ConnectorOnboarding({
27556
- connectionSetupInstructions: {
27557
- en: `Follow these steps to verify the Power BI Service Principal connection.
27558
-
27559
- 1. Call \`powerbi_request\` with \`method: "GET"\` and \`path: "/groups"\` to list workspaces the Service Principal can access
27560
- 2. If the response is an empty \`value\` array, ask the user to add the Service Principal as Member/Admin to at least one workspace (Power BI Service > Workspace > Access). The 'Allow service principals to use Power BI APIs' tenant setting must also be enabled
27561
-
27562
- #### Constraints
27563
- - **Do NOT execute DAX queries or refresh datasets during setup**. Only the workspace listing above is allowed
27564
- - Service Principals cannot access "My workspace" \u2014 always work through workspace (group) IDs`,
27565
- ja: `Power BI Service Principal \u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u306F\u4EE5\u4E0B\u306E\u624B\u9806\u3067\u884C\u3063\u3066\u304F\u3060\u3055\u3044\u3002
27566
-
27567
- 1. \`powerbi_request\` \u3092 \`method: "GET"\`\u3001\`path: "/groups"\` \u3067\u547C\u3073\u51FA\u3057\u3001Service Principal \u304C\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306A\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u4E00\u89A7\u3092\u53D6\u5F97\u3059\u308B
27568
- 2. \`value\` \u304C\u7A7A\u914D\u5217\u3067\u8FD4\u3063\u3066\u304D\u305F\u5834\u5408\u306F\u3001Power BI Service > \u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9 > \u30A2\u30AF\u30BB\u30B9 \u304B\u3089\u8A72\u5F53\u306E Service Principal \u3092 Member/Admin \u3068\u3057\u3066\u8FFD\u52A0\u3059\u308B\u3088\u3046\u30E6\u30FC\u30B6\u30FC\u306B\u4F1D\u3048\u308B\u3002\u30C6\u30CA\u30F3\u30C8\u7BA1\u7406\u8A2D\u5B9A\u3067\u300C\u30B5\u30FC\u30D3\u30B9 \u30D7\u30EA\u30F3\u30B7\u30D1\u30EB\u306B Power BI API \u306E\u4F7F\u7528\u3092\u8A31\u53EF\u3059\u308B\u300D\u3082\u6709\u52B9\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308B
27569
-
27570
- #### \u5236\u7D04
27571
- - **\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u4E2D\u306B DAX \u30AF\u30A8\u30EA\u306E\u5B9F\u884C\u3084\u30C7\u30FC\u30BF\u30BB\u30C3\u30C8\u306E\u66F4\u65B0\u3092\u884C\u308F\u306A\u3044\u3053\u3068**\u3002\u4E0A\u8A18\u306E\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u4E00\u89A7\u53D6\u5F97\u306E\u307F\u8A31\u53EF
27572
- - Service Principal \u306F\u300C\u30DE\u30A4 \u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u300D\u306B\u30A2\u30AF\u30BB\u30B9\u3067\u304D\u306A\u3044 \u2014 \u5FC5\u305A\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9 (group) ID \u7D4C\u7531\u3067\u64CD\u4F5C\u3059\u308B\u3053\u3068`
27573
- },
27574
- dataOverviewInstructions: {
27575
- en: `1. Call powerbi_request with GET /groups to list accessible workspaces
27576
- 2. For a target workspace, call powerbi_request with GET /groups/{groupId}/datasets to list datasets
27577
- 3. Call powerbi_request with GET /groups/{groupId}/reports to list reports
27578
- 4. For each interesting dataset call powerbi_request with GET /groups/{groupId}/datasets/{datasetId}/tables to inspect tables (requires the dataset to allow XMLA / metadata reads)`,
27579
- ja: `1. powerbi_request \u3067 GET /groups \u3092\u547C\u3073\u51FA\u3057\u3001\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306A\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u4E00\u89A7\u3092\u53D6\u5F97
27580
- 2. \u5BFE\u8C61\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u306B\u5BFE\u3057\u3066 powerbi_request \u3067 GET /groups/{groupId}/datasets \u3092\u547C\u3073\u51FA\u3057\u3001\u30C7\u30FC\u30BF\u30BB\u30C3\u30C8\u4E00\u89A7\u3092\u53D6\u5F97
27581
- 3. powerbi_request \u3067 GET /groups/{groupId}/reports \u3092\u547C\u3073\u51FA\u3057\u3001\u30EC\u30DD\u30FC\u30C8\u4E00\u89A7\u3092\u53D6\u5F97
27582
- 4. \u8208\u5473\u306E\u3042\u308B\u30C7\u30FC\u30BF\u30BB\u30C3\u30C8\u306B\u3064\u3044\u3066 powerbi_request \u3067 GET /groups/{groupId}/datasets/{datasetId}/tables \u3092\u547C\u3073\u51FA\u3057\u3001\u30C6\u30FC\u30D6\u30EB\u69CB\u9020\u3092\u78BA\u8A8D\uFF08XMLA / \u30E1\u30BF\u30C7\u30FC\u30BF\u8AAD\u307F\u53D6\u308A\u304C\u8A31\u53EF\u3055\u308C\u3066\u3044\u308B\u30C7\u30FC\u30BF\u30BB\u30C3\u30C8\u306B\u9650\u308B\uFF09`
27583
- }
27584
- });
27585
-
27586
- // ../connectors/src/connectors/powerbi/parameters.ts
27587
- var parameters80 = {
27588
- tenantId: new ParameterDefinition({
27589
- slug: "tenant-id",
27590
- name: "Azure Tenant ID",
27591
- description: "The Microsoft Entra ID (Azure AD) tenant ID that owns the Service Principal. Found in Azure Portal > Microsoft Entra ID > Overview > Tenant ID.",
27592
- envVarBaseKey: "POWERBI_TENANT_ID",
27593
- type: "text",
27594
- secret: false,
27595
- required: true
27596
- }),
27597
- clientId: new ParameterDefinition({
27598
- slug: "client-id",
27599
- name: "Application (Client) ID",
27600
- description: "The Application (client) ID of the Microsoft Entra app registration used as the Power BI Service Principal. Found in Azure Portal > App registrations > Overview.",
27601
- envVarBaseKey: "POWERBI_CLIENT_ID",
27602
- type: "text",
27603
- secret: false,
27604
- required: true
27605
- }),
27606
- clientSecret: new ParameterDefinition({
27607
- slug: "client-secret",
27608
- name: "Client Secret",
27609
- description: "A client secret value for the app registration. Generated under App registrations > Certificates & secrets > Client secrets. The Service Principal must be granted Power BI tenant access (via 'Allow service principals to use Power BI APIs' admin setting) and added to each workspace as a Member/Admin.",
27610
- envVarBaseKey: "POWERBI_CLIENT_SECRET",
27611
- type: "text",
27612
- secret: true,
27613
- required: true
27614
- })
27615
- };
27616
-
27617
- // ../connectors/src/connectors/powerbi/tools/request.ts
27813
+ // ../connectors/src/connectors/powerbi-oauth/tools/request.ts
27618
27814
  import { z as z97 } from "zod";
27619
27815
  var BASE_HOST12 = "https://api.powerbi.com";
27620
27816
  var BASE_PATH_SEGMENT15 = "/v1.0/myorg";
27621
27817
  var BASE_URL41 = `${BASE_HOST12}${BASE_PATH_SEGMENT15}`;
27622
- var TOKEN_SCOPE = "https://analysis.windows.net/powerbi/api/.default";
27623
27818
  var REQUEST_TIMEOUT_MS74 = 6e4;
27624
- var tokenCache = /* @__PURE__ */ new Map();
27625
- async function getAccessToken(tenantId, clientId, clientSecret) {
27626
- const cacheKey = `${tenantId}:${clientId}`;
27627
- const cached = tokenCache.get(cacheKey);
27628
- if (cached && cached.expiresAt > Date.now() + 6e4) {
27629
- return cached.token;
27630
- }
27631
- const tokenUrl = `https://login.microsoftonline.com/${encodeURIComponent(tenantId)}/oauth2/v2.0/token`;
27632
- const body = new URLSearchParams({
27633
- grant_type: "client_credentials",
27634
- client_id: clientId,
27635
- client_secret: clientSecret,
27636
- scope: TOKEN_SCOPE
27637
- });
27638
- const res = await fetch(tokenUrl, {
27639
- method: "POST",
27640
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
27641
- body: body.toString()
27642
- });
27643
- if (!res.ok) {
27644
- const errorText = await res.text().catch(() => res.statusText);
27645
- throw new Error(
27646
- `Power BI token request failed: HTTP ${res.status} ${errorText}`
27647
- );
27648
- }
27649
- const data = await res.json();
27650
- tokenCache.set(cacheKey, {
27651
- token: data.access_token,
27652
- expiresAt: Date.now() + data.expires_in * 1e3
27653
- });
27654
- return data.access_token;
27655
- }
27656
- var inputSchema97 = z97.object({
27657
- toolUseIntent: z97.string().optional().describe(
27658
- "Brief description of what you intend to accomplish with this tool call"
27659
- ),
27660
- connectionId: z97.string().describe("ID of the Power BI connection to use"),
27661
- method: z97.enum(["GET", "POST", "PATCH", "PUT", "DELETE"]).describe(
27662
- "HTTP method. Use GET for reading workspaces/datasets/reports, POST for execute queries / refresh, PATCH/PUT for updates, DELETE for removal."
27663
- ),
27664
- path: z97.string().describe(
27665
- "API path appended to https://api.powerbi.com/v1.0/myorg (e.g., '/groups', '/groups/{groupId}/datasets', '/groups/{groupId}/reports/{reportId}'). Service Principal cannot access 'My workspace' \u2014 always work through workspace (group) IDs."
27666
- ),
27667
- queryParams: z97.record(z97.string(), z97.string()).optional().describe(
27668
- `Query parameters to append to the URL (e.g., { $top: '50', $filter: "name eq 'Sales'" }). OData operators ($filter, $top, $skip, $expand) are supported on many list endpoints.`
27669
- ),
27670
- body: z97.record(z97.string(), z97.unknown()).optional().describe(
27671
- "JSON request body for POST/PATCH/PUT/DELETE. Example: executeQueries body { queries: [{ query: 'EVALUATE TOPN(10, Sales)' }], serializerSettings: { includeNulls: true } }."
27672
- )
27673
- });
27674
- var outputSchema97 = z97.discriminatedUnion("success", [
27675
- z97.object({
27676
- success: z97.literal(true),
27677
- status: z97.number(),
27678
- data: z97.unknown()
27679
- }),
27680
- z97.object({
27681
- success: z97.literal(false),
27682
- error: z97.string()
27683
- })
27684
- ]);
27685
- var requestTool56 = new ConnectorTool({
27686
- name: "request",
27687
- description: `Send authenticated requests to the Power BI REST API v1.0.
27688
- Authentication uses a Microsoft Entra Service Principal (client_credentials) \u2014 the token is acquired and cached automatically.
27689
- All paths are relative to https://api.powerbi.com/v1.0/myorg. Service Principals cannot access 'My workspace'; always operate on workspaces ('groups') the SP has been added to.
27690
- Use the executeQueries endpoint (POST /groups/{groupId}/datasets/{datasetId}/executeQueries) to run DAX against a dataset.`,
27691
- inputSchema: inputSchema97,
27692
- outputSchema: outputSchema97,
27693
- async execute({ connectionId, method, path: path4, queryParams, body }, connections) {
27694
- const connection = connections.find((c) => c.id === connectionId);
27695
- if (!connection) {
27696
- return {
27697
- success: false,
27698
- error: `Connection ${connectionId} not found`
27699
- };
27700
- }
27701
- console.log(
27702
- `[connector-request] powerbi/${connection.name}: ${method} ${path4}`
27703
- );
27704
- try {
27705
- const tenantId = parameters80.tenantId.getValue(connection);
27706
- const clientId = parameters80.clientId.getValue(connection);
27707
- const clientSecret = parameters80.clientSecret.getValue(connection);
27708
- const normalizedPath = normalizeRequestPath(path4, BASE_PATH_SEGMENT15);
27709
- let url = `${BASE_URL41}${normalizedPath}`;
27710
- if (queryParams) {
27711
- const searchParams = new URLSearchParams(queryParams);
27712
- url += `?${searchParams.toString()}`;
27713
- }
27714
- const token = await getAccessToken(tenantId, clientId, clientSecret);
27715
- const controller = new AbortController();
27716
- const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS74);
27717
- try {
27718
- const init = {
27719
- method,
27720
- headers: {
27721
- Authorization: `Bearer ${token}`,
27722
- "Content-Type": "application/json",
27723
- Accept: "application/json"
27724
- },
27725
- signal: controller.signal
27726
- };
27727
- if (body !== void 0) {
27728
- init.body = JSON.stringify(body);
27729
- }
27730
- const response = await fetch(url, init);
27731
- const text = await response.text();
27732
- const data = text ? (() => {
27733
- try {
27734
- return JSON.parse(text);
27735
- } catch {
27736
- return text;
27737
- }
27738
- })() : null;
27739
- if (!response.ok) {
27740
- const errorMessage = data && typeof data === "object" && "error" in data ? JSON.stringify(data.error) : typeof data === "string" && data ? data : `HTTP ${response.status} ${response.statusText}`;
27741
- return { success: false, error: errorMessage };
27742
- }
27743
- return { success: true, status: response.status, data };
27744
- } finally {
27745
- clearTimeout(timeout);
27746
- }
27747
- } catch (err) {
27748
- const msg = err instanceof Error ? err.message : String(err);
27749
- return { success: false, error: msg };
27750
- }
27751
- }
27752
- });
27753
-
27754
- // ../connectors/src/connectors/powerbi/index.ts
27755
- var tools80 = { request: requestTool56 };
27756
- var powerbiConnector = new ConnectorPlugin({
27757
- slug: "powerbi",
27758
- authType: AUTH_TYPES.API_KEY,
27759
- name: "Power BI",
27760
- description: "Connect to Microsoft Power BI via a Service Principal (Microsoft Entra ID app + tenant ID / client ID / client secret). Use it to enumerate workspaces, datasets, and reports, and to run DAX queries.",
27761
- iconUrl: "https://upload.wikimedia.org/wikipedia/commons/c/cf/New_Power_BI_Logo.svg",
27762
- parameters: parameters80,
27763
- releaseFlag: { dev1: true, dev2: false, prod: false },
27764
- categories: ["other"],
27765
- onboarding: powerbiOnboarding,
27766
- systemPrompt: {
27767
- en: `### Tools
27768
-
27769
- - \`powerbi_request\`: The only way to call the Power BI REST API v1.0. Use it to list workspaces (\`/groups\`), datasets, reports, dashboards, and to run DAX via the \`executeQueries\` endpoint. Service Principal authentication (\`client_credentials\`) is handled automatically and the bearer token is cached.
27770
-
27771
- ### Business Logic
27772
-
27773
- The business logic type for this connector is "typescript". Use the connector SDK in your handler. Do NOT read credentials from environment variables.
27774
-
27775
- SDK methods (client created via \`connection(connectionId)\`):
27776
- - \`client.request(path, init?)\` \u2014 low-level authenticated fetch (path appended to \`https://api.powerbi.com/v1.0/myorg\`)
27777
- - \`client.listGroups(options?)\` \u2014 list workspaces (\`$top\`, \`$skip\`, \`$filter\`)
27778
- - \`client.listDatasets(groupId)\` / \`client.listReports(groupId)\` \u2014 list datasets / reports in a workspace
27779
- - \`client.getDataset(groupId, datasetId)\` \u2014 fetch a single dataset
27780
- - \`client.executeQueries(groupId, datasetId, queries, options?)\` \u2014 run DAX queries against a dataset
27781
- - \`client.refreshDataset(groupId, datasetId, options?)\` \u2014 trigger an async refresh
27782
-
27783
- \`\`\`ts
27784
- import type { Context } from "hono";
27785
- import { connection } from "@squadbase/vite-server/connectors/powerbi";
27786
-
27787
- const powerbi = connection("<connectionId>");
27788
-
27789
- export default async function handler(c: Context) {
27790
- const { groupId, datasetId, dax } = await c.req.json<{
27791
- groupId: string;
27792
- datasetId: string;
27793
- dax: string;
27794
- }>();
27795
-
27796
- const result = await powerbi.executeQueries(groupId, datasetId, [dax]);
27797
- const rows = result.results[0]?.tables[0]?.rows ?? [];
27798
- return c.json({ rows });
27799
- }
27800
- \`\`\`
27801
-
27802
- ### Power BI REST API Reference
27803
-
27804
- - Base URL: \`https://api.powerbi.com/v1.0/myorg\`
27805
- - Authentication: Microsoft Entra Service Principal via OAuth2 \`client_credentials\` grant against \`https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token\` with scope \`https://analysis.windows.net/powerbi/api/.default\` (handled automatically)
27806
- - Service Principals cannot access "My workspace"; the SP must be added as Member/Admin to each workspace
27807
- - The tenant admin must enable "Allow service principals to use Power BI APIs" in the Power BI admin portal
27808
-
27809
- #### Common Endpoints
27810
- - GET \`/groups\` \u2014 List workspaces accessible to the Service Principal
27811
- - GET \`/groups/{groupId}/datasets\` \u2014 List datasets in a workspace
27812
- - GET \`/groups/{groupId}/datasets/{datasetId}\` \u2014 Get dataset metadata
27813
- - GET \`/groups/{groupId}/datasets/{datasetId}/tables\` \u2014 List tables (requires XMLA / metadata reads enabled)
27814
- - GET \`/groups/{groupId}/reports\` \u2014 List reports
27815
- - GET \`/groups/{groupId}/dashboards\` \u2014 List dashboards
27816
- - POST \`/groups/{groupId}/datasets/{datasetId}/executeQueries\` \u2014 Run DAX (body: \`{ queries: [{ query: "EVALUATE ..." }], serializerSettings: { includeNulls: true } }\`)
27817
- - POST \`/groups/{groupId}/datasets/{datasetId}/refreshes\` \u2014 Trigger a dataset refresh
27818
- - GET \`/groups/{groupId}/datasets/{datasetId}/refreshes\` \u2014 List recent refresh history
27819
-
27820
- #### DAX Tips
27821
- - \`EVALUATE TOPN(10, 'TableName')\` \u2014 sample 10 rows from a table
27822
- - \`EVALUATE SUMMARIZECOLUMNS('Date'[Year], "Sales", SUM('Sales'[Amount]))\` \u2014 aggregate
27823
- - Each \`executeQueries\` call accepts one query in the \`queries\` array (per current Power BI API limits); large result sets are truncated server-side (100k rows max)`,
27824
- ja: `### \u30C4\u30FC\u30EB
27825
-
27826
- - \`powerbi_request\`: Power BI REST API v1.0 \u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9 (\`/groups\`)\u3001\u30C7\u30FC\u30BF\u30BB\u30C3\u30C8\u3001\u30EC\u30DD\u30FC\u30C8\u3001\u30C0\u30C3\u30B7\u30E5\u30DC\u30FC\u30C9\u306E\u4E00\u89A7\u53D6\u5F97\u3084\u3001\`executeQueries\` \u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u306B\u3088\u308B DAX \u306E\u5B9F\u884C\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002Service Principal \u8A8D\u8A3C (\`client_credentials\`) \u306F\u81EA\u52D5\u3067\u51E6\u7406\u3055\u308C\u3001Bearer \u30C8\u30FC\u30AF\u30F3\u306F\u30AD\u30E3\u30C3\u30B7\u30E5\u3055\u308C\u307E\u3059\u3002
27827
-
27828
- ### Business Logic
27829
-
27830
- \u3053\u306E\u30B3\u30CD\u30AF\u30BF\u306E\u30D3\u30B8\u30CD\u30B9\u30ED\u30B8\u30C3\u30AF\u30BF\u30A4\u30D7\u306F "typescript" \u3067\u3059\u3002\u30CF\u30F3\u30C9\u30E9\u5185\u3067\u306F\u30B3\u30CD\u30AF\u30BF SDK \u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u74B0\u5883\u5909\u6570\u304B\u3089\u8A8D\u8A3C\u60C5\u5831\u3092\u8AAD\u307F\u53D6\u3089\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002
27831
-
27832
- SDK\u30E1\u30BD\u30C3\u30C9 (\`connection(connectionId)\` \u3067\u4F5C\u6210\u3057\u305F\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8):
27833
- - \`client.request(path, init?)\` \u2014 \u4F4E\u30EC\u30D9\u30EB\u8A8D\u8A3C\u4ED8\u304D fetch (path \u306F \`https://api.powerbi.com/v1.0/myorg\` \u306B\u8FFD\u52A0\u3055\u308C\u307E\u3059)
27834
- - \`client.listGroups(options?)\` \u2014 \u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u4E00\u89A7 (\`$top\`, \`$skip\`, \`$filter\`)
27835
- - \`client.listDatasets(groupId)\` / \`client.listReports(groupId)\` \u2014 \u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u5185\u306E\u30C7\u30FC\u30BF\u30BB\u30C3\u30C8/\u30EC\u30DD\u30FC\u30C8\u4E00\u89A7
27836
- - \`client.getDataset(groupId, datasetId)\` \u2014 \u30C7\u30FC\u30BF\u30BB\u30C3\u30C8\u5358\u4F53\u53D6\u5F97
27837
- - \`client.executeQueries(groupId, datasetId, queries, options?)\` \u2014 DAX \u30AF\u30A8\u30EA\u5B9F\u884C
27838
- - \`client.refreshDataset(groupId, datasetId, options?)\` \u2014 \u30C7\u30FC\u30BF\u30BB\u30C3\u30C8\u66F4\u65B0\u3092\u975E\u540C\u671F\u30C8\u30EA\u30AC\u30FC
27839
-
27840
- \`\`\`ts
27841
- import type { Context } from "hono";
27842
- import { connection } from "@squadbase/vite-server/connectors/powerbi";
27843
-
27844
- const powerbi = connection("<connectionId>");
27845
-
27846
- export default async function handler(c: Context) {
27847
- const { groupId, datasetId, dax } = await c.req.json<{
27848
- groupId: string;
27849
- datasetId: string;
27850
- dax: string;
27851
- }>();
27852
-
27853
- const result = await powerbi.executeQueries(groupId, datasetId, [dax]);
27854
- const rows = result.results[0]?.tables[0]?.rows ?? [];
27855
- return c.json({ rows });
27856
- }
27857
- \`\`\`
27858
-
27859
- ### Power BI REST API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
27860
-
27861
- - \u30D9\u30FC\u30B9 URL: \`https://api.powerbi.com/v1.0/myorg\`
27862
- - \u8A8D\u8A3C: Microsoft Entra Service Principal \u306B\u3088\u308B OAuth2 \`client_credentials\` \u30B0\u30E9\u30F3\u30C8\u3002\`https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token\` \u306B\u5BFE\u3057\u30B9\u30B3\u30FC\u30D7 \`https://analysis.windows.net/powerbi/api/.default\` \u3067\u30C8\u30FC\u30AF\u30F3\u53D6\u5F97 (\u81EA\u52D5)
27863
- - Service Principal \u306F\u300C\u30DE\u30A4 \u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u300D\u306B\u30A2\u30AF\u30BB\u30B9\u4E0D\u53EF\u3002\u5404\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u306B Member/Admin \u3068\u3057\u3066\u8FFD\u52A0\u304C\u5FC5\u8981
27864
- - \u30C6\u30CA\u30F3\u30C8\u7BA1\u7406\u8005\u304C Power BI \u7BA1\u7406\u30DD\u30FC\u30BF\u30EB\u3067\u300C\u30B5\u30FC\u30D3\u30B9 \u30D7\u30EA\u30F3\u30B7\u30D1\u30EB\u306B Power BI API \u306E\u4F7F\u7528\u3092\u8A31\u53EF\u3059\u308B\u300D\u3092\u6709\u52B9\u306B\u3057\u3066\u3044\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059
27865
-
27866
- #### \u4E3B\u8981\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8
27867
- - GET \`/groups\` \u2014 Service Principal \u304C\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306A\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u4E00\u89A7
27868
- - GET \`/groups/{groupId}/datasets\` \u2014 \u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u5185\u306E\u30C7\u30FC\u30BF\u30BB\u30C3\u30C8\u4E00\u89A7
27869
- - GET \`/groups/{groupId}/datasets/{datasetId}\` \u2014 \u30C7\u30FC\u30BF\u30BB\u30C3\u30C8 \u30E1\u30BF\u30C7\u30FC\u30BF
27870
- - GET \`/groups/{groupId}/datasets/{datasetId}/tables\` \u2014 \u30C6\u30FC\u30D6\u30EB\u4E00\u89A7 (XMLA / \u30E1\u30BF\u30C7\u30FC\u30BF\u8AAD\u307F\u53D6\u308A\u304C\u6709\u52B9\u3067\u3042\u308B\u5FC5\u8981\u3042\u308A)
27871
- - GET \`/groups/{groupId}/reports\` \u2014 \u30EC\u30DD\u30FC\u30C8\u4E00\u89A7
27872
- - GET \`/groups/{groupId}/dashboards\` \u2014 \u30C0\u30C3\u30B7\u30E5\u30DC\u30FC\u30C9\u4E00\u89A7
27873
- - POST \`/groups/{groupId}/datasets/{datasetId}/executeQueries\` \u2014 DAX \u5B9F\u884C (body: \`{ queries: [{ query: "EVALUATE ..." }], serializerSettings: { includeNulls: true } }\`)
27874
- - POST \`/groups/{groupId}/datasets/{datasetId}/refreshes\` \u2014 \u30C7\u30FC\u30BF\u30BB\u30C3\u30C8\u66F4\u65B0\u30C8\u30EA\u30AC\u30FC
27875
- - GET \`/groups/{groupId}/datasets/{datasetId}/refreshes\` \u2014 \u76F4\u8FD1\u306E\u66F4\u65B0\u5C65\u6B74
27876
-
27877
- #### DAX Tips
27878
- - \`EVALUATE TOPN(10, 'TableName')\` \u2014 \u30C6\u30FC\u30D6\u30EB\u304B\u3089 10 \u884C\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0
27879
- - \`EVALUATE SUMMARIZECOLUMNS('Date'[Year], "Sales", SUM('Sales'[Amount]))\` \u2014 \u96C6\u8A08
27880
- - \`executeQueries\` \u306F\u73FE\u72B6 1 \u30EA\u30AF\u30A8\u30B9\u30C8\u306B\u3064\u304D 1 \u30AF\u30A8\u30EA\u306E\u307F\u3002\u7D50\u679C\u306F\u6700\u5927 10 \u4E07\u884C\u307E\u3067\u30B5\u30FC\u30D0\u30FC\u5074\u3067\u5207\u308A\u8A70\u3081\u3089\u308C\u307E\u3059`
27881
- },
27882
- tools: tools80,
27883
- async checkConnection(params) {
27884
- const tenantId = params[parameters80.tenantId.slug];
27885
- const clientId = params[parameters80.clientId.slug];
27886
- const clientSecret = params[parameters80.clientSecret.slug];
27887
- if (!tenantId || !clientId || !clientSecret) {
27888
- return {
27889
- success: false,
27890
- error: "Missing required parameters: tenant-id, client-id, client-secret"
27891
- };
27892
- }
27893
- try {
27894
- const tokenUrl = `https://login.microsoftonline.com/${encodeURIComponent(tenantId)}/oauth2/v2.0/token`;
27895
- const body = new URLSearchParams({
27896
- grant_type: "client_credentials",
27897
- client_id: clientId,
27898
- client_secret: clientSecret,
27899
- scope: "https://analysis.windows.net/powerbi/api/.default"
27900
- });
27901
- const tokenRes = await fetch(tokenUrl, {
27902
- method: "POST",
27903
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
27904
- body: body.toString()
27905
- });
27906
- if (!tokenRes.ok) {
27907
- const errorText = await tokenRes.text().catch(() => tokenRes.statusText);
27908
- return {
27909
- success: false,
27910
- error: `Power BI token request failed: HTTP ${tokenRes.status} ${errorText}`
27911
- };
27912
- }
27913
- const { access_token } = await tokenRes.json();
27914
- const apiRes = await fetch(
27915
- "https://api.powerbi.com/v1.0/myorg/groups?$top=1",
27916
- {
27917
- method: "GET",
27918
- headers: {
27919
- Authorization: `Bearer ${access_token}`,
27920
- Accept: "application/json"
27921
- }
27922
- }
27923
- );
27924
- if (!apiRes.ok) {
27925
- const errorText = await apiRes.text().catch(() => apiRes.statusText);
27926
- return {
27927
- success: false,
27928
- error: `Power BI API failed: HTTP ${apiRes.status} ${errorText}`
27929
- };
27930
- }
27931
- return { success: true };
27932
- } catch (error) {
27933
- return {
27934
- success: false,
27935
- error: error instanceof Error ? error.message : String(error)
27936
- };
27937
- }
27938
- }
27939
- });
27940
-
27941
- // ../connectors/src/connectors/powerbi-oauth/tools/request.ts
27942
- import { z as z98 } from "zod";
27943
- var BASE_HOST13 = "https://api.powerbi.com";
27944
- var BASE_PATH_SEGMENT16 = "/v1.0/myorg";
27945
- var BASE_URL42 = `${BASE_HOST13}${BASE_PATH_SEGMENT16}`;
27946
- var REQUEST_TIMEOUT_MS75 = 6e4;
27947
27819
  var cachedToken32 = null;
27948
27820
  async function getProxyToken32(config) {
27949
27821
  if (cachedToken32 && cachedToken32.expiresAt > Date.now() + 6e4) {
@@ -27975,42 +27847,42 @@ async function getProxyToken32(config) {
27975
27847
  };
27976
27848
  return data.token;
27977
27849
  }
27978
- var inputSchema98 = z98.object({
27979
- toolUseIntent: z98.string().optional().describe(
27850
+ var inputSchema97 = z97.object({
27851
+ toolUseIntent: z97.string().optional().describe(
27980
27852
  "Brief description of what you intend to accomplish with this tool call"
27981
27853
  ),
27982
- connectionId: z98.string().describe("ID of the Power BI OAuth connection to use"),
27983
- method: z98.enum(["GET", "POST", "PATCH", "PUT", "DELETE"]).describe(
27854
+ connectionId: z97.string().describe("ID of the Power BI OAuth connection to use"),
27855
+ method: z97.enum(["GET", "POST", "PATCH", "PUT", "DELETE"]).describe(
27984
27856
  "HTTP method. GET for reading workspaces/datasets/reports, POST for executeQueries / refresh, PATCH/PUT for updates, DELETE for removal."
27985
27857
  ),
27986
- path: z98.string().describe(
27858
+ path: z97.string().describe(
27987
27859
  "API path appended to https://api.powerbi.com/v1.0/myorg (e.g., '/groups', '/groups/{groupId}/datasets'). The authenticated user must have access to the workspace."
27988
27860
  ),
27989
- queryParams: z98.record(z98.string(), z98.string()).optional().describe(
27861
+ queryParams: z97.record(z97.string(), z97.string()).optional().describe(
27990
27862
  `Query parameters to append (e.g., { $top: '50', $filter: "name eq 'Sales'" }).`
27991
27863
  ),
27992
- body: z98.record(z98.string(), z98.unknown()).optional().describe(
27864
+ body: z97.record(z97.string(), z97.unknown()).optional().describe(
27993
27865
  "JSON request body for POST/PATCH/PUT/DELETE. Example executeQueries body: { queries: [{ query: 'EVALUATE TOPN(10, Sales)' }], serializerSettings: { includeNulls: true } }."
27994
27866
  )
27995
27867
  });
27996
- var outputSchema98 = z98.discriminatedUnion("success", [
27997
- z98.object({
27998
- success: z98.literal(true),
27999
- status: z98.number(),
28000
- data: z98.unknown()
27868
+ var outputSchema97 = z97.discriminatedUnion("success", [
27869
+ z97.object({
27870
+ success: z97.literal(true),
27871
+ status: z97.number(),
27872
+ data: z97.unknown()
28001
27873
  }),
28002
- z98.object({
28003
- success: z98.literal(false),
28004
- error: z98.string()
27874
+ z97.object({
27875
+ success: z97.literal(false),
27876
+ error: z97.string()
28005
27877
  })
28006
27878
  ]);
28007
- var requestTool57 = new ConnectorTool({
27879
+ var requestTool56 = new ConnectorTool({
28008
27880
  name: "request",
28009
27881
  description: `Send authenticated requests to the Power BI REST API v1.0 using the user's Microsoft Entra OAuth token (proxied automatically).
28010
27882
  All paths are relative to https://api.powerbi.com/v1.0/myorg. Use the executeQueries endpoint to run DAX against a dataset.
28011
27883
  The signed-in user must have access to the workspace; unlike Service Principals, OAuth users can also access "My workspace" via the \`/datasets\` (without \`/groups/\`) endpoints.`,
28012
- inputSchema: inputSchema98,
28013
- outputSchema: outputSchema98,
27884
+ inputSchema: inputSchema97,
27885
+ outputSchema: outputSchema97,
28014
27886
  async execute({ connectionId, method, path: path4, queryParams, body }, connections, config) {
28015
27887
  const connection = connections.find((c) => c.id === connectionId);
28016
27888
  if (!connection) {
@@ -28023,8 +27895,8 @@ The signed-in user must have access to the workspace; unlike Service Principals,
28023
27895
  `[connector-request] powerbi-oauth/${connection.name}: ${method} ${path4}`
28024
27896
  );
28025
27897
  try {
28026
- const normalizedPath = normalizeRequestPath(path4, BASE_PATH_SEGMENT16);
28027
- let url = `${BASE_URL42}${normalizedPath}`;
27898
+ const normalizedPath = normalizeRequestPath(path4, BASE_PATH_SEGMENT15);
27899
+ let url = `${BASE_URL41}${normalizedPath}`;
28028
27900
  if (queryParams) {
28029
27901
  const searchParams = new URLSearchParams(queryParams);
28030
27902
  url += `?${searchParams.toString()}`;
@@ -28032,7 +27904,7 @@ The signed-in user must have access to the workspace; unlike Service Principals,
28032
27904
  const token = await getProxyToken32(config.oauthProxy);
28033
27905
  const proxyUrl = `https://${config.oauthProxy.sandboxId}.${config.oauthProxy.previewBaseDomain}/_sqcore/connections/${connectionId}/request`;
28034
27906
  const controller = new AbortController();
28035
- const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS75);
27907
+ const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS74);
28036
27908
  try {
28037
27909
  const response = await fetch(proxyUrl, {
28038
27910
  method: "POST",
@@ -28071,7 +27943,7 @@ The signed-in user must have access to the workspace; unlike Service Principals,
28071
27943
  });
28072
27944
 
28073
27945
  // ../connectors/src/connectors/powerbi-oauth/setup.ts
28074
- var requestToolName13 = `powerbi-oauth_${requestTool57.name}`;
27946
+ var requestToolName13 = `powerbi-oauth_${requestTool56.name}`;
28075
27947
  var powerbiOauthOnboarding = new ConnectorOnboarding({
28076
27948
  connectionSetupInstructions: {
28077
27949
  ja: `Power BI OAuth \u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u306F\u4EE5\u4E0B\u306E\u624B\u9806\u3067\u884C\u3063\u3066\u304F\u3060\u3055\u3044\u3002
@@ -28104,19 +27976,19 @@ var powerbiOauthOnboarding = new ConnectorOnboarding({
28104
27976
  });
28105
27977
 
28106
27978
  // ../connectors/src/connectors/powerbi-oauth/parameters.ts
28107
- var parameters81 = {};
27979
+ var parameters80 = {};
28108
27980
 
28109
27981
  // ../connectors/src/connectors/powerbi-oauth/index.ts
28110
- var tools81 = { request: requestTool57 };
27982
+ var tools80 = { request: requestTool56 };
28111
27983
  var powerbiOauthConnector = new ConnectorPlugin({
28112
27984
  slug: "powerbi",
28113
27985
  authType: AUTH_TYPES.OAUTH,
28114
27986
  name: "Power BI",
28115
27987
  description: "Connect to Microsoft Power BI using OAuth (Microsoft Entra ID). Use it to enumerate workspaces, datasets, and reports the signed-in user has access to, and to run DAX queries.",
28116
- iconUrl: "https://upload.wikimedia.org/wikipedia/commons/c/cf/New_Power_BI_Logo.svg",
28117
- parameters: parameters81,
27988
+ iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/2vXQCKGpMJ9kGSaqkZl9IS/cc5669c267fc5d11e7b1f8c01723e461/power-bi-icon.png",
27989
+ parameters: parameters80,
28118
27990
  releaseFlag: { dev1: true, dev2: false, prod: false },
28119
- categories: ["other"],
27991
+ categories: ["bi"],
28120
27992
  onboarding: powerbiOauthOnboarding,
28121
27993
  proxyPolicy: {
28122
27994
  allowlist: [
@@ -28240,7 +28112,7 @@ export default async function handler(c: Context) {
28240
28112
  - \`EVALUATE SUMMARIZECOLUMNS('Date'[Year], "Sales", SUM('Sales'[Amount]))\` \u2014 \u96C6\u8A08
28241
28113
  - \`executeQueries\` \u306F\u73FE\u72B6 1 \u30EA\u30AF\u30A8\u30B9\u30C8\u306B\u3064\u304D 1 \u30AF\u30A8\u30EA\u306E\u307F`
28242
28114
  },
28243
- tools: tools81,
28115
+ tools: tools80,
28244
28116
  async checkConnection(_params, config) {
28245
28117
  const { proxyFetch } = config;
28246
28118
  const url = "https://api.powerbi.com/v1.0/myorg/groups?$top=1";
@@ -28296,7 +28168,7 @@ var tableauOnboarding = new ConnectorOnboarding({
28296
28168
  });
28297
28169
 
28298
28170
  // ../connectors/src/connectors/tableau/parameters.ts
28299
- var parameters82 = {
28171
+ var parameters81 = {
28300
28172
  serverUrl: new ParameterDefinition({
28301
28173
  slug: "server-url",
28302
28174
  name: "Tableau Server URL",
@@ -28345,10 +28217,14 @@ var parameters82 = {
28345
28217
  };
28346
28218
 
28347
28219
  // ../connectors/src/connectors/tableau/tools/request.ts
28348
- import { z as z99 } from "zod";
28220
+ import { z as z98 } from "zod";
28349
28221
  var DEFAULT_API_VERSION = "3.28";
28350
- var REQUEST_TIMEOUT_MS76 = 6e4;
28222
+ var REQUEST_TIMEOUT_MS75 = 6e4;
28351
28223
  var sessionCache = /* @__PURE__ */ new Map();
28224
+ var inFlightSignIns = /* @__PURE__ */ new Map();
28225
+ function sessionCacheKey(serverUrl, siteContentUrl, patName) {
28226
+ return `${serverUrl}|${siteContentUrl}|${patName}`;
28227
+ }
28352
28228
  function buildBaseUrl4(serverUrl, apiVersion) {
28353
28229
  return `${serverUrl.replace(/\/$/, "")}/api/${apiVersion}`;
28354
28230
  }
@@ -28383,59 +28259,77 @@ async function signIn(serverUrl, apiVersion, siteContentUrl, patName, patSecret)
28383
28259
  expiresAt: Date.now() + 30 * 60 * 1e3
28384
28260
  };
28385
28261
  }
28386
- async function getSession(serverUrl, apiVersion, siteContentUrl, patName, patSecret) {
28387
- const cacheKey = `${serverUrl}|${siteContentUrl}|${patName}`;
28388
- const cached = sessionCache.get(cacheKey);
28389
- if (cached && cached.expiresAt > Date.now() + 6e4) {
28390
- return cached;
28262
+ async function getSession(serverUrl, apiVersion, siteContentUrl, patName, patSecret, { forceRefresh = false } = {}) {
28263
+ const cacheKey = sessionCacheKey(serverUrl, siteContentUrl, patName);
28264
+ if (forceRefresh) {
28265
+ sessionCache.delete(cacheKey);
28266
+ } else {
28267
+ const cached = sessionCache.get(cacheKey);
28268
+ if (cached && cached.expiresAt > Date.now() + 6e4) {
28269
+ return cached;
28270
+ }
28391
28271
  }
28392
- const session = await signIn(
28272
+ const existing = inFlightSignIns.get(cacheKey);
28273
+ if (existing) return existing;
28274
+ const promise = signIn(
28393
28275
  serverUrl,
28394
28276
  apiVersion,
28395
28277
  siteContentUrl,
28396
28278
  patName,
28397
28279
  patSecret
28398
- );
28399
- sessionCache.set(cacheKey, session);
28400
- return session;
28280
+ ).then((session) => {
28281
+ sessionCache.set(cacheKey, session);
28282
+ return session;
28283
+ }).finally(() => {
28284
+ inFlightSignIns.delete(cacheKey);
28285
+ });
28286
+ inFlightSignIns.set(cacheKey, promise);
28287
+ return promise;
28401
28288
  }
28402
- var inputSchema99 = z99.object({
28403
- toolUseIntent: z99.string().optional().describe(
28289
+ function invalidateSession(serverUrl, siteContentUrl, patName, staleAuthToken) {
28290
+ const cacheKey = sessionCacheKey(serverUrl, siteContentUrl, patName);
28291
+ const current = sessionCache.get(cacheKey);
28292
+ if (current && current.authToken === staleAuthToken) {
28293
+ sessionCache.delete(cacheKey);
28294
+ }
28295
+ }
28296
+ var inputSchema98 = z98.object({
28297
+ toolUseIntent: z98.string().optional().describe(
28404
28298
  "Brief description of what you intend to accomplish with this tool call"
28405
28299
  ),
28406
- connectionId: z99.string().describe("ID of the Tableau connection to use"),
28407
- method: z99.enum(["GET", "POST", "PUT", "DELETE"]).describe(
28300
+ connectionId: z98.string().describe("ID of the Tableau connection to use"),
28301
+ method: z98.enum(["GET", "POST", "PUT", "DELETE"]).describe(
28408
28302
  "HTTP method. GET for listing/reading, POST for creating, PUT for updates, DELETE for removal."
28409
28303
  ),
28410
- path: z99.string().describe(
28304
+ path: z98.string().describe(
28411
28305
  "API path appended to {serverUrl}/api/{apiVersion} (e.g., '/sites/{siteId}/projects', '/sites/{siteId}/workbooks/{workbookId}', '/sites/{siteId}/views/{viewId}/data'). The {siteId} placeholder is automatically replaced with the signed-in site ID."
28412
28306
  ),
28413
- queryParams: z99.record(z99.string(), z99.string()).optional().describe(
28307
+ queryParams: z98.record(z98.string(), z98.string()).optional().describe(
28414
28308
  "Query parameters to append (e.g., { pageSize: '100', filter: 'name:eq:Sales' }). Tableau supports field filtering via 'fields' and sorting via 'sort'."
28415
28309
  ),
28416
- body: z99.record(z99.string(), z99.unknown()).optional().describe(
28310
+ body: z98.record(z98.string(), z98.unknown()).optional().describe(
28417
28311
  "JSON request body for POST/PUT (Tableau also accepts XML, but JSON is recommended with Accept: application/json)."
28418
28312
  )
28419
28313
  });
28420
- var outputSchema99 = z99.discriminatedUnion("success", [
28421
- z99.object({
28422
- success: z99.literal(true),
28423
- status: z99.number(),
28424
- data: z99.unknown()
28314
+ var outputSchema98 = z98.discriminatedUnion("success", [
28315
+ z98.object({
28316
+ success: z98.literal(true),
28317
+ status: z98.number(),
28318
+ data: z98.unknown()
28425
28319
  }),
28426
- z99.object({
28427
- success: z99.literal(false),
28428
- error: z99.string()
28320
+ z98.object({
28321
+ success: z98.literal(false),
28322
+ error: z98.string()
28429
28323
  })
28430
28324
  ]);
28431
- var requestTool58 = new ConnectorTool({
28325
+ var requestTool57 = new ConnectorTool({
28432
28326
  name: "request",
28433
28327
  description: `Send authenticated requests to the Tableau REST API.
28434
28328
  The tool signs in once with the configured Personal Access Token (PAT) to obtain an X-Tableau-Auth token (cached per connection), then forwards the request with the token attached.
28435
28329
  All paths are relative to {serverUrl}/api/{apiVersion}. Use the literal placeholder \`{siteId}\` in the path \u2014 it is automatically substituted with the site ID returned from sign-in.
28436
28330
  Accept and Content-Type headers default to application/json so list responses come back as JSON instead of Tableau's default XML.`,
28437
- inputSchema: inputSchema99,
28438
- outputSchema: outputSchema99,
28331
+ inputSchema: inputSchema98,
28332
+ outputSchema: outputSchema98,
28439
28333
  async execute({ connectionId, method, path: path4, queryParams, body }, connections) {
28440
28334
  const connection = connections.find((c) => c.id === connectionId);
28441
28335
  if (!connection) {
@@ -28448,53 +28342,69 @@ Accept and Content-Type headers default to application/json so list responses co
28448
28342
  `[connector-request] tableau/${connection.name}: ${method} ${path4}`
28449
28343
  );
28450
28344
  try {
28451
- const serverUrl = parameters82.serverUrl.getValue(connection);
28452
- const siteContentUrl = parameters82.siteContentUrl.getValue(connection);
28453
- const patName = parameters82.patName.getValue(connection);
28454
- const patSecret = parameters82.patSecret.getValue(connection);
28455
- const apiVersion = parameters82.apiVersion.tryGetValue(connection) || DEFAULT_API_VERSION;
28456
- const session = await getSession(
28457
- serverUrl,
28458
- apiVersion,
28459
- siteContentUrl,
28460
- patName,
28461
- patSecret
28462
- );
28463
- const resolvedPath = path4.trim().replace(/\{siteId\}/g, session.siteId).replace(/^([^/])/, "/$1");
28464
- let url = `${buildBaseUrl4(serverUrl, apiVersion)}${resolvedPath}`;
28465
- if (queryParams) {
28466
- const searchParams = new URLSearchParams(queryParams);
28467
- url += `?${searchParams.toString()}`;
28468
- }
28345
+ const serverUrl = parameters81.serverUrl.getValue(connection);
28346
+ const siteContentUrl = parameters81.siteContentUrl.getValue(connection);
28347
+ const patName = parameters81.patName.getValue(connection);
28348
+ const patSecret = parameters81.patSecret.getValue(connection);
28349
+ const apiVersion = parameters81.apiVersion.tryGetValue(connection) || DEFAULT_API_VERSION;
28350
+ const trimmedPath = path4.trim().replace(/^([^/])/, "/$1");
28351
+ const queryString = queryParams ? `?${new URLSearchParams(queryParams).toString()}` : "";
28352
+ const baseUrl = buildBaseUrl4(serverUrl, apiVersion);
28469
28353
  const controller = new AbortController();
28470
- const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS76);
28354
+ const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS75);
28471
28355
  try {
28472
- const init = {
28473
- method,
28474
- headers: {
28475
- "X-Tableau-Auth": session.authToken,
28476
- Accept: "application/json",
28477
- "Content-Type": "application/json"
28478
- },
28479
- signal: controller.signal
28480
- };
28481
- if (body !== void 0) {
28482
- init.body = JSON.stringify(body);
28483
- }
28484
- const response = await fetch(url, init);
28485
- const text = await response.text();
28486
- const data = text ? (() => {
28487
- try {
28488
- return JSON.parse(text);
28489
- } catch {
28490
- return text;
28356
+ let attempt = 0;
28357
+ while (true) {
28358
+ const session = await getSession(
28359
+ serverUrl,
28360
+ apiVersion,
28361
+ siteContentUrl,
28362
+ patName,
28363
+ patSecret,
28364
+ { forceRefresh: attempt > 0 }
28365
+ );
28366
+ const resolvedPath = trimmedPath.replace(
28367
+ /\{siteId\}/g,
28368
+ session.siteId
28369
+ );
28370
+ const url = `${baseUrl}${resolvedPath}${queryString}`;
28371
+ const init = {
28372
+ method,
28373
+ headers: {
28374
+ "X-Tableau-Auth": session.authToken,
28375
+ Accept: "application/json",
28376
+ "Content-Type": "application/json"
28377
+ },
28378
+ signal: controller.signal
28379
+ };
28380
+ if (body !== void 0) {
28381
+ init.body = JSON.stringify(body);
28491
28382
  }
28492
- })() : null;
28493
- if (!response.ok) {
28494
- const errorMessage = data && typeof data === "object" && "error" in data ? JSON.stringify(data.error) : typeof data === "string" && data ? data : `HTTP ${response.status} ${response.statusText}`;
28495
- return { success: false, error: errorMessage };
28383
+ const response = await fetch(url, init);
28384
+ const text = await response.text();
28385
+ const data = text ? (() => {
28386
+ try {
28387
+ return JSON.parse(text);
28388
+ } catch {
28389
+ return text;
28390
+ }
28391
+ })() : null;
28392
+ if (response.status === 401 && attempt === 0) {
28393
+ invalidateSession(
28394
+ serverUrl,
28395
+ siteContentUrl,
28396
+ patName,
28397
+ session.authToken
28398
+ );
28399
+ attempt++;
28400
+ continue;
28401
+ }
28402
+ if (!response.ok) {
28403
+ const errorMessage = data && typeof data === "object" && "error" in data ? JSON.stringify(data.error) : typeof data === "string" && data ? data : `HTTP ${response.status} ${response.statusText}`;
28404
+ return { success: false, error: errorMessage };
28405
+ }
28406
+ return { success: true, status: response.status, data };
28496
28407
  }
28497
- return { success: true, status: response.status, data };
28498
28408
  } finally {
28499
28409
  clearTimeout(timeout);
28500
28410
  }
@@ -28506,16 +28416,16 @@ Accept and Content-Type headers default to application/json so list responses co
28506
28416
  });
28507
28417
 
28508
28418
  // ../connectors/src/connectors/tableau/index.ts
28509
- var tools82 = { request: requestTool58 };
28419
+ var tools81 = { request: requestTool57 };
28510
28420
  var tableauConnector = new ConnectorPlugin({
28511
28421
  slug: "tableau",
28512
28422
  authType: AUTH_TYPES.PAT,
28513
28423
  name: "Tableau",
28514
28424
  description: "Connect to Tableau Cloud or Tableau Server via a Personal Access Token (PAT). Use it to enumerate projects, workbooks, views, and data sources, and to pull view data.",
28515
- iconUrl: "https://upload.wikimedia.org/wikipedia/commons/4/4b/Tableau_Logo.png",
28516
- parameters: parameters82,
28425
+ iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/3ejrZvfw7zCDa3FPbUNQx9/d810e117b3a86c45dd96205453bf67a0/tableau-icon.svg",
28426
+ parameters: parameters81,
28517
28427
  releaseFlag: { dev1: true, dev2: false, prod: false },
28518
- categories: ["other"],
28428
+ categories: ["bi"],
28519
28429
  onboarding: tableauOnboarding,
28520
28430
  systemPrompt: {
28521
28431
  en: `### Tools
@@ -28633,13 +28543,13 @@ export default async function handler(c: Context) {
28633
28543
  - \`filter=updatedAt:gte:2024-01-01T00:00:00Z\` \u2014 \u6BD4\u8F03\u6F14\u7B97\u5B50 (gt/gte/lt/lte)
28634
28544
  - \u7D44\u307F\u5408\u308F\u305B: \`filter=ownerName:eq:alice,tags:in:[finance]\``
28635
28545
  },
28636
- tools: tools82,
28546
+ tools: tools81,
28637
28547
  async checkConnection(params) {
28638
- const serverUrl = params[parameters82.serverUrl.slug];
28639
- const siteContentUrl = params[parameters82.siteContentUrl.slug];
28640
- const patName = params[parameters82.patName.slug];
28641
- const patSecret = params[parameters82.patSecret.slug];
28642
- const apiVersion = params[parameters82.apiVersion.slug] || "3.28";
28548
+ const serverUrl = params[parameters81.serverUrl.slug];
28549
+ const siteContentUrl = params[parameters81.siteContentUrl.slug];
28550
+ const patName = params[parameters81.patName.slug];
28551
+ const patSecret = params[parameters81.patSecret.slug];
28552
+ const apiVersion = params[parameters81.apiVersion.slug] || "3.28";
28643
28553
  if (!serverUrl || siteContentUrl == null || !patName || !patSecret) {
28644
28554
  return {
28645
28555
  success: false,
@@ -28682,11 +28592,11 @@ export default async function handler(c: Context) {
28682
28592
  });
28683
28593
 
28684
28594
  // ../connectors/src/connectors/outlook-oauth/tools/request.ts
28685
- import { z as z100 } from "zod";
28686
- var BASE_HOST14 = "https://graph.microsoft.com";
28687
- var BASE_PATH_SEGMENT17 = "/v1.0";
28688
- var BASE_URL43 = `${BASE_HOST14}${BASE_PATH_SEGMENT17}`;
28689
- var REQUEST_TIMEOUT_MS77 = 6e4;
28595
+ import { z as z99 } from "zod";
28596
+ var BASE_HOST13 = "https://graph.microsoft.com";
28597
+ var BASE_PATH_SEGMENT16 = "/v1.0";
28598
+ var BASE_URL42 = `${BASE_HOST13}${BASE_PATH_SEGMENT16}`;
28599
+ var REQUEST_TIMEOUT_MS76 = 6e4;
28690
28600
  var cachedToken33 = null;
28691
28601
  async function getProxyToken33(config) {
28692
28602
  if (cachedToken33 && cachedToken33.expiresAt > Date.now() + 6e4) {
@@ -28718,39 +28628,39 @@ async function getProxyToken33(config) {
28718
28628
  };
28719
28629
  return data.token;
28720
28630
  }
28721
- var inputSchema100 = z100.object({
28722
- toolUseIntent: z100.string().optional().describe(
28631
+ var inputSchema99 = z99.object({
28632
+ toolUseIntent: z99.string().optional().describe(
28723
28633
  "Brief description of what you intend to accomplish with this tool call"
28724
28634
  ),
28725
- connectionId: z100.string().describe("ID of the Outlook OAuth connection to use"),
28726
- method: z100.enum(["GET"]).describe("HTTP method (read-only, GET only)"),
28727
- path: z100.string().describe(
28635
+ connectionId: z99.string().describe("ID of the Outlook OAuth connection to use"),
28636
+ method: z99.enum(["GET"]).describe("HTTP method (read-only, GET only)"),
28637
+ path: z99.string().describe(
28728
28638
  "Microsoft Graph path appended to https://graph.microsoft.com/v1.0. Covers Outlook Mail (e.g. '/me', '/me/messages', '/me/messages/{id}', '/me/mailFolders', '/me/messages/{id}/attachments') and Outlook Calendar (e.g. '/me/calendars', '/me/events', '/me/events/{id}', '/me/calendarView'). Use '/me' as the user prefix."
28729
28639
  ),
28730
- queryParams: z100.record(z100.string(), z100.string()).optional().describe(
28640
+ queryParams: z99.record(z99.string(), z99.string()).optional().describe(
28731
28641
  `Query parameters to append. Microsoft Graph supports OData operators ($filter, $orderby, $top, $skip, $select, $expand, $search). Examples: { $top: '10', $select: 'subject,from,receivedDateTime' } for mail; { $filter: "conversationId eq '<id>'", $orderby: 'receivedDateTime asc' } for a thread; { startDateTime: '2025-01-15T00:00:00Z', endDateTime: '2025-01-16T00:00:00Z', $orderby: 'start/dateTime' } for calendarView.`
28732
28642
  )
28733
28643
  });
28734
- var outputSchema100 = z100.discriminatedUnion("success", [
28735
- z100.object({
28736
- success: z100.literal(true),
28737
- status: z100.number(),
28738
- data: z100.record(z100.string(), z100.unknown())
28644
+ var outputSchema99 = z99.discriminatedUnion("success", [
28645
+ z99.object({
28646
+ success: z99.literal(true),
28647
+ status: z99.number(),
28648
+ data: z99.record(z99.string(), z99.unknown())
28739
28649
  }),
28740
- z100.object({
28741
- success: z100.literal(false),
28742
- error: z100.string()
28650
+ z99.object({
28651
+ success: z99.literal(false),
28652
+ error: z99.string()
28743
28653
  })
28744
28654
  ]);
28745
- var requestTool59 = new ConnectorTool({
28655
+ var requestTool58 = new ConnectorTool({
28746
28656
  name: "request",
28747
28657
  description: `Send authenticated GET requests to Microsoft Graph for Outlook Mail and Calendar.
28748
28658
  Authentication is handled automatically via OAuth proxy (Microsoft Entra ID).
28749
28659
  All paths are relative to https://graph.microsoft.com/v1.0. Use '/me' as the user prefix.
28750
28660
  Covers mailbox (\`/me/messages\`, \`/me/mailFolders\`), threads (\`/me/messages?$filter=conversationId eq '<id>'\`), attachments (\`/me/messages/{id}/attachments\`), calendars (\`/me/calendars\`), and events (\`/me/events\`, \`/me/calendarView\` for expanded occurrences).
28751
28661
  For full-text search use the \`$search\` query parameter (must be wrapped in double quotes); for filtering use \`$filter\` with OData syntax (e.g., \`receivedDateTime ge 2025-01-01T00:00:00Z\`).`,
28752
- inputSchema: inputSchema100,
28753
- outputSchema: outputSchema100,
28662
+ inputSchema: inputSchema99,
28663
+ outputSchema: outputSchema99,
28754
28664
  async execute({ connectionId, method, path: path4, queryParams }, connections, config) {
28755
28665
  const connection = connections.find((c) => c.id === connectionId);
28756
28666
  if (!connection) {
@@ -28763,8 +28673,8 @@ For full-text search use the \`$search\` query parameter (must be wrapped in dou
28763
28673
  `[connector-request] outlook-oauth/${connection.name}: ${method} ${path4}`
28764
28674
  );
28765
28675
  try {
28766
- const normalizedPath = normalizeRequestPath(path4, BASE_PATH_SEGMENT17);
28767
- let url = `${BASE_URL43}${normalizedPath}`;
28676
+ const normalizedPath = normalizeRequestPath(path4, BASE_PATH_SEGMENT16);
28677
+ let url = `${BASE_URL42}${normalizedPath}`;
28768
28678
  if (queryParams) {
28769
28679
  const searchParams = new URLSearchParams(queryParams);
28770
28680
  url += `?${searchParams.toString()}`;
@@ -28772,7 +28682,7 @@ For full-text search use the \`$search\` query parameter (must be wrapped in dou
28772
28682
  const token = await getProxyToken33(config.oauthProxy);
28773
28683
  const proxyUrl = `https://${config.oauthProxy.sandboxId}.${config.oauthProxy.previewBaseDomain}/_sqcore/connections/${connectionId}/request`;
28774
28684
  const controller = new AbortController();
28775
- const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS77);
28685
+ const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS76);
28776
28686
  try {
28777
28687
  const response = await fetch(proxyUrl, {
28778
28688
  method: "POST",
@@ -28803,7 +28713,7 @@ For full-text search use the \`$search\` query parameter (must be wrapped in dou
28803
28713
  });
28804
28714
 
28805
28715
  // ../connectors/src/connectors/outlook-oauth/setup.ts
28806
- var requestToolName14 = `outlook-oauth_${requestTool59.name}`;
28716
+ var requestToolName14 = `outlook-oauth_${requestTool58.name}`;
28807
28717
  var outlookOnboarding = new ConnectorOnboarding({
28808
28718
  connectionSetupInstructions: {
28809
28719
  ja: `\u4EE5\u4E0B\u306E\u624B\u9806\u3067 Outlook \u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3092\u884C\u3063\u3066\u304F\u3060\u3055\u3044\u3002
@@ -28860,17 +28770,17 @@ Calendar
28860
28770
  });
28861
28771
 
28862
28772
  // ../connectors/src/connectors/outlook-oauth/parameters.ts
28863
- var parameters83 = {};
28773
+ var parameters82 = {};
28864
28774
 
28865
28775
  // ../connectors/src/connectors/outlook-oauth/index.ts
28866
- var tools83 = { request: requestTool59 };
28776
+ var tools82 = { request: requestTool58 };
28867
28777
  var outlookOauthConnector = new ConnectorPlugin({
28868
28778
  slug: "outlook",
28869
28779
  authType: AUTH_TYPES.OAUTH,
28870
28780
  name: "Outlook",
28871
28781
  description: "Connect to Microsoft Outlook (Mail + Calendar) via Microsoft Graph using OAuth. Read-only access to the user's mailbox, mail folders, messages, attachments, calendars, and events.",
28872
- iconUrl: "https://upload.wikimedia.org/wikipedia/commons/d/df/Microsoft_Office_Outlook_%282018%E2%80%93present%29.svg",
28873
- parameters: parameters83,
28782
+ iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/1J1FrRTYJjOh3CcSIqsz3I/6a467b4d926075ff99dc60820e0ae4b1/Microsoft_Outlook_Icon__2025%C3%A2__present_.svg",
28783
+ parameters: parameters82,
28874
28784
  releaseFlag: { dev1: true, dev2: false, prod: false },
28875
28785
  categories: ["productivity"],
28876
28786
  onboarding: outlookOnboarding,
@@ -29150,7 +29060,7 @@ const events = await outlook.listCalendarView(
29150
29060
  events.value.forEach(e => console.log(e.start.dateTime, e.subject));
29151
29061
  \`\`\``
29152
29062
  },
29153
- tools: tools83,
29063
+ tools: tools82,
29154
29064
  async checkConnection(_params, config) {
29155
29065
  const { proxyFetch } = config;
29156
29066
  const url = "https://graph.microsoft.com/v1.0/me";
@@ -29254,7 +29164,6 @@ var plugins = {
29254
29164
  freshdesk: freshdeskConnector,
29255
29165
  freshsales: freshsalesConnector,
29256
29166
  github: githubConnector,
29257
- powerbi: powerbiConnector,
29258
29167
  powerbiOauth: powerbiOauthConnector,
29259
29168
  tableau: tableauConnector,
29260
29169
  outlookOauth: outlookOauthConnector
@@ -29468,62 +29377,62 @@ function resolveParams(entry, connectionId, plugin) {
29468
29377
  var { getQuery, loadConnections, reloadEnvFile, watchConnectionsFile } = createConnectorRegistry();
29469
29378
 
29470
29379
  // src/types/server-logic.ts
29471
- import { z as z101 } from "zod";
29472
- var parameterMetaSchema = z101.object({
29473
- name: z101.string(),
29474
- type: z101.enum(["string", "number", "boolean"]),
29475
- description: z101.string(),
29476
- required: z101.boolean().optional(),
29477
- default: z101.union([z101.string(), z101.number(), z101.boolean()]).optional()
29478
- });
29479
- var serverLogicCacheConfigSchema = z101.object({
29480
- ttl: z101.number(),
29481
- staleWhileRevalidate: z101.boolean().optional()
29482
- });
29483
- var serverLogicSchemaObjectSchema = z101.lazy(
29484
- () => z101.object({
29485
- type: z101.enum(["string", "number", "integer", "boolean", "object", "array", "null"]).optional(),
29486
- format: z101.string().optional(),
29487
- description: z101.string().optional(),
29488
- nullable: z101.boolean().optional(),
29489
- enum: z101.array(z101.union([z101.string(), z101.number(), z101.boolean(), z101.null()])).optional(),
29380
+ import { z as z100 } from "zod";
29381
+ var parameterMetaSchema = z100.object({
29382
+ name: z100.string(),
29383
+ type: z100.enum(["string", "number", "boolean"]),
29384
+ description: z100.string(),
29385
+ required: z100.boolean().optional(),
29386
+ default: z100.union([z100.string(), z100.number(), z100.boolean()]).optional()
29387
+ });
29388
+ var serverLogicCacheConfigSchema = z100.object({
29389
+ ttl: z100.number(),
29390
+ staleWhileRevalidate: z100.boolean().optional()
29391
+ });
29392
+ var serverLogicSchemaObjectSchema = z100.lazy(
29393
+ () => z100.object({
29394
+ type: z100.enum(["string", "number", "integer", "boolean", "object", "array", "null"]).optional(),
29395
+ format: z100.string().optional(),
29396
+ description: z100.string().optional(),
29397
+ nullable: z100.boolean().optional(),
29398
+ enum: z100.array(z100.union([z100.string(), z100.number(), z100.boolean(), z100.null()])).optional(),
29490
29399
  items: serverLogicSchemaObjectSchema.optional(),
29491
- properties: z101.record(z101.string(), serverLogicSchemaObjectSchema).optional(),
29492
- required: z101.array(z101.string()).optional(),
29493
- additionalProperties: z101.union([z101.boolean(), serverLogicSchemaObjectSchema]).optional(),
29494
- minimum: z101.number().optional(),
29495
- maximum: z101.number().optional(),
29496
- minLength: z101.number().optional(),
29497
- maxLength: z101.number().optional(),
29498
- pattern: z101.string().optional()
29400
+ properties: z100.record(z100.string(), serverLogicSchemaObjectSchema).optional(),
29401
+ required: z100.array(z100.string()).optional(),
29402
+ additionalProperties: z100.union([z100.boolean(), serverLogicSchemaObjectSchema]).optional(),
29403
+ minimum: z100.number().optional(),
29404
+ maximum: z100.number().optional(),
29405
+ minLength: z100.number().optional(),
29406
+ maxLength: z100.number().optional(),
29407
+ pattern: z100.string().optional()
29499
29408
  })
29500
29409
  );
29501
- var serverLogicMediaTypeSchema = z101.object({
29410
+ var serverLogicMediaTypeSchema = z100.object({
29502
29411
  schema: serverLogicSchemaObjectSchema.optional(),
29503
- example: z101.unknown().optional()
29412
+ example: z100.unknown().optional()
29504
29413
  });
29505
- var serverLogicResponseSchema = z101.object({
29506
- description: z101.string().optional(),
29507
- content: z101.record(z101.string(), serverLogicMediaTypeSchema).optional()
29414
+ var serverLogicResponseSchema = z100.object({
29415
+ description: z100.string().optional(),
29416
+ content: z100.record(z100.string(), serverLogicMediaTypeSchema).optional()
29508
29417
  });
29509
29418
  var jsonBaseFields = {
29510
- description: z101.string(),
29511
- parameters: z101.array(parameterMetaSchema).optional(),
29419
+ description: z100.string(),
29420
+ parameters: z100.array(parameterMetaSchema).optional(),
29512
29421
  response: serverLogicResponseSchema.optional(),
29513
29422
  cache: serverLogicCacheConfigSchema.optional()
29514
29423
  };
29515
- var jsonSqlServerLogicSchema = z101.object({
29424
+ var jsonSqlServerLogicSchema = z100.object({
29516
29425
  ...jsonBaseFields,
29517
- type: z101.literal("sql").optional(),
29518
- query: z101.string(),
29519
- connectionId: z101.string()
29426
+ type: z100.literal("sql").optional(),
29427
+ query: z100.string(),
29428
+ connectionId: z100.string()
29520
29429
  });
29521
- var jsonTypeScriptServerLogicSchema = z101.object({
29430
+ var jsonTypeScriptServerLogicSchema = z100.object({
29522
29431
  ...jsonBaseFields,
29523
- type: z101.literal("typescript"),
29524
- handlerPath: z101.string()
29432
+ type: z100.literal("typescript"),
29433
+ handlerPath: z100.string()
29525
29434
  });
29526
- var anyJsonServerLogicSchema = z101.union([
29435
+ var anyJsonServerLogicSchema = z100.union([
29527
29436
  jsonTypeScriptServerLogicSchema,
29528
29437
  jsonSqlServerLogicSchema
29529
29438
  ]);