@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/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;
|
|
@@ -28036,6 +28295,10 @@ import { z as z98 } from "zod";
|
|
|
28036
28295
|
var DEFAULT_API_VERSION = "3.28";
|
|
28037
28296
|
var REQUEST_TIMEOUT_MS75 = 6e4;
|
|
28038
28297
|
var sessionCache = /* @__PURE__ */ new Map();
|
|
28298
|
+
var inFlightSignIns = /* @__PURE__ */ new Map();
|
|
28299
|
+
function sessionCacheKey(serverUrl, siteContentUrl, patName) {
|
|
28300
|
+
return `${serverUrl}|${siteContentUrl}|${patName}`;
|
|
28301
|
+
}
|
|
28039
28302
|
function buildBaseUrl4(serverUrl, apiVersion) {
|
|
28040
28303
|
return `${serverUrl.replace(/\/$/, "")}/api/${apiVersion}`;
|
|
28041
28304
|
}
|
|
@@ -28070,21 +28333,39 @@ async function signIn(serverUrl, apiVersion, siteContentUrl, patName, patSecret)
|
|
|
28070
28333
|
expiresAt: Date.now() + 30 * 60 * 1e3
|
|
28071
28334
|
};
|
|
28072
28335
|
}
|
|
28073
|
-
async function getSession(serverUrl, apiVersion, siteContentUrl, patName, patSecret) {
|
|
28074
|
-
const cacheKey =
|
|
28075
|
-
|
|
28076
|
-
|
|
28077
|
-
|
|
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
|
+
}
|
|
28078
28345
|
}
|
|
28079
|
-
const
|
|
28346
|
+
const existing = inFlightSignIns.get(cacheKey);
|
|
28347
|
+
if (existing) return existing;
|
|
28348
|
+
const promise = signIn(
|
|
28080
28349
|
serverUrl,
|
|
28081
28350
|
apiVersion,
|
|
28082
28351
|
siteContentUrl,
|
|
28083
28352
|
patName,
|
|
28084
28353
|
patSecret
|
|
28085
|
-
)
|
|
28086
|
-
|
|
28087
|
-
|
|
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;
|
|
28362
|
+
}
|
|
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
|
+
}
|
|
28088
28369
|
}
|
|
28089
28370
|
var inputSchema98 = z98.object({
|
|
28090
28371
|
toolUseIntent: z98.string().optional().describe(
|
|
@@ -28140,48 +28421,64 @@ Accept and Content-Type headers default to application/json so list responses co
|
|
|
28140
28421
|
const patName = parameters81.patName.getValue(connection);
|
|
28141
28422
|
const patSecret = parameters81.patSecret.getValue(connection);
|
|
28142
28423
|
const apiVersion = parameters81.apiVersion.tryGetValue(connection) || DEFAULT_API_VERSION;
|
|
28143
|
-
const
|
|
28144
|
-
|
|
28145
|
-
|
|
28146
|
-
siteContentUrl,
|
|
28147
|
-
patName,
|
|
28148
|
-
patSecret
|
|
28149
|
-
);
|
|
28150
|
-
const resolvedPath = path5.trim().replace(/\{siteId\}/g, session.siteId).replace(/^([^/])/, "/$1");
|
|
28151
|
-
let url = `${buildBaseUrl4(serverUrl, apiVersion)}${resolvedPath}`;
|
|
28152
|
-
if (queryParams) {
|
|
28153
|
-
const searchParams = new URLSearchParams(queryParams);
|
|
28154
|
-
url += `?${searchParams.toString()}`;
|
|
28155
|
-
}
|
|
28424
|
+
const trimmedPath = path5.trim().replace(/^([^/])/, "/$1");
|
|
28425
|
+
const queryString = queryParams ? `?${new URLSearchParams(queryParams).toString()}` : "";
|
|
28426
|
+
const baseUrl = buildBaseUrl4(serverUrl, apiVersion);
|
|
28156
28427
|
const controller = new AbortController();
|
|
28157
28428
|
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS75);
|
|
28158
28429
|
try {
|
|
28159
|
-
|
|
28160
|
-
|
|
28161
|
-
|
|
28162
|
-
|
|
28163
|
-
|
|
28164
|
-
|
|
28165
|
-
|
|
28166
|
-
|
|
28167
|
-
|
|
28168
|
-
|
|
28169
|
-
|
|
28170
|
-
|
|
28171
|
-
|
|
28172
|
-
|
|
28173
|
-
|
|
28174
|
-
|
|
28175
|
-
|
|
28176
|
-
|
|
28177
|
-
|
|
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);
|
|
28178
28456
|
}
|
|
28179
|
-
|
|
28180
|
-
|
|
28181
|
-
const
|
|
28182
|
-
|
|
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 };
|
|
28183
28481
|
}
|
|
28184
|
-
return { success: true, status: response.status, data };
|
|
28185
28482
|
} finally {
|
|
28186
28483
|
clearTimeout(timeout);
|
|
28187
28484
|
}
|
|
@@ -126,6 +126,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
126
126
|
tools;
|
|
127
127
|
query;
|
|
128
128
|
checkConnection;
|
|
129
|
+
/**
|
|
130
|
+
* SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
|
|
131
|
+
* implement this expose a step-by-step exploration flow (database/schema/
|
|
132
|
+
* table/etc. discovery) that the dashboard backend drives via the
|
|
133
|
+
* `/connections/:connectionId/setup` endpoint. Implement by delegating to
|
|
134
|
+
* `runSetupFlow` from `setup-flow.ts`.
|
|
135
|
+
*/
|
|
136
|
+
setup;
|
|
129
137
|
constructor(config) {
|
|
130
138
|
this.slug = config.slug;
|
|
131
139
|
this.authType = config.authType;
|
|
@@ -142,6 +150,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
142
150
|
this.tools = config.tools;
|
|
143
151
|
this.query = config.query;
|
|
144
152
|
this.checkConnection = config.checkConnection;
|
|
153
|
+
this.setup = config.setup;
|
|
145
154
|
}
|
|
146
155
|
get connectorKey() {
|
|
147
156
|
return _ConnectorPlugin.deriveKey(this.slug, this.authType);
|
|
@@ -256,6 +256,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
256
256
|
tools;
|
|
257
257
|
query;
|
|
258
258
|
checkConnection;
|
|
259
|
+
/**
|
|
260
|
+
* SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
|
|
261
|
+
* implement this expose a step-by-step exploration flow (database/schema/
|
|
262
|
+
* table/etc. discovery) that the dashboard backend drives via the
|
|
263
|
+
* `/connections/:connectionId/setup` endpoint. Implement by delegating to
|
|
264
|
+
* `runSetupFlow` from `setup-flow.ts`.
|
|
265
|
+
*/
|
|
266
|
+
setup;
|
|
259
267
|
constructor(config) {
|
|
260
268
|
this.slug = config.slug;
|
|
261
269
|
this.authType = config.authType;
|
|
@@ -272,6 +280,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
272
280
|
this.tools = config.tools;
|
|
273
281
|
this.query = config.query;
|
|
274
282
|
this.checkConnection = config.checkConnection;
|
|
283
|
+
this.setup = config.setup;
|
|
275
284
|
}
|
|
276
285
|
get connectorKey() {
|
|
277
286
|
return _ConnectorPlugin.deriveKey(this.slug, this.authType);
|
|
@@ -216,6 +216,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
216
216
|
tools;
|
|
217
217
|
query;
|
|
218
218
|
checkConnection;
|
|
219
|
+
/**
|
|
220
|
+
* SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
|
|
221
|
+
* implement this expose a step-by-step exploration flow (database/schema/
|
|
222
|
+
* table/etc. discovery) that the dashboard backend drives via the
|
|
223
|
+
* `/connections/:connectionId/setup` endpoint. Implement by delegating to
|
|
224
|
+
* `runSetupFlow` from `setup-flow.ts`.
|
|
225
|
+
*/
|
|
226
|
+
setup;
|
|
219
227
|
constructor(config) {
|
|
220
228
|
this.slug = config.slug;
|
|
221
229
|
this.authType = config.authType;
|
|
@@ -232,6 +240,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
232
240
|
this.tools = config.tools;
|
|
233
241
|
this.query = config.query;
|
|
234
242
|
this.checkConnection = config.checkConnection;
|
|
243
|
+
this.setup = config.setup;
|
|
235
244
|
}
|
|
236
245
|
get connectorKey() {
|
|
237
246
|
return _ConnectorPlugin.deriveKey(this.slug, this.authType);
|
|
@@ -83,6 +83,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
83
83
|
tools;
|
|
84
84
|
query;
|
|
85
85
|
checkConnection;
|
|
86
|
+
/**
|
|
87
|
+
* SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
|
|
88
|
+
* implement this expose a step-by-step exploration flow (database/schema/
|
|
89
|
+
* table/etc. discovery) that the dashboard backend drives via the
|
|
90
|
+
* `/connections/:connectionId/setup` endpoint. Implement by delegating to
|
|
91
|
+
* `runSetupFlow` from `setup-flow.ts`.
|
|
92
|
+
*/
|
|
93
|
+
setup;
|
|
86
94
|
constructor(config) {
|
|
87
95
|
this.slug = config.slug;
|
|
88
96
|
this.authType = config.authType;
|
|
@@ -99,6 +107,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
99
107
|
this.tools = config.tools;
|
|
100
108
|
this.query = config.query;
|
|
101
109
|
this.checkConnection = config.checkConnection;
|
|
110
|
+
this.setup = config.setup;
|
|
102
111
|
}
|
|
103
112
|
get connectorKey() {
|
|
104
113
|
return _ConnectorPlugin.deriveKey(this.slug, this.authType);
|
package/dist/connectors/asana.js
CHANGED
|
@@ -253,6 +253,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
253
253
|
tools;
|
|
254
254
|
query;
|
|
255
255
|
checkConnection;
|
|
256
|
+
/**
|
|
257
|
+
* SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
|
|
258
|
+
* implement this expose a step-by-step exploration flow (database/schema/
|
|
259
|
+
* table/etc. discovery) that the dashboard backend drives via the
|
|
260
|
+
* `/connections/:connectionId/setup` endpoint. Implement by delegating to
|
|
261
|
+
* `runSetupFlow` from `setup-flow.ts`.
|
|
262
|
+
*/
|
|
263
|
+
setup;
|
|
256
264
|
constructor(config) {
|
|
257
265
|
this.slug = config.slug;
|
|
258
266
|
this.authType = config.authType;
|
|
@@ -269,6 +277,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
269
277
|
this.tools = config.tools;
|
|
270
278
|
this.query = config.query;
|
|
271
279
|
this.checkConnection = config.checkConnection;
|
|
280
|
+
this.setup = config.setup;
|
|
272
281
|
}
|
|
273
282
|
get connectorKey() {
|
|
274
283
|
return _ConnectorPlugin.deriveKey(this.slug, this.authType);
|
package/dist/connectors/attio.js
CHANGED
|
@@ -389,6 +389,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
389
389
|
tools;
|
|
390
390
|
query;
|
|
391
391
|
checkConnection;
|
|
392
|
+
/**
|
|
393
|
+
* SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
|
|
394
|
+
* implement this expose a step-by-step exploration flow (database/schema/
|
|
395
|
+
* table/etc. discovery) that the dashboard backend drives via the
|
|
396
|
+
* `/connections/:connectionId/setup` endpoint. Implement by delegating to
|
|
397
|
+
* `runSetupFlow` from `setup-flow.ts`.
|
|
398
|
+
*/
|
|
399
|
+
setup;
|
|
392
400
|
constructor(config) {
|
|
393
401
|
this.slug = config.slug;
|
|
394
402
|
this.authType = config.authType;
|
|
@@ -405,6 +413,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
405
413
|
this.tools = config.tools;
|
|
406
414
|
this.query = config.query;
|
|
407
415
|
this.checkConnection = config.checkConnection;
|
|
416
|
+
this.setup = config.setup;
|
|
408
417
|
}
|
|
409
418
|
get connectorKey() {
|
|
410
419
|
return _ConnectorPlugin.deriveKey(this.slug, this.authType);
|
|
@@ -155,6 +155,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
155
155
|
tools;
|
|
156
156
|
query;
|
|
157
157
|
checkConnection;
|
|
158
|
+
/**
|
|
159
|
+
* SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
|
|
160
|
+
* implement this expose a step-by-step exploration flow (database/schema/
|
|
161
|
+
* table/etc. discovery) that the dashboard backend drives via the
|
|
162
|
+
* `/connections/:connectionId/setup` endpoint. Implement by delegating to
|
|
163
|
+
* `runSetupFlow` from `setup-flow.ts`.
|
|
164
|
+
*/
|
|
165
|
+
setup;
|
|
158
166
|
constructor(config) {
|
|
159
167
|
this.slug = config.slug;
|
|
160
168
|
this.authType = config.authType;
|
|
@@ -171,6 +179,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
171
179
|
this.tools = config.tools;
|
|
172
180
|
this.query = config.query;
|
|
173
181
|
this.checkConnection = config.checkConnection;
|
|
182
|
+
this.setup = config.setup;
|
|
174
183
|
}
|
|
175
184
|
get connectorKey() {
|
|
176
185
|
return _ConnectorPlugin.deriveKey(this.slug, this.authType);
|
|
@@ -405,6 +405,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
405
405
|
tools;
|
|
406
406
|
query;
|
|
407
407
|
checkConnection;
|
|
408
|
+
/**
|
|
409
|
+
* SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
|
|
410
|
+
* implement this expose a step-by-step exploration flow (database/schema/
|
|
411
|
+
* table/etc. discovery) that the dashboard backend drives via the
|
|
412
|
+
* `/connections/:connectionId/setup` endpoint. Implement by delegating to
|
|
413
|
+
* `runSetupFlow` from `setup-flow.ts`.
|
|
414
|
+
*/
|
|
415
|
+
setup;
|
|
408
416
|
constructor(config) {
|
|
409
417
|
this.slug = config.slug;
|
|
410
418
|
this.authType = config.authType;
|
|
@@ -421,6 +429,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
421
429
|
this.tools = config.tools;
|
|
422
430
|
this.query = config.query;
|
|
423
431
|
this.checkConnection = config.checkConnection;
|
|
432
|
+
this.setup = config.setup;
|
|
424
433
|
}
|
|
425
434
|
get connectorKey() {
|
|
426
435
|
return _ConnectorPlugin.deriveKey(this.slug, this.authType);
|