@squadbase/vite-server 0.1.12-dev.a9ac647 → 0.1.17-dev.3b633bb

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 (77) hide show
  1. package/dist/cli/index.js +14375 -1652
  2. package/dist/connectors/airtable-oauth.js +282 -46
  3. package/dist/connectors/airtable.js +319 -51
  4. package/dist/connectors/amplitude.js +322 -47
  5. package/dist/connectors/anthropic.js +135 -47
  6. package/dist/connectors/asana.js +327 -49
  7. package/dist/connectors/attio.js +302 -49
  8. package/dist/connectors/aws-billing.js +287 -46
  9. package/dist/connectors/azure-sql.js +421 -102
  10. package/dist/connectors/backlog-api-key.js +317 -47
  11. package/dist/connectors/clickup.js +338 -49
  12. package/dist/connectors/cosmosdb.js +305 -50
  13. package/dist/connectors/customerio.js +319 -47
  14. package/dist/connectors/dbt.js +340 -47
  15. package/dist/connectors/freshdesk.js +342 -53
  16. package/dist/connectors/freshsales.js +333 -52
  17. package/dist/connectors/freshservice.js +361 -53
  18. package/dist/connectors/gamma.js +327 -52
  19. package/dist/connectors/gemini.js +134 -47
  20. package/dist/connectors/github.js +386 -49
  21. package/dist/connectors/gmail-oauth.js +204 -7
  22. package/dist/connectors/gmail.js +350 -47
  23. package/dist/connectors/google-ads.js +288 -46
  24. package/dist/connectors/google-analytics-oauth.js +310 -46
  25. package/dist/connectors/google-analytics.js +547 -87
  26. package/dist/connectors/google-audit-log.js +438 -47
  27. package/dist/connectors/google-calendar-oauth.js +259 -46
  28. package/dist/connectors/google-calendar.js +359 -47
  29. package/dist/connectors/google-docs.js +220 -6
  30. package/dist/connectors/google-drive.js +262 -5
  31. package/dist/connectors/google-search-console-oauth.js +256 -46
  32. package/dist/connectors/google-sheets.js +272 -47
  33. package/dist/connectors/google-slides.js +205 -6
  34. package/dist/connectors/grafana.js +332 -49
  35. package/dist/connectors/hubspot-oauth.js +208 -5
  36. package/dist/connectors/hubspot.js +306 -49
  37. package/dist/connectors/influxdb.js +416 -51
  38. package/dist/connectors/intercom-oauth.js +210 -5
  39. package/dist/connectors/intercom.js +302 -49
  40. package/dist/connectors/jdbc.js +762 -110
  41. package/dist/connectors/jira-api-key.js +326 -47
  42. package/dist/connectors/kintone-api-token.js +281 -47
  43. package/dist/connectors/kintone.js +328 -47
  44. package/dist/connectors/linear.js +330 -49
  45. package/dist/connectors/linkedin-ads.js +268 -50
  46. package/dist/connectors/mailchimp-oauth.js +268 -46
  47. package/dist/connectors/mailchimp.js +320 -49
  48. package/dist/connectors/meta-ads-oauth.js +273 -48
  49. package/dist/connectors/meta-ads.js +285 -50
  50. package/dist/connectors/mixpanel.js +338 -47
  51. package/dist/connectors/monday.js +360 -49
  52. package/dist/connectors/mongodb.js +319 -57
  53. package/dist/connectors/notion-oauth.js +231 -5
  54. package/dist/connectors/notion.js +323 -51
  55. package/dist/connectors/openai.js +134 -47
  56. package/dist/connectors/oracle.js +454 -103
  57. package/dist/connectors/outlook-oauth.js +204 -5
  58. package/dist/connectors/powerbi-oauth.js +498 -5
  59. package/dist/connectors/salesforce.js +384 -49
  60. package/dist/connectors/semrush.js +609 -49
  61. package/dist/connectors/sentry.js +289 -50
  62. package/dist/connectors/shopify-oauth.js +187 -5
  63. package/dist/connectors/shopify.js +357 -47
  64. package/dist/connectors/sqlserver.js +415 -102
  65. package/dist/connectors/stripe-api-key.js +269 -46
  66. package/dist/connectors/stripe-oauth.js +202 -5
  67. package/dist/connectors/supabase.js +303 -48
  68. package/dist/connectors/tableau.js +536 -163
  69. package/dist/connectors/tiktok-ads.js +279 -48
  70. package/dist/connectors/wix-store.js +320 -49
  71. package/dist/connectors/zendesk-oauth.js +239 -5
  72. package/dist/connectors/zendesk.js +358 -47
  73. package/dist/index.d.ts +149 -1
  74. package/dist/index.js +15057 -2117
  75. package/dist/main.js +15005 -2073
  76. package/dist/vite-plugin.js +14752 -2019
  77. package/package.json +1 -1
