@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/freshservice/parameters.ts
57
+ init_parameter_definition();
46
58
  var parameters = {
47
59
  domain: new ParameterDefinition({
48
60
  slug: "domain",
@@ -254,6 +266,28 @@ var ConnectorPlugin = class _ConnectorPlugin {
254
266
  tools;
255
267
  query;
256
268
  checkConnection;
269
+ /**
270
+ * SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
271
+ * implement this expose a step-by-step exploration flow (database/schema/
272
+ * table/etc. discovery) that the dashboard backend drives via the
273
+ * `/connections/:connectionId/setup` endpoint. Implement by delegating to
274
+ * `runSetupFlow` from `setup-flow.ts`.
275
+ */
276
+ setup;
277
+ /**
278
+ * Opt-out of the default "verify before save" behavior on connection
279
+ * creation. The backend invokes `checkConnection` synchronously while
280
+ * creating the connection and aborts (no row inserted) if it fails — this
281
+ * flag disables that for connectors where the check cannot succeed pre-save:
282
+ *
283
+ * - `squadbase-db` populates `connection-url` only after Neon provisioning
284
+ * - OAuth connectors require an OAuth-aware proxyFetch keyed by the
285
+ * connectionId, which doesn't exist until the row is saved
286
+ *
287
+ * Exceptions are the explicit position; new credential-input connectors get
288
+ * the default verify-on-create behavior without opt-in.
289
+ */
290
+ skipConnectionCheckOnCreate;
257
291
  constructor(config) {
258
292
  this.slug = config.slug;
259
293
  this.authType = config.authType;
@@ -270,6 +304,8 @@ var ConnectorPlugin = class _ConnectorPlugin {
270
304
  this.tools = config.tools;
271
305
  this.query = config.query;
272
306
  this.checkConnection = config.checkConnection;
307
+ this.setup = config.setup;
308
+ this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
273
309
  }
274
310
  get connectorKey() {
275
311
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -334,6 +370,76 @@ var ConnectorPlugin = class _ConnectorPlugin {
334
370
  }
335
371
  };
336
372
 
373
+ // ../connectors/src/setup-flow.ts
374
+ async function runSetupFlow(flow, params, ctx, config) {
375
+ const runtime = {
376
+ params,
377
+ language: ctx.language,
378
+ config
379
+ };
380
+ let state = flow.initialState();
381
+ let answerIdx = 0;
382
+ const pendingParameterUpdates = [];
383
+ for (const step of flow.steps) {
384
+ const ans = ctx.answers[answerIdx];
385
+ if (ans && ans.questionSlug === step.slug) {
386
+ state = step.applyAnswer(state, ans.answer);
387
+ if (step.toParameterUpdates) {
388
+ pendingParameterUpdates.push(...step.toParameterUpdates(state));
389
+ }
390
+ answerIdx += 1;
391
+ continue;
392
+ }
393
+ const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
394
+ if (step.type === "text") {
395
+ if (step.fetchOptions) {
396
+ const options2 = await step.fetchOptions(state, runtime);
397
+ if (options2.length === 0) {
398
+ continue;
399
+ }
400
+ }
401
+ return {
402
+ type: "nextQuestion",
403
+ questionSlug: step.slug,
404
+ question: step.question[ctx.language],
405
+ questionType: "text",
406
+ allowFreeText: resolvedAllowFreeText,
407
+ ...pendingParameterUpdates.length > 0 && {
408
+ parameterUpdates: pendingParameterUpdates
409
+ }
410
+ };
411
+ }
412
+ const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
413
+ if (options.length === 0) {
414
+ continue;
415
+ }
416
+ return {
417
+ type: "nextQuestion",
418
+ questionSlug: step.slug,
419
+ question: step.question[ctx.language],
420
+ questionType: step.type,
421
+ options,
422
+ allowFreeText: resolvedAllowFreeText,
423
+ ...pendingParameterUpdates.length > 0 && {
424
+ parameterUpdates: pendingParameterUpdates
425
+ }
426
+ };
427
+ }
428
+ const dataInvestigationResult = await flow.finalize(state, runtime);
429
+ return {
430
+ type: "fulfilled",
431
+ dataInvestigationResult,
432
+ ...pendingParameterUpdates.length > 0 && {
433
+ parameterUpdates: pendingParameterUpdates
434
+ }
435
+ };
436
+ }
437
+ async function resolveSetupSelection(params) {
438
+ const { selected, allSentinel, fetchAll, limit } = params;
439
+ const resolved = selected.includes(allSentinel) ? await fetchAll() : selected.filter((v) => v !== allSentinel);
440
+ return resolved.slice(0, limit);
441
+ }
442
+
337
443
  // ../connectors/src/auth-types.ts
338
444
  var AUTH_TYPES = {
339
445
  OAUTH: "oauth",
@@ -370,10 +476,8 @@ var freshserviceOnboarding = new ConnectorOnboarding({
370
476
  }
371
477
  });
372
478
 
373
- // ../connectors/src/connectors/freshservice/tools/request.ts
374
- import { z } from "zod";
479
+ // ../connectors/src/connectors/freshservice/utils.ts
375
480
  var BASE_PATH_SEGMENT = "/api/v2";
376
- var REQUEST_TIMEOUT_MS = 6e4;
377
481
  function buildBaseUrl2(domain) {
378
482
  const trimmed = domain.trim().replace(/^https?:\/\//, "").replace(/\/+$/, "");
379
483
  const subdomain = trimmed.split(".")[0];
@@ -382,6 +486,151 @@ function buildBaseUrl2(domain) {
382
486
  function basicAuthHeader2(apiKey) {
383
487
  return `Basic ${Buffer.from(`${apiKey}:X`).toString("base64")}`;
384
488
  }
489
+ async function apiFetch(params, path2, init) {
490
+ const apiKey = params[parameters.apiKey.slug];
491
+ const domain = params[parameters.domain.slug];
492
+ if (!apiKey || !domain) {
493
+ throw new Error(
494
+ "freshservice: missing required parameter(s) (api-key, domain)"
495
+ );
496
+ }
497
+ const baseUrl = buildBaseUrl2(domain);
498
+ const url = `${baseUrl}${path2.startsWith("/") ? "" : "/"}${path2}`;
499
+ const headers = new Headers(init?.headers);
500
+ headers.set("Authorization", basicAuthHeader2(apiKey));
501
+ headers.set("Accept", "application/json");
502
+ return fetch(url, { ...init, headers });
503
+ }
504
+
505
+ // ../connectors/src/connectors/freshservice/setup-flow.ts
506
+ var FRESHSERVICE_SETUP_MAX_ENTITIES = 10;
507
+ var FRESHSERVICE_ENTITIES = [
508
+ {
509
+ value: "tickets",
510
+ label: "Tickets",
511
+ countPath: "/tickets?per_page=1"
512
+ },
513
+ {
514
+ value: "agents",
515
+ label: "Agents",
516
+ countPath: "/agents?per_page=1"
517
+ },
518
+ {
519
+ value: "requesters",
520
+ label: "Requesters",
521
+ countPath: "/requesters?per_page=1"
522
+ },
523
+ {
524
+ value: "groups",
525
+ label: "Groups",
526
+ countPath: "/groups?per_page=1"
527
+ },
528
+ {
529
+ value: "departments",
530
+ label: "Departments",
531
+ countPath: "/departments?per_page=1"
532
+ },
533
+ {
534
+ value: "assets",
535
+ label: "Assets",
536
+ countPath: "/assets?per_page=1"
537
+ },
538
+ {
539
+ value: "problems",
540
+ label: "Problems",
541
+ countPath: "/problems?per_page=1"
542
+ },
543
+ {
544
+ value: "changes",
545
+ label: "Changes",
546
+ countPath: "/changes?per_page=1"
547
+ },
548
+ {
549
+ value: "releases",
550
+ label: "Releases",
551
+ countPath: "/releases?per_page=1"
552
+ },
553
+ {
554
+ value: "service_catalog",
555
+ label: "Service catalog items",
556
+ countPath: "/service_catalog/items?per_page=1"
557
+ }
558
+ ];
559
+ async function fetchEntityCount(params, path2) {
560
+ const res = await apiFetch(params, path2);
561
+ if (!res.ok) return null;
562
+ const data = await res.json();
563
+ if (typeof data["total"] === "number") return data["total"];
564
+ return null;
565
+ }
566
+ var freshserviceSetupFlow = {
567
+ initialState: () => ({}),
568
+ steps: [
569
+ {
570
+ slug: "entities",
571
+ type: "multiSelect",
572
+ question: {
573
+ ja: "\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3067\u6982\u89B3\u3057\u305F\u3044Freshservice\u30A8\u30F3\u30C6\u30A3\u30C6\u30A3\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
574
+ en: "Select the Freshservice entities to include in setup (multi-select allowed)"
575
+ },
576
+ async fetchOptions(_state, _rt) {
577
+ return FRESHSERVICE_ENTITIES.map((e) => ({
578
+ value: e.value,
579
+ label: e.label
580
+ }));
581
+ },
582
+ applyAnswer: (state, answer) => ({ ...state, entities: answer })
583
+ }
584
+ ],
585
+ async finalize(state, rt) {
586
+ if (!state.entities) {
587
+ throw new Error("Freshservice setup: incomplete state on finalize");
588
+ }
589
+ const targetEntities = await resolveSetupSelection({
590
+ selected: state.entities,
591
+ allSentinel: "__ALL__",
592
+ fetchAll: async () => FRESHSERVICE_ENTITIES.map((e) => e.value),
593
+ limit: FRESHSERVICE_SETUP_MAX_ENTITIES
594
+ });
595
+ const entityByValue = new Map(
596
+ FRESHSERVICE_ENTITIES.map((e) => [e.value, e])
597
+ );
598
+ const sections = [
599
+ "## Freshservice",
600
+ "",
601
+ "### Selected entities",
602
+ "",
603
+ "| Entity | Count |",
604
+ "|--------|-------|"
605
+ ];
606
+ for (const value of targetEntities) {
607
+ const entity = entityByValue.get(value);
608
+ if (!entity) {
609
+ sections.push(`| ${value} | _unknown_ |`);
610
+ continue;
611
+ }
612
+ const count = await fetchEntityCount(rt.params, entity.countPath);
613
+ sections.push(
614
+ `| ${entity.label} (${entity.value}) | ${count == null ? "-" : count} |`
615
+ );
616
+ }
617
+ sections.push("");
618
+ return sections.join("\n");
619
+ }
620
+ };
621
+
622
+ // ../connectors/src/connectors/freshservice/tools/request.ts
623
+ import { z } from "zod";
624
+ var BASE_PATH_SEGMENT2 = "/api/v2";
625
+ var REQUEST_TIMEOUT_MS = 6e4;
626
+ function buildBaseUrl3(domain) {
627
+ const trimmed = domain.trim().replace(/^https?:\/\//, "").replace(/\/+$/, "");
628
+ const subdomain = trimmed.split(".")[0];
629
+ return `https://${subdomain}.freshservice.com${BASE_PATH_SEGMENT2}`;
630
+ }
631
+ function basicAuthHeader3(apiKey) {
632
+ return `Basic ${Buffer.from(`${apiKey}:X`).toString("base64")}`;
633
+ }
385
634
  var inputSchema = z.object({
386
635
  toolUseIntent: z.string().optional().describe(
387
636
  "Brief description of what you intend to accomplish with this tool call"
@@ -455,8 +704,8 @@ Field codes:
455
704
  try {
456
705
  const apiKey = parameters.apiKey.getValue(connection2);
457
706
  const domain = parameters.domain.getValue(connection2);
458
- const baseUrl = buildBaseUrl2(domain);
459
- const normalizedPath = normalizeRequestPath(path2, BASE_PATH_SEGMENT);
707
+ const baseUrl = buildBaseUrl3(domain);
708
+ const normalizedPath = normalizeRequestPath(path2, BASE_PATH_SEGMENT2);
460
709
  const url = `${baseUrl}${normalizedPath}`;
461
710
  const controller = new AbortController();
462
711
  const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
@@ -464,7 +713,7 @@ Field codes:
464
713
  const response = await fetch(url, {
465
714
  method,
466
715
  headers: {
467
- Authorization: basicAuthHeader2(apiKey),
716
+ Authorization: basicAuthHeader3(apiKey),
468
717
  "Content-Type": "application/json",
469
718
  Accept: "application/json"
470
719
  },
@@ -658,7 +907,46 @@ export default async function handler(c: Context) {
658
907
  - \`status\`: 2=Open, 3=Pending, 4=Resolved, 5=Closed
659
908
  - \`source\`: 1=Email, 2=Portal, 3=Phone, 4=Chat, 5=Feedback widget, 7=Yammer, 8=AwsCloudwatch, 9=Pagerduty, 10=Walkup, 11=Slack`
660
909
  },
661
- tools
910
+ tools,
911
+ setup: (params, ctx, config) => runSetupFlow(freshserviceSetupFlow, params, ctx, config),
912
+ async checkConnection(params, _config) {
913
+ const domain = params[parameters.domain.slug];
914
+ const apiKey = params[parameters.apiKey.slug];
915
+ if (!domain || !apiKey) {
916
+ return {
917
+ success: false,
918
+ error: `Missing required parameter(s): ${parameters.domain.slug}, ${parameters.apiKey.slug}`
919
+ };
920
+ }
921
+ try {
922
+ const credentials = Buffer.from(`${apiKey}:X`, "utf-8").toString(
923
+ "base64"
924
+ );
925
+ const res = await fetch(
926
+ `https://${domain}.freshservice.com/api/v2/agents/me`,
927
+ {
928
+ method: "GET",
929
+ headers: {
930
+ Authorization: `Basic ${credentials}`,
931
+ Accept: "application/json"
932
+ }
933
+ }
934
+ );
935
+ if (!res.ok) {
936
+ const errText = await res.text().catch(() => res.statusText);
937
+ return {
938
+ success: false,
939
+ error: `Freshservice API failed: HTTP ${res.status} ${errText}`
940
+ };
941
+ }
942
+ return { success: true };
943
+ } catch (error) {
944
+ return {
945
+ success: false,
946
+ error: error instanceof Error ? error.message : String(error)
947
+ };
948
+ }
949
+ }
662
950
  });
663
951
 
664
952
  // src/connectors/create-connector-sdk.ts
@@ -687,6 +975,7 @@ function resolveEnvVarOptional(entry, key) {
687
975
  import { getContext } from "hono/context-storage";
688
976
  import { getCookie } from "hono/cookie";
689
977
  var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
978
+ var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
690
979
  function normalizeHeaders(input) {
691
980
  const out = {};
692
981
  if (!input) return out;
@@ -695,6 +984,11 @@ function normalizeHeaders(input) {
695
984
  });
696
985
  return out;
697
986
  }
987
+ function extractInputUrl(input) {
988
+ if (typeof input === "string") return input;
989
+ if (input instanceof URL) return input.href;
990
+ return input.url;
991
+ }
698
992
  function createSandboxProxyFetch(connectionId) {
699
993
  return async (input, init) => {
700
994
  const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
@@ -704,10 +998,17 @@ function createSandboxProxyFetch(connectionId) {
704
998
  "Connection proxy is not configured. Please check your deployment settings."
705
999
  );
706
1000
  }
707
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
1001
+ const originalUrl = extractInputUrl(input);
1002
+ const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
1003
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
1004
+ const sessionUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
1005
+ return fetch(sessionUrl, {
1006
+ method: "POST",
1007
+ headers: { Authorization: `Bearer ${token}` }
1008
+ });
1009
+ }
708
1010
  const originalMethod = init?.method ?? "GET";
709
1011
  const originalBody = init?.body ? JSON.parse(init.body) : void 0;
710
- const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
711
1012
  const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
712
1013
  return fetch(proxyUrl, {
713
1014
  method: "POST",
@@ -733,10 +1034,9 @@ function createDeployedAppProxyFetch(connectionId) {
733
1034
  }
734
1035
  const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
735
1036
  const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
1037
+ const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
736
1038
  return async (input, init) => {
737
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
738
- const originalMethod = init?.method ?? "GET";
739
- const originalBody = init?.body ? JSON.parse(init.body) : void 0;
1039
+ const originalUrl = extractInputUrl(input);
740
1040
  const c = getContext();
741
1041
  const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
742
1042
  if (!appSession) {
@@ -744,6 +1044,14 @@ function createDeployedAppProxyFetch(connectionId) {
744
1044
  "No authentication method available for connection proxy."
745
1045
  );
746
1046
  }
1047
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
1048
+ return fetch(sessionUrl, {
1049
+ method: "POST",
1050
+ headers: { Authorization: `Bearer ${appSession}` }
1051
+ });
1052
+ }
1053
+ const originalMethod = init?.method ?? "GET";
1054
+ const originalBody = init?.body ? JSON.parse(init.body) : void 0;
747
1055
  return fetch(proxyUrl, {
748
1056
  method: "POST",
749
1057
  headers: {