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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/dist/cli/index.js +482 -573
  2. package/dist/connectors/airtable-oauth.js +9 -0
  3. package/dist/connectors/airtable.js +9 -0
  4. package/dist/connectors/amplitude.js +9 -0
  5. package/dist/connectors/anthropic.js +9 -0
  6. package/dist/connectors/asana.js +9 -0
  7. package/dist/connectors/attio.js +9 -0
  8. package/dist/connectors/aws-billing.js +9 -0
  9. package/dist/connectors/azure-sql.js +9 -0
  10. package/dist/connectors/backlog-api-key.js +9 -0
  11. package/dist/connectors/clickup.js +9 -0
  12. package/dist/connectors/cosmosdb.js +9 -0
  13. package/dist/connectors/customerio.js +9 -0
  14. package/dist/connectors/dbt.js +9 -0
  15. package/dist/connectors/freshdesk.js +9 -0
  16. package/dist/connectors/freshsales.js +9 -0
  17. package/dist/connectors/freshservice.js +9 -0
  18. package/dist/connectors/gamma.js +9 -0
  19. package/dist/connectors/gemini.js +9 -0
  20. package/dist/connectors/github.js +9 -0
  21. package/dist/connectors/gmail-oauth.js +9 -0
  22. package/dist/connectors/gmail.js +9 -0
  23. package/dist/connectors/google-ads.js +9 -0
  24. package/dist/connectors/google-analytics-oauth.js +9 -0
  25. package/dist/connectors/google-analytics.js +9 -0
  26. package/dist/connectors/google-audit-log.js +9 -0
  27. package/dist/connectors/google-calendar-oauth.js +9 -0
  28. package/dist/connectors/google-calendar.js +9 -0
  29. package/dist/connectors/google-docs.js +9 -0
  30. package/dist/connectors/google-drive.js +9 -0
  31. package/dist/connectors/google-search-console-oauth.js +9 -0
  32. package/dist/connectors/google-sheets.js +9 -0
  33. package/dist/connectors/google-slides.js +9 -0
  34. package/dist/connectors/grafana.js +9 -0
  35. package/dist/connectors/hubspot-oauth.js +9 -0
  36. package/dist/connectors/hubspot.js +9 -0
  37. package/dist/connectors/influxdb.js +9 -0
  38. package/dist/connectors/intercom-oauth.js +9 -0
  39. package/dist/connectors/intercom.js +9 -0
  40. package/dist/connectors/jdbc.js +9 -0
  41. package/dist/connectors/jira-api-key.js +9 -0
  42. package/dist/connectors/kintone-api-token.js +9 -0
  43. package/dist/connectors/kintone.js +9 -0
  44. package/dist/connectors/linear.js +9 -0
  45. package/dist/connectors/linkedin-ads.js +9 -0
  46. package/dist/connectors/mailchimp-oauth.js +9 -0
  47. package/dist/connectors/mailchimp.js +9 -0
  48. package/dist/connectors/meta-ads-oauth.js +9 -0
  49. package/dist/connectors/meta-ads.js +9 -0
  50. package/dist/connectors/mixpanel.js +9 -0
  51. package/dist/connectors/monday.js +9 -0
  52. package/dist/connectors/mongodb.js +9 -0
  53. package/dist/connectors/notion-oauth.js +9 -0
  54. package/dist/connectors/notion.js +9 -0
  55. package/dist/connectors/openai.js +9 -0
  56. package/dist/connectors/oracle.js +9 -0
  57. package/dist/connectors/outlook-oauth.js +10 -1
  58. package/dist/connectors/powerbi-oauth.js +11 -2
  59. package/dist/connectors/salesforce.js +9 -0
  60. package/dist/connectors/semrush.js +9 -0
  61. package/dist/connectors/sentry.js +9 -0
  62. package/dist/connectors/shopify-oauth.js +9 -0
  63. package/dist/connectors/shopify.js +9 -0
  64. package/dist/connectors/sqlserver.js +9 -0
  65. package/dist/connectors/stripe-api-key.js +9 -0
  66. package/dist/connectors/stripe-oauth.js +9 -0
  67. package/dist/connectors/supabase.js +9 -0
  68. package/dist/connectors/tableau.js +131 -57
  69. package/dist/connectors/tiktok-ads.js +9 -0
  70. package/dist/connectors/wix-store.js +9 -0
  71. package/dist/connectors/zendesk-oauth.js +9 -0
  72. package/dist/connectors/zendesk.js +9 -0
  73. package/dist/index.js +482 -573
  74. package/dist/main.js +482 -573
  75. package/dist/vite-plugin.js +482 -573
  76. package/package.json +1 -5
  77. package/dist/connectors/powerbi.d.ts +0 -5
  78. package/dist/connectors/powerbi.js +0 -869
