@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/cli/index.js
CHANGED
|
@@ -192,6 +192,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
192
192
|
tools;
|
|
193
193
|
query;
|
|
194
194
|
checkConnection;
|
|
195
|
+
/**
|
|
196
|
+
* SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
|
|
197
|
+
* implement this expose a step-by-step exploration flow (database/schema/
|
|
198
|
+
* table/etc. discovery) that the dashboard backend drives via the
|
|
199
|
+
* `/connections/:connectionId/setup` endpoint. Implement by delegating to
|
|
200
|
+
* `runSetupFlow` from `setup-flow.ts`.
|
|
201
|
+
*/
|
|
202
|
+
setup;
|
|
195
203
|
constructor(config) {
|
|
196
204
|
this.slug = config.slug;
|
|
197
205
|
this.authType = config.authType;
|
|
@@ -208,6 +216,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
208
216
|
this.tools = config.tools;
|
|
209
217
|
this.query = config.query;
|
|
210
218
|
this.checkConnection = config.checkConnection;
|
|
219
|
+
this.setup = config.setup;
|
|
211
220
|
}
|
|
212
221
|
get connectorKey() {
|
|
213
222
|
return _ConnectorPlugin.deriveKey(this.slug, this.authType);
|
|
@@ -272,6 +281,50 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
272
281
|
}
|
|
273
282
|
};
|
|
274
283
|
|
|
284
|
+
// ../connectors/src/setup-flow.ts
|
|
285
|
+
async function runSetupFlow(flow, params, ctx, config) {
|
|
286
|
+
const runtime = {
|
|
287
|
+
params,
|
|
288
|
+
language: ctx.language,
|
|
289
|
+
config
|
|
290
|
+
};
|
|
291
|
+
let state = flow.initialState();
|
|
292
|
+
let answerIdx = 0;
|
|
293
|
+
for (const step of flow.steps) {
|
|
294
|
+
const ans = ctx.answers[answerIdx];
|
|
295
|
+
if (ans && ans.questionSlug === step.slug) {
|
|
296
|
+
state = step.applyAnswer(state, ans.answer);
|
|
297
|
+
answerIdx += 1;
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
if (step.type === "text") {
|
|
301
|
+
return {
|
|
302
|
+
type: "nextQuestion",
|
|
303
|
+
questionSlug: step.slug,
|
|
304
|
+
question: step.question[ctx.language],
|
|
305
|
+
questionType: "text"
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
|
|
309
|
+
if (options.length === 0) {
|
|
310
|
+
continue;
|
|
311
|
+
}
|
|
312
|
+
if (step.autoSelectIfSingle && options.length === 1) {
|
|
313
|
+
state = step.applyAnswer(state, [options[0].value]);
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
return {
|
|
317
|
+
type: "nextQuestion",
|
|
318
|
+
questionSlug: step.slug,
|
|
319
|
+
question: step.question[ctx.language],
|
|
320
|
+
questionType: "multiSelect",
|
|
321
|
+
options
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
const dataInvestigationResult = await flow.finalize(state, runtime);
|
|
325
|
+
return { type: "fulfilled", dataInvestigationResult };
|
|
326
|
+
}
|
|
327
|
+
|
|
275
328
|
// ../connectors/src/auth-types.ts
|
|
276
329
|
var AUTH_TYPES = {
|
|
277
330
|
OAUTH: "oauth",
|
|
@@ -433,6 +486,125 @@ var parameters = {
|
|
|
433
486
|
})
|
|
434
487
|
};
|
|
435
488
|
|
|
489
|
+
// ../connectors/src/connectors/snowflake/setup-flow.ts
|
|
490
|
+
var ALL_TABLES = "__ALL_TABLES__";
|
|
491
|
+
var INTERNAL_SCHEMAS = /* @__PURE__ */ new Set([
|
|
492
|
+
"INFORMATION_SCHEMA",
|
|
493
|
+
"ACCOUNT_USAGE",
|
|
494
|
+
"READER_ACCOUNT_USAGE",
|
|
495
|
+
"DATA_SHARING_USAGE"
|
|
496
|
+
]);
|
|
497
|
+
function createSnowflakeSetupFlow(runQuery3) {
|
|
498
|
+
return {
|
|
499
|
+
initialState: () => ({}),
|
|
500
|
+
steps: [
|
|
501
|
+
{
|
|
502
|
+
slug: "database",
|
|
503
|
+
type: "multiSelect",
|
|
504
|
+
autoSelectIfSingle: true,
|
|
505
|
+
question: {
|
|
506
|
+
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",
|
|
507
|
+
en: "Select the database to use for setup (pick one)"
|
|
508
|
+
},
|
|
509
|
+
async fetchOptions(_state, rt) {
|
|
510
|
+
const rows = await runQuery3(rt.params, "SHOW DATABASES");
|
|
511
|
+
return rows.map((r) => String(r["name"] ?? "")).filter((name) => name && !name.endsWith("_SHARE")).map((value) => ({ value }));
|
|
512
|
+
},
|
|
513
|
+
applyAnswer: (state, answer) => ({ ...state, database: answer[0] })
|
|
514
|
+
},
|
|
515
|
+
{
|
|
516
|
+
slug: "schema",
|
|
517
|
+
type: "multiSelect",
|
|
518
|
+
autoSelectIfSingle: true,
|
|
519
|
+
question: {
|
|
520
|
+
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",
|
|
521
|
+
en: "Select the schema to use for setup (pick one)"
|
|
522
|
+
},
|
|
523
|
+
async fetchOptions(state, rt) {
|
|
524
|
+
if (!state.database) return [];
|
|
525
|
+
const rows = await runQuery3(
|
|
526
|
+
rt.params,
|
|
527
|
+
`SHOW SCHEMAS IN DATABASE "${state.database}"`
|
|
528
|
+
);
|
|
529
|
+
return rows.map((r) => String(r["name"] ?? "")).filter(
|
|
530
|
+
(name) => name && !INTERNAL_SCHEMAS.has(name.toUpperCase())
|
|
531
|
+
).map((value) => ({ value }));
|
|
532
|
+
},
|
|
533
|
+
applyAnswer: (state, answer) => ({ ...state, schema: answer[0] })
|
|
534
|
+
},
|
|
535
|
+
{
|
|
536
|
+
slug: "tables",
|
|
537
|
+
type: "multiSelect",
|
|
538
|
+
question: {
|
|
539
|
+
ja: "\u5BFE\u8C61\u30C6\u30FC\u30D6\u30EB\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
|
|
540
|
+
en: "Select target tables (multi-select allowed)"
|
|
541
|
+
},
|
|
542
|
+
async fetchOptions(state, rt) {
|
|
543
|
+
if (!state.database || !state.schema) return [];
|
|
544
|
+
const rows = await runQuery3(
|
|
545
|
+
rt.params,
|
|
546
|
+
`SHOW TABLES IN SCHEMA "${state.database}"."${state.schema}"`
|
|
547
|
+
);
|
|
548
|
+
const tableOptions = rows.map((r) => String(r["name"] ?? "")).filter((name) => name).map((value) => ({ value }));
|
|
549
|
+
return [
|
|
550
|
+
{
|
|
551
|
+
value: ALL_TABLES,
|
|
552
|
+
label: rt.language === "ja" ? "\u3059\u3079\u3066\u306E\u30C6\u30FC\u30D6\u30EB" : "All tables"
|
|
553
|
+
},
|
|
554
|
+
...tableOptions
|
|
555
|
+
];
|
|
556
|
+
},
|
|
557
|
+
applyAnswer: (state, answer) => ({ ...state, tables: answer })
|
|
558
|
+
}
|
|
559
|
+
],
|
|
560
|
+
async finalize(state, rt) {
|
|
561
|
+
if (!state.database || !state.schema || !state.tables) {
|
|
562
|
+
throw new Error("Snowflake setup: incomplete state on finalize");
|
|
563
|
+
}
|
|
564
|
+
const db = state.database;
|
|
565
|
+
const schema = state.schema;
|
|
566
|
+
let targetTables;
|
|
567
|
+
if (state.tables.includes(ALL_TABLES)) {
|
|
568
|
+
const rows = await runQuery3(
|
|
569
|
+
rt.params,
|
|
570
|
+
`SHOW TABLES IN SCHEMA "${db}"."${schema}"`
|
|
571
|
+
);
|
|
572
|
+
targetTables = rows.map((r) => String(r["name"] ?? "")).filter((name) => name);
|
|
573
|
+
} else {
|
|
574
|
+
targetTables = state.tables.filter((t) => t !== ALL_TABLES);
|
|
575
|
+
}
|
|
576
|
+
const sections = [
|
|
577
|
+
"## Snowflake",
|
|
578
|
+
"",
|
|
579
|
+
`### Database: ${db}`,
|
|
580
|
+
"",
|
|
581
|
+
`#### Schema: ${schema}`,
|
|
582
|
+
""
|
|
583
|
+
];
|
|
584
|
+
for (const table of targetTables) {
|
|
585
|
+
const cols = await runQuery3(
|
|
586
|
+
rt.params,
|
|
587
|
+
`DESCRIBE TABLE "${db}"."${schema}"."${table}"`
|
|
588
|
+
);
|
|
589
|
+
sections.push(`##### Table: ${table}`, "");
|
|
590
|
+
sections.push("| Column | Type | Nullable | Default |");
|
|
591
|
+
sections.push("|--------|------|----------|---------|");
|
|
592
|
+
for (const c of cols) {
|
|
593
|
+
const name = String(c["name"] ?? "");
|
|
594
|
+
const type = String(c["type"] ?? "");
|
|
595
|
+
const nullable = String(c["null?"] ?? "");
|
|
596
|
+
const defaultValue = c["default"] == null ? "-" : String(c["default"]);
|
|
597
|
+
sections.push(
|
|
598
|
+
`| ${name} | ${type} | ${nullable} | ${defaultValue} |`
|
|
599
|
+
);
|
|
600
|
+
}
|
|
601
|
+
sections.push("");
|
|
602
|
+
}
|
|
603
|
+
return sections.join("\n");
|
|
604
|
+
}
|
|
605
|
+
};
|
|
606
|
+
}
|
|
607
|
+
|
|
436
608
|
// ../connectors/src/connectors/snowflake/tools/execute-query.ts
|
|
437
609
|
import { z } from "zod";
|
|
438
610
|
|
|
@@ -477,6 +649,49 @@ function decryptPrivateKey(pem, passphrase) {
|
|
|
477
649
|
passphrase
|
|
478
650
|
}).export({ type: "pkcs8", format: "pem" });
|
|
479
651
|
}
|
|
652
|
+
async function runQuery(params, sql) {
|
|
653
|
+
const snowflake = (await import("snowflake-sdk")).default;
|
|
654
|
+
snowflake.configure({ logLevel: "ERROR" });
|
|
655
|
+
const privateKeyPem = Buffer.from(
|
|
656
|
+
params[parameters.privateKeyBase64.slug],
|
|
657
|
+
"base64"
|
|
658
|
+
).toString("utf-8");
|
|
659
|
+
const privateKeyPass = params[parameters.privateKeyPassphrase.slug] || void 0;
|
|
660
|
+
const privateKey = decryptPrivateKey(privateKeyPem, privateKeyPass);
|
|
661
|
+
const conn = snowflake.createConnection({
|
|
662
|
+
account: params[parameters.account.slug],
|
|
663
|
+
username: params[parameters.user.slug],
|
|
664
|
+
role: params[parameters.role.slug],
|
|
665
|
+
warehouse: params[parameters.warehouse.slug],
|
|
666
|
+
authenticator: "SNOWFLAKE_JWT",
|
|
667
|
+
privateKey
|
|
668
|
+
});
|
|
669
|
+
await new Promise((resolve, reject) => {
|
|
670
|
+
conn.connect((err) => {
|
|
671
|
+
if (err) reject(new Error(`Snowflake connect failed: ${err.message}`));
|
|
672
|
+
else resolve();
|
|
673
|
+
});
|
|
674
|
+
});
|
|
675
|
+
try {
|
|
676
|
+
return await new Promise((resolve, reject) => {
|
|
677
|
+
conn.execute({
|
|
678
|
+
sqlText: sql,
|
|
679
|
+
complete: (err, _stmt, rows) => {
|
|
680
|
+
if (err) reject(new Error(`Snowflake query failed: ${err.message}`));
|
|
681
|
+
else resolve(rows ?? []);
|
|
682
|
+
}
|
|
683
|
+
});
|
|
684
|
+
});
|
|
685
|
+
} finally {
|
|
686
|
+
conn.destroy((err) => {
|
|
687
|
+
if (err) {
|
|
688
|
+
console.warn(
|
|
689
|
+
`[connector-query] Snowflake destroy error: ${err.message}`
|
|
690
|
+
);
|
|
691
|
+
}
|
|
692
|
+
});
|
|
693
|
+
}
|
|
694
|
+
}
|
|
480
695
|
async function executeWithSizeLimit(conn, sql, options) {
|
|
481
696
|
const rows = [];
|
|
482
697
|
let acc = 0;
|
|
@@ -631,6 +846,7 @@ Memory guidance:
|
|
|
631
846
|
});
|
|
632
847
|
|
|
633
848
|
// ../connectors/src/connectors/snowflake/index.ts
|
|
849
|
+
var snowflakeSetupFlow = createSnowflakeSetupFlow(runQuery);
|
|
634
850
|
var tools = { executeQuery: executeQueryTool };
|
|
635
851
|
var snowflakeConnector = new ConnectorPlugin({
|
|
636
852
|
slug: "snowflake",
|
|
@@ -677,6 +893,7 @@ The business logic type for this connector is "sql".
|
|
|
677
893
|
- INFORMATION_SCHEMA \u3082\u5229\u7528\u53EF\u80FD: \`SELECT * FROM db_name.INFORMATION_SCHEMA.TABLES\``
|
|
678
894
|
},
|
|
679
895
|
tools,
|
|
896
|
+
setup: (params, ctx, config) => runSetupFlow(snowflakeSetupFlow, params, ctx, config),
|
|
680
897
|
async checkConnection(params, _config) {
|
|
681
898
|
try {
|
|
682
899
|
const snowflake = (await import("snowflake-sdk")).default;
|
|
@@ -809,6 +1026,47 @@ var parameters2 = {
|
|
|
809
1026
|
})
|
|
810
1027
|
};
|
|
811
1028
|
|
|
1029
|
+
// ../connectors/src/connectors/snowflake-pat/utils.ts
|
|
1030
|
+
async function runQuery2(params, sql) {
|
|
1031
|
+
const snowflake = (await import("snowflake-sdk")).default;
|
|
1032
|
+
snowflake.configure({ logLevel: "ERROR" });
|
|
1033
|
+
const conn = snowflake.createConnection({
|
|
1034
|
+
account: params[parameters2.account.slug],
|
|
1035
|
+
username: params[parameters2.user.slug],
|
|
1036
|
+
role: params[parameters2.role.slug],
|
|
1037
|
+
warehouse: params[parameters2.warehouse.slug],
|
|
1038
|
+
password: params[parameters2.pat.slug]
|
|
1039
|
+
});
|
|
1040
|
+
await new Promise((resolve, reject) => {
|
|
1041
|
+
conn.connect((err) => {
|
|
1042
|
+
if (err) reject(new Error(`Snowflake connect failed: ${err.message}`));
|
|
1043
|
+
else resolve();
|
|
1044
|
+
});
|
|
1045
|
+
});
|
|
1046
|
+
try {
|
|
1047
|
+
return await new Promise((resolve, reject) => {
|
|
1048
|
+
conn.execute({
|
|
1049
|
+
sqlText: sql,
|
|
1050
|
+
complete: (err, _stmt, rows) => {
|
|
1051
|
+
if (err) reject(new Error(`Snowflake query failed: ${err.message}`));
|
|
1052
|
+
else resolve(rows ?? []);
|
|
1053
|
+
}
|
|
1054
|
+
});
|
|
1055
|
+
});
|
|
1056
|
+
} finally {
|
|
1057
|
+
conn.destroy((err) => {
|
|
1058
|
+
if (err) {
|
|
1059
|
+
console.warn(
|
|
1060
|
+
`[connector-query] Snowflake destroy error: ${err.message}`
|
|
1061
|
+
);
|
|
1062
|
+
}
|
|
1063
|
+
});
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
// ../connectors/src/connectors/snowflake-pat/setup-flow.ts
|
|
1068
|
+
var snowflakePatSetupFlow = createSnowflakeSetupFlow(runQuery2);
|
|
1069
|
+
|
|
812
1070
|
// ../connectors/src/connectors/snowflake-pat/tools/execute-query.ts
|
|
813
1071
|
import { z as z2 } from "zod";
|
|
814
1072
|
var MAX_ROWS = 500;
|
|
@@ -961,6 +1219,7 @@ The business logic type for this connector is "sql".
|
|
|
961
1219
|
- INFORMATION_SCHEMA \u3082\u5229\u7528\u53EF\u80FD: \`SELECT * FROM db_name.INFORMATION_SCHEMA.TABLES\``
|
|
962
1220
|
},
|
|
963
1221
|
tools: tools2,
|
|
1222
|
+
setup: (params, ctx, config) => runSetupFlow(snowflakePatSetupFlow, params, ctx, config),
|
|
964
1223
|
async checkConnection(params, _config) {
|
|
965
1224
|
try {
|
|
966
1225
|
const snowflake = (await import("snowflake-sdk")).default;
|
|
@@ -27625,399 +27884,12 @@ export default async function handler(c: Context) {
|
|
|
27625
27884
|
tools: tools79
|
|
27626
27885
|
});
|
|
27627
27886
|
|
|
27628
|
-
// ../connectors/src/connectors/powerbi/
|
|
27629
|
-
var powerbiOnboarding = new ConnectorOnboarding({
|
|
27630
|
-
connectionSetupInstructions: {
|
|
27631
|
-
en: `Follow these steps to verify the Power BI Service Principal connection.
|
|
27632
|
-
|
|
27633
|
-
1. Call \`powerbi_request\` with \`method: "GET"\` and \`path: "/groups"\` to list workspaces the Service Principal can access
|
|
27634
|
-
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
|
|
27635
|
-
|
|
27636
|
-
#### Constraints
|
|
27637
|
-
- **Do NOT execute DAX queries or refresh datasets during setup**. Only the workspace listing above is allowed
|
|
27638
|
-
- Service Principals cannot access "My workspace" \u2014 always work through workspace (group) IDs`,
|
|
27639
|
-
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
|
|
27640
|
-
|
|
27641
|
-
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
|
|
27642
|
-
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
|
|
27643
|
-
|
|
27644
|
-
#### \u5236\u7D04
|
|
27645
|
-
- **\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
|
|
27646
|
-
- 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`
|
|
27647
|
-
},
|
|
27648
|
-
dataOverviewInstructions: {
|
|
27649
|
-
en: `1. Call powerbi_request with GET /groups to list accessible workspaces
|
|
27650
|
-
2. For a target workspace, call powerbi_request with GET /groups/{groupId}/datasets to list datasets
|
|
27651
|
-
3. Call powerbi_request with GET /groups/{groupId}/reports to list reports
|
|
27652
|
-
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)`,
|
|
27653
|
-
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
|
|
27654
|
-
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
|
|
27655
|
-
3. powerbi_request \u3067 GET /groups/{groupId}/reports \u3092\u547C\u3073\u51FA\u3057\u3001\u30EC\u30DD\u30FC\u30C8\u4E00\u89A7\u3092\u53D6\u5F97
|
|
27656
|
-
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`
|
|
27657
|
-
}
|
|
27658
|
-
});
|
|
27659
|
-
|
|
27660
|
-
// ../connectors/src/connectors/powerbi/parameters.ts
|
|
27661
|
-
var parameters80 = {
|
|
27662
|
-
tenantId: new ParameterDefinition({
|
|
27663
|
-
slug: "tenant-id",
|
|
27664
|
-
name: "Azure Tenant ID",
|
|
27665
|
-
description: "The Microsoft Entra ID (Azure AD) tenant ID that owns the Service Principal. Found in Azure Portal > Microsoft Entra ID > Overview > Tenant ID.",
|
|
27666
|
-
envVarBaseKey: "POWERBI_TENANT_ID",
|
|
27667
|
-
type: "text",
|
|
27668
|
-
secret: false,
|
|
27669
|
-
required: true
|
|
27670
|
-
}),
|
|
27671
|
-
clientId: new ParameterDefinition({
|
|
27672
|
-
slug: "client-id",
|
|
27673
|
-
name: "Application (Client) ID",
|
|
27674
|
-
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.",
|
|
27675
|
-
envVarBaseKey: "POWERBI_CLIENT_ID",
|
|
27676
|
-
type: "text",
|
|
27677
|
-
secret: false,
|
|
27678
|
-
required: true
|
|
27679
|
-
}),
|
|
27680
|
-
clientSecret: new ParameterDefinition({
|
|
27681
|
-
slug: "client-secret",
|
|
27682
|
-
name: "Client Secret",
|
|
27683
|
-
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.",
|
|
27684
|
-
envVarBaseKey: "POWERBI_CLIENT_SECRET",
|
|
27685
|
-
type: "text",
|
|
27686
|
-
secret: true,
|
|
27687
|
-
required: true
|
|
27688
|
-
})
|
|
27689
|
-
};
|
|
27690
|
-
|
|
27691
|
-
// ../connectors/src/connectors/powerbi/tools/request.ts
|
|
27887
|
+
// ../connectors/src/connectors/powerbi-oauth/tools/request.ts
|
|
27692
27888
|
import { z as z97 } from "zod";
|
|
27693
27889
|
var BASE_HOST12 = "https://api.powerbi.com";
|
|
27694
27890
|
var BASE_PATH_SEGMENT15 = "/v1.0/myorg";
|
|
27695
27891
|
var BASE_URL41 = `${BASE_HOST12}${BASE_PATH_SEGMENT15}`;
|
|
27696
|
-
var TOKEN_SCOPE = "https://analysis.windows.net/powerbi/api/.default";
|
|
27697
27892
|
var REQUEST_TIMEOUT_MS74 = 6e4;
|
|
27698
|
-
var tokenCache = /* @__PURE__ */ new Map();
|
|
27699
|
-
async function getAccessToken(tenantId, clientId, clientSecret) {
|
|
27700
|
-
const cacheKey = `${tenantId}:${clientId}`;
|
|
27701
|
-
const cached = tokenCache.get(cacheKey);
|
|
27702
|
-
if (cached && cached.expiresAt > Date.now() + 6e4) {
|
|
27703
|
-
return cached.token;
|
|
27704
|
-
}
|
|
27705
|
-
const tokenUrl = `https://login.microsoftonline.com/${encodeURIComponent(tenantId)}/oauth2/v2.0/token`;
|
|
27706
|
-
const body = new URLSearchParams({
|
|
27707
|
-
grant_type: "client_credentials",
|
|
27708
|
-
client_id: clientId,
|
|
27709
|
-
client_secret: clientSecret,
|
|
27710
|
-
scope: TOKEN_SCOPE
|
|
27711
|
-
});
|
|
27712
|
-
const res = await fetch(tokenUrl, {
|
|
27713
|
-
method: "POST",
|
|
27714
|
-
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
27715
|
-
body: body.toString()
|
|
27716
|
-
});
|
|
27717
|
-
if (!res.ok) {
|
|
27718
|
-
const errorText = await res.text().catch(() => res.statusText);
|
|
27719
|
-
throw new Error(
|
|
27720
|
-
`Power BI token request failed: HTTP ${res.status} ${errorText}`
|
|
27721
|
-
);
|
|
27722
|
-
}
|
|
27723
|
-
const data = await res.json();
|
|
27724
|
-
tokenCache.set(cacheKey, {
|
|
27725
|
-
token: data.access_token,
|
|
27726
|
-
expiresAt: Date.now() + data.expires_in * 1e3
|
|
27727
|
-
});
|
|
27728
|
-
return data.access_token;
|
|
27729
|
-
}
|
|
27730
|
-
var inputSchema97 = z97.object({
|
|
27731
|
-
toolUseIntent: z97.string().optional().describe(
|
|
27732
|
-
"Brief description of what you intend to accomplish with this tool call"
|
|
27733
|
-
),
|
|
27734
|
-
connectionId: z97.string().describe("ID of the Power BI connection to use"),
|
|
27735
|
-
method: z97.enum(["GET", "POST", "PATCH", "PUT", "DELETE"]).describe(
|
|
27736
|
-
"HTTP method. Use GET for reading workspaces/datasets/reports, POST for execute queries / refresh, PATCH/PUT for updates, DELETE for removal."
|
|
27737
|
-
),
|
|
27738
|
-
path: z97.string().describe(
|
|
27739
|
-
"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."
|
|
27740
|
-
),
|
|
27741
|
-
queryParams: z97.record(z97.string(), z97.string()).optional().describe(
|
|
27742
|
-
`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.`
|
|
27743
|
-
),
|
|
27744
|
-
body: z97.record(z97.string(), z97.unknown()).optional().describe(
|
|
27745
|
-
"JSON request body for POST/PATCH/PUT/DELETE. Example: executeQueries body { queries: [{ query: 'EVALUATE TOPN(10, Sales)' }], serializerSettings: { includeNulls: true } }."
|
|
27746
|
-
)
|
|
27747
|
-
});
|
|
27748
|
-
var outputSchema97 = z97.discriminatedUnion("success", [
|
|
27749
|
-
z97.object({
|
|
27750
|
-
success: z97.literal(true),
|
|
27751
|
-
status: z97.number(),
|
|
27752
|
-
data: z97.unknown()
|
|
27753
|
-
}),
|
|
27754
|
-
z97.object({
|
|
27755
|
-
success: z97.literal(false),
|
|
27756
|
-
error: z97.string()
|
|
27757
|
-
})
|
|
27758
|
-
]);
|
|
27759
|
-
var requestTool56 = new ConnectorTool({
|
|
27760
|
-
name: "request",
|
|
27761
|
-
description: `Send authenticated requests to the Power BI REST API v1.0.
|
|
27762
|
-
Authentication uses a Microsoft Entra Service Principal (client_credentials) \u2014 the token is acquired and cached automatically.
|
|
27763
|
-
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.
|
|
27764
|
-
Use the executeQueries endpoint (POST /groups/{groupId}/datasets/{datasetId}/executeQueries) to run DAX against a dataset.`,
|
|
27765
|
-
inputSchema: inputSchema97,
|
|
27766
|
-
outputSchema: outputSchema97,
|
|
27767
|
-
async execute({ connectionId, method, path: path5, queryParams, body }, connections) {
|
|
27768
|
-
const connection = connections.find((c) => c.id === connectionId);
|
|
27769
|
-
if (!connection) {
|
|
27770
|
-
return {
|
|
27771
|
-
success: false,
|
|
27772
|
-
error: `Connection ${connectionId} not found`
|
|
27773
|
-
};
|
|
27774
|
-
}
|
|
27775
|
-
console.log(
|
|
27776
|
-
`[connector-request] powerbi/${connection.name}: ${method} ${path5}`
|
|
27777
|
-
);
|
|
27778
|
-
try {
|
|
27779
|
-
const tenantId = parameters80.tenantId.getValue(connection);
|
|
27780
|
-
const clientId = parameters80.clientId.getValue(connection);
|
|
27781
|
-
const clientSecret = parameters80.clientSecret.getValue(connection);
|
|
27782
|
-
const normalizedPath = normalizeRequestPath(path5, BASE_PATH_SEGMENT15);
|
|
27783
|
-
let url = `${BASE_URL41}${normalizedPath}`;
|
|
27784
|
-
if (queryParams) {
|
|
27785
|
-
const searchParams = new URLSearchParams(queryParams);
|
|
27786
|
-
url += `?${searchParams.toString()}`;
|
|
27787
|
-
}
|
|
27788
|
-
const token = await getAccessToken(tenantId, clientId, clientSecret);
|
|
27789
|
-
const controller = new AbortController();
|
|
27790
|
-
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS74);
|
|
27791
|
-
try {
|
|
27792
|
-
const init = {
|
|
27793
|
-
method,
|
|
27794
|
-
headers: {
|
|
27795
|
-
Authorization: `Bearer ${token}`,
|
|
27796
|
-
"Content-Type": "application/json",
|
|
27797
|
-
Accept: "application/json"
|
|
27798
|
-
},
|
|
27799
|
-
signal: controller.signal
|
|
27800
|
-
};
|
|
27801
|
-
if (body !== void 0) {
|
|
27802
|
-
init.body = JSON.stringify(body);
|
|
27803
|
-
}
|
|
27804
|
-
const response = await fetch(url, init);
|
|
27805
|
-
const text = await response.text();
|
|
27806
|
-
const data = text ? (() => {
|
|
27807
|
-
try {
|
|
27808
|
-
return JSON.parse(text);
|
|
27809
|
-
} catch {
|
|
27810
|
-
return text;
|
|
27811
|
-
}
|
|
27812
|
-
})() : null;
|
|
27813
|
-
if (!response.ok) {
|
|
27814
|
-
const errorMessage = data && typeof data === "object" && "error" in data ? JSON.stringify(data.error) : typeof data === "string" && data ? data : `HTTP ${response.status} ${response.statusText}`;
|
|
27815
|
-
return { success: false, error: errorMessage };
|
|
27816
|
-
}
|
|
27817
|
-
return { success: true, status: response.status, data };
|
|
27818
|
-
} finally {
|
|
27819
|
-
clearTimeout(timeout);
|
|
27820
|
-
}
|
|
27821
|
-
} catch (err) {
|
|
27822
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
27823
|
-
return { success: false, error: msg };
|
|
27824
|
-
}
|
|
27825
|
-
}
|
|
27826
|
-
});
|
|
27827
|
-
|
|
27828
|
-
// ../connectors/src/connectors/powerbi/index.ts
|
|
27829
|
-
var tools80 = { request: requestTool56 };
|
|
27830
|
-
var powerbiConnector = new ConnectorPlugin({
|
|
27831
|
-
slug: "powerbi",
|
|
27832
|
-
authType: AUTH_TYPES.API_KEY,
|
|
27833
|
-
name: "Power BI",
|
|
27834
|
-
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.",
|
|
27835
|
-
iconUrl: "https://upload.wikimedia.org/wikipedia/commons/c/cf/New_Power_BI_Logo.svg",
|
|
27836
|
-
parameters: parameters80,
|
|
27837
|
-
releaseFlag: { dev1: true, dev2: false, prod: false },
|
|
27838
|
-
categories: ["other"],
|
|
27839
|
-
onboarding: powerbiOnboarding,
|
|
27840
|
-
systemPrompt: {
|
|
27841
|
-
en: `### Tools
|
|
27842
|
-
|
|
27843
|
-
- \`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.
|
|
27844
|
-
|
|
27845
|
-
### Business Logic
|
|
27846
|
-
|
|
27847
|
-
The business logic type for this connector is "typescript". Use the connector SDK in your handler. Do NOT read credentials from environment variables.
|
|
27848
|
-
|
|
27849
|
-
SDK methods (client created via \`connection(connectionId)\`):
|
|
27850
|
-
- \`client.request(path, init?)\` \u2014 low-level authenticated fetch (path appended to \`https://api.powerbi.com/v1.0/myorg\`)
|
|
27851
|
-
- \`client.listGroups(options?)\` \u2014 list workspaces (\`$top\`, \`$skip\`, \`$filter\`)
|
|
27852
|
-
- \`client.listDatasets(groupId)\` / \`client.listReports(groupId)\` \u2014 list datasets / reports in a workspace
|
|
27853
|
-
- \`client.getDataset(groupId, datasetId)\` \u2014 fetch a single dataset
|
|
27854
|
-
- \`client.executeQueries(groupId, datasetId, queries, options?)\` \u2014 run DAX queries against a dataset
|
|
27855
|
-
- \`client.refreshDataset(groupId, datasetId, options?)\` \u2014 trigger an async refresh
|
|
27856
|
-
|
|
27857
|
-
\`\`\`ts
|
|
27858
|
-
import type { Context } from "hono";
|
|
27859
|
-
import { connection } from "@squadbase/vite-server/connectors/powerbi";
|
|
27860
|
-
|
|
27861
|
-
const powerbi = connection("<connectionId>");
|
|
27862
|
-
|
|
27863
|
-
export default async function handler(c: Context) {
|
|
27864
|
-
const { groupId, datasetId, dax } = await c.req.json<{
|
|
27865
|
-
groupId: string;
|
|
27866
|
-
datasetId: string;
|
|
27867
|
-
dax: string;
|
|
27868
|
-
}>();
|
|
27869
|
-
|
|
27870
|
-
const result = await powerbi.executeQueries(groupId, datasetId, [dax]);
|
|
27871
|
-
const rows = result.results[0]?.tables[0]?.rows ?? [];
|
|
27872
|
-
return c.json({ rows });
|
|
27873
|
-
}
|
|
27874
|
-
\`\`\`
|
|
27875
|
-
|
|
27876
|
-
### Power BI REST API Reference
|
|
27877
|
-
|
|
27878
|
-
- Base URL: \`https://api.powerbi.com/v1.0/myorg\`
|
|
27879
|
-
- 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)
|
|
27880
|
-
- Service Principals cannot access "My workspace"; the SP must be added as Member/Admin to each workspace
|
|
27881
|
-
- The tenant admin must enable "Allow service principals to use Power BI APIs" in the Power BI admin portal
|
|
27882
|
-
|
|
27883
|
-
#### Common Endpoints
|
|
27884
|
-
- GET \`/groups\` \u2014 List workspaces accessible to the Service Principal
|
|
27885
|
-
- GET \`/groups/{groupId}/datasets\` \u2014 List datasets in a workspace
|
|
27886
|
-
- GET \`/groups/{groupId}/datasets/{datasetId}\` \u2014 Get dataset metadata
|
|
27887
|
-
- GET \`/groups/{groupId}/datasets/{datasetId}/tables\` \u2014 List tables (requires XMLA / metadata reads enabled)
|
|
27888
|
-
- GET \`/groups/{groupId}/reports\` \u2014 List reports
|
|
27889
|
-
- GET \`/groups/{groupId}/dashboards\` \u2014 List dashboards
|
|
27890
|
-
- POST \`/groups/{groupId}/datasets/{datasetId}/executeQueries\` \u2014 Run DAX (body: \`{ queries: [{ query: "EVALUATE ..." }], serializerSettings: { includeNulls: true } }\`)
|
|
27891
|
-
- POST \`/groups/{groupId}/datasets/{datasetId}/refreshes\` \u2014 Trigger a dataset refresh
|
|
27892
|
-
- GET \`/groups/{groupId}/datasets/{datasetId}/refreshes\` \u2014 List recent refresh history
|
|
27893
|
-
|
|
27894
|
-
#### DAX Tips
|
|
27895
|
-
- \`EVALUATE TOPN(10, 'TableName')\` \u2014 sample 10 rows from a table
|
|
27896
|
-
- \`EVALUATE SUMMARIZECOLUMNS('Date'[Year], "Sales", SUM('Sales'[Amount]))\` \u2014 aggregate
|
|
27897
|
-
- 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)`,
|
|
27898
|
-
ja: `### \u30C4\u30FC\u30EB
|
|
27899
|
-
|
|
27900
|
-
- \`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
|
|
27901
|
-
|
|
27902
|
-
### Business Logic
|
|
27903
|
-
|
|
27904
|
-
\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
|
|
27905
|
-
|
|
27906
|
-
SDK\u30E1\u30BD\u30C3\u30C9 (\`connection(connectionId)\` \u3067\u4F5C\u6210\u3057\u305F\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8):
|
|
27907
|
-
- \`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)
|
|
27908
|
-
- \`client.listGroups(options?)\` \u2014 \u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u4E00\u89A7 (\`$top\`, \`$skip\`, \`$filter\`)
|
|
27909
|
-
- \`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
|
|
27910
|
-
- \`client.getDataset(groupId, datasetId)\` \u2014 \u30C7\u30FC\u30BF\u30BB\u30C3\u30C8\u5358\u4F53\u53D6\u5F97
|
|
27911
|
-
- \`client.executeQueries(groupId, datasetId, queries, options?)\` \u2014 DAX \u30AF\u30A8\u30EA\u5B9F\u884C
|
|
27912
|
-
- \`client.refreshDataset(groupId, datasetId, options?)\` \u2014 \u30C7\u30FC\u30BF\u30BB\u30C3\u30C8\u66F4\u65B0\u3092\u975E\u540C\u671F\u30C8\u30EA\u30AC\u30FC
|
|
27913
|
-
|
|
27914
|
-
\`\`\`ts
|
|
27915
|
-
import type { Context } from "hono";
|
|
27916
|
-
import { connection } from "@squadbase/vite-server/connectors/powerbi";
|
|
27917
|
-
|
|
27918
|
-
const powerbi = connection("<connectionId>");
|
|
27919
|
-
|
|
27920
|
-
export default async function handler(c: Context) {
|
|
27921
|
-
const { groupId, datasetId, dax } = await c.req.json<{
|
|
27922
|
-
groupId: string;
|
|
27923
|
-
datasetId: string;
|
|
27924
|
-
dax: string;
|
|
27925
|
-
}>();
|
|
27926
|
-
|
|
27927
|
-
const result = await powerbi.executeQueries(groupId, datasetId, [dax]);
|
|
27928
|
-
const rows = result.results[0]?.tables[0]?.rows ?? [];
|
|
27929
|
-
return c.json({ rows });
|
|
27930
|
-
}
|
|
27931
|
-
\`\`\`
|
|
27932
|
-
|
|
27933
|
-
### Power BI REST API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
|
|
27934
|
-
|
|
27935
|
-
- \u30D9\u30FC\u30B9 URL: \`https://api.powerbi.com/v1.0/myorg\`
|
|
27936
|
-
- \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)
|
|
27937
|
-
- 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
|
|
27938
|
-
- \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
|
|
27939
|
-
|
|
27940
|
-
#### \u4E3B\u8981\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8
|
|
27941
|
-
- GET \`/groups\` \u2014 Service Principal \u304C\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306A\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u4E00\u89A7
|
|
27942
|
-
- GET \`/groups/{groupId}/datasets\` \u2014 \u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u5185\u306E\u30C7\u30FC\u30BF\u30BB\u30C3\u30C8\u4E00\u89A7
|
|
27943
|
-
- GET \`/groups/{groupId}/datasets/{datasetId}\` \u2014 \u30C7\u30FC\u30BF\u30BB\u30C3\u30C8 \u30E1\u30BF\u30C7\u30FC\u30BF
|
|
27944
|
-
- 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)
|
|
27945
|
-
- GET \`/groups/{groupId}/reports\` \u2014 \u30EC\u30DD\u30FC\u30C8\u4E00\u89A7
|
|
27946
|
-
- GET \`/groups/{groupId}/dashboards\` \u2014 \u30C0\u30C3\u30B7\u30E5\u30DC\u30FC\u30C9\u4E00\u89A7
|
|
27947
|
-
- POST \`/groups/{groupId}/datasets/{datasetId}/executeQueries\` \u2014 DAX \u5B9F\u884C (body: \`{ queries: [{ query: "EVALUATE ..." }], serializerSettings: { includeNulls: true } }\`)
|
|
27948
|
-
- POST \`/groups/{groupId}/datasets/{datasetId}/refreshes\` \u2014 \u30C7\u30FC\u30BF\u30BB\u30C3\u30C8\u66F4\u65B0\u30C8\u30EA\u30AC\u30FC
|
|
27949
|
-
- GET \`/groups/{groupId}/datasets/{datasetId}/refreshes\` \u2014 \u76F4\u8FD1\u306E\u66F4\u65B0\u5C65\u6B74
|
|
27950
|
-
|
|
27951
|
-
#### DAX Tips
|
|
27952
|
-
- \`EVALUATE TOPN(10, 'TableName')\` \u2014 \u30C6\u30FC\u30D6\u30EB\u304B\u3089 10 \u884C\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0
|
|
27953
|
-
- \`EVALUATE SUMMARIZECOLUMNS('Date'[Year], "Sales", SUM('Sales'[Amount]))\` \u2014 \u96C6\u8A08
|
|
27954
|
-
- \`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`
|
|
27955
|
-
},
|
|
27956
|
-
tools: tools80,
|
|
27957
|
-
async checkConnection(params) {
|
|
27958
|
-
const tenantId = params[parameters80.tenantId.slug];
|
|
27959
|
-
const clientId = params[parameters80.clientId.slug];
|
|
27960
|
-
const clientSecret = params[parameters80.clientSecret.slug];
|
|
27961
|
-
if (!tenantId || !clientId || !clientSecret) {
|
|
27962
|
-
return {
|
|
27963
|
-
success: false,
|
|
27964
|
-
error: "Missing required parameters: tenant-id, client-id, client-secret"
|
|
27965
|
-
};
|
|
27966
|
-
}
|
|
27967
|
-
try {
|
|
27968
|
-
const tokenUrl = `https://login.microsoftonline.com/${encodeURIComponent(tenantId)}/oauth2/v2.0/token`;
|
|
27969
|
-
const body = new URLSearchParams({
|
|
27970
|
-
grant_type: "client_credentials",
|
|
27971
|
-
client_id: clientId,
|
|
27972
|
-
client_secret: clientSecret,
|
|
27973
|
-
scope: "https://analysis.windows.net/powerbi/api/.default"
|
|
27974
|
-
});
|
|
27975
|
-
const tokenRes = await fetch(tokenUrl, {
|
|
27976
|
-
method: "POST",
|
|
27977
|
-
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
27978
|
-
body: body.toString()
|
|
27979
|
-
});
|
|
27980
|
-
if (!tokenRes.ok) {
|
|
27981
|
-
const errorText = await tokenRes.text().catch(() => tokenRes.statusText);
|
|
27982
|
-
return {
|
|
27983
|
-
success: false,
|
|
27984
|
-
error: `Power BI token request failed: HTTP ${tokenRes.status} ${errorText}`
|
|
27985
|
-
};
|
|
27986
|
-
}
|
|
27987
|
-
const { access_token } = await tokenRes.json();
|
|
27988
|
-
const apiRes = await fetch(
|
|
27989
|
-
"https://api.powerbi.com/v1.0/myorg/groups?$top=1",
|
|
27990
|
-
{
|
|
27991
|
-
method: "GET",
|
|
27992
|
-
headers: {
|
|
27993
|
-
Authorization: `Bearer ${access_token}`,
|
|
27994
|
-
Accept: "application/json"
|
|
27995
|
-
}
|
|
27996
|
-
}
|
|
27997
|
-
);
|
|
27998
|
-
if (!apiRes.ok) {
|
|
27999
|
-
const errorText = await apiRes.text().catch(() => apiRes.statusText);
|
|
28000
|
-
return {
|
|
28001
|
-
success: false,
|
|
28002
|
-
error: `Power BI API failed: HTTP ${apiRes.status} ${errorText}`
|
|
28003
|
-
};
|
|
28004
|
-
}
|
|
28005
|
-
return { success: true };
|
|
28006
|
-
} catch (error) {
|
|
28007
|
-
return {
|
|
28008
|
-
success: false,
|
|
28009
|
-
error: error instanceof Error ? error.message : String(error)
|
|
28010
|
-
};
|
|
28011
|
-
}
|
|
28012
|
-
}
|
|
28013
|
-
});
|
|
28014
|
-
|
|
28015
|
-
// ../connectors/src/connectors/powerbi-oauth/tools/request.ts
|
|
28016
|
-
import { z as z98 } from "zod";
|
|
28017
|
-
var BASE_HOST13 = "https://api.powerbi.com";
|
|
28018
|
-
var BASE_PATH_SEGMENT16 = "/v1.0/myorg";
|
|
28019
|
-
var BASE_URL42 = `${BASE_HOST13}${BASE_PATH_SEGMENT16}`;
|
|
28020
|
-
var REQUEST_TIMEOUT_MS75 = 6e4;
|
|
28021
27893
|
var cachedToken32 = null;
|
|
28022
27894
|
async function getProxyToken32(config) {
|
|
28023
27895
|
if (cachedToken32 && cachedToken32.expiresAt > Date.now() + 6e4) {
|
|
@@ -28049,42 +27921,42 @@ async function getProxyToken32(config) {
|
|
|
28049
27921
|
};
|
|
28050
27922
|
return data.token;
|
|
28051
27923
|
}
|
|
28052
|
-
var
|
|
28053
|
-
toolUseIntent:
|
|
27924
|
+
var inputSchema97 = z97.object({
|
|
27925
|
+
toolUseIntent: z97.string().optional().describe(
|
|
28054
27926
|
"Brief description of what you intend to accomplish with this tool call"
|
|
28055
27927
|
),
|
|
28056
|
-
connectionId:
|
|
28057
|
-
method:
|
|
27928
|
+
connectionId: z97.string().describe("ID of the Power BI OAuth connection to use"),
|
|
27929
|
+
method: z97.enum(["GET", "POST", "PATCH", "PUT", "DELETE"]).describe(
|
|
28058
27930
|
"HTTP method. GET for reading workspaces/datasets/reports, POST for executeQueries / refresh, PATCH/PUT for updates, DELETE for removal."
|
|
28059
27931
|
),
|
|
28060
|
-
path:
|
|
27932
|
+
path: z97.string().describe(
|
|
28061
27933
|
"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."
|
|
28062
27934
|
),
|
|
28063
|
-
queryParams:
|
|
27935
|
+
queryParams: z97.record(z97.string(), z97.string()).optional().describe(
|
|
28064
27936
|
`Query parameters to append (e.g., { $top: '50', $filter: "name eq 'Sales'" }).`
|
|
28065
27937
|
),
|
|
28066
|
-
body:
|
|
27938
|
+
body: z97.record(z97.string(), z97.unknown()).optional().describe(
|
|
28067
27939
|
"JSON request body for POST/PATCH/PUT/DELETE. Example executeQueries body: { queries: [{ query: 'EVALUATE TOPN(10, Sales)' }], serializerSettings: { includeNulls: true } }."
|
|
28068
27940
|
)
|
|
28069
27941
|
});
|
|
28070
|
-
var
|
|
28071
|
-
|
|
28072
|
-
success:
|
|
28073
|
-
status:
|
|
28074
|
-
data:
|
|
27942
|
+
var outputSchema97 = z97.discriminatedUnion("success", [
|
|
27943
|
+
z97.object({
|
|
27944
|
+
success: z97.literal(true),
|
|
27945
|
+
status: z97.number(),
|
|
27946
|
+
data: z97.unknown()
|
|
28075
27947
|
}),
|
|
28076
|
-
|
|
28077
|
-
success:
|
|
28078
|
-
error:
|
|
27948
|
+
z97.object({
|
|
27949
|
+
success: z97.literal(false),
|
|
27950
|
+
error: z97.string()
|
|
28079
27951
|
})
|
|
28080
27952
|
]);
|
|
28081
|
-
var
|
|
27953
|
+
var requestTool56 = new ConnectorTool({
|
|
28082
27954
|
name: "request",
|
|
28083
27955
|
description: `Send authenticated requests to the Power BI REST API v1.0 using the user's Microsoft Entra OAuth token (proxied automatically).
|
|
28084
27956
|
All paths are relative to https://api.powerbi.com/v1.0/myorg. Use the executeQueries endpoint to run DAX against a dataset.
|
|
28085
27957
|
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.`,
|
|
28086
|
-
inputSchema:
|
|
28087
|
-
outputSchema:
|
|
27958
|
+
inputSchema: inputSchema97,
|
|
27959
|
+
outputSchema: outputSchema97,
|
|
28088
27960
|
async execute({ connectionId, method, path: path5, queryParams, body }, connections, config) {
|
|
28089
27961
|
const connection = connections.find((c) => c.id === connectionId);
|
|
28090
27962
|
if (!connection) {
|
|
@@ -28097,8 +27969,8 @@ The signed-in user must have access to the workspace; unlike Service Principals,
|
|
|
28097
27969
|
`[connector-request] powerbi-oauth/${connection.name}: ${method} ${path5}`
|
|
28098
27970
|
);
|
|
28099
27971
|
try {
|
|
28100
|
-
const normalizedPath = normalizeRequestPath(path5,
|
|
28101
|
-
let url = `${
|
|
27972
|
+
const normalizedPath = normalizeRequestPath(path5, BASE_PATH_SEGMENT15);
|
|
27973
|
+
let url = `${BASE_URL41}${normalizedPath}`;
|
|
28102
27974
|
if (queryParams) {
|
|
28103
27975
|
const searchParams = new URLSearchParams(queryParams);
|
|
28104
27976
|
url += `?${searchParams.toString()}`;
|
|
@@ -28106,7 +27978,7 @@ The signed-in user must have access to the workspace; unlike Service Principals,
|
|
|
28106
27978
|
const token = await getProxyToken32(config.oauthProxy);
|
|
28107
27979
|
const proxyUrl = `https://${config.oauthProxy.sandboxId}.${config.oauthProxy.previewBaseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
28108
27980
|
const controller = new AbortController();
|
|
28109
|
-
const timeout = setTimeout(() => controller.abort(),
|
|
27981
|
+
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS74);
|
|
28110
27982
|
try {
|
|
28111
27983
|
const response = await fetch(proxyUrl, {
|
|
28112
27984
|
method: "POST",
|
|
@@ -28145,7 +28017,7 @@ The signed-in user must have access to the workspace; unlike Service Principals,
|
|
|
28145
28017
|
});
|
|
28146
28018
|
|
|
28147
28019
|
// ../connectors/src/connectors/powerbi-oauth/setup.ts
|
|
28148
|
-
var requestToolName13 = `powerbi-oauth_${
|
|
28020
|
+
var requestToolName13 = `powerbi-oauth_${requestTool56.name}`;
|
|
28149
28021
|
var powerbiOauthOnboarding = new ConnectorOnboarding({
|
|
28150
28022
|
connectionSetupInstructions: {
|
|
28151
28023
|
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
|
|
@@ -28178,19 +28050,19 @@ var powerbiOauthOnboarding = new ConnectorOnboarding({
|
|
|
28178
28050
|
});
|
|
28179
28051
|
|
|
28180
28052
|
// ../connectors/src/connectors/powerbi-oauth/parameters.ts
|
|
28181
|
-
var
|
|
28053
|
+
var parameters80 = {};
|
|
28182
28054
|
|
|
28183
28055
|
// ../connectors/src/connectors/powerbi-oauth/index.ts
|
|
28184
|
-
var
|
|
28056
|
+
var tools80 = { request: requestTool56 };
|
|
28185
28057
|
var powerbiOauthConnector = new ConnectorPlugin({
|
|
28186
28058
|
slug: "powerbi",
|
|
28187
28059
|
authType: AUTH_TYPES.OAUTH,
|
|
28188
28060
|
name: "Power BI",
|
|
28189
28061
|
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.",
|
|
28190
|
-
iconUrl: "https://
|
|
28191
|
-
parameters:
|
|
28062
|
+
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/2vXQCKGpMJ9kGSaqkZl9IS/cc5669c267fc5d11e7b1f8c01723e461/power-bi-icon.png",
|
|
28063
|
+
parameters: parameters80,
|
|
28192
28064
|
releaseFlag: { dev1: true, dev2: false, prod: false },
|
|
28193
|
-
categories: ["
|
|
28065
|
+
categories: ["bi"],
|
|
28194
28066
|
onboarding: powerbiOauthOnboarding,
|
|
28195
28067
|
proxyPolicy: {
|
|
28196
28068
|
allowlist: [
|
|
@@ -28314,7 +28186,7 @@ export default async function handler(c: Context) {
|
|
|
28314
28186
|
- \`EVALUATE SUMMARIZECOLUMNS('Date'[Year], "Sales", SUM('Sales'[Amount]))\` \u2014 \u96C6\u8A08
|
|
28315
28187
|
- \`executeQueries\` \u306F\u73FE\u72B6 1 \u30EA\u30AF\u30A8\u30B9\u30C8\u306B\u3064\u304D 1 \u30AF\u30A8\u30EA\u306E\u307F`
|
|
28316
28188
|
},
|
|
28317
|
-
tools:
|
|
28189
|
+
tools: tools80,
|
|
28318
28190
|
async checkConnection(_params, config) {
|
|
28319
28191
|
const { proxyFetch } = config;
|
|
28320
28192
|
const url = "https://api.powerbi.com/v1.0/myorg/groups?$top=1";
|
|
@@ -28370,7 +28242,7 @@ var tableauOnboarding = new ConnectorOnboarding({
|
|
|
28370
28242
|
});
|
|
28371
28243
|
|
|
28372
28244
|
// ../connectors/src/connectors/tableau/parameters.ts
|
|
28373
|
-
var
|
|
28245
|
+
var parameters81 = {
|
|
28374
28246
|
serverUrl: new ParameterDefinition({
|
|
28375
28247
|
slug: "server-url",
|
|
28376
28248
|
name: "Tableau Server URL",
|
|
@@ -28419,10 +28291,14 @@ var parameters82 = {
|
|
|
28419
28291
|
};
|
|
28420
28292
|
|
|
28421
28293
|
// ../connectors/src/connectors/tableau/tools/request.ts
|
|
28422
|
-
import { z as
|
|
28294
|
+
import { z as z98 } from "zod";
|
|
28423
28295
|
var DEFAULT_API_VERSION = "3.28";
|
|
28424
|
-
var
|
|
28296
|
+
var REQUEST_TIMEOUT_MS75 = 6e4;
|
|
28425
28297
|
var sessionCache = /* @__PURE__ */ new Map();
|
|
28298
|
+
var inFlightSignIns = /* @__PURE__ */ new Map();
|
|
28299
|
+
function sessionCacheKey(serverUrl, siteContentUrl, patName) {
|
|
28300
|
+
return `${serverUrl}|${siteContentUrl}|${patName}`;
|
|
28301
|
+
}
|
|
28426
28302
|
function buildBaseUrl4(serverUrl, apiVersion) {
|
|
28427
28303
|
return `${serverUrl.replace(/\/$/, "")}/api/${apiVersion}`;
|
|
28428
28304
|
}
|
|
@@ -28457,59 +28333,77 @@ async function signIn(serverUrl, apiVersion, siteContentUrl, patName, patSecret)
|
|
|
28457
28333
|
expiresAt: Date.now() + 30 * 60 * 1e3
|
|
28458
28334
|
};
|
|
28459
28335
|
}
|
|
28460
|
-
async function getSession(serverUrl, apiVersion, siteContentUrl, patName, patSecret) {
|
|
28461
|
-
const cacheKey =
|
|
28462
|
-
|
|
28463
|
-
|
|
28464
|
-
|
|
28336
|
+
async function getSession(serverUrl, apiVersion, siteContentUrl, patName, patSecret, { forceRefresh = false } = {}) {
|
|
28337
|
+
const cacheKey = sessionCacheKey(serverUrl, siteContentUrl, patName);
|
|
28338
|
+
if (forceRefresh) {
|
|
28339
|
+
sessionCache.delete(cacheKey);
|
|
28340
|
+
} else {
|
|
28341
|
+
const cached = sessionCache.get(cacheKey);
|
|
28342
|
+
if (cached && cached.expiresAt > Date.now() + 6e4) {
|
|
28343
|
+
return cached;
|
|
28344
|
+
}
|
|
28465
28345
|
}
|
|
28466
|
-
const
|
|
28346
|
+
const existing = inFlightSignIns.get(cacheKey);
|
|
28347
|
+
if (existing) return existing;
|
|
28348
|
+
const promise = signIn(
|
|
28467
28349
|
serverUrl,
|
|
28468
28350
|
apiVersion,
|
|
28469
28351
|
siteContentUrl,
|
|
28470
28352
|
patName,
|
|
28471
28353
|
patSecret
|
|
28472
|
-
)
|
|
28473
|
-
|
|
28474
|
-
|
|
28354
|
+
).then((session) => {
|
|
28355
|
+
sessionCache.set(cacheKey, session);
|
|
28356
|
+
return session;
|
|
28357
|
+
}).finally(() => {
|
|
28358
|
+
inFlightSignIns.delete(cacheKey);
|
|
28359
|
+
});
|
|
28360
|
+
inFlightSignIns.set(cacheKey, promise);
|
|
28361
|
+
return promise;
|
|
28475
28362
|
}
|
|
28476
|
-
|
|
28477
|
-
|
|
28363
|
+
function invalidateSession(serverUrl, siteContentUrl, patName, staleAuthToken) {
|
|
28364
|
+
const cacheKey = sessionCacheKey(serverUrl, siteContentUrl, patName);
|
|
28365
|
+
const current = sessionCache.get(cacheKey);
|
|
28366
|
+
if (current && current.authToken === staleAuthToken) {
|
|
28367
|
+
sessionCache.delete(cacheKey);
|
|
28368
|
+
}
|
|
28369
|
+
}
|
|
28370
|
+
var inputSchema98 = z98.object({
|
|
28371
|
+
toolUseIntent: z98.string().optional().describe(
|
|
28478
28372
|
"Brief description of what you intend to accomplish with this tool call"
|
|
28479
28373
|
),
|
|
28480
|
-
connectionId:
|
|
28481
|
-
method:
|
|
28374
|
+
connectionId: z98.string().describe("ID of the Tableau connection to use"),
|
|
28375
|
+
method: z98.enum(["GET", "POST", "PUT", "DELETE"]).describe(
|
|
28482
28376
|
"HTTP method. GET for listing/reading, POST for creating, PUT for updates, DELETE for removal."
|
|
28483
28377
|
),
|
|
28484
|
-
path:
|
|
28378
|
+
path: z98.string().describe(
|
|
28485
28379
|
"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."
|
|
28486
28380
|
),
|
|
28487
|
-
queryParams:
|
|
28381
|
+
queryParams: z98.record(z98.string(), z98.string()).optional().describe(
|
|
28488
28382
|
"Query parameters to append (e.g., { pageSize: '100', filter: 'name:eq:Sales' }). Tableau supports field filtering via 'fields' and sorting via 'sort'."
|
|
28489
28383
|
),
|
|
28490
|
-
body:
|
|
28384
|
+
body: z98.record(z98.string(), z98.unknown()).optional().describe(
|
|
28491
28385
|
"JSON request body for POST/PUT (Tableau also accepts XML, but JSON is recommended with Accept: application/json)."
|
|
28492
28386
|
)
|
|
28493
28387
|
});
|
|
28494
|
-
var
|
|
28495
|
-
|
|
28496
|
-
success:
|
|
28497
|
-
status:
|
|
28498
|
-
data:
|
|
28388
|
+
var outputSchema98 = z98.discriminatedUnion("success", [
|
|
28389
|
+
z98.object({
|
|
28390
|
+
success: z98.literal(true),
|
|
28391
|
+
status: z98.number(),
|
|
28392
|
+
data: z98.unknown()
|
|
28499
28393
|
}),
|
|
28500
|
-
|
|
28501
|
-
success:
|
|
28502
|
-
error:
|
|
28394
|
+
z98.object({
|
|
28395
|
+
success: z98.literal(false),
|
|
28396
|
+
error: z98.string()
|
|
28503
28397
|
})
|
|
28504
28398
|
]);
|
|
28505
|
-
var
|
|
28399
|
+
var requestTool57 = new ConnectorTool({
|
|
28506
28400
|
name: "request",
|
|
28507
28401
|
description: `Send authenticated requests to the Tableau REST API.
|
|
28508
28402
|
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.
|
|
28509
28403
|
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.
|
|
28510
28404
|
Accept and Content-Type headers default to application/json so list responses come back as JSON instead of Tableau's default XML.`,
|
|
28511
|
-
inputSchema:
|
|
28512
|
-
outputSchema:
|
|
28405
|
+
inputSchema: inputSchema98,
|
|
28406
|
+
outputSchema: outputSchema98,
|
|
28513
28407
|
async execute({ connectionId, method, path: path5, queryParams, body }, connections) {
|
|
28514
28408
|
const connection = connections.find((c) => c.id === connectionId);
|
|
28515
28409
|
if (!connection) {
|
|
@@ -28522,53 +28416,69 @@ Accept and Content-Type headers default to application/json so list responses co
|
|
|
28522
28416
|
`[connector-request] tableau/${connection.name}: ${method} ${path5}`
|
|
28523
28417
|
);
|
|
28524
28418
|
try {
|
|
28525
|
-
const serverUrl =
|
|
28526
|
-
const siteContentUrl =
|
|
28527
|
-
const patName =
|
|
28528
|
-
const patSecret =
|
|
28529
|
-
const apiVersion =
|
|
28530
|
-
const
|
|
28531
|
-
|
|
28532
|
-
|
|
28533
|
-
siteContentUrl,
|
|
28534
|
-
patName,
|
|
28535
|
-
patSecret
|
|
28536
|
-
);
|
|
28537
|
-
const resolvedPath = path5.trim().replace(/\{siteId\}/g, session.siteId).replace(/^([^/])/, "/$1");
|
|
28538
|
-
let url = `${buildBaseUrl4(serverUrl, apiVersion)}${resolvedPath}`;
|
|
28539
|
-
if (queryParams) {
|
|
28540
|
-
const searchParams = new URLSearchParams(queryParams);
|
|
28541
|
-
url += `?${searchParams.toString()}`;
|
|
28542
|
-
}
|
|
28419
|
+
const serverUrl = parameters81.serverUrl.getValue(connection);
|
|
28420
|
+
const siteContentUrl = parameters81.siteContentUrl.getValue(connection);
|
|
28421
|
+
const patName = parameters81.patName.getValue(connection);
|
|
28422
|
+
const patSecret = parameters81.patSecret.getValue(connection);
|
|
28423
|
+
const apiVersion = parameters81.apiVersion.tryGetValue(connection) || DEFAULT_API_VERSION;
|
|
28424
|
+
const trimmedPath = path5.trim().replace(/^([^/])/, "/$1");
|
|
28425
|
+
const queryString = queryParams ? `?${new URLSearchParams(queryParams).toString()}` : "";
|
|
28426
|
+
const baseUrl = buildBaseUrl4(serverUrl, apiVersion);
|
|
28543
28427
|
const controller = new AbortController();
|
|
28544
|
-
const timeout = setTimeout(() => controller.abort(),
|
|
28428
|
+
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS75);
|
|
28545
28429
|
try {
|
|
28546
|
-
|
|
28547
|
-
|
|
28548
|
-
|
|
28549
|
-
|
|
28550
|
-
|
|
28551
|
-
|
|
28552
|
-
|
|
28553
|
-
|
|
28554
|
-
|
|
28555
|
-
|
|
28556
|
-
|
|
28557
|
-
|
|
28558
|
-
|
|
28559
|
-
|
|
28560
|
-
|
|
28561
|
-
|
|
28562
|
-
|
|
28563
|
-
|
|
28564
|
-
|
|
28430
|
+
let attempt = 0;
|
|
28431
|
+
while (true) {
|
|
28432
|
+
const session = await getSession(
|
|
28433
|
+
serverUrl,
|
|
28434
|
+
apiVersion,
|
|
28435
|
+
siteContentUrl,
|
|
28436
|
+
patName,
|
|
28437
|
+
patSecret,
|
|
28438
|
+
{ forceRefresh: attempt > 0 }
|
|
28439
|
+
);
|
|
28440
|
+
const resolvedPath = trimmedPath.replace(
|
|
28441
|
+
/\{siteId\}/g,
|
|
28442
|
+
session.siteId
|
|
28443
|
+
);
|
|
28444
|
+
const url = `${baseUrl}${resolvedPath}${queryString}`;
|
|
28445
|
+
const init = {
|
|
28446
|
+
method,
|
|
28447
|
+
headers: {
|
|
28448
|
+
"X-Tableau-Auth": session.authToken,
|
|
28449
|
+
Accept: "application/json",
|
|
28450
|
+
"Content-Type": "application/json"
|
|
28451
|
+
},
|
|
28452
|
+
signal: controller.signal
|
|
28453
|
+
};
|
|
28454
|
+
if (body !== void 0) {
|
|
28455
|
+
init.body = JSON.stringify(body);
|
|
28565
28456
|
}
|
|
28566
|
-
|
|
28567
|
-
|
|
28568
|
-
const
|
|
28569
|
-
|
|
28457
|
+
const response = await fetch(url, init);
|
|
28458
|
+
const text = await response.text();
|
|
28459
|
+
const data = text ? (() => {
|
|
28460
|
+
try {
|
|
28461
|
+
return JSON.parse(text);
|
|
28462
|
+
} catch {
|
|
28463
|
+
return text;
|
|
28464
|
+
}
|
|
28465
|
+
})() : null;
|
|
28466
|
+
if (response.status === 401 && attempt === 0) {
|
|
28467
|
+
invalidateSession(
|
|
28468
|
+
serverUrl,
|
|
28469
|
+
siteContentUrl,
|
|
28470
|
+
patName,
|
|
28471
|
+
session.authToken
|
|
28472
|
+
);
|
|
28473
|
+
attempt++;
|
|
28474
|
+
continue;
|
|
28475
|
+
}
|
|
28476
|
+
if (!response.ok) {
|
|
28477
|
+
const errorMessage = data && typeof data === "object" && "error" in data ? JSON.stringify(data.error) : typeof data === "string" && data ? data : `HTTP ${response.status} ${response.statusText}`;
|
|
28478
|
+
return { success: false, error: errorMessage };
|
|
28479
|
+
}
|
|
28480
|
+
return { success: true, status: response.status, data };
|
|
28570
28481
|
}
|
|
28571
|
-
return { success: true, status: response.status, data };
|
|
28572
28482
|
} finally {
|
|
28573
28483
|
clearTimeout(timeout);
|
|
28574
28484
|
}
|
|
@@ -28580,16 +28490,16 @@ Accept and Content-Type headers default to application/json so list responses co
|
|
|
28580
28490
|
});
|
|
28581
28491
|
|
|
28582
28492
|
// ../connectors/src/connectors/tableau/index.ts
|
|
28583
|
-
var
|
|
28493
|
+
var tools81 = { request: requestTool57 };
|
|
28584
28494
|
var tableauConnector = new ConnectorPlugin({
|
|
28585
28495
|
slug: "tableau",
|
|
28586
28496
|
authType: AUTH_TYPES.PAT,
|
|
28587
28497
|
name: "Tableau",
|
|
28588
28498
|
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.",
|
|
28589
|
-
iconUrl: "https://
|
|
28590
|
-
parameters:
|
|
28499
|
+
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/3ejrZvfw7zCDa3FPbUNQx9/d810e117b3a86c45dd96205453bf67a0/tableau-icon.svg",
|
|
28500
|
+
parameters: parameters81,
|
|
28591
28501
|
releaseFlag: { dev1: true, dev2: false, prod: false },
|
|
28592
|
-
categories: ["
|
|
28502
|
+
categories: ["bi"],
|
|
28593
28503
|
onboarding: tableauOnboarding,
|
|
28594
28504
|
systemPrompt: {
|
|
28595
28505
|
en: `### Tools
|
|
@@ -28707,13 +28617,13 @@ export default async function handler(c: Context) {
|
|
|
28707
28617
|
- \`filter=updatedAt:gte:2024-01-01T00:00:00Z\` \u2014 \u6BD4\u8F03\u6F14\u7B97\u5B50 (gt/gte/lt/lte)
|
|
28708
28618
|
- \u7D44\u307F\u5408\u308F\u305B: \`filter=ownerName:eq:alice,tags:in:[finance]\``
|
|
28709
28619
|
},
|
|
28710
|
-
tools:
|
|
28620
|
+
tools: tools81,
|
|
28711
28621
|
async checkConnection(params) {
|
|
28712
|
-
const serverUrl = params[
|
|
28713
|
-
const siteContentUrl = params[
|
|
28714
|
-
const patName = params[
|
|
28715
|
-
const patSecret = params[
|
|
28716
|
-
const apiVersion = params[
|
|
28622
|
+
const serverUrl = params[parameters81.serverUrl.slug];
|
|
28623
|
+
const siteContentUrl = params[parameters81.siteContentUrl.slug];
|
|
28624
|
+
const patName = params[parameters81.patName.slug];
|
|
28625
|
+
const patSecret = params[parameters81.patSecret.slug];
|
|
28626
|
+
const apiVersion = params[parameters81.apiVersion.slug] || "3.28";
|
|
28717
28627
|
if (!serverUrl || siteContentUrl == null || !patName || !patSecret) {
|
|
28718
28628
|
return {
|
|
28719
28629
|
success: false,
|
|
@@ -28756,11 +28666,11 @@ export default async function handler(c: Context) {
|
|
|
28756
28666
|
});
|
|
28757
28667
|
|
|
28758
28668
|
// ../connectors/src/connectors/outlook-oauth/tools/request.ts
|
|
28759
|
-
import { z as
|
|
28760
|
-
var
|
|
28761
|
-
var
|
|
28762
|
-
var
|
|
28763
|
-
var
|
|
28669
|
+
import { z as z99 } from "zod";
|
|
28670
|
+
var BASE_HOST13 = "https://graph.microsoft.com";
|
|
28671
|
+
var BASE_PATH_SEGMENT16 = "/v1.0";
|
|
28672
|
+
var BASE_URL42 = `${BASE_HOST13}${BASE_PATH_SEGMENT16}`;
|
|
28673
|
+
var REQUEST_TIMEOUT_MS76 = 6e4;
|
|
28764
28674
|
var cachedToken33 = null;
|
|
28765
28675
|
async function getProxyToken33(config) {
|
|
28766
28676
|
if (cachedToken33 && cachedToken33.expiresAt > Date.now() + 6e4) {
|
|
@@ -28792,39 +28702,39 @@ async function getProxyToken33(config) {
|
|
|
28792
28702
|
};
|
|
28793
28703
|
return data.token;
|
|
28794
28704
|
}
|
|
28795
|
-
var
|
|
28796
|
-
toolUseIntent:
|
|
28705
|
+
var inputSchema99 = z99.object({
|
|
28706
|
+
toolUseIntent: z99.string().optional().describe(
|
|
28797
28707
|
"Brief description of what you intend to accomplish with this tool call"
|
|
28798
28708
|
),
|
|
28799
|
-
connectionId:
|
|
28800
|
-
method:
|
|
28801
|
-
path:
|
|
28709
|
+
connectionId: z99.string().describe("ID of the Outlook OAuth connection to use"),
|
|
28710
|
+
method: z99.enum(["GET"]).describe("HTTP method (read-only, GET only)"),
|
|
28711
|
+
path: z99.string().describe(
|
|
28802
28712
|
"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."
|
|
28803
28713
|
),
|
|
28804
|
-
queryParams:
|
|
28714
|
+
queryParams: z99.record(z99.string(), z99.string()).optional().describe(
|
|
28805
28715
|
`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.`
|
|
28806
28716
|
)
|
|
28807
28717
|
});
|
|
28808
|
-
var
|
|
28809
|
-
|
|
28810
|
-
success:
|
|
28811
|
-
status:
|
|
28812
|
-
data:
|
|
28718
|
+
var outputSchema99 = z99.discriminatedUnion("success", [
|
|
28719
|
+
z99.object({
|
|
28720
|
+
success: z99.literal(true),
|
|
28721
|
+
status: z99.number(),
|
|
28722
|
+
data: z99.record(z99.string(), z99.unknown())
|
|
28813
28723
|
}),
|
|
28814
|
-
|
|
28815
|
-
success:
|
|
28816
|
-
error:
|
|
28724
|
+
z99.object({
|
|
28725
|
+
success: z99.literal(false),
|
|
28726
|
+
error: z99.string()
|
|
28817
28727
|
})
|
|
28818
28728
|
]);
|
|
28819
|
-
var
|
|
28729
|
+
var requestTool58 = new ConnectorTool({
|
|
28820
28730
|
name: "request",
|
|
28821
28731
|
description: `Send authenticated GET requests to Microsoft Graph for Outlook Mail and Calendar.
|
|
28822
28732
|
Authentication is handled automatically via OAuth proxy (Microsoft Entra ID).
|
|
28823
28733
|
All paths are relative to https://graph.microsoft.com/v1.0. Use '/me' as the user prefix.
|
|
28824
28734
|
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).
|
|
28825
28735
|
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\`).`,
|
|
28826
|
-
inputSchema:
|
|
28827
|
-
outputSchema:
|
|
28736
|
+
inputSchema: inputSchema99,
|
|
28737
|
+
outputSchema: outputSchema99,
|
|
28828
28738
|
async execute({ connectionId, method, path: path5, queryParams }, connections, config) {
|
|
28829
28739
|
const connection = connections.find((c) => c.id === connectionId);
|
|
28830
28740
|
if (!connection) {
|
|
@@ -28837,8 +28747,8 @@ For full-text search use the \`$search\` query parameter (must be wrapped in dou
|
|
|
28837
28747
|
`[connector-request] outlook-oauth/${connection.name}: ${method} ${path5}`
|
|
28838
28748
|
);
|
|
28839
28749
|
try {
|
|
28840
|
-
const normalizedPath = normalizeRequestPath(path5,
|
|
28841
|
-
let url = `${
|
|
28750
|
+
const normalizedPath = normalizeRequestPath(path5, BASE_PATH_SEGMENT16);
|
|
28751
|
+
let url = `${BASE_URL42}${normalizedPath}`;
|
|
28842
28752
|
if (queryParams) {
|
|
28843
28753
|
const searchParams = new URLSearchParams(queryParams);
|
|
28844
28754
|
url += `?${searchParams.toString()}`;
|
|
@@ -28846,7 +28756,7 @@ For full-text search use the \`$search\` query parameter (must be wrapped in dou
|
|
|
28846
28756
|
const token = await getProxyToken33(config.oauthProxy);
|
|
28847
28757
|
const proxyUrl = `https://${config.oauthProxy.sandboxId}.${config.oauthProxy.previewBaseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
28848
28758
|
const controller = new AbortController();
|
|
28849
|
-
const timeout = setTimeout(() => controller.abort(),
|
|
28759
|
+
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS76);
|
|
28850
28760
|
try {
|
|
28851
28761
|
const response = await fetch(proxyUrl, {
|
|
28852
28762
|
method: "POST",
|
|
@@ -28877,7 +28787,7 @@ For full-text search use the \`$search\` query parameter (must be wrapped in dou
|
|
|
28877
28787
|
});
|
|
28878
28788
|
|
|
28879
28789
|
// ../connectors/src/connectors/outlook-oauth/setup.ts
|
|
28880
|
-
var requestToolName14 = `outlook-oauth_${
|
|
28790
|
+
var requestToolName14 = `outlook-oauth_${requestTool58.name}`;
|
|
28881
28791
|
var outlookOnboarding = new ConnectorOnboarding({
|
|
28882
28792
|
connectionSetupInstructions: {
|
|
28883
28793
|
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
|
|
@@ -28934,17 +28844,17 @@ Calendar
|
|
|
28934
28844
|
});
|
|
28935
28845
|
|
|
28936
28846
|
// ../connectors/src/connectors/outlook-oauth/parameters.ts
|
|
28937
|
-
var
|
|
28847
|
+
var parameters82 = {};
|
|
28938
28848
|
|
|
28939
28849
|
// ../connectors/src/connectors/outlook-oauth/index.ts
|
|
28940
|
-
var
|
|
28850
|
+
var tools82 = { request: requestTool58 };
|
|
28941
28851
|
var outlookOauthConnector = new ConnectorPlugin({
|
|
28942
28852
|
slug: "outlook",
|
|
28943
28853
|
authType: AUTH_TYPES.OAUTH,
|
|
28944
28854
|
name: "Outlook",
|
|
28945
28855
|
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.",
|
|
28946
|
-
iconUrl: "https://
|
|
28947
|
-
parameters:
|
|
28856
|
+
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/1J1FrRTYJjOh3CcSIqsz3I/6a467b4d926075ff99dc60820e0ae4b1/Microsoft_Outlook_Icon__2025%C3%A2__present_.svg",
|
|
28857
|
+
parameters: parameters82,
|
|
28948
28858
|
releaseFlag: { dev1: true, dev2: false, prod: false },
|
|
28949
28859
|
categories: ["productivity"],
|
|
28950
28860
|
onboarding: outlookOnboarding,
|
|
@@ -29224,7 +29134,7 @@ const events = await outlook.listCalendarView(
|
|
|
29224
29134
|
events.value.forEach(e => console.log(e.start.dateTime, e.subject));
|
|
29225
29135
|
\`\`\``
|
|
29226
29136
|
},
|
|
29227
|
-
tools:
|
|
29137
|
+
tools: tools82,
|
|
29228
29138
|
async checkConnection(_params, config) {
|
|
29229
29139
|
const { proxyFetch } = config;
|
|
29230
29140
|
const url = "https://graph.microsoft.com/v1.0/me";
|
|
@@ -29328,7 +29238,6 @@ var plugins = {
|
|
|
29328
29238
|
freshdesk: freshdeskConnector,
|
|
29329
29239
|
freshsales: freshsalesConnector,
|
|
29330
29240
|
github: githubConnector,
|
|
29331
|
-
powerbi: powerbiConnector,
|
|
29332
29241
|
powerbiOauth: powerbiOauthConnector,
|
|
29333
29242
|
tableau: tableauConnector,
|
|
29334
29243
|
outlookOauth: outlookOauthConnector
|
|
@@ -29558,62 +29467,62 @@ import { watch as fsWatch2 } from "fs";
|
|
|
29558
29467
|
import path2 from "path";
|
|
29559
29468
|
|
|
29560
29469
|
// src/types/server-logic.ts
|
|
29561
|
-
import { z as
|
|
29562
|
-
var parameterMetaSchema =
|
|
29563
|
-
name:
|
|
29564
|
-
type:
|
|
29565
|
-
description:
|
|
29566
|
-
required:
|
|
29567
|
-
default:
|
|
29568
|
-
});
|
|
29569
|
-
var serverLogicCacheConfigSchema =
|
|
29570
|
-
ttl:
|
|
29571
|
-
staleWhileRevalidate:
|
|
29572
|
-
});
|
|
29573
|
-
var serverLogicSchemaObjectSchema =
|
|
29574
|
-
() =>
|
|
29575
|
-
type:
|
|
29576
|
-
format:
|
|
29577
|
-
description:
|
|
29578
|
-
nullable:
|
|
29579
|
-
enum:
|
|
29470
|
+
import { z as z100 } from "zod";
|
|
29471
|
+
var parameterMetaSchema = z100.object({
|
|
29472
|
+
name: z100.string(),
|
|
29473
|
+
type: z100.enum(["string", "number", "boolean"]),
|
|
29474
|
+
description: z100.string(),
|
|
29475
|
+
required: z100.boolean().optional(),
|
|
29476
|
+
default: z100.union([z100.string(), z100.number(), z100.boolean()]).optional()
|
|
29477
|
+
});
|
|
29478
|
+
var serverLogicCacheConfigSchema = z100.object({
|
|
29479
|
+
ttl: z100.number(),
|
|
29480
|
+
staleWhileRevalidate: z100.boolean().optional()
|
|
29481
|
+
});
|
|
29482
|
+
var serverLogicSchemaObjectSchema = z100.lazy(
|
|
29483
|
+
() => z100.object({
|
|
29484
|
+
type: z100.enum(["string", "number", "integer", "boolean", "object", "array", "null"]).optional(),
|
|
29485
|
+
format: z100.string().optional(),
|
|
29486
|
+
description: z100.string().optional(),
|
|
29487
|
+
nullable: z100.boolean().optional(),
|
|
29488
|
+
enum: z100.array(z100.union([z100.string(), z100.number(), z100.boolean(), z100.null()])).optional(),
|
|
29580
29489
|
items: serverLogicSchemaObjectSchema.optional(),
|
|
29581
|
-
properties:
|
|
29582
|
-
required:
|
|
29583
|
-
additionalProperties:
|
|
29584
|
-
minimum:
|
|
29585
|
-
maximum:
|
|
29586
|
-
minLength:
|
|
29587
|
-
maxLength:
|
|
29588
|
-
pattern:
|
|
29490
|
+
properties: z100.record(z100.string(), serverLogicSchemaObjectSchema).optional(),
|
|
29491
|
+
required: z100.array(z100.string()).optional(),
|
|
29492
|
+
additionalProperties: z100.union([z100.boolean(), serverLogicSchemaObjectSchema]).optional(),
|
|
29493
|
+
minimum: z100.number().optional(),
|
|
29494
|
+
maximum: z100.number().optional(),
|
|
29495
|
+
minLength: z100.number().optional(),
|
|
29496
|
+
maxLength: z100.number().optional(),
|
|
29497
|
+
pattern: z100.string().optional()
|
|
29589
29498
|
})
|
|
29590
29499
|
);
|
|
29591
|
-
var serverLogicMediaTypeSchema =
|
|
29500
|
+
var serverLogicMediaTypeSchema = z100.object({
|
|
29592
29501
|
schema: serverLogicSchemaObjectSchema.optional(),
|
|
29593
|
-
example:
|
|
29502
|
+
example: z100.unknown().optional()
|
|
29594
29503
|
});
|
|
29595
|
-
var serverLogicResponseSchema =
|
|
29596
|
-
description:
|
|
29597
|
-
content:
|
|
29504
|
+
var serverLogicResponseSchema = z100.object({
|
|
29505
|
+
description: z100.string().optional(),
|
|
29506
|
+
content: z100.record(z100.string(), serverLogicMediaTypeSchema).optional()
|
|
29598
29507
|
});
|
|
29599
29508
|
var jsonBaseFields = {
|
|
29600
|
-
description:
|
|
29601
|
-
parameters:
|
|
29509
|
+
description: z100.string(),
|
|
29510
|
+
parameters: z100.array(parameterMetaSchema).optional(),
|
|
29602
29511
|
response: serverLogicResponseSchema.optional(),
|
|
29603
29512
|
cache: serverLogicCacheConfigSchema.optional()
|
|
29604
29513
|
};
|
|
29605
|
-
var jsonSqlServerLogicSchema =
|
|
29514
|
+
var jsonSqlServerLogicSchema = z100.object({
|
|
29606
29515
|
...jsonBaseFields,
|
|
29607
|
-
type:
|
|
29608
|
-
query:
|
|
29609
|
-
connectionId:
|
|
29516
|
+
type: z100.literal("sql").optional(),
|
|
29517
|
+
query: z100.string(),
|
|
29518
|
+
connectionId: z100.string()
|
|
29610
29519
|
});
|
|
29611
|
-
var jsonTypeScriptServerLogicSchema =
|
|
29520
|
+
var jsonTypeScriptServerLogicSchema = z100.object({
|
|
29612
29521
|
...jsonBaseFields,
|
|
29613
|
-
type:
|
|
29614
|
-
handlerPath:
|
|
29522
|
+
type: z100.literal("typescript"),
|
|
29523
|
+
handlerPath: z100.string()
|
|
29615
29524
|
});
|
|
29616
|
-
var anyJsonServerLogicSchema =
|
|
29525
|
+
var anyJsonServerLogicSchema = z100.union([
|
|
29617
29526
|
jsonTypeScriptServerLogicSchema,
|
|
29618
29527
|
jsonSqlServerLogicSchema
|
|
29619
29528
|
]);
|