@squadbase/vite-server 0.1.12-dev.93b8799 → 0.1.17-dev.24af54e

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 +12128 -934
  2. package/dist/connectors/airtable-oauth.js +248 -46
  3. package/dist/connectors/airtable.js +285 -51
  4. package/dist/connectors/amplitude.js +288 -47
  5. package/dist/connectors/anthropic.js +126 -47
  6. package/dist/connectors/asana.js +293 -49
  7. package/dist/connectors/attio.js +268 -49
  8. package/dist/connectors/aws-billing.js +253 -46
  9. package/dist/connectors/azure-sql.js +387 -102
  10. package/dist/connectors/backlog-api-key.js +283 -47
  11. package/dist/connectors/clickup.js +304 -49
  12. package/dist/connectors/cosmosdb.js +271 -50
  13. package/dist/connectors/customerio.js +285 -47
  14. package/dist/connectors/dbt.js +306 -47
  15. package/dist/connectors/freshdesk.js +308 -53
  16. package/dist/connectors/freshsales.js +299 -52
  17. package/dist/connectors/freshservice.js +327 -53
  18. package/dist/connectors/gamma.js +293 -52
  19. package/dist/connectors/gemini.js +125 -47
  20. package/dist/connectors/github.js +352 -49
  21. package/dist/connectors/gmail-oauth.js +170 -7
  22. package/dist/connectors/gmail.js +316 -47
  23. package/dist/connectors/google-ads.js +254 -46
  24. package/dist/connectors/google-analytics-oauth.js +276 -46
  25. package/dist/connectors/google-analytics.js +378 -49
  26. package/dist/connectors/google-audit-log.js +404 -47
  27. package/dist/connectors/google-calendar-oauth.js +225 -46
  28. package/dist/connectors/google-calendar.js +325 -47
  29. package/dist/connectors/google-docs.js +186 -6
  30. package/dist/connectors/google-drive.js +228 -5
  31. package/dist/connectors/google-search-console-oauth.js +222 -46
  32. package/dist/connectors/google-sheets.js +238 -47
  33. package/dist/connectors/google-slides.js +171 -6
  34. package/dist/connectors/grafana.js +298 -49
  35. package/dist/connectors/hubspot-oauth.js +174 -5
  36. package/dist/connectors/hubspot.js +272 -49
  37. package/dist/connectors/influxdb.js +382 -51
  38. package/dist/connectors/intercom-oauth.js +176 -5
  39. package/dist/connectors/intercom.js +268 -49
  40. package/dist/connectors/jdbc.js +728 -110
  41. package/dist/connectors/jira-api-key.js +292 -47
  42. package/dist/connectors/kintone-api-token.js +247 -47
  43. package/dist/connectors/kintone.js +294 -47
  44. package/dist/connectors/linear.js +296 -49
  45. package/dist/connectors/linkedin-ads.js +234 -50
  46. package/dist/connectors/mailchimp-oauth.js +234 -46
  47. package/dist/connectors/mailchimp.js +286 -49
  48. package/dist/connectors/meta-ads-oauth.js +239 -48
  49. package/dist/connectors/meta-ads.js +251 -50
  50. package/dist/connectors/mixpanel.js +304 -47
  51. package/dist/connectors/monday.js +326 -49
  52. package/dist/connectors/mongodb.js +285 -57
  53. package/dist/connectors/notion-oauth.js +197 -5
  54. package/dist/connectors/notion.js +289 -51
  55. package/dist/connectors/openai.js +125 -47
  56. package/dist/connectors/oracle.js +405 -103
  57. package/dist/connectors/outlook-oauth.js +170 -5
  58. package/dist/connectors/powerbi-oauth.js +217 -5
  59. package/dist/connectors/salesforce.js +350 -49
  60. package/dist/connectors/semrush.js +280 -49
  61. package/dist/connectors/sentry.js +255 -50
  62. package/dist/connectors/shopify-oauth.js +153 -5
  63. package/dist/connectors/shopify.js +323 -47
  64. package/dist/connectors/sqlserver.js +381 -102
  65. package/dist/connectors/stripe-api-key.js +235 -46
  66. package/dist/connectors/stripe-oauth.js +168 -5
  67. package/dist/connectors/supabase.js +269 -48
  68. package/dist/connectors/tableau.js +337 -206
  69. package/dist/connectors/tiktok-ads.js +245 -48
  70. package/dist/connectors/wix-store.js +286 -49
  71. package/dist/connectors/zendesk-oauth.js +205 -5
  72. package/dist/connectors/zendesk.js +324 -47
  73. package/dist/index.d.ts +149 -1
  74. package/dist/index.js +18297 -6886
  75. package/dist/main.js +12785 -1382
  76. package/dist/vite-plugin.js +12140 -936
  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/influxdb/parameters.ts