@@ -143,6 +143,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
143
143
  tools;
144
144
  query;
145
145
  checkConnection;
146
+ /**
147
+ * SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
148
+ * implement this expose a step-by-step exploration flow (database/schema/
149
+ * table/etc. discovery) that the dashboard backend drives via the
150
+ * `/connections/:connectionId/setup` endpoint. Implement by delegating to
151
+ * `runSetupFlow` from `setup-flow.ts`.
152
+ */
153
+ setup;
146
154
  constructor(config) {
147
155
  this.slug = config.slug;
148
156
  this.authType = config.authType;
@@ -159,6 +167,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
159
167
  this.tools = config.tools;
160
168
  this.query = config.query;
161
169
  this.checkConnection = config.checkConnection;
170
+ this.setup = config.setup;
162
171
  }
163
172
  get connectorKey() {
164
173
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -418,10 +427,10 @@ var powerbiOauthConnector = new ConnectorPlugin({
418
427
  authType: AUTH_TYPES.OAUTH,
419
428
  name: "Power BI",
420
429
  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.",
421
- iconUrl: "https://upload.wikimedia.org/wikipedia/commons/c/cf/New_Power_BI_Logo.svg",
430
+ iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/2vXQCKGpMJ9kGSaqkZl9IS/cc5669c267fc5d11e7b1f8c01723e461/power-bi-icon.png",
422
431
  parameters,
423
432
  releaseFlag: { dev1: true, dev2: false, prod: false },
424
- categories: ["other"],
433
+ categories: ["bi"],
425
434
  onboarding: powerbiOauthOnboarding,
426
435
  proxyPolicy: {
427
436
  allowlist: [
@@ -272,6 +272,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
272
272
  tools;
273
273
  query;
274
274
  checkConnection;
275
+ /**
276
+ * SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
277
+ * implement this expose a step-by-step exploration flow (database/schema/
278
+ * table/etc. discovery) that the dashboard backend drives via the
279
+ * `/connections/:connectionId/setup` endpoint. Implement by delegating to
280
+ * `runSetupFlow` from `setup-flow.ts`.
281
+ */
282
+ setup;
275
283
  constructor(config) {
276
284
  this.slug = config.slug;
277
285
  this.authType = config.authType;
@@ -288,6 +296,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
288
296
  this.tools = config.tools;
289
297
  this.query = config.query;
290
298
  this.checkConnection = config.checkConnection;
299
+ this.setup = config.setup;
291
300
  }
292
301
  get connectorKey() {
293
302
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -236,6 +236,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
236
236
  tools;
237
237
  query;
238
238
  checkConnection;
239
+ /**
240
+ * SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
241
+ * implement this expose a step-by-step exploration flow (database/schema/
242
+ * table/etc. discovery) that the dashboard backend drives via the
243
+ * `/connections/:connectionId/setup` endpoint. Implement by delegating to
244
+ * `runSetupFlow` from `setup-flow.ts`.
245
+ */
246
+ setup;
239
247
  constructor(config) {
240
248
  this.slug = config.slug;
241
249
  this.authType = config.authType;
@@ -252,6 +260,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
252
260
  this.tools = config.tools;
253
261
  this.query = config.query;
254
262
  this.checkConnection = config.checkConnection;
263
+ this.setup = config.setup;
255
264
  }
256
265
  get connectorKey() {
257
266
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -227,6 +227,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
227
227
  tools;
228
228
  query;
229
229
  checkConnection;
230
+ /**
231
+ * SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
232
+ * implement this expose a step-by-step exploration flow (database/schema/
233
+ * table/etc. discovery) that the dashboard backend drives via the
234
+ * `/connections/:connectionId/setup` endpoint. Implement by delegating to
235
+ * `runSetupFlow` from `setup-flow.ts`.
236
+ */
237
+ setup;
230
238
  constructor(config) {
231
239
  this.slug = config.slug;
232
240
  this.authType = config.authType;
@@ -243,6 +251,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
243
251
  this.tools = config.tools;
244
252
  this.query = config.query;
245
253
  this.checkConnection = config.checkConnection;
254
+ this.setup = config.setup;
246
255
  }
247
256
  get connectorKey() {
248
257
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -65,6 +65,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
65
65
  tools;
66
66
  query;
67
67
  checkConnection;
68
+ /**
69
+ * SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
70
+ * implement this expose a step-by-step exploration flow (database/schema/
71
+ * table/etc. discovery) that the dashboard backend drives via the
72
+ * `/connections/:connectionId/setup` endpoint. Implement by delegating to
73
+ * `runSetupFlow` from `setup-flow.ts`.
74
+ */
75
+ setup;
68
76
  constructor(config) {
69
77
  this.slug = config.slug;
70
78
  this.authType = config.authType;
@@ -81,6 +89,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
81
89
  this.tools = config.tools;
82
90
  this.query = config.query;
83
91
  this.checkConnection = config.checkConnection;
92
+ this.setup = config.setup;
84
93
  }
85
94
  get connectorKey() {
86
95
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -340,6 +340,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
340
340
  tools;
341
341
  query;
342
342
  checkConnection;
343
+ /**
344
+ * SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
345
+ * implement this expose a step-by-step exploration flow (database/schema/
346
+ * table/etc. discovery) that the dashboard backend drives via the
347
+ * `/connections/:connectionId/setup` endpoint. Implement by delegating to
348
+ * `runSetupFlow` from `setup-flow.ts`.
349
+ */
350
+ setup;
343
351
  constructor(config) {
344
352
  this.slug = config.slug;
345
353
  this.authType = config.authType;
@@ -356,6 +364,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
356
364
  this.tools = config.tools;
357
365
  this.query = config.query;
358
366
  this.checkConnection = config.checkConnection;
367
+ this.setup = config.setup;
359
368
  }
360
369
  get connectorKey() {
361
370
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -404,6 +404,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
404
404
  tools;
405
405
  query;
406
406
  checkConnection;
407
+ /**
408
+ * SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
409
+ * implement this expose a step-by-step exploration flow (database/schema/
410
+ * table/etc. discovery) that the dashboard backend drives via the
411
+ * `/connections/:connectionId/setup` endpoint. Implement by delegating to
412
+ * `runSetupFlow` from `setup-flow.ts`.
413
+ */
414
+ setup;
407
415
  constructor(config) {
408
416
  this.slug = config.slug;
409
417
  this.authType = config.authType;
@@ -420,6 +428,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
420
428
  this.tools = config.tools;
421
429
  this.query = config.query;
422
430
  this.checkConnection = config.checkConnection;
431
+ this.setup = config.setup;
423
432
  }
424
433
  get connectorKey() {
425
434
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -133,6 +133,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
133
133
  tools;
134
134
  query;
135
135
  checkConnection;
136
+ /**
137
+ * SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
138
+ * implement this expose a step-by-step exploration flow (database/schema/
139
+ * table/etc. discovery) that the dashboard backend drives via the
140
+ * `/connections/:connectionId/setup` endpoint. Implement by delegating to
141
+ * `runSetupFlow` from `setup-flow.ts`.
142
+ */
143
+ setup;
136
144
  constructor(config) {
137
145
  this.slug = config.slug;
138
146
  this.authType = config.authType;
@@ -149,6 +157,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
149
157
  this.tools = config.tools;
150
158
  this.query = config.query;
151
159
  this.checkConnection = config.checkConnection;
160
+ this.setup = config.setup;
152
161
  }
153
162
  get connectorKey() {
154
163
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -67,6 +67,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
67
67
  tools;
68
68
  query;
69
69
  checkConnection;
70
+ /**
71
+ * SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
72
+ * implement this expose a step-by-step exploration flow (database/schema/
73
+ * table/etc. discovery) that the dashboard backend drives via the
74
+ * `/connections/:connectionId/setup` endpoint. Implement by delegating to
75
+ * `runSetupFlow` from `setup-flow.ts`.
76
+ */
77
+ setup;
70
78
  constructor(config) {
71
79
  this.slug = config.slug;
72
80
  this.authType = config.authType;
@@ -83,6 +91,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
83
91
  this.tools = config.tools;
84
92
  this.query = config.query;
85
93
  this.checkConnection = config.checkConnection;
94
+ this.setup = config.setup;
86
95
  }
87
96
  get connectorKey() {
88
97
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -147,6 +147,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
147
147
  tools;
148
148
  query;
149
149
  checkConnection;
150
+ /**
151
+ * SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
152
+ * implement this expose a step-by-step exploration flow (database/schema/
153
+ * table/etc. discovery) that the dashboard backend drives via the
154
+ * `/connections/:connectionId/setup` endpoint. Implement by delegating to
155
+ * `runSetupFlow` from `setup-flow.ts`.
156
+ */
157
+ setup;
150
158
  constructor(config) {
151
159
  this.slug = config.slug;
152
160
  this.authType = config.authType;
@@ -163,6 +171,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
163
171
  this.tools = config.tools;
164
172
  this.query = config.query;
165
173
  this.checkConnection = config.checkConnection;
174
+ this.setup = config.setup;
166
175
  }
167
176
  get connectorKey() {
168
177
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -106,6 +106,7 @@ function createClient(params) {
106
106
  }
107
107
  const baseUrl = `${serverUrl.replace(/\/$/, "")}/api/${apiVersion}`;
108
108
  let session = null;
109
+ let inFlightSignIn = null;
109
110
  async function signIn2() {
110
111
  const res = await fetch(`${baseUrl}/auth/signin`, {
111
112
  method: "POST",
@@ -133,24 +134,50 @@ function createClient(params) {
133
134
  expiresAt: Date.now() + 30 * 60 * 1e3
134
135
  };
135
136
  }
136
- async function ensureSession() {
137
- if (session && session.expiresAt > Date.now() + 6e4) {
137
+ async function ensureSession(options) {
138
+ if (options?.forceRefresh) {
139
+ if (session && (!options.invalidateToken || session.authToken === options.invalidateToken)) {
140
+ session = null;
141
+ }
142
+ } else if (session && session.expiresAt > Date.now() + 6e4) {
138
143
  return session;
139
144
  }
140
- session = await signIn2();
141
- return session;
145
+ if (inFlightSignIn) return inFlightSignIn;
146
+ inFlightSignIn = signIn2().then((s) => {
147
+ session = s;
148
+ return s;
149
+ }).finally(() => {
150
+ inFlightSignIn = null;
151
+ });
152
+ return inFlightSignIn;
142
153
  }
143
- async function request(path2, init) {
144
- const s = await ensureSession();
145
- const resolvedPath = path2.replace(/\{siteId\}/g, s.siteId).replace(/^([^/])/, "/$1");
146
- const url = `${baseUrl}${resolvedPath}`;
154
+ function buildRequestInit(s, init) {
147
155
  const headers = new Headers(init?.headers);
148
156
  headers.set("X-Tableau-Auth", s.authToken);
149
157
  if (!headers.has("Accept")) headers.set("Accept", "application/json");
150
158
  if (!headers.has("Content-Type") && init?.body) {
151
159
  headers.set("Content-Type", "application/json");
152
160
  }
153
- return fetch(url, { ...init, headers });
161
+ return { ...init, headers };
162
+ }
163
+ async function request(path2, init) {
164
+ const trimmedPath = path2.replace(/^([^/])/, "/$1");
165
+ let attempt = 0;
166
+ while (true) {
167
+ const s = await ensureSession();
168
+ const url = `${baseUrl}${trimmedPath.replace(/\{siteId\}/g, s.siteId)}`;
169
+ const response = await fetch(url, buildRequestInit(s, init));
170
+ if (response.status === 401 && attempt === 0) {
171
+ await response.text().catch(() => void 0);
172
+ await ensureSession({
173
+ forceRefresh: true,
174
+ invalidateToken: s.authToken
175
+ });
176
+ attempt++;
177
+ continue;
178
+ }
179
+ return response;
180
+ }
154
181
  }
155
182
  async function getJson(path2) {
156
183
  const res = await request(path2);
@@ -271,6 +298,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
271
298
  tools;
272
299
  query;
273
300
  checkConnection;
301
+ /**
302
+ * SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
303
+ * implement this expose a step-by-step exploration flow (database/schema/
304
+ * table/etc. discovery) that the dashboard backend drives via the
305
+ * `/connections/:connectionId/setup` endpoint. Implement by delegating to
306
+ * `runSetupFlow` from `setup-flow.ts`.
307
+ */
308
+ setup;
274
309
  constructor(config) {
275
310
  this.slug = config.slug;
276
311
  this.authType = config.authType;
@@ -287,6 +322,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
287
322
  this.tools = config.tools;
288
323
  this.query = config.query;
289
324
  this.checkConnection = config.checkConnection;
325
+ this.setup = config.setup;
290
326
  }
291
327
  get connectorKey() {
292
328
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -398,6 +434,10 @@ import { z } from "zod";
398
434
  var DEFAULT_API_VERSION2 = "3.28";
399
435
  var REQUEST_TIMEOUT_MS = 6e4;
400
436
  var sessionCache = /* @__PURE__ */ new Map();
437
+ var inFlightSignIns = /* @__PURE__ */ new Map();
438
+ function sessionCacheKey(serverUrl, siteContentUrl, patName) {
439
+ return `${serverUrl}|${siteContentUrl}|${patName}`;
440
+ }
401
441
  function buildBaseUrl(serverUrl, apiVersion) {
402
442
  return `${serverUrl.replace(/\/$/, "")}/api/${apiVersion}`;
403
443
  }
@@ -432,21 +472,39 @@ async function signIn(serverUrl, apiVersion, siteContentUrl, patName, patSecret)
432
472
  expiresAt: Date.now() + 30 * 60 * 1e3
433
473
  };
434
474
  }
435
- async function getSession(serverUrl, apiVersion, siteContentUrl, patName, patSecret) {
436
- const cacheKey = `${serverUrl}|${siteContentUrl}|${patName}`;
437
- const cached = sessionCache.get(cacheKey);
438
- if (cached && cached.expiresAt > Date.now() + 6e4) {
439
- return cached;
475
+ async function getSession(serverUrl, apiVersion, siteContentUrl, patName, patSecret, { forceRefresh = false } = {}) {
476
+ const cacheKey = sessionCacheKey(serverUrl, siteContentUrl, patName);
477
+ if (forceRefresh) {
478
+ sessionCache.delete(cacheKey);
479
+ } else {
480
+ const cached = sessionCache.get(cacheKey);
481
+ if (cached && cached.expiresAt > Date.now() + 6e4) {
482
+ return cached;
483
+ }
440
484
  }
441
- const session = await signIn(
485
+ const existing = inFlightSignIns.get(cacheKey);
486
+ if (existing) return existing;
487
+ const promise = signIn(
442
488
  serverUrl,
443
489
  apiVersion,
444
490
  siteContentUrl,
445
491
  patName,
446
492
  patSecret
447
- );
448
- sessionCache.set(cacheKey, session);
449
- return session;
493
+ ).then((session) => {
494
+ sessionCache.set(cacheKey, session);
495
+ return session;
496
+ }).finally(() => {
497
+ inFlightSignIns.delete(cacheKey);
498
+ });
499
+ inFlightSignIns.set(cacheKey, promise);
500
+ return promise;
501
+ }
502
+ function invalidateSession(serverUrl, siteContentUrl, patName, staleAuthToken) {
503
+ const cacheKey = sessionCacheKey(serverUrl, siteContentUrl, patName);
504
+ const current = sessionCache.get(cacheKey);
505
+ if (current && current.authToken === staleAuthToken) {
506
+ sessionCache.delete(cacheKey);
507
+ }
450
508
  }
451
509
  var inputSchema = z.object({
452
510
  toolUseIntent: z.string().optional().describe(
@@ -502,48 +560,64 @@ Accept and Content-Type headers default to application/json so list responses co
502
560
  const patName = parameters.patName.getValue(connection2);
503
561
  const patSecret = parameters.patSecret.getValue(connection2);
504
562
  const apiVersion = parameters.apiVersion.tryGetValue(connection2) || DEFAULT_API_VERSION2;
505
- const session = await getSession(
506
- serverUrl,
507
- apiVersion,
508
- siteContentUrl,
509
- patName,
510
- patSecret
511
- );
512
- const resolvedPath = path2.trim().replace(/\{siteId\}/g, session.siteId).replace(/^([^/])/, "/$1");
513
- let url = `${buildBaseUrl(serverUrl, apiVersion)}${resolvedPath}`;
514
- if (queryParams) {
515
- const searchParams = new URLSearchParams(queryParams);
516
- url += `?${searchParams.toString()}`;
517
- }
563
+ const trimmedPath = path2.trim().replace(/^([^/])/, "/$1");
564
+ const queryString = queryParams ? `?${new URLSearchParams(queryParams).toString()}` : "";
565
+ const baseUrl = buildBaseUrl(serverUrl, apiVersion);
518
566
  const controller = new AbortController();
519
567
  const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
520
568
  try {
521
- const init = {
522
- method,
523
- headers: {
524
- "X-Tableau-Auth": session.authToken,
525
- Accept: "application/json",
526
- "Content-Type": "application/json"
527
- },
528
- signal: controller.signal
529
- };
530
- if (body !== void 0) {
531
- init.body = JSON.stringify(body);
532
- }
533
- const response = await fetch(url, init);
534
- const text = await response.text();
535
- const data = text ? (() => {
536
- try {
537
- return JSON.parse(text);
538
- } catch {
539
- return text;
569
+ let attempt = 0;
570
+ while (true) {
571
+ const session = await getSession(
572
+ serverUrl,
573
+ apiVersion,
574
+ siteContentUrl,
575
+ patName,
576
+ patSecret,
577
+ { forceRefresh: attempt > 0 }
578
+ );
579
+ const resolvedPath = trimmedPath.replace(
580
+ /\{siteId\}/g,
581
+ session.siteId
582
+ );
583
+ const url = `${baseUrl}${resolvedPath}${queryString}`;
584
+ const init = {
585
+ method,
586
+ headers: {
587
+ "X-Tableau-Auth": session.authToken,
588
+ Accept: "application/json",
589
+ "Content-Type": "application/json"
590
+ },
591
+ signal: controller.signal
592
+ };
593
+ if (body !== void 0) {
594
+ init.body = JSON.stringify(body);
595
+ }
596
+ const response = await fetch(url, init);
597
+ const text = await response.text();
598
+ const data = text ? (() => {
599
+ try {
600
+ return JSON.parse(text);
601
+ } catch {
602
+ return text;
603
+ }
604
+ })() : null;
605
+ if (response.status === 401 && attempt === 0) {
606
+ invalidateSession(
607
+ serverUrl,
608
+ siteContentUrl,
609
+ patName,
610
+ session.authToken
611
+ );
612
+ attempt++;
613
+ continue;
614
+ }
615
+ if (!response.ok) {
616
+ const errorMessage = data && typeof data === "object" && "error" in data ? JSON.stringify(data.error) : typeof data === "string" && data ? data : `HTTP ${response.status} ${response.statusText}`;
617
+ return { success: false, error: errorMessage };
540
618
  }
541
- })() : null;
542
- if (!response.ok) {
543
- const errorMessage = data && typeof data === "object" && "error" in data ? JSON.stringify(data.error) : typeof data === "string" && data ? data : `HTTP ${response.status} ${response.statusText}`;
544
- return { success: false, error: errorMessage };
619
+ return { success: true, status: response.status, data };
545
620
  }
546
- return { success: true, status: response.status, data };
547
621
  } finally {
548
622
  clearTimeout(timeout);
549
623
  }
@@ -561,10 +635,10 @@ var tableauConnector = new ConnectorPlugin({
561
635
  authType: AUTH_TYPES.PAT,
562
636
  name: "Tableau",
563
637
  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.",
564
- iconUrl: "https://upload.wikimedia.org/wikipedia/commons/4/4b/Tableau_Logo.png",
638
+ iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/3ejrZvfw7zCDa3FPbUNQx9/d810e117b3a86c45dd96205453bf67a0/tableau-icon.svg",
565
639
  parameters,
566
640
  releaseFlag: { dev1: true, dev2: false, prod: false },
567
- categories: ["other"],
641
+ categories: ["bi"],
568
642
  onboarding: tableauOnboarding,
569
643
  systemPrompt: {
570
644
  en: `### Tools
@@ -111,6 +111,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
111
111
  tools;
112
112
  query;
113
113
  checkConnection;
114
+ /**
115
+ * SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
116
+ * implement this expose a step-by-step exploration flow (database/schema/
117
+ * table/etc. discovery) that the dashboard backend drives via the
118
+ * `/connections/:connectionId/setup` endpoint. Implement by delegating to
119
+ * `runSetupFlow` from `setup-flow.ts`.
120
+ */
121
+ setup;
114
122
  constructor(config) {
115
123
  this.slug = config.slug;
116
124
  this.authType = config.authType;
@@ -127,6 +135,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
127
135
  this.tools = config.tools;
128
136
  this.query = config.query;
129
137
  this.checkConnection = config.checkConnection;
138
+ this.setup = config.setup;
130
139
  }
131
140
  get connectorKey() {
132
141
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -258,6 +258,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
258
258
  tools;
259
259
  query;
260
260
  checkConnection;
261
+ /**
262
+ * SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
263
+ * implement this expose a step-by-step exploration flow (database/schema/
264
+ * table/etc. discovery) that the dashboard backend drives via the
265
+ * `/connections/:connectionId/setup` endpoint. Implement by delegating to
266
+ * `runSetupFlow` from `setup-flow.ts`.
267
+ */
268
+ setup;
261
269
  constructor(config) {
262
270
  this.slug = config.slug;
263
271
  this.authType = config.authType;
@@ -274,6 +282,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
274
282
  this.tools = config.tools;
275
283
  this.query = config.query;
276
284
  this.checkConnection = config.checkConnection;
285
+ this.setup = config.setup;
277
286
  }
278
287
  get connectorKey() {
279
288
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -65,6 +65,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
65
65
  tools;
66
66
  query;
67
67
  checkConnection;
68
+ /**
69
+ * SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
70
+ * implement this expose a step-by-step exploration flow (database/schema/
71
+ * table/etc. discovery) that the dashboard backend drives via the
72
+ * `/connections/:connectionId/setup` endpoint. Implement by delegating to
73
+ * `runSetupFlow` from `setup-flow.ts`.
74
+ */
75
+ setup;
68
76
  constructor(config) {
69
77
  this.slug = config.slug;
70
78
  this.authType = config.authType;
@@ -81,6 +89,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
81
89
  this.tools = config.tools;
82
90
  this.query = config.query;
83
91
  this.checkConnection = config.checkConnection;
92
+ this.setup = config.setup;
84
93
  }
85
94
  get connectorKey() {
86
95
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -240,6 +240,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
240
240
  tools;
241
241
  query;
242
242
  checkConnection;
243
+ /**
244
+ * SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
245
+ * implement this expose a step-by-step exploration flow (database/schema/
246
+ * table/etc. discovery) that the dashboard backend drives via the
247
+ * `/connections/:connectionId/setup` endpoint. Implement by delegating to
248
+ * `runSetupFlow` from `setup-flow.ts`.
249
+ */
250
+ setup;
243
251
  constructor(config) {
244
252
  this.slug = config.slug;
245
253
  this.authType = config.authType;
@@ -256,6 +264,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
256
264
  this.tools = config.tools;
257
265
  this.query = config.query;
258
266
  this.checkConnection = config.checkConnection;
267
+ this.setup = config.setup;
259
268
  }
260
269
  get connectorKey() {
261
270
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);