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