57
+ init_parameter_definition();
46
58
  var parameters = {
47
59
  url: new ParameterDefinition({
48
60
  slug: "url",
@@ -103,7 +115,7 @@ function createClient(params) {
103
115
  `influxdb: missing required parameter: ${parameters.database.slug}`
104
116
  );
105
117
  }
106
- function authHeaders(extra) {
118
+ function authHeaders2(extra) {
107
119
  const headers = new Headers(extra);
108
120
  headers.set("Authorization", `Token ${token}`);
109
121
  if (!headers.has("Accept")) headers.set("Accept", "application/json");
@@ -139,7 +151,7 @@ function createClient(params) {
139
151
  async querySql(sql, options) {
140
152
  const res = await fetch(`${url}/api/v3/query_sql`, {
141
153
  method: "POST",
142
- headers: authHeaders({ "Content-Type": "application/json" }),
154
+ headers: authHeaders2({ "Content-Type": "application/json" }),
143
155
  body: JSON.stringify({
144
156
  db: options?.database ?? database,
145
157
  q: sql
@@ -151,7 +163,7 @@ function createClient(params) {
151
163
  async queryInfluxql(influxql, options) {
152
164
  const res = await fetch(`${url}/api/v3/query_influxql`, {
153
165
  method: "POST",
154
- headers: authHeaders({ "Content-Type": "application/json" }),
166
+ headers: authHeaders2({ "Content-Type": "application/json" }),
155
167
  body: JSON.stringify({
156
168
  db: options?.database ?? database,
157
169
  q: influxql
@@ -171,7 +183,7 @@ function createClient(params) {
171
183
  `${url}/api/v2/query?org=${encodeURIComponent(resolvedOrg)}`,
172
184
  {
173
185
  method: "POST",
174
- headers: authHeaders({
186
+ headers: authHeaders2({
175
187
  "Content-Type": "application/vnd.flux",
176
188
  Accept: "application/csv"
177
189
  }),
@@ -188,7 +200,7 @@ function createClient(params) {
188
200
  const endpoint = resolvedOrg ? `${url}/api/v2/write?org=${encodeURIComponent(resolvedOrg)}&bucket=${encodeURIComponent(resolvedDatabase)}&precision=${precision}` : `${url}/api/v3/write_lp?db=${encodeURIComponent(resolvedDatabase)}&precision=${precision}`;
189
201
  const res = await fetch(endpoint, {
190
202
  method: "POST",
191
- headers: authHeaders({ "Content-Type": "text/plain; charset=utf-8" }),
203
+ headers: authHeaders2({ "Content-Type": "text/plain; charset=utf-8" }),
192
204
  body: lineProtocol
193
205
  });
194
206
  await assertOk(res, "writeLineProtocol");
@@ -263,6 +275,20 @@ var ConnectorPlugin = class _ConnectorPlugin {
263
275
  * `runSetupFlow` from `setup-flow.ts`.
264
276
  */
265
277
  setup;
278
+ /**
279
+ * Opt-out of the default "verify before save" behavior on connection
280
+ * creation. The backend invokes `checkConnection` synchronously while
281
+ * creating the connection and aborts (no row inserted) if it fails — this
282
+ * flag disables that for connectors where the check cannot succeed pre-save:
283
+ *
284
+ * - `squadbase-db` populates `connection-url` only after Neon provisioning
285
+ * - OAuth connectors require an OAuth-aware proxyFetch keyed by the
286
+ * connectionId, which doesn't exist until the row is saved
287
+ *
288
+ * Exceptions are the explicit position; new credential-input connectors get
289
+ * the default verify-on-create behavior without opt-in.
290
+ */
291
+ skipConnectionCheckOnCreate;
266
292
  constructor(config) {
267
293
  this.slug = config.slug;
268
294
  this.authType = config.authType;
@@ -280,6 +306,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
280
306
  this.query = config.query;
281
307
  this.checkConnection = config.checkConnection;
282
308
  this.setup = config.setup;
309
+ this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
283
310
  }
284
311
  get connectorKey() {
285
312
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -344,6 +371,51 @@ var ConnectorPlugin = class _ConnectorPlugin {
344
371
  }
345
372
  };
346
373
 
374
+ // ../connectors/src/setup-flow.ts
375
+ async function runSetupFlow(flow, params, ctx, config) {
376
+ const runtime = {
377
+ params,
378
+ language: ctx.language,
379
+ config
380
+ };
381
+ let state = flow.initialState();
382
+ let answerIdx = 0;
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
+ answerIdx += 1;
388
+ continue;
389
+ }
390
+ if (step.type === "text") {
391
+ return {
392
+ type: "nextQuestion",
393
+ questionSlug: step.slug,
394
+ question: step.question[ctx.language],
395
+ questionType: "text"
396
+ };
397
+ }
398
+ const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
399
+ if (options.length === 0) {
400
+ continue;
401
+ }
402
+ return {
403
+ type: "nextQuestion",
404
+ questionSlug: step.slug,
405
+ question: step.question[ctx.language],
406
+ questionType: step.type,
407
+ options
408
+ };
409
+ }
410
+ const dataInvestigationResult = await flow.finalize(state, runtime);
411
+ return { type: "fulfilled", dataInvestigationResult };
412
+ }
413
+ async function resolveSetupSelection(params) {
414
+ const { selected, allSentinel, fetchAll, limit } = params;
415
+ const resolved = selected.includes(allSentinel) ? await fetchAll() : selected.filter((v) => v !== allSentinel);
416
+ return resolved.slice(0, limit);
417
+ }
418
+
347
419
  // ../connectors/src/auth-types.ts
348
420
  var AUTH_TYPES = {
349
421
  OAUTH: "oauth",
@@ -412,6 +484,244 @@ var influxdbOnboarding = new ConnectorOnboarding({
412
484
  }
413
485
  });
414
486
 
487
+ // ../connectors/src/connectors/influxdb/utils.ts
488
+ function authHeaders(token, extra) {
489
+ const headers = new Headers(extra);
490
+ headers.set("Authorization", `Token ${token}`);
491
+ if (!headers.has("Accept")) headers.set("Accept", "application/json");
492
+ return headers;
493
+ }
494
+ async function detectVariant(params) {
495
+ const url = (params[parameters.url.slug] ?? "").replace(/\/$/, "");
496
+ const token = params[parameters.token.slug];
497
+ const database = params[parameters.database.slug];
498
+ const res = await fetch(`${url}/api/v3/query_sql`, {
499
+ method: "POST",
500
+ headers: authHeaders(token, { "Content-Type": "application/json" }),
501
+ body: JSON.stringify({ db: database, q: "SELECT 1" })
502
+ });
503
+ if (res.ok) {
504
+ const contentType = res.headers.get("content-type") ?? "";
505
+ if (contentType.includes("application/json")) return "v3";
506
+ }
507
+ return "v2";
508
+ }
509
+ async function runSql(params, sql) {
510
+ const url = (params[parameters.url.slug] ?? "").replace(/\/$/, "");
511
+ const token = params[parameters.token.slug];
512
+ const database = params[parameters.database.slug];
513
+ const res = await fetch(`${url}/api/v3/query_sql`, {
514
+ method: "POST",
515
+ headers: authHeaders(token, { "Content-Type": "application/json" }),
516
+ body: JSON.stringify({ db: database, q: sql })
517
+ });
518
+ if (!res.ok) {
519
+ const body = await res.text().catch(() => res.statusText);
520
+ throw new Error(
521
+ `InfluxDB SQL query failed: HTTP ${res.status} \u2014 ${body.slice(0, 200)}`
522
+ );
523
+ }
524
+ return await res.json();
525
+ }
526
+ async function runFlux(params, flux) {
527
+ const url = (params[parameters.url.slug] ?? "").replace(/\/$/, "");
528
+ const token = params[parameters.token.slug];
529
+ const org = params[parameters.org.slug];
530
+ if (!org) {
531
+ throw new Error(
532
+ "InfluxDB 2 Flux queries require the 'org' connection parameter, which is not configured"
533
+ );
534
+ }
535
+ const res = await fetch(
536
+ `${url}/api/v2/query?org=${encodeURIComponent(org)}`,
537
+ {
538
+ method: "POST",
539
+ headers: authHeaders(token, {
540
+ "Content-Type": "application/vnd.flux",
541
+ Accept: "application/csv"
542
+ }),
543
+ body: flux
544
+ }
545
+ );
546
+ if (!res.ok) {
547
+ const body = await res.text().catch(() => res.statusText);
548
+ throw new Error(
549
+ `InfluxDB Flux query failed: HTTP ${res.status} \u2014 ${body.slice(0, 200)}`
550
+ );
551
+ }
552
+ return await res.text();
553
+ }
554
+ function parseAnnotatedCsv(csv) {
555
+ const lines = csv.split(/\r?\n/).filter((line) => line.trim().length > 0);
556
+ const rows = [];
557
+ let headers = null;
558
+ for (const line of lines) {
559
+ if (line.startsWith("#")) {
560
+ headers = null;
561
+ continue;
562
+ }
563
+ const fields = splitCsvLine(line);
564
+ if (headers === null) {
565
+ headers = fields;
566
+ continue;
567
+ }
568
+ const row = {};
569
+ headers.forEach((h, i) => {
570
+ row[h] = fields[i] ?? "";
571
+ });
572
+ rows.push(row);
573
+ }
574
+ return { columns: headers ?? [], rows };
575
+ }
576
+ function splitCsvLine(line) {
577
+ const out = [];
578
+ let cur = "";
579
+ let inQuotes = false;
580
+ for (let i = 0; i < line.length; i++) {
581
+ const c = line[i];
582
+ if (inQuotes) {
583
+ if (c === '"' && line[i + 1] === '"') {
584
+ cur += '"';
585
+ i += 1;
586
+ } else if (c === '"') {
587
+ inQuotes = false;
588
+ } else {
589
+ cur += c;
590
+ }
591
+ } else if (c === '"') {
592
+ inQuotes = true;
593
+ } else if (c === ",") {
594
+ out.push(cur);
595
+ cur = "";
596
+ } else {
597
+ cur += c;
598
+ }
599
+ }
600
+ out.push(cur);
601
+ return out;
602
+ }
603
+
604
+ // ../connectors/src/connectors/influxdb/setup-flow.ts
605
+ var ALL_MEASUREMENTS = "__ALL_MEASUREMENTS__";
606
+ var INFLUXDB_SETUP_MAX_MEASUREMENTS = 20;
607
+ async function listMeasurements(params, variant) {
608
+ if (variant === "v3") {
609
+ const rows2 = await runSql(params, "SHOW TABLES");
610
+ return rows2.map((r) => String(r["table_name"] ?? r["name"] ?? "")).filter((name) => name).filter((name) => !name.includes("::"));
611
+ }
612
+ const bucket = params[parameters.database.slug];
613
+ if (!bucket) {
614
+ throw new Error(
615
+ "InfluxDB 2 setup: 'database' (bucket) parameter is required to list measurements"
616
+ );
617
+ }
618
+ const flux = [
619
+ `import "influxdata/influxdb/schema"`,
620
+ `schema.measurements(bucket: ${JSON.stringify(bucket)})`
621
+ ].join("\n");
622
+ const csv = await runFlux(params, flux);
623
+ const { rows } = parseAnnotatedCsv(csv);
624
+ return rows.map((r) => r["_value"] ?? "").filter((name) => name);
625
+ }
626
+ async function listMeasurementColumns(params, variant, measurement) {
627
+ if (variant === "v3") {
628
+ const safeName2 = measurement.replace(/"/g, '""');
629
+ const rows = await runSql(params, `SHOW COLUMNS FROM "${safeName2}"`);
630
+ return rows.map((r) => ({
631
+ name: String(r["column_name"] ?? r["name"] ?? ""),
632
+ kind: String(r["data_type"] ?? r["type"] ?? "")
633
+ }));
634
+ }
635
+ const bucket = params[parameters.database.slug];
636
+ const safeName = measurement.replace(/"/g, '\\"');
637
+ const fieldsFlux = [
638
+ `import "influxdata/influxdb/schema"`,
639
+ `schema.measurementFieldKeys(bucket: ${JSON.stringify(bucket)}, measurement: "${safeName}")`
640
+ ].join("\n");
641
+ const tagsFlux = [
642
+ `import "influxdata/influxdb/schema"`,
643
+ `schema.measurementTagKeys(bucket: ${JSON.stringify(bucket)}, measurement: "${safeName}")`
644
+ ].join("\n");
645
+ const [fieldsCsv, tagsCsv] = await Promise.all([
646
+ runFlux(params, fieldsFlux),
647
+ runFlux(params, tagsFlux)
648
+ ]);
649
+ const fields = parseAnnotatedCsv(fieldsCsv).rows.map((r) => ({
650
+ name: r["_value"] ?? "",
651
+ kind: "field"
652
+ }));
653
+ const tags = parseAnnotatedCsv(tagsCsv).rows.map((r) => ({
654
+ name: r["_value"] ?? "",
655
+ kind: "tag"
656
+ }));
657
+ return [...tags, ...fields].filter((c) => c.name);
658
+ }
659
+ var influxdbSetupFlow = {
660
+ initialState: () => ({}),
661
+ steps: [
662
+ {
663
+ slug: "measurements",
664
+ type: "multiSelect",
665
+ question: {
666
+ ja: "\u5BFE\u8C61 measurement \u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
667
+ en: "Select target measurements (multi-select allowed)"
668
+ },
669
+ async fetchOptions(_state, rt) {
670
+ const variant = await detectVariant(rt.params);
671
+ const ms = await listMeasurements(rt.params, variant);
672
+ const options = ms.map((value) => ({ value }));
673
+ return [
674
+ {
675
+ value: ALL_MEASUREMENTS,
676
+ label: rt.language === "ja" ? "\u3059\u3079\u3066\u306E measurement" : "All measurements"
677
+ },
678
+ ...options
679
+ ];
680
+ },
681
+ applyAnswer: (state, answer) => ({ ...state, measurements: answer })
682
+ }
683
+ ],
684
+ async finalize(state, rt) {
685
+ if (!state.measurements) {
686
+ throw new Error("InfluxDB setup: incomplete state on finalize");
687
+ }
688
+ const variant = await detectVariant(rt.params);
689
+ const database = rt.params[parameters.database.slug];
690
+ const org = rt.params[parameters.org.slug];
691
+ const targetMeasurements = await resolveSetupSelection({
692
+ selected: state.measurements,
693
+ allSentinel: ALL_MEASUREMENTS,
694
+ fetchAll: () => listMeasurements(rt.params, variant),
695
+ limit: INFLUXDB_SETUP_MAX_MEASUREMENTS
696
+ });
697
+ const sections = [
698
+ "## InfluxDB",
699
+ "",
700
+ `### Variant: ${variant === "v3" ? "InfluxDB 3 (SQL)" : "InfluxDB 2 (Flux)"}`,
701
+ `### ${variant === "v3" ? "Database" : "Bucket"}: ${database}`
702
+ ];
703
+ if (variant === "v2" && org) {
704
+ sections.push(`### Organization: ${org}`);
705
+ }
706
+ sections.push("");
707
+ for (const measurement of targetMeasurements) {
708
+ const cols = await listMeasurementColumns(rt.params, variant, measurement);
709
+ sections.push(`#### Measurement: ${measurement}`, "");
710
+ if (cols.length === 0) {
711
+ sections.push("_(no fields or tags found)_", "");
712
+ continue;
713
+ }
714
+ sections.push("| Column | Kind |");
715
+ sections.push("|--------|------|");
716
+ for (const c of cols) {
717
+ sections.push(`| ${c.name} | ${c.kind || "-"} |`);
718
+ }
719
+ sections.push("");
720
+ }
721
+ return sections.join("\n");
722
+ }
723
+ };
724
+
415
725
  // ../connectors/src/connectors/influxdb/tools/request.ts
416
726
  import { z } from "zod";
417
727
  var REQUEST_TIMEOUT_MS = 6e4;
@@ -678,6 +988,7 @@ export default async function handler(c: Context) {
678
988
  - measurement \u4E00\u89A7: \`SHOW TABLES\`\u3001\u5217\u4E00\u89A7: \`SHOW COLUMNS FROM <measurement>\``
679
989
  },
680
990
  tools,
991
+ setup: (params, ctx, config) => runSetupFlow(influxdbSetupFlow, params, ctx, config),
681
992
  async checkConnection(params) {
682
993
  const url = (params.url ?? "").replace(/\/$/, "");
683
994
  const token = params.token;
@@ -746,6 +1057,7 @@ function resolveEnvVarOptional(entry, key) {
746
1057
  import { getContext } from "hono/context-storage";
747
1058
  import { getCookie } from "hono/cookie";
748
1059
  var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
1060
+ var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
749
1061
  function normalizeHeaders(input) {
750
1062
  const out = {};
751
1063
  if (!input) return out;
@@ -754,6 +1066,11 @@ function normalizeHeaders(input) {
754
1066
  });
755
1067
  return out;
756
1068
  }
1069
+ function extractInputUrl(input) {
1070
+ if (typeof input === "string") return input;
1071
+ if (input instanceof URL) return input.href;
1072
+ return input.url;
1073
+ }
757
1074
  function createSandboxProxyFetch(connectionId) {
758
1075
  return async (input, init) => {
759
1076
  const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
@@ -763,10 +1080,17 @@ function createSandboxProxyFetch(connectionId) {
763
1080
  "Connection proxy is not configured. Please check your deployment settings."
764
1081
  );
765
1082
  }
766
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
1083
+ const originalUrl = extractInputUrl(input);
1084
+ const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
1085
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
1086
+ const sessionUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
1087
+ return fetch(sessionUrl, {
1088
+ method: "POST",
1089
+ headers: { Authorization: `Bearer ${token}` }
1090
+ });
1091
+ }
767
1092
  const originalMethod = init?.method ?? "GET";
768
1093
  const originalBody = init?.body ? JSON.parse(init.body) : void 0;
769
- const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
770
1094
  const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
771
1095
  return fetch(proxyUrl, {
772
1096
  method: "POST",
@@ -792,10 +1116,9 @@ function createDeployedAppProxyFetch(connectionId) {
792
1116
  }
793
1117
  const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
794
1118
  const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
1119
+ const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
795
1120
  return async (input, init) => {
796
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
797
- const originalMethod = init?.method ?? "GET";
798
- const originalBody = init?.body ? JSON.parse(init.body) : void 0;
1121
+ const originalUrl = extractInputUrl(input);
799
1122
  const c = getContext();
800
1123
  const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
801
1124
  if (!appSession) {
@@ -803,6 +1126,14 @@ function createDeployedAppProxyFetch(connectionId) {
803
1126
  "No authentication method available for connection proxy."
804
1127
  );
805
1128
  }
1129
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
1130
+ return fetch(sessionUrl, {
1131
+ method: "POST",
1132
+ headers: { Authorization: `Bearer ${appSession}` }
1133
+ });
1134
+ }
1135
+ const originalMethod = init?.method ?? "GET";
1136
+ const originalBody = init?.body ? JSON.parse(init.body) : void 0;
806
1137
  return fetch(proxyUrl, {
807
1138
  method: "POST",
808
1139
  headers: {