@@ -1,48 +1,60 @@
1
+ var __getOwnPropNames = Object.getOwnPropertyNames;
2
+ var __esm = (fn, res) => function __init() {
3
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
4
+ };
5
+
1
6
  // ../connectors/src/parameter-definition.ts
2
- var ParameterDefinition = class {
3
- slug;
4
- name;
5
- description;
6
- envVarBaseKey;
7
- type;
8
- secret;
9
- required;
10
- constructor(config) {
11
- this.slug = config.slug;
12
- this.name = config.name;
13
- this.description = config.description;
14
- this.envVarBaseKey = config.envVarBaseKey;
15
- this.type = config.type;
16
- this.secret = config.secret;
17
- this.required = config.required;
18
- }
19
- /**
20
- * Get the parameter value from a ConnectorConnectionObject.
21
- */
22
- getValue(connection2) {
23
- const param = connection2.parameters.find(
24
- (p) => p.parameterSlug === this.slug
25
- );
26
- if (!param || param.value == null) {
27
- throw new Error(
28
- `Parameter "${this.slug}" not found or has no value in connection "${connection2.id}"`
29
- );
30
- }
31
- return param.value;
32
- }
33
- /**
34
- * Try to get the parameter value. Returns undefined if not found (for optional params).
35
- */
36
- tryGetValue(connection2) {
37
- const param = connection2.parameters.find(
38
- (p) => p.parameterSlug === this.slug
39
- );
40
- if (!param || param.value == null) return void 0;
41
- return param.value;
7
+ var ParameterDefinition;
8
+ var init_parameter_definition = __esm({
9
+ "../connectors/src/parameter-definition.ts"() {
10
+ "use strict";
11
+ ParameterDefinition = class {
12
+ slug;
13
+ name;
14
+ description;
15
+ envVarBaseKey;
16
+ type;
17
+ secret;
18
+ required;
19
+ constructor(config) {
20
+ this.slug = config.slug;
21
+ this.name = config.name;
22
+ this.description = config.description;
23
+ this.envVarBaseKey = config.envVarBaseKey;
24
+ this.type = config.type;
25
+ this.secret = config.secret;
26
+ this.required = config.required;
27
+ }
28
+ /**
29
+ * Get the parameter value from a ConnectorConnectionObject.
30
+ */
31
+ getValue(connection2) {
32
+ const param = connection2.parameters.find(
33
+ (p) => p.parameterSlug === this.slug
34
+ );
35
+ if (!param || param.value == null) {
36
+ throw new Error(
37
+ `Parameter "${this.slug}" not found or has no value in connection "${connection2.id}"`
38
+ );
39
+ }
40
+ return param.value;
41
+ }
42
+ /**
43
+ * Try to get the parameter value. Returns undefined if not found (for optional params).
44
+ */
45
+ tryGetValue(connection2) {
46
+ const param = connection2.parameters.find(
47
+ (p) => p.parameterSlug === this.slug
48
+ );
49
+ if (!param || param.value == null) return void 0;
50
+ return param.value;
51
+ }
52
+ };
42
53
  }
43
- };
54
+ });
44
55
 
45
56
  // ../connectors/src/connectors/airtable/parameters.ts
57
+ init_parameter_definition();
46
58
  var parameters = {
47
59
  baseId: new ParameterDefinition({
48
60
  slug: "base-id",
@@ -176,7 +188,7 @@ function createClient(params) {
176
188
  }
177
189
  return await response.json();
178
190
  }
179
- async function listTables() {
191
+ async function listTables2() {
180
192
  const path2 = `/meta/bases/${baseId}/tables`;
181
193
  const response = await request(path2);
182
194
  if (!response.ok) {
@@ -193,7 +205,7 @@ function createClient(params) {
193
205
  getRecord,
194
206
  createRecords,
195
207
  updateRecords,
196
- listTables
208
+ listTables: listTables2
197
209
  };
198
210
  }
199
211
 
@@ -256,6 +268,28 @@ var ConnectorPlugin = class _ConnectorPlugin {
256
268
  tools;
257
269
  query;
258
270
  checkConnection;
271
+ /**
272
+ * SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
273
+ * implement this expose a step-by-step exploration flow (database/schema/
274
+ * table/etc. discovery) that the dashboard backend drives via the
275
+ * `/connections/:connectionId/setup` endpoint. Implement by delegating to
276
+ * `runSetupFlow` from `setup-flow.ts`.
277
+ */
278
+ setup;
279
+ /**
280
+ * Opt-out of the default "verify before save" behavior on connection
281
+ * creation. The backend invokes `checkConnection` synchronously while
282
+ * creating the connection and aborts (no row inserted) if it fails — this
283
+ * flag disables that for connectors where the check cannot succeed pre-save:
284
+ *
285
+ * - `squadbase-db` populates `connection-url` only after Neon provisioning
286
+ * - OAuth connectors require an OAuth-aware proxyFetch keyed by the
287
+ * connectionId, which doesn't exist until the row is saved
288
+ *
289
+ * Exceptions are the explicit position; new credential-input connectors get
290
+ * the default verify-on-create behavior without opt-in.
291
+ */
292
+ skipConnectionCheckOnCreate;
259
293
  constructor(config) {
260
294
  this.slug = config.slug;
261
295
  this.authType = config.authType;
@@ -272,6 +306,8 @@ var ConnectorPlugin = class _ConnectorPlugin {
272
306
  this.tools = config.tools;
273
307
  this.query = config.query;
274
308
  this.checkConnection = config.checkConnection;
309
+ this.setup = config.setup;
310
+ this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
275
311
  }
276
312
  get connectorKey() {
277
313
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -336,6 +372,76 @@ var ConnectorPlugin = class _ConnectorPlugin {
336
372
  }
337
373
  };
338
374
 
375
+ // ../connectors/src/setup-flow.ts
376
+ async function runSetupFlow(flow, params, ctx, config) {
377
+ const runtime = {
378
+ params,
379
+ language: ctx.language,
380
+ config
381
+ };
382
+ let state = flow.initialState();
383
+ let answerIdx = 0;
384
+ const pendingParameterUpdates = [];
385
+ for (const step of flow.steps) {
386
+ const ans = ctx.answers[answerIdx];
387
+ if (ans && ans.questionSlug === step.slug) {
388
+ state = step.applyAnswer(state, ans.answer);
389
+ if (step.toParameterUpdates) {
390
+ pendingParameterUpdates.push(...step.toParameterUpdates(state));
391
+ }
392
+ answerIdx += 1;
393
+ continue;
394
+ }
395
+ const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
396
+ if (step.type === "text") {
397
+ if (step.fetchOptions) {
398
+ const options2 = await step.fetchOptions(state, runtime);
399
+ if (options2.length === 0) {
400
+ continue;
401
+ }
402
+ }
403
+ return {
404
+ type: "nextQuestion",
405
+ questionSlug: step.slug,
406
+ question: step.question[ctx.language],
407
+ questionType: "text",
408
+ allowFreeText: resolvedAllowFreeText,
409
+ ...pendingParameterUpdates.length > 0 && {
410
+ parameterUpdates: pendingParameterUpdates
411
+ }
412
+ };
413
+ }
414
+ const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
415
+ if (options.length === 0) {
416
+ continue;
417
+ }
418
+ return {
419
+ type: "nextQuestion",
420
+ questionSlug: step.slug,
421
+ question: step.question[ctx.language],
422
+ questionType: step.type,
423
+ options,
424
+ allowFreeText: resolvedAllowFreeText,
425
+ ...pendingParameterUpdates.length > 0 && {
426
+ parameterUpdates: pendingParameterUpdates
427
+ }
428
+ };
429
+ }
430
+ const dataInvestigationResult = await flow.finalize(state, runtime);
431
+ return {
432
+ type: "fulfilled",
433
+ dataInvestigationResult,
434
+ ...pendingParameterUpdates.length > 0 && {
435
+ parameterUpdates: pendingParameterUpdates
436
+ }
437
+ };
438
+ }
439
+ async function resolveSetupSelection(params) {
440
+ const { selected, allSentinel, fetchAll, limit } = params;
441
+ const resolved = selected.includes(allSentinel) ? await fetchAll() : selected.filter((v) => v !== allSentinel);
442
+ return resolved.slice(0, limit);
443
+ }
444
+
339
445
  // ../connectors/src/auth-types.ts
340
446
  var AUTH_TYPES = {
341
447
  OAUTH: "oauth",
@@ -356,9 +462,119 @@ var airtableOnboarding = new ConnectorOnboarding({
356
462
  }
357
463
  });
358
464
 
465
+ // ../connectors/src/connectors/airtable/utils.ts
466
+ var BASE_URL2 = "https://api.airtable.com/v0";
467
+ async function apiFetch(params, path2, init) {
468
+ const apiKey = params[parameters.apiKey.slug];
469
+ if (!apiKey) {
470
+ throw new Error("airtable: missing required parameter: api-key");
471
+ }
472
+ const url = `${BASE_URL2}${path2.startsWith("/") ? "" : "/"}${path2}`;
473
+ const headers = new Headers(init?.headers);
474
+ headers.set("Authorization", `Bearer ${apiKey}`);
475
+ return fetch(url, { ...init, headers });
476
+ }
477
+
478
+ // ../connectors/src/connectors/airtable/setup-flow.ts
479
+ var ALL_TABLES = "__ALL_TABLES__";
480
+ var AIRTABLE_SETUP_MAX_TABLES = 20;
481
+ async function listBases(params) {
482
+ const res = await apiFetch(params, "/meta/bases");
483
+ if (!res.ok) {
484
+ const body = await res.text().catch(() => res.statusText);
485
+ throw new Error(`airtable: listBases failed (${res.status}): ${body}`);
486
+ }
487
+ const data = await res.json();
488
+ return data.bases ?? [];
489
+ }
490
+ async function listTables(params, baseId) {
491
+ const res = await apiFetch(params, `/meta/bases/${baseId}/tables`);
492
+ if (!res.ok) {
493
+ const body = await res.text().catch(() => res.statusText);
494
+ throw new Error(`airtable: listTables failed (${res.status}): ${body}`);
495
+ }
496
+ const data = await res.json();
497
+ return data.tables ?? [];
498
+ }
499
+ var airtableSetupFlow = {
500
+ initialState: () => ({}),
501
+ steps: [
502
+ {
503
+ slug: "base",
504
+ type: "select",
505
+ question: {
506
+ ja: "\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u306B\u4F7F\u3046\u30D9\u30FC\u30B9\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044",
507
+ en: "Select the base to use for setup"
508
+ },
509
+ async fetchOptions(_state, rt) {
510
+ const bases = await listBases(rt.params);
511
+ return bases.filter((b) => b.id && b.name).map((b) => ({ value: b.id, label: b.name }));
512
+ },
513
+ applyAnswer: (state, answer) => ({ ...state, base: answer[0] })
514
+ },
515
+ {
516
+ slug: "tables",
517
+ type: "multiSelect",
518
+ question: {
519
+ ja: "\u5BFE\u8C61\u30C6\u30FC\u30D6\u30EB\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
520
+ en: "Select target tables (multi-select allowed)"
521
+ },
522
+ async fetchOptions(state, rt) {
523
+ if (!state.base) return [];
524
+ const tables = await listTables(rt.params, state.base);
525
+ const tableOptions = tables.filter((t) => t.name).map((t) => ({ value: t.name }));
526
+ return [
527
+ {
528
+ value: ALL_TABLES,
529
+ label: rt.language === "ja" ? "\u3059\u3079\u3066\u306E\u30C6\u30FC\u30D6\u30EB" : "All tables"
530
+ },
531
+ ...tableOptions
532
+ ];
533
+ },
534
+ applyAnswer: (state, answer) => ({ ...state, tables: answer })
535
+ }
536
+ ],
537
+ async finalize(state, rt) {
538
+ if (!state.base || !state.tables) {
539
+ throw new Error("Airtable setup: incomplete state on finalize");
540
+ }
541
+ const baseId = state.base;
542
+ const tables = await listTables(rt.params, baseId);
543
+ const tableByName = new Map(tables.map((t) => [t.name, t]));
544
+ const targetTableNames = await resolveSetupSelection({
545
+ selected: state.tables,
546
+ allSentinel: ALL_TABLES,
547
+ fetchAll: async () => tables.map((t) => t.name).filter((n) => n),
548
+ limit: AIRTABLE_SETUP_MAX_TABLES
549
+ });
550
+ const sections = [
551
+ "## Airtable",
552
+ "",
553
+ `### Base: ${baseId}`,
554
+ ""
555
+ ];
556
+ for (const tableName of targetTableNames) {
557
+ const table = tableByName.get(tableName);
558
+ if (!table) {
559
+ sections.push(`#### Table: ${tableName}`, "", "_Not found._", "");
560
+ continue;
561
+ }
562
+ sections.push(`#### Table: ${table.name}`, "");
563
+ sections.push("| Field | Type | Description |");
564
+ sections.push("|-------|------|-------------|");
565
+ for (const f of table.fields ?? []) {
566
+ const description = (f.description ?? "").replace(/\|/g, "\\|");
567
+ sections.push(`| ${f.name} | ${f.type} | ${description || "-"} |`);
568
+ }
569
+ sections.push("");
570
+ }
571
+ return sections.join("\n");
572
+ }
573
+ };
574
+
359
575
  // ../connectors/src/connectors/airtable/tools/request.ts
360
576
  import { z } from "zod";
361
- var BASE_URL2 = "https://api.airtable.com/v0/";
577
+ var BASE_URL3 = "https://api.airtable.com/v0/";
362
578
  var REQUEST_TIMEOUT_MS = 6e4;
363
579
  var inputSchema = z.object({
364
580
  toolUseIntent: z.string().optional().describe("Brief description of what you intend to accomplish with this tool call"),
@@ -395,7 +611,7 @@ Authentication is handled automatically using the API Key.
395
611
  const apiKey = parameters.apiKey.getValue(connection2);
396
612
  const baseId = parameters.baseId.getValue(connection2);
397
613
  const resolvedPath = path2.replace(/\{baseId\}/g, baseId);
398
- const url = `${BASE_URL2}${resolvedPath}`;
614
+ const url = `${BASE_URL3}${resolvedPath}`;
399
615
  const controller = new AbortController();
400
616
  const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
401
617
  try {
@@ -559,7 +775,39 @@ export default async function handler(c: Context) {
559
775
  #### \u30DA\u30FC\u30B8\u30CD\u30FC\u30B7\u30E7\u30F3
560
776
  - \u30EC\u30B9\u30DD\u30F3\u30B9\u306B \`offset\` \u304C\u542B\u307E\u308C\u308B\u5834\u5408\u3001\u6B21\u306E\u30EA\u30AF\u30A8\u30B9\u30C8\u306B \`?offset={offset}\` \u3092\u8FFD\u52A0\u3057\u3066\u6B21\u306E\u30DA\u30FC\u30B8\u3092\u53D6\u5F97\u3057\u307E\u3059`
561
777
  },
562
- tools
778
+ tools,
779
+ setup: (params, ctx, config) => runSetupFlow(airtableSetupFlow, params, ctx, config),
780
+ async checkConnection(params, _config) {
781
+ const apiKey = params[parameters.apiKey.slug];
782
+ if (!apiKey) {
783
+ return {
784
+ success: false,
785
+ error: `Missing required parameter: ${parameters.apiKey.slug}`
786
+ };
787
+ }
788
+ try {
789
+ const res = await fetch("https://api.airtable.com/v0/meta/whoami", {
790
+ method: "GET",
791
+ headers: {
792
+ Authorization: `Bearer ${apiKey}`,
793
+ Accept: "application/json"
794
+ }
795
+ });
796
+ if (!res.ok) {
797
+ const errorText = await res.text().catch(() => res.statusText);
798
+ return {
799
+ success: false,
800
+ error: `Airtable API failed: HTTP ${res.status} ${errorText}`
801
+ };
802
+ }
803
+ return { success: true };
804
+ } catch (error) {
805
+ return {
806
+ success: false,
807
+ error: error instanceof Error ? error.message : String(error)
808
+ };
809
+ }
810
+ }
563
811
  });
564
812
 
565
813
  // src/connectors/create-connector-sdk.ts
@@ -588,6 +836,7 @@ function resolveEnvVarOptional(entry, key) {
588
836
  import { getContext } from "hono/context-storage";
589
837
  import { getCookie } from "hono/cookie";
590
838
  var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
839
+ var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
591
840
  function normalizeHeaders(input) {
592
841
  const out = {};
593
842
  if (!input) return out;
@@ -596,6 +845,11 @@ function normalizeHeaders(input) {
596
845
  });
597
846
  return out;
598
847
  }
848
+ function extractInputUrl(input) {
849
+ if (typeof input === "string") return input;
850
+ if (input instanceof URL) return input.href;
851
+ return input.url;
852
+ }
599
853
  function createSandboxProxyFetch(connectionId) {
600
854
  return async (input, init) => {
601
855
  const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
@@ -605,10 +859,17 @@ function createSandboxProxyFetch(connectionId) {
605
859
  "Connection proxy is not configured. Please check your deployment settings."
606
860
  );
607
861
  }
608
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
862
+ const originalUrl = extractInputUrl(input);
863
+ const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
864
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
865
+ const sessionUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
866
+ return fetch(sessionUrl, {
867
+ method: "POST",
868
+ headers: { Authorization: `Bearer ${token}` }
869
+ });
870
+ }
609
871
  const originalMethod = init?.method ?? "GET";
610
872
  const originalBody = init?.body ? JSON.parse(init.body) : void 0;
611
- const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
612
873
  const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
613
874
  return fetch(proxyUrl, {
614
875
  method: "POST",
@@ -634,10 +895,9 @@ function createDeployedAppProxyFetch(connectionId) {
634
895
  }
635
896
  const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
636
897
  const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
898
+ const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
637
899
  return async (input, init) => {
638
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
639
- const originalMethod = init?.method ?? "GET";
640
- const originalBody = init?.body ? JSON.parse(init.body) : void 0;
900
+ const originalUrl = extractInputUrl(input);
641
901
  const c = getContext();
642
902
  const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
643
903
  if (!appSession) {
@@ -645,6 +905,14 @@ function createDeployedAppProxyFetch(connectionId) {
645
905
  "No authentication method available for connection proxy."
646
906
  );
647
907
  }
908
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
909
+ return fetch(sessionUrl, {
910
+ method: "POST",
911
+ headers: { Authorization: `Bearer ${appSession}` }
912
+ });
913
+ }
914
+ const originalMethod = init?.method ?? "GET";
915
+ const originalBody = init?.body ? JSON.parse(init.body) : void 0;
648
916
  return fetch(proxyUrl, {
649
917
  method: "POST",
650
918
  headers: {