@squadbase/vite-server 0.1.12-dev.a9ac647 → 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.
- package/dist/cli/index.js +12374 -883
- package/dist/connectors/airtable-oauth.js +257 -46
- package/dist/connectors/airtable.js +294 -51
- package/dist/connectors/amplitude.js +297 -47
- package/dist/connectors/anthropic.js +135 -47
- package/dist/connectors/asana.js +302 -49
- package/dist/connectors/attio.js +277 -49
- package/dist/connectors/aws-billing.js +262 -46
- package/dist/connectors/azure-sql.js +396 -102
- package/dist/connectors/backlog-api-key.js +292 -47
- package/dist/connectors/clickup.js +313 -49
- package/dist/connectors/cosmosdb.js +280 -50
- package/dist/connectors/customerio.js +294 -47
- package/dist/connectors/dbt.js +315 -47
- package/dist/connectors/freshdesk.js +317 -53
- package/dist/connectors/freshsales.js +308 -52
- package/dist/connectors/freshservice.js +336 -53
- package/dist/connectors/gamma.js +302 -52
- package/dist/connectors/gemini.js +134 -47
- package/dist/connectors/github.js +361 -49
- package/dist/connectors/gmail-oauth.js +179 -7
- package/dist/connectors/gmail.js +325 -47
- package/dist/connectors/google-ads.js +263 -46
- package/dist/connectors/google-analytics-oauth.js +285 -46
- package/dist/connectors/google-analytics.js +387 -49
- package/dist/connectors/google-audit-log.js +413 -47
- package/dist/connectors/google-calendar-oauth.js +234 -46
- package/dist/connectors/google-calendar.js +334 -47
- package/dist/connectors/google-docs.js +195 -6
- package/dist/connectors/google-drive.js +237 -5
- package/dist/connectors/google-search-console-oauth.js +231 -46
- package/dist/connectors/google-sheets.js +247 -47
- package/dist/connectors/google-slides.js +180 -6
- package/dist/connectors/grafana.js +307 -49
- package/dist/connectors/hubspot-oauth.js +183 -5
- package/dist/connectors/hubspot.js +281 -49
- package/dist/connectors/influxdb.js +391 -51
- package/dist/connectors/intercom-oauth.js +185 -5
- package/dist/connectors/intercom.js +277 -49
- package/dist/connectors/jdbc.js +737 -110
- package/dist/connectors/jira-api-key.js +301 -47
- package/dist/connectors/kintone-api-token.js +256 -47
- package/dist/connectors/kintone.js +303 -47
- package/dist/connectors/linear.js +305 -49
- package/dist/connectors/linkedin-ads.js +243 -50
- package/dist/connectors/mailchimp-oauth.js +243 -46
- package/dist/connectors/mailchimp.js +295 -49
- package/dist/connectors/meta-ads-oauth.js +248 -48
- package/dist/connectors/meta-ads.js +260 -50
- package/dist/connectors/mixpanel.js +313 -47
- package/dist/connectors/monday.js +335 -49
- package/dist/connectors/mongodb.js +294 -57
- package/dist/connectors/notion-oauth.js +206 -5
- package/dist/connectors/notion.js +298 -51
- package/dist/connectors/openai.js +134 -47
- package/dist/connectors/oracle.js +414 -103
- package/dist/connectors/outlook-oauth.js +179 -5
- package/dist/connectors/powerbi-oauth.js +226 -5
- package/dist/connectors/salesforce.js +359 -49
- package/dist/connectors/semrush.js +289 -49
- package/dist/connectors/sentry.js +264 -50
- package/dist/connectors/shopify-oauth.js +162 -5
- package/dist/connectors/shopify.js +332 -47
- package/dist/connectors/sqlserver.js +390 -102
- package/dist/connectors/stripe-api-key.js +244 -46
- package/dist/connectors/stripe-oauth.js +177 -5
- package/dist/connectors/supabase.js +278 -48
- package/dist/connectors/tableau.js +389 -184
- package/dist/connectors/tiktok-ads.js +254 -48
- package/dist/connectors/wix-store.js +295 -49
- package/dist/connectors/zendesk-oauth.js +214 -5
- package/dist/connectors/zendesk.js +333 -47
- package/dist/index.d.ts +149 -1
- package/dist/index.js +13677 -1969
- package/dist/main.js +13627 -1927
- package/dist/vite-plugin.js +12391 -890
- 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
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
|
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,51 @@ 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
|
+
for (const step of flow.steps) {
|
|
385
|
+
const ans = ctx.answers[answerIdx];
|
|
386
|
+
if (ans && ans.questionSlug === step.slug) {
|
|
387
|
+
state = step.applyAnswer(state, ans.answer);
|
|
388
|
+
answerIdx += 1;
|
|
389
|
+
continue;
|
|
390
|
+
}
|
|
391
|
+
if (step.type === "text") {
|
|
392
|
+
return {
|
|
393
|
+
type: "nextQuestion",
|
|
394
|
+
questionSlug: step.slug,
|
|
395
|
+
question: step.question[ctx.language],
|
|
396
|
+
questionType: "text"
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
|
|
400
|
+
if (options.length === 0) {
|
|
401
|
+
continue;
|
|
402
|
+
}
|
|
403
|
+
return {
|
|
404
|
+
type: "nextQuestion",
|
|
405
|
+
questionSlug: step.slug,
|
|
406
|
+
question: step.question[ctx.language],
|
|
407
|
+
questionType: step.type,
|
|
408
|
+
options
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
const dataInvestigationResult = await flow.finalize(state, runtime);
|
|
412
|
+
return { type: "fulfilled", dataInvestigationResult };
|
|
413
|
+
}
|
|
414
|
+
async function resolveSetupSelection(params) {
|
|
415
|
+
const { selected, allSentinel, fetchAll, limit } = params;
|
|
416
|
+
const resolved = selected.includes(allSentinel) ? await fetchAll() : selected.filter((v) => v !== allSentinel);
|
|
417
|
+
return resolved.slice(0, limit);
|
|
418
|
+
}
|
|
419
|
+
|
|
339
420
|
// ../connectors/src/auth-types.ts
|
|
340
421
|
var AUTH_TYPES = {
|
|
341
422
|
OAUTH: "oauth",
|
|
@@ -356,9 +437,119 @@ var airtableOnboarding = new ConnectorOnboarding({
|
|
|
356
437
|
}
|
|
357
438
|
});
|
|
358
439
|
|
|
440
|
+
// ../connectors/src/connectors/airtable/utils.ts
|
|
441
|
+
var BASE_URL2 = "https://api.airtable.com/v0";
|
|
442
|
+
async function apiFetch(params, path2, init) {
|
|
443
|
+
const apiKey = params[parameters.apiKey.slug];
|
|
444
|
+
if (!apiKey) {
|
|
445
|
+
throw new Error("airtable: missing required parameter: api-key");
|
|
446
|
+
}
|
|
447
|
+
const url = `${BASE_URL2}${path2.startsWith("/") ? "" : "/"}${path2}`;
|
|
448
|
+
const headers = new Headers(init?.headers);
|
|
449
|
+
headers.set("Authorization", `Bearer ${apiKey}`);
|
|
450
|
+
return fetch(url, { ...init, headers });
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
// ../connectors/src/connectors/airtable/setup-flow.ts
|
|
454
|
+
var ALL_TABLES = "__ALL_TABLES__";
|
|
455
|
+
var AIRTABLE_SETUP_MAX_TABLES = 20;
|
|
456
|
+
async function listBases(params) {
|
|
457
|
+
const res = await apiFetch(params, "/meta/bases");
|
|
458
|
+
if (!res.ok) {
|
|
459
|
+
const body = await res.text().catch(() => res.statusText);
|
|
460
|
+
throw new Error(`airtable: listBases failed (${res.status}): ${body}`);
|
|
461
|
+
}
|
|
462
|
+
const data = await res.json();
|
|
463
|
+
return data.bases ?? [];
|
|
464
|
+
}
|
|
465
|
+
async function listTables(params, baseId) {
|
|
466
|
+
const res = await apiFetch(params, `/meta/bases/${baseId}/tables`);
|
|
467
|
+
if (!res.ok) {
|
|
468
|
+
const body = await res.text().catch(() => res.statusText);
|
|
469
|
+
throw new Error(`airtable: listTables failed (${res.status}): ${body}`);
|
|
470
|
+
}
|
|
471
|
+
const data = await res.json();
|
|
472
|
+
return data.tables ?? [];
|
|
473
|
+
}
|
|
474
|
+
var airtableSetupFlow = {
|
|
475
|
+
initialState: () => ({}),
|
|
476
|
+
steps: [
|
|
477
|
+
{
|
|
478
|
+
slug: "base",
|
|
479
|
+
type: "select",
|
|
480
|
+
question: {
|
|
481
|
+
ja: "\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u306B\u4F7F\u3046\u30D9\u30FC\u30B9\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044",
|
|
482
|
+
en: "Select the base to use for setup"
|
|
483
|
+
},
|
|
484
|
+
async fetchOptions(_state, rt) {
|
|
485
|
+
const bases = await listBases(rt.params);
|
|
486
|
+
return bases.filter((b) => b.id && b.name).map((b) => ({ value: b.id, label: b.name }));
|
|
487
|
+
},
|
|
488
|
+
applyAnswer: (state, answer) => ({ ...state, base: answer[0] })
|
|
489
|
+
},
|
|
490
|
+
{
|
|
491
|
+
slug: "tables",
|
|
492
|
+
type: "multiSelect",
|
|
493
|
+
question: {
|
|
494
|
+
ja: "\u5BFE\u8C61\u30C6\u30FC\u30D6\u30EB\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
|
|
495
|
+
en: "Select target tables (multi-select allowed)"
|
|
496
|
+
},
|
|
497
|
+
async fetchOptions(state, rt) {
|
|
498
|
+
if (!state.base) return [];
|
|
499
|
+
const tables = await listTables(rt.params, state.base);
|
|
500
|
+
const tableOptions = tables.filter((t) => t.name).map((t) => ({ value: t.name }));
|
|
501
|
+
return [
|
|
502
|
+
{
|
|
503
|
+
value: ALL_TABLES,
|
|
504
|
+
label: rt.language === "ja" ? "\u3059\u3079\u3066\u306E\u30C6\u30FC\u30D6\u30EB" : "All tables"
|
|
505
|
+
},
|
|
506
|
+
...tableOptions
|
|
507
|
+
];
|
|
508
|
+
},
|
|
509
|
+
applyAnswer: (state, answer) => ({ ...state, tables: answer })
|
|
510
|
+
}
|
|
511
|
+
],
|
|
512
|
+
async finalize(state, rt) {
|
|
513
|
+
if (!state.base || !state.tables) {
|
|
514
|
+
throw new Error("Airtable setup: incomplete state on finalize");
|
|
515
|
+
}
|
|
516
|
+
const baseId = state.base;
|
|
517
|
+
const tables = await listTables(rt.params, baseId);
|
|
518
|
+
const tableByName = new Map(tables.map((t) => [t.name, t]));
|
|
519
|
+
const targetTableNames = await resolveSetupSelection({
|
|
520
|
+
selected: state.tables,
|
|
521
|
+
allSentinel: ALL_TABLES,
|
|
522
|
+
fetchAll: async () => tables.map((t) => t.name).filter((n) => n),
|
|
523
|
+
limit: AIRTABLE_SETUP_MAX_TABLES
|
|
524
|
+
});
|
|
525
|
+
const sections = [
|
|
526
|
+
"## Airtable",
|
|
527
|
+
"",
|
|
528
|
+
`### Base: ${baseId}`,
|
|
529
|
+
""
|
|
530
|
+
];
|
|
531
|
+
for (const tableName of targetTableNames) {
|
|
532
|
+
const table = tableByName.get(tableName);
|
|
533
|
+
if (!table) {
|
|
534
|
+
sections.push(`#### Table: ${tableName}`, "", "_Not found._", "");
|
|
535
|
+
continue;
|
|
536
|
+
}
|
|
537
|
+
sections.push(`#### Table: ${table.name}`, "");
|
|
538
|
+
sections.push("| Field | Type | Description |");
|
|
539
|
+
sections.push("|-------|------|-------------|");
|
|
540
|
+
for (const f of table.fields ?? []) {
|
|
541
|
+
const description = (f.description ?? "").replace(/\|/g, "\\|");
|
|
542
|
+
sections.push(`| ${f.name} | ${f.type} | ${description || "-"} |`);
|
|
543
|
+
}
|
|
544
|
+
sections.push("");
|
|
545
|
+
}
|
|
546
|
+
return sections.join("\n");
|
|
547
|
+
}
|
|
548
|
+
};
|
|
549
|
+
|
|
359
550
|
// ../connectors/src/connectors/airtable/tools/request.ts
|
|
360
551
|
import { z } from "zod";
|
|
361
|
-
var
|
|
552
|
+
var BASE_URL3 = "https://api.airtable.com/v0/";
|
|
362
553
|
var REQUEST_TIMEOUT_MS = 6e4;
|
|
363
554
|
var inputSchema = z.object({
|
|
364
555
|
toolUseIntent: z.string().optional().describe("Brief description of what you intend to accomplish with this tool call"),
|
|
@@ -395,7 +586,7 @@ Authentication is handled automatically using the API Key.
|
|
|
395
586
|
const apiKey = parameters.apiKey.getValue(connection2);
|
|
396
587
|
const baseId = parameters.baseId.getValue(connection2);
|
|
397
588
|
const resolvedPath = path2.replace(/\{baseId\}/g, baseId);
|
|
398
|
-
const url = `${
|
|
589
|
+
const url = `${BASE_URL3}${resolvedPath}`;
|
|
399
590
|
const controller = new AbortController();
|
|
400
591
|
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
401
592
|
try {
|
|
@@ -559,7 +750,39 @@ export default async function handler(c: Context) {
|
|
|
559
750
|
#### \u30DA\u30FC\u30B8\u30CD\u30FC\u30B7\u30E7\u30F3
|
|
560
751
|
- \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
752
|
},
|
|
562
|
-
tools
|
|
753
|
+
tools,
|
|
754
|
+
setup: (params, ctx, config) => runSetupFlow(airtableSetupFlow, params, ctx, config),
|
|
755
|
+
async checkConnection(params, _config) {
|
|
756
|
+
const apiKey = params[parameters.apiKey.slug];
|
|
757
|
+
if (!apiKey) {
|
|
758
|
+
return {
|
|
759
|
+
success: false,
|
|
760
|
+
error: `Missing required parameter: ${parameters.apiKey.slug}`
|
|
761
|
+
};
|
|
762
|
+
}
|
|
763
|
+
try {
|
|
764
|
+
const res = await fetch("https://api.airtable.com/v0/meta/whoami", {
|
|
765
|
+
method: "GET",
|
|
766
|
+
headers: {
|
|
767
|
+
Authorization: `Bearer ${apiKey}`,
|
|
768
|
+
Accept: "application/json"
|
|
769
|
+
}
|
|
770
|
+
});
|
|
771
|
+
if (!res.ok) {
|
|
772
|
+
const errorText = await res.text().catch(() => res.statusText);
|
|
773
|
+
return {
|
|
774
|
+
success: false,
|
|
775
|
+
error: `Airtable API failed: HTTP ${res.status} ${errorText}`
|
|
776
|
+
};
|
|
777
|
+
}
|
|
778
|
+
return { success: true };
|
|
779
|
+
} catch (error) {
|
|
780
|
+
return {
|
|
781
|
+
success: false,
|
|
782
|
+
error: error instanceof Error ? error.message : String(error)
|
|
783
|
+
};
|
|
784
|
+
}
|
|
785
|
+
}
|
|
563
786
|
});
|
|
564
787
|
|
|
565
788
|
// src/connectors/create-connector-sdk.ts
|
|
@@ -588,6 +811,7 @@ function resolveEnvVarOptional(entry, key) {
|
|
|
588
811
|
import { getContext } from "hono/context-storage";
|
|
589
812
|
import { getCookie } from "hono/cookie";
|
|
590
813
|
var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
|
|
814
|
+
var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
|
|
591
815
|
function normalizeHeaders(input) {
|
|
592
816
|
const out = {};
|
|
593
817
|
if (!input) return out;
|
|
@@ -596,6 +820,11 @@ function normalizeHeaders(input) {
|
|
|
596
820
|
});
|
|
597
821
|
return out;
|
|
598
822
|
}
|
|
823
|
+
function extractInputUrl(input) {
|
|
824
|
+
if (typeof input === "string") return input;
|
|
825
|
+
if (input instanceof URL) return input.href;
|
|
826
|
+
return input.url;
|
|
827
|
+
}
|
|
599
828
|
function createSandboxProxyFetch(connectionId) {
|
|
600
829
|
return async (input, init) => {
|
|
601
830
|
const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
|
|
@@ -605,10 +834,17 @@ function createSandboxProxyFetch(connectionId) {
|
|
|
605
834
|
"Connection proxy is not configured. Please check your deployment settings."
|
|
606
835
|
);
|
|
607
836
|
}
|
|
608
|
-
const originalUrl =
|
|
837
|
+
const originalUrl = extractInputUrl(input);
|
|
838
|
+
const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
|
|
839
|
+
if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
|
|
840
|
+
const sessionUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
|
|
841
|
+
return fetch(sessionUrl, {
|
|
842
|
+
method: "POST",
|
|
843
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
844
|
+
});
|
|
845
|
+
}
|
|
609
846
|
const originalMethod = init?.method ?? "GET";
|
|
610
847
|
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
611
|
-
const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
|
|
612
848
|
const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
613
849
|
return fetch(proxyUrl, {
|
|
614
850
|
method: "POST",
|
|
@@ -634,10 +870,9 @@ function createDeployedAppProxyFetch(connectionId) {
|
|
|
634
870
|
}
|
|
635
871
|
const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
|
|
636
872
|
const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
873
|
+
const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
|
|
637
874
|
return async (input, init) => {
|
|
638
|
-
const originalUrl =
|
|
639
|
-
const originalMethod = init?.method ?? "GET";
|
|
640
|
-
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
875
|
+
const originalUrl = extractInputUrl(input);
|
|
641
876
|
const c = getContext();
|
|
642
877
|
const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
|
|
643
878
|
if (!appSession) {
|
|
@@ -645,6 +880,14 @@ function createDeployedAppProxyFetch(connectionId) {
|
|
|
645
880
|
"No authentication method available for connection proxy."
|
|
646
881
|
);
|
|
647
882
|
}
|
|
883
|
+
if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
|
|
884
|
+
return fetch(sessionUrl, {
|
|
885
|
+
method: "POST",
|
|
886
|
+
headers: { Authorization: `Bearer ${appSession}` }
|
|
887
|
+
});
|
|
888
|
+
}
|
|
889
|
+
const originalMethod = init?.method ?? "GET";
|
|
890
|
+
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
648
891
|
return fetch(proxyUrl, {
|
|
649
892
|
method: "POST",
|
|
650
893
|
headers: {
|