@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.
- package/dist/cli/index.js +14375 -1652
- package/dist/connectors/airtable-oauth.js +282 -46
- package/dist/connectors/airtable.js +319 -51
- package/dist/connectors/amplitude.js +322 -47
- package/dist/connectors/anthropic.js +135 -47
- package/dist/connectors/asana.js +327 -49
- package/dist/connectors/attio.js +302 -49
- package/dist/connectors/aws-billing.js +287 -46
- package/dist/connectors/azure-sql.js +421 -102
- package/dist/connectors/backlog-api-key.js +317 -47
- package/dist/connectors/clickup.js +338 -49
- package/dist/connectors/cosmosdb.js +305 -50
- package/dist/connectors/customerio.js +319 -47
- package/dist/connectors/dbt.js +340 -47
- package/dist/connectors/freshdesk.js +342 -53
- package/dist/connectors/freshsales.js +333 -52
- package/dist/connectors/freshservice.js +361 -53
- package/dist/connectors/gamma.js +327 -52
- package/dist/connectors/gemini.js +134 -47
- package/dist/connectors/github.js +386 -49
- package/dist/connectors/gmail-oauth.js +204 -7
- package/dist/connectors/gmail.js +350 -47
- package/dist/connectors/google-ads.js +288 -46
- package/dist/connectors/google-analytics-oauth.js +310 -46
- package/dist/connectors/google-analytics.js +547 -87
- package/dist/connectors/google-audit-log.js +438 -47
- package/dist/connectors/google-calendar-oauth.js +259 -46
- package/dist/connectors/google-calendar.js +359 -47
- package/dist/connectors/google-docs.js +220 -6
- package/dist/connectors/google-drive.js +262 -5
- package/dist/connectors/google-search-console-oauth.js +256 -46
- package/dist/connectors/google-sheets.js +272 -47
- package/dist/connectors/google-slides.js +205 -6
- package/dist/connectors/grafana.js +332 -49
- package/dist/connectors/hubspot-oauth.js +208 -5
- package/dist/connectors/hubspot.js +306 -49
- package/dist/connectors/influxdb.js +416 -51
- package/dist/connectors/intercom-oauth.js +210 -5
- package/dist/connectors/intercom.js +302 -49
- package/dist/connectors/jdbc.js +762 -110
- package/dist/connectors/jira-api-key.js +326 -47
- package/dist/connectors/kintone-api-token.js +281 -47
- package/dist/connectors/kintone.js +328 -47
- package/dist/connectors/linear.js +330 -49
- package/dist/connectors/linkedin-ads.js +268 -50
- package/dist/connectors/mailchimp-oauth.js +268 -46
- package/dist/connectors/mailchimp.js +320 -49
- package/dist/connectors/meta-ads-oauth.js +273 -48
- package/dist/connectors/meta-ads.js +285 -50
- package/dist/connectors/mixpanel.js +338 -47
- package/dist/connectors/monday.js +360 -49
- package/dist/connectors/mongodb.js +319 -57
- package/dist/connectors/notion-oauth.js +231 -5
- package/dist/connectors/notion.js +323 -51
- package/dist/connectors/openai.js +134 -47
- package/dist/connectors/oracle.js +454 -103
- package/dist/connectors/outlook-oauth.js +204 -5
- package/dist/connectors/powerbi-oauth.js +498 -5
- package/dist/connectors/salesforce.js +384 -49
- package/dist/connectors/semrush.js +609 -49
- package/dist/connectors/sentry.js +289 -50
- package/dist/connectors/shopify-oauth.js +187 -5
- package/dist/connectors/shopify.js +357 -47
- package/dist/connectors/sqlserver.js +415 -102
- package/dist/connectors/stripe-api-key.js +269 -46
- package/dist/connectors/stripe-oauth.js +202 -5
- package/dist/connectors/supabase.js +303 -48
- package/dist/connectors/tableau.js +536 -163
- package/dist/connectors/tiktok-ads.js +279 -48
- package/dist/connectors/wix-store.js +320 -49
- package/dist/connectors/zendesk-oauth.js +239 -5
- package/dist/connectors/zendesk.js +358 -47
- package/dist/index.d.ts +149 -1
- package/dist/index.js +15057 -2117
- package/dist/main.js +15005 -2073
- package/dist/vite-plugin.js +14752 -2019
- 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/sentry/parameters.ts
|
|
57
|
+
init_parameter_definition();
|
|
46
58
|
var parameters = {
|
|
47
59
|
organizationSlug: new ParameterDefinition({
|
|
48
60
|
slug: "organization-slug",
|
|
@@ -94,7 +106,7 @@ function createClient(params) {
|
|
|
94
106
|
const url = `${BASE_URL}${resolved.startsWith("/") ? "" : "/"}${resolved}`;
|
|
95
107
|
return authenticatedFetch(url, init);
|
|
96
108
|
}
|
|
97
|
-
async function
|
|
109
|
+
async function listProjects2() {
|
|
98
110
|
const url = `${BASE_URL}/organizations/${organizationSlug}/projects/`;
|
|
99
111
|
const response = await authenticatedFetch(url);
|
|
100
112
|
if (!response.ok) {
|
|
@@ -160,7 +172,7 @@ function createClient(params) {
|
|
|
160
172
|
}
|
|
161
173
|
return {
|
|
162
174
|
request,
|
|
163
|
-
listProjects,
|
|
175
|
+
listProjects: listProjects2,
|
|
164
176
|
listIssues,
|
|
165
177
|
getIssue,
|
|
166
178
|
listIssueEvents,
|
|
@@ -227,6 +239,28 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
227
239
|
tools;
|
|
228
240
|
query;
|
|
229
241
|
checkConnection;
|
|
242
|
+
/**
|
|
243
|
+
* SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
|
|
244
|
+
* implement this expose a step-by-step exploration flow (database/schema/
|
|
245
|
+
* table/etc. discovery) that the dashboard backend drives via the
|
|
246
|
+
* `/connections/:connectionId/setup` endpoint. Implement by delegating to
|
|
247
|
+
* `runSetupFlow` from `setup-flow.ts`.
|
|
248
|
+
*/
|
|
249
|
+
setup;
|
|
250
|
+
/**
|
|
251
|
+
* Opt-out of the default "verify before save" behavior on connection
|
|
252
|
+
* creation. The backend invokes `checkConnection` synchronously while
|
|
253
|
+
* creating the connection and aborts (no row inserted) if it fails — this
|
|
254
|
+
* flag disables that for connectors where the check cannot succeed pre-save:
|
|
255
|
+
*
|
|
256
|
+
* - `squadbase-db` populates `connection-url` only after Neon provisioning
|
|
257
|
+
* - OAuth connectors require an OAuth-aware proxyFetch keyed by the
|
|
258
|
+
* connectionId, which doesn't exist until the row is saved
|
|
259
|
+
*
|
|
260
|
+
* Exceptions are the explicit position; new credential-input connectors get
|
|
261
|
+
* the default verify-on-create behavior without opt-in.
|
|
262
|
+
*/
|
|
263
|
+
skipConnectionCheckOnCreate;
|
|
230
264
|
constructor(config) {
|
|
231
265
|
this.slug = config.slug;
|
|
232
266
|
this.authType = config.authType;
|
|
@@ -243,6 +277,8 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
243
277
|
this.tools = config.tools;
|
|
244
278
|
this.query = config.query;
|
|
245
279
|
this.checkConnection = config.checkConnection;
|
|
280
|
+
this.setup = config.setup;
|
|
281
|
+
this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
|
|
246
282
|
}
|
|
247
283
|
get connectorKey() {
|
|
248
284
|
return _ConnectorPlugin.deriveKey(this.slug, this.authType);
|
|
@@ -307,6 +343,76 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
307
343
|
}
|
|
308
344
|
};
|
|
309
345
|
|
|
346
|
+
// ../connectors/src/setup-flow.ts
|
|
347
|
+
async function runSetupFlow(flow, params, ctx, config) {
|
|
348
|
+
const runtime = {
|
|
349
|
+
params,
|
|
350
|
+
language: ctx.language,
|
|
351
|
+
config
|
|
352
|
+
};
|
|
353
|
+
let state = flow.initialState();
|
|
354
|
+
let answerIdx = 0;
|
|
355
|
+
const pendingParameterUpdates = [];
|
|
356
|
+
for (const step of flow.steps) {
|
|
357
|
+
const ans = ctx.answers[answerIdx];
|
|
358
|
+
if (ans && ans.questionSlug === step.slug) {
|
|
359
|
+
state = step.applyAnswer(state, ans.answer);
|
|
360
|
+
if (step.toParameterUpdates) {
|
|
361
|
+
pendingParameterUpdates.push(...step.toParameterUpdates(state));
|
|
362
|
+
}
|
|
363
|
+
answerIdx += 1;
|
|
364
|
+
continue;
|
|
365
|
+
}
|
|
366
|
+
const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
|
|
367
|
+
if (step.type === "text") {
|
|
368
|
+
if (step.fetchOptions) {
|
|
369
|
+
const options2 = await step.fetchOptions(state, runtime);
|
|
370
|
+
if (options2.length === 0) {
|
|
371
|
+
continue;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
return {
|
|
375
|
+
type: "nextQuestion",
|
|
376
|
+
questionSlug: step.slug,
|
|
377
|
+
question: step.question[ctx.language],
|
|
378
|
+
questionType: "text",
|
|
379
|
+
allowFreeText: resolvedAllowFreeText,
|
|
380
|
+
...pendingParameterUpdates.length > 0 && {
|
|
381
|
+
parameterUpdates: pendingParameterUpdates
|
|
382
|
+
}
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
|
|
386
|
+
if (options.length === 0) {
|
|
387
|
+
continue;
|
|
388
|
+
}
|
|
389
|
+
return {
|
|
390
|
+
type: "nextQuestion",
|
|
391
|
+
questionSlug: step.slug,
|
|
392
|
+
question: step.question[ctx.language],
|
|
393
|
+
questionType: step.type,
|
|
394
|
+
options,
|
|
395
|
+
allowFreeText: resolvedAllowFreeText,
|
|
396
|
+
...pendingParameterUpdates.length > 0 && {
|
|
397
|
+
parameterUpdates: pendingParameterUpdates
|
|
398
|
+
}
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
const dataInvestigationResult = await flow.finalize(state, runtime);
|
|
402
|
+
return {
|
|
403
|
+
type: "fulfilled",
|
|
404
|
+
dataInvestigationResult,
|
|
405
|
+
...pendingParameterUpdates.length > 0 && {
|
|
406
|
+
parameterUpdates: pendingParameterUpdates
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
async function resolveSetupSelection(params) {
|
|
411
|
+
const { selected, allSentinel, fetchAll, limit } = params;
|
|
412
|
+
const resolved = selected.includes(allSentinel) ? await fetchAll() : selected.filter((v) => v !== allSentinel);
|
|
413
|
+
return resolved.slice(0, limit);
|
|
414
|
+
}
|
|
415
|
+
|
|
310
416
|
// ../connectors/src/auth-types.ts
|
|
311
417
|
var AUTH_TYPES = {
|
|
312
418
|
OAUTH: "oauth",
|
|
@@ -329,9 +435,121 @@ var sentryOnboarding = new ConnectorOnboarding({
|
|
|
329
435
|
}
|
|
330
436
|
});
|
|
331
437
|
|
|
438
|
+
// ../connectors/src/connectors/sentry/utils.ts
|
|
439
|
+
var BASE_URL2 = "https://sentry.io/api/0";
|
|
440
|
+
async function apiFetch(params, path2, init) {
|
|
441
|
+
const authToken = params[parameters.authToken.slug];
|
|
442
|
+
if (!authToken) {
|
|
443
|
+
throw new Error("sentry: missing required parameter: auth-token");
|
|
444
|
+
}
|
|
445
|
+
const url = `${BASE_URL2}${path2.startsWith("/") ? "" : "/"}${path2}`;
|
|
446
|
+
const headers = new Headers(init?.headers);
|
|
447
|
+
headers.set("Authorization", `Bearer ${authToken}`);
|
|
448
|
+
if (!headers.has("Accept")) headers.set("Accept", "application/json");
|
|
449
|
+
return fetch(url, { ...init, headers });
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// ../connectors/src/connectors/sentry/setup-flow.ts
|
|
453
|
+
var ALL_PROJECTS = "__ALL_PROJECTS__";
|
|
454
|
+
var SENTRY_SETUP_MAX_PROJECTS = 20;
|
|
455
|
+
async function listOrganizations(params) {
|
|
456
|
+
const res = await apiFetch(params, "/organizations/");
|
|
457
|
+
if (!res.ok) {
|
|
458
|
+
const body = await res.text().catch(() => res.statusText);
|
|
459
|
+
throw new Error(`sentry: listOrganizations failed (${res.status}): ${body}`);
|
|
460
|
+
}
|
|
461
|
+
const data = await res.json();
|
|
462
|
+
return data ?? [];
|
|
463
|
+
}
|
|
464
|
+
async function listProjects(params, orgSlug) {
|
|
465
|
+
const res = await apiFetch(params, `/organizations/${orgSlug}/projects/`);
|
|
466
|
+
if (!res.ok) {
|
|
467
|
+
const body = await res.text().catch(() => res.statusText);
|
|
468
|
+
throw new Error(`sentry: listProjects failed (${res.status}): ${body}`);
|
|
469
|
+
}
|
|
470
|
+
const data = await res.json();
|
|
471
|
+
return data ?? [];
|
|
472
|
+
}
|
|
473
|
+
var sentrySetupFlow = {
|
|
474
|
+
initialState: () => ({}),
|
|
475
|
+
steps: [
|
|
476
|
+
{
|
|
477
|
+
slug: "organization",
|
|
478
|
+
type: "select",
|
|
479
|
+
question: {
|
|
480
|
+
ja: "\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u306B\u4F7F\u3046\u7D44\u7E54\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044",
|
|
481
|
+
en: "Select the organization to use for setup"
|
|
482
|
+
},
|
|
483
|
+
async fetchOptions(_state, rt) {
|
|
484
|
+
const orgs = await listOrganizations(rt.params);
|
|
485
|
+
return orgs.filter((o) => o.slug).map((o) => ({ value: o.slug, label: o.name || o.slug }));
|
|
486
|
+
},
|
|
487
|
+
applyAnswer: (state, answer) => ({ ...state, organization: answer[0] })
|
|
488
|
+
},
|
|
489
|
+
{
|
|
490
|
+
slug: "projects",
|
|
491
|
+
type: "multiSelect",
|
|
492
|
+
question: {
|
|
493
|
+
ja: "\u5BFE\u8C61\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
|
|
494
|
+
en: "Select target projects (multi-select allowed)"
|
|
495
|
+
},
|
|
496
|
+
async fetchOptions(state, rt) {
|
|
497
|
+
if (!state.organization) return [];
|
|
498
|
+
const projects = await listProjects(rt.params, state.organization);
|
|
499
|
+
const opts = projects.filter((p) => p.slug).map((p) => ({ value: p.slug, label: p.name || p.slug }));
|
|
500
|
+
if (opts.length === 0) return [];
|
|
501
|
+
return [
|
|
502
|
+
{
|
|
503
|
+
value: ALL_PROJECTS,
|
|
504
|
+
label: rt.language === "ja" ? "\u3059\u3079\u3066\u306E\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8" : "All projects"
|
|
505
|
+
},
|
|
506
|
+
...opts
|
|
507
|
+
];
|
|
508
|
+
},
|
|
509
|
+
applyAnswer: (state, answer) => ({ ...state, projects: answer })
|
|
510
|
+
}
|
|
511
|
+
],
|
|
512
|
+
async finalize(state, rt) {
|
|
513
|
+
if (!state.organization || !state.projects) {
|
|
514
|
+
throw new Error("Sentry setup: incomplete state on finalize");
|
|
515
|
+
}
|
|
516
|
+
const orgSlug = state.organization;
|
|
517
|
+
const projects = await listProjects(rt.params, orgSlug);
|
|
518
|
+
const bySlug = new Map(projects.map((p) => [p.slug, p]));
|
|
519
|
+
const targetSlugs = await resolveSetupSelection({
|
|
520
|
+
selected: state.projects,
|
|
521
|
+
allSentinel: ALL_PROJECTS,
|
|
522
|
+
fetchAll: async () => projects.map((p) => p.slug).filter((s) => s),
|
|
523
|
+
limit: SENTRY_SETUP_MAX_PROJECTS
|
|
524
|
+
});
|
|
525
|
+
const sections = [
|
|
526
|
+
"## Sentry",
|
|
527
|
+
"",
|
|
528
|
+
`### Organization: ${orgSlug}`,
|
|
529
|
+
""
|
|
530
|
+
];
|
|
531
|
+
for (const slug of targetSlugs) {
|
|
532
|
+
const project = bySlug.get(slug);
|
|
533
|
+
if (!project) {
|
|
534
|
+
sections.push(`#### Project: ${slug}`, "", "_Not found._", "");
|
|
535
|
+
continue;
|
|
536
|
+
}
|
|
537
|
+
sections.push(`#### Project: ${project.name || project.slug}`, "");
|
|
538
|
+
sections.push("| Field | Value |");
|
|
539
|
+
sections.push("|-------|-------|");
|
|
540
|
+
sections.push(`| Slug | ${project.slug} |`);
|
|
541
|
+
sections.push(`| Platform | ${project.platform ?? "-"} |`);
|
|
542
|
+
sections.push(`| First event | ${project.firstEvent ?? "-"} |`);
|
|
543
|
+
sections.push(`| Created | ${project.dateCreated ?? "-"} |`);
|
|
544
|
+
sections.push("");
|
|
545
|
+
}
|
|
546
|
+
return sections.join("\n");
|
|
547
|
+
}
|
|
548
|
+
};
|
|
549
|
+
|
|
332
550
|
// ../connectors/src/connectors/sentry/tools/request.ts
|
|
333
551
|
import { z } from "zod";
|
|
334
|
-
var
|
|
552
|
+
var BASE_URL3 = "https://sentry.io/api/0";
|
|
335
553
|
var REQUEST_TIMEOUT_MS = 6e4;
|
|
336
554
|
var inputSchema = z.object({
|
|
337
555
|
toolUseIntent: z.string().optional().describe(
|
|
@@ -381,7 +599,7 @@ Authentication is handled automatically via Bearer token.
|
|
|
381
599
|
/\{organizationSlug\}/g,
|
|
382
600
|
organizationSlug
|
|
383
601
|
);
|
|
384
|
-
const url = `${
|
|
602
|
+
const url = `${BASE_URL3}${resolvedPath.startsWith("/") ? "" : "/"}${resolvedPath}`;
|
|
385
603
|
const controller = new AbortController();
|
|
386
604
|
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
387
605
|
try {
|
|
@@ -590,6 +808,7 @@ await sentry.updateIssue("12345", { status: "resolved" });
|
|
|
590
808
|
\`\`\``
|
|
591
809
|
},
|
|
592
810
|
tools,
|
|
811
|
+
setup: (params, ctx, config) => runSetupFlow(sentrySetupFlow, params, ctx, config),
|
|
593
812
|
async checkConnection(params) {
|
|
594
813
|
const authToken = params[parameters.authToken.slug];
|
|
595
814
|
const organizationSlug = params[parameters.organizationSlug.slug];
|
|
@@ -651,6 +870,7 @@ function resolveEnvVarOptional(entry, key) {
|
|
|
651
870
|
import { getContext } from "hono/context-storage";
|
|
652
871
|
import { getCookie } from "hono/cookie";
|
|
653
872
|
var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
|
|
873
|
+
var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
|
|
654
874
|
function normalizeHeaders(input) {
|
|
655
875
|
const out = {};
|
|
656
876
|
if (!input) return out;
|
|
@@ -659,6 +879,11 @@ function normalizeHeaders(input) {
|
|
|
659
879
|
});
|
|
660
880
|
return out;
|
|
661
881
|
}
|
|
882
|
+
function extractInputUrl(input) {
|
|
883
|
+
if (typeof input === "string") return input;
|
|
884
|
+
if (input instanceof URL) return input.href;
|
|
885
|
+
return input.url;
|
|
886
|
+
}
|
|
662
887
|
function createSandboxProxyFetch(connectionId) {
|
|
663
888
|
return async (input, init) => {
|
|
664
889
|
const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
|
|
@@ -668,10 +893,17 @@ function createSandboxProxyFetch(connectionId) {
|
|
|
668
893
|
"Connection proxy is not configured. Please check your deployment settings."
|
|
669
894
|
);
|
|
670
895
|
}
|
|
671
|
-
const originalUrl =
|
|
896
|
+
const originalUrl = extractInputUrl(input);
|
|
897
|
+
const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
|
|
898
|
+
if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
|
|
899
|
+
const sessionUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
|
|
900
|
+
return fetch(sessionUrl, {
|
|
901
|
+
method: "POST",
|
|
902
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
903
|
+
});
|
|
904
|
+
}
|
|
672
905
|
const originalMethod = init?.method ?? "GET";
|
|
673
906
|
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
674
|
-
const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
|
|
675
907
|
const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
676
908
|
return fetch(proxyUrl, {
|
|
677
909
|
method: "POST",
|
|
@@ -697,10 +929,9 @@ function createDeployedAppProxyFetch(connectionId) {
|
|
|
697
929
|
}
|
|
698
930
|
const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
|
|
699
931
|
const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
932
|
+
const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
|
|
700
933
|
return async (input, init) => {
|
|
701
|
-
const originalUrl =
|
|
702
|
-
const originalMethod = init?.method ?? "GET";
|
|
703
|
-
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
934
|
+
const originalUrl = extractInputUrl(input);
|
|
704
935
|
const c = getContext();
|
|
705
936
|
const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
|
|
706
937
|
if (!appSession) {
|
|
@@ -708,6 +939,14 @@ function createDeployedAppProxyFetch(connectionId) {
|
|
|
708
939
|
"No authentication method available for connection proxy."
|
|
709
940
|
);
|
|
710
941
|
}
|
|
942
|
+
if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
|
|
943
|
+
return fetch(sessionUrl, {
|
|
944
|
+
method: "POST",
|
|
945
|
+
headers: { Authorization: `Bearer ${appSession}` }
|
|
946
|
+
});
|
|
947
|
+
}
|
|
948
|
+
const originalMethod = init?.method ?? "GET";
|
|
949
|
+
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
711
950
|
return fetch(proxyUrl, {
|
|
712
951
|
method: "POST",
|
|
713
952
|
headers: {
|