@squadbase/vite-server 0.1.12-dev.822582a → 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 +343 -46
- 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 +9 -0
- package/dist/connectors/powerbi-oauth.js +9 -0
- 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 +129 -55
- 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 +343 -46
- package/dist/main.js +343 -46
- package/dist/vite-plugin.js +343 -46
- package/package.json +1 -1
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;
|
|
@@ -27961,6 +28220,10 @@ import { z as z98 } from "zod";
|
|
|
27961
28220
|
var DEFAULT_API_VERSION = "3.28";
|
|
27962
28221
|
var REQUEST_TIMEOUT_MS75 = 6e4;
|
|
27963
28222
|
var sessionCache = /* @__PURE__ */ new Map();
|
|
28223
|
+
var inFlightSignIns = /* @__PURE__ */ new Map();
|
|
28224
|
+
function sessionCacheKey(serverUrl, siteContentUrl, patName) {
|
|
28225
|
+
return `${serverUrl}|${siteContentUrl}|${patName}`;
|
|
28226
|
+
}
|
|
27964
28227
|
function buildBaseUrl4(serverUrl, apiVersion) {
|
|
27965
28228
|
return `${serverUrl.replace(/\/$/, "")}/api/${apiVersion}`;
|
|
27966
28229
|
}
|
|
@@ -27995,21 +28258,39 @@ async function signIn(serverUrl, apiVersion, siteContentUrl, patName, patSecret)
|
|
|
27995
28258
|
expiresAt: Date.now() + 30 * 60 * 1e3
|
|
27996
28259
|
};
|
|
27997
28260
|
}
|
|
27998
|
-
async function getSession(serverUrl, apiVersion, siteContentUrl, patName, patSecret) {
|
|
27999
|
-
const cacheKey =
|
|
28000
|
-
|
|
28001
|
-
|
|
28002
|
-
|
|
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
|
+
}
|
|
28003
28270
|
}
|
|
28004
|
-
const
|
|
28271
|
+
const existing = inFlightSignIns.get(cacheKey);
|
|
28272
|
+
if (existing) return existing;
|
|
28273
|
+
const promise = signIn(
|
|
28005
28274
|
serverUrl,
|
|
28006
28275
|
apiVersion,
|
|
28007
28276
|
siteContentUrl,
|
|
28008
28277
|
patName,
|
|
28009
28278
|
patSecret
|
|
28010
|
-
)
|
|
28011
|
-
|
|
28012
|
-
|
|
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;
|
|
28287
|
+
}
|
|
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
|
+
}
|
|
28013
28294
|
}
|
|
28014
28295
|
var inputSchema98 = z98.object({
|
|
28015
28296
|
toolUseIntent: z98.string().optional().describe(
|
|
@@ -28065,48 +28346,64 @@ Accept and Content-Type headers default to application/json so list responses co
|
|
|
28065
28346
|
const patName = parameters81.patName.getValue(connection2);
|
|
28066
28347
|
const patSecret = parameters81.patSecret.getValue(connection2);
|
|
28067
28348
|
const apiVersion = parameters81.apiVersion.tryGetValue(connection2) || DEFAULT_API_VERSION;
|
|
28068
|
-
const
|
|
28069
|
-
|
|
28070
|
-
|
|
28071
|
-
siteContentUrl,
|
|
28072
|
-
patName,
|
|
28073
|
-
patSecret
|
|
28074
|
-
);
|
|
28075
|
-
const resolvedPath = path6.trim().replace(/\{siteId\}/g, session.siteId).replace(/^([^/])/, "/$1");
|
|
28076
|
-
let url = `${buildBaseUrl4(serverUrl, apiVersion)}${resolvedPath}`;
|
|
28077
|
-
if (queryParams) {
|
|
28078
|
-
const searchParams = new URLSearchParams(queryParams);
|
|
28079
|
-
url += `?${searchParams.toString()}`;
|
|
28080
|
-
}
|
|
28349
|
+
const trimmedPath = path6.trim().replace(/^([^/])/, "/$1");
|
|
28350
|
+
const queryString = queryParams ? `?${new URLSearchParams(queryParams).toString()}` : "";
|
|
28351
|
+
const baseUrl = buildBaseUrl4(serverUrl, apiVersion);
|
|
28081
28352
|
const controller = new AbortController();
|
|
28082
28353
|
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS75);
|
|
28083
28354
|
try {
|
|
28084
|
-
|
|
28085
|
-
|
|
28086
|
-
|
|
28087
|
-
|
|
28088
|
-
|
|
28089
|
-
|
|
28090
|
-
|
|
28091
|
-
|
|
28092
|
-
|
|
28093
|
-
|
|
28094
|
-
|
|
28095
|
-
|
|
28096
|
-
|
|
28097
|
-
|
|
28098
|
-
|
|
28099
|
-
|
|
28100
|
-
|
|
28101
|
-
|
|
28102
|
-
|
|
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);
|
|
28103
28381
|
}
|
|
28104
|
-
|
|
28105
|
-
|
|
28106
|
-
const
|
|
28107
|
-
|
|
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 };
|
|
28108
28406
|
}
|
|
28109
|
-
return { success: true, status: response.status, data };
|
|
28110
28407
|
} finally {
|
|
28111
28408
|
clearTimeout(timeout);
|
|
28112
28409
|
}
|