@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.
- package/dist/cli/index.js +12128 -934
- package/dist/connectors/airtable-oauth.js +248 -46
- package/dist/connectors/airtable.js +285 -51
- package/dist/connectors/amplitude.js +288 -47
- package/dist/connectors/anthropic.js +126 -47
- package/dist/connectors/asana.js +293 -49
- package/dist/connectors/attio.js +268 -49
- package/dist/connectors/aws-billing.js +253 -46
- package/dist/connectors/azure-sql.js +387 -102
- package/dist/connectors/backlog-api-key.js +283 -47
- package/dist/connectors/clickup.js +304 -49
- package/dist/connectors/cosmosdb.js +271 -50
- package/dist/connectors/customerio.js +285 -47
- package/dist/connectors/dbt.js +306 -47
- package/dist/connectors/freshdesk.js +308 -53
- package/dist/connectors/freshsales.js +299 -52
- package/dist/connectors/freshservice.js +327 -53
- package/dist/connectors/gamma.js +293 -52
- package/dist/connectors/gemini.js +125 -47
- package/dist/connectors/github.js +352 -49
- package/dist/connectors/gmail-oauth.js +170 -7
- package/dist/connectors/gmail.js +316 -47
- package/dist/connectors/google-ads.js +254 -46
- package/dist/connectors/google-analytics-oauth.js +276 -46
- package/dist/connectors/google-analytics.js +378 -49
- package/dist/connectors/google-audit-log.js +404 -47
- package/dist/connectors/google-calendar-oauth.js +225 -46
- package/dist/connectors/google-calendar.js +325 -47
- package/dist/connectors/google-docs.js +186 -6
- package/dist/connectors/google-drive.js +228 -5
- package/dist/connectors/google-search-console-oauth.js +222 -46
- package/dist/connectors/google-sheets.js +238 -47
- package/dist/connectors/google-slides.js +171 -6
- package/dist/connectors/grafana.js +298 -49
- package/dist/connectors/hubspot-oauth.js +174 -5
- package/dist/connectors/hubspot.js +272 -49
- package/dist/connectors/influxdb.js +382 -51
- package/dist/connectors/intercom-oauth.js +176 -5
- package/dist/connectors/intercom.js +268 -49
- package/dist/connectors/jdbc.js +728 -110
- package/dist/connectors/jira-api-key.js +292 -47
- package/dist/connectors/kintone-api-token.js +247 -47
- package/dist/connectors/kintone.js +294 -47
- package/dist/connectors/linear.js +296 -49
- package/dist/connectors/linkedin-ads.js +234 -50
- package/dist/connectors/mailchimp-oauth.js +234 -46
- package/dist/connectors/mailchimp.js +286 -49
- package/dist/connectors/meta-ads-oauth.js +239 -48
- package/dist/connectors/meta-ads.js +251 -50
- package/dist/connectors/mixpanel.js +304 -47
- package/dist/connectors/monday.js +326 -49
- package/dist/connectors/mongodb.js +285 -57
- package/dist/connectors/notion-oauth.js +197 -5
- package/dist/connectors/notion.js +289 -51
- package/dist/connectors/openai.js +125 -47
- package/dist/connectors/oracle.js +405 -103
- package/dist/connectors/outlook-oauth.js +170 -5
- package/dist/connectors/powerbi-oauth.js +217 -5
- package/dist/connectors/salesforce.js +350 -49
- package/dist/connectors/semrush.js +280 -49
- package/dist/connectors/sentry.js +255 -50
- package/dist/connectors/shopify-oauth.js +153 -5
- package/dist/connectors/shopify.js +323 -47
- package/dist/connectors/sqlserver.js +381 -102
- package/dist/connectors/stripe-api-key.js +235 -46
- package/dist/connectors/stripe-oauth.js +168 -5
- package/dist/connectors/supabase.js +269 -48
- package/dist/connectors/tableau.js +337 -206
- package/dist/connectors/tiktok-ads.js +245 -48
- package/dist/connectors/wix-store.js +286 -49
- package/dist/connectors/zendesk-oauth.js +205 -5
- package/dist/connectors/zendesk.js +324 -47
- package/dist/index.d.ts +149 -1
- package/dist/index.js +18297 -6886
- package/dist/main.js +12785 -1382
- package/dist/vite-plugin.js +12140 -936
- 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/mixpanel/parameters.ts
|
|
57
|
+
init_parameter_definition();
|
|
46
58
|
var parameters = {
|
|
47
59
|
serviceAccountUsername: new ParameterDefinition({
|
|
48
60
|
slug: "service-account-username",
|
|
@@ -281,6 +293,20 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
281
293
|
* `runSetupFlow` from `setup-flow.ts`.
|
|
282
294
|
*/
|
|
283
295
|
setup;
|
|
296
|
+
/**
|
|
297
|
+
* Opt-out of the default "verify before save" behavior on connection
|
|
298
|
+
* creation. The backend invokes `checkConnection` synchronously while
|
|
299
|
+
* creating the connection and aborts (no row inserted) if it fails — this
|
|
300
|
+
* flag disables that for connectors where the check cannot succeed pre-save:
|
|
301
|
+
*
|
|
302
|
+
* - `squadbase-db` populates `connection-url` only after Neon provisioning
|
|
303
|
+
* - OAuth connectors require an OAuth-aware proxyFetch keyed by the
|
|
304
|
+
* connectionId, which doesn't exist until the row is saved
|
|
305
|
+
*
|
|
306
|
+
* Exceptions are the explicit position; new credential-input connectors get
|
|
307
|
+
* the default verify-on-create behavior without opt-in.
|
|
308
|
+
*/
|
|
309
|
+
skipConnectionCheckOnCreate;
|
|
284
310
|
constructor(config) {
|
|
285
311
|
this.slug = config.slug;
|
|
286
312
|
this.authType = config.authType;
|
|
@@ -298,6 +324,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
298
324
|
this.query = config.query;
|
|
299
325
|
this.checkConnection = config.checkConnection;
|
|
300
326
|
this.setup = config.setup;
|
|
327
|
+
this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
|
|
301
328
|
}
|
|
302
329
|
get connectorKey() {
|
|
303
330
|
return _ConnectorPlugin.deriveKey(this.slug, this.authType);
|
|
@@ -362,6 +389,46 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
362
389
|
}
|
|
363
390
|
};
|
|
364
391
|
|
|
392
|
+
// ../connectors/src/setup-flow.ts
|
|
393
|
+
async function runSetupFlow(flow, params, ctx, config) {
|
|
394
|
+
const runtime = {
|
|
395
|
+
params,
|
|
396
|
+
language: ctx.language,
|
|
397
|
+
config
|
|
398
|
+
};
|
|
399
|
+
let state = flow.initialState();
|
|
400
|
+
let answerIdx = 0;
|
|
401
|
+
for (const step of flow.steps) {
|
|
402
|
+
const ans = ctx.answers[answerIdx];
|
|
403
|
+
if (ans && ans.questionSlug === step.slug) {
|
|
404
|
+
state = step.applyAnswer(state, ans.answer);
|
|
405
|
+
answerIdx += 1;
|
|
406
|
+
continue;
|
|
407
|
+
}
|
|
408
|
+
if (step.type === "text") {
|
|
409
|
+
return {
|
|
410
|
+
type: "nextQuestion",
|
|
411
|
+
questionSlug: step.slug,
|
|
412
|
+
question: step.question[ctx.language],
|
|
413
|
+
questionType: "text"
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
|
|
417
|
+
if (options.length === 0) {
|
|
418
|
+
continue;
|
|
419
|
+
}
|
|
420
|
+
return {
|
|
421
|
+
type: "nextQuestion",
|
|
422
|
+
questionSlug: step.slug,
|
|
423
|
+
question: step.question[ctx.language],
|
|
424
|
+
questionType: step.type,
|
|
425
|
+
options
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
const dataInvestigationResult = await flow.finalize(state, runtime);
|
|
429
|
+
return { type: "fulfilled", dataInvestigationResult };
|
|
430
|
+
}
|
|
431
|
+
|
|
365
432
|
// ../connectors/src/auth-types.ts
|
|
366
433
|
var AUTH_TYPES = {
|
|
367
434
|
OAUTH: "oauth",
|
|
@@ -392,6 +459,137 @@ NOTE: The Query API endpoints (insights, funnels, retention) require a bookmark_
|
|
|
392
459
|
}
|
|
393
460
|
});
|
|
394
461
|
|
|
462
|
+
// ../connectors/src/connectors/mixpanel/utils.ts
|
|
463
|
+
function getQueryBaseUrl(params) {
|
|
464
|
+
const region = params[parameters.region.slug];
|
|
465
|
+
if (region === "eu") return "https://eu.mixpanel.com/api";
|
|
466
|
+
if (region === "in") return "https://in.mixpanel.com/api";
|
|
467
|
+
return "https://mixpanel.com/api";
|
|
468
|
+
}
|
|
469
|
+
async function apiFetch(params, path2, init) {
|
|
470
|
+
const username = params[parameters.serviceAccountUsername.slug];
|
|
471
|
+
const secret = params[parameters.serviceAccountSecret.slug];
|
|
472
|
+
const projectId = params[parameters.projectId.slug];
|
|
473
|
+
if (!username || !secret || !projectId) {
|
|
474
|
+
throw new Error(
|
|
475
|
+
"mixpanel: missing required parameters: service-account-username, service-account-secret, project-id"
|
|
476
|
+
);
|
|
477
|
+
}
|
|
478
|
+
const base = getQueryBaseUrl(params);
|
|
479
|
+
const url = new URL(`${base}${path2.startsWith("/") ? "" : "/"}${path2}`);
|
|
480
|
+
if (!url.searchParams.has("project_id")) {
|
|
481
|
+
url.searchParams.set("project_id", projectId);
|
|
482
|
+
}
|
|
483
|
+
const headers = new Headers(init?.headers);
|
|
484
|
+
headers.set("Authorization", `Basic ${btoa(`${username}:${secret}`)}`);
|
|
485
|
+
if (!headers.has("Accept")) headers.set("Accept", "application/json");
|
|
486
|
+
return fetch(url.toString(), { ...init, headers });
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
// ../connectors/src/connectors/mixpanel/setup-flow.ts
|
|
490
|
+
var MIXPANEL_SETUP_MAX_ENTITIES = 10;
|
|
491
|
+
var MIXPANEL_SETUP_MAX_EVENTS = 50;
|
|
492
|
+
var ENTITY_LABELS = {
|
|
493
|
+
events: { en: "Events", ja: "Events (\u30A4\u30D9\u30F3\u30C8)" },
|
|
494
|
+
userProperties: {
|
|
495
|
+
en: "User properties",
|
|
496
|
+
ja: "User properties (\u30E6\u30FC\u30B6\u30FC\u30D7\u30ED\u30D1\u30C6\u30A3)"
|
|
497
|
+
},
|
|
498
|
+
cohorts: { en: "Cohorts", ja: "Cohorts (\u30B3\u30DB\u30FC\u30C8)" },
|
|
499
|
+
funnels: { en: "Funnels", ja: "Funnels (\u30D5\u30A1\u30CD\u30EB)" },
|
|
500
|
+
retentionReports: {
|
|
501
|
+
en: "Retention reports",
|
|
502
|
+
ja: "Retention reports (\u30EA\u30C6\u30F3\u30B7\u30E7\u30F3\u30EC\u30DD\u30FC\u30C8)"
|
|
503
|
+
}
|
|
504
|
+
};
|
|
505
|
+
var ENTITY_DESCRIPTIONS = {
|
|
506
|
+
events: {
|
|
507
|
+
en: "Tracked event names.",
|
|
508
|
+
ja: "\u8FFD\u8DE1\u3055\u308C\u3066\u3044\u308B\u30A4\u30D9\u30F3\u30C8\u540D\u3002"
|
|
509
|
+
},
|
|
510
|
+
userProperties: {
|
|
511
|
+
en: "User-level properties available for segmentation.",
|
|
512
|
+
ja: "\u30BB\u30B0\u30E1\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3\u306B\u4F7F\u3048\u308B\u30E6\u30FC\u30B6\u30FC\u30EC\u30D9\u30EB\u306E\u30D7\u30ED\u30D1\u30C6\u30A3\u3002"
|
|
513
|
+
},
|
|
514
|
+
cohorts: {
|
|
515
|
+
en: "Saved user cohorts.",
|
|
516
|
+
ja: "\u4FDD\u5B58\u6E08\u307F\u306E\u30E6\u30FC\u30B6\u30FC\u30B3\u30DB\u30FC\u30C8\u3002"
|
|
517
|
+
},
|
|
518
|
+
funnels: {
|
|
519
|
+
en: "Saved funnel definitions.",
|
|
520
|
+
ja: "\u4FDD\u5B58\u6E08\u307F\u306E\u30D5\u30A1\u30CD\u30EB\u5B9A\u7FA9\u3002"
|
|
521
|
+
},
|
|
522
|
+
retentionReports: {
|
|
523
|
+
en: "Saved retention reports.",
|
|
524
|
+
ja: "\u4FDD\u5B58\u6E08\u307F\u306E\u30EA\u30C6\u30F3\u30B7\u30E7\u30F3\u30EC\u30DD\u30FC\u30C8\u3002"
|
|
525
|
+
}
|
|
526
|
+
};
|
|
527
|
+
var ENTITY_VALUES = [
|
|
528
|
+
"events",
|
|
529
|
+
"userProperties",
|
|
530
|
+
"cohorts",
|
|
531
|
+
"funnels",
|
|
532
|
+
"retentionReports"
|
|
533
|
+
];
|
|
534
|
+
async function fetchEventNames(params) {
|
|
535
|
+
try {
|
|
536
|
+
const res = await apiFetch(params, "/2.0/events/names?type=general");
|
|
537
|
+
if (!res.ok) return [];
|
|
538
|
+
const data = await res.json();
|
|
539
|
+
if (!Array.isArray(data)) return [];
|
|
540
|
+
return data.filter((v) => typeof v === "string");
|
|
541
|
+
} catch {
|
|
542
|
+
return [];
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
var mixpanelSetupFlow = {
|
|
546
|
+
initialState: () => ({}),
|
|
547
|
+
steps: [
|
|
548
|
+
{
|
|
549
|
+
slug: "entities",
|
|
550
|
+
type: "multiSelect",
|
|
551
|
+
question: {
|
|
552
|
+
ja: "\u5BFE\u8C61\u306E\u30A8\u30F3\u30C6\u30A3\u30C6\u30A3\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
|
|
553
|
+
en: "Select target entities (multi-select allowed)"
|
|
554
|
+
},
|
|
555
|
+
async fetchOptions(_state, rt) {
|
|
556
|
+
return ENTITY_VALUES.map((value) => ({
|
|
557
|
+
value,
|
|
558
|
+
label: ENTITY_LABELS[value][rt.language]
|
|
559
|
+
}));
|
|
560
|
+
},
|
|
561
|
+
applyAnswer: (state, answer) => ({ ...state, entities: answer })
|
|
562
|
+
}
|
|
563
|
+
],
|
|
564
|
+
async finalize(state, rt) {
|
|
565
|
+
if (!state.entities) {
|
|
566
|
+
throw new Error("Mixpanel setup: incomplete state on finalize");
|
|
567
|
+
}
|
|
568
|
+
const selected = state.entities.filter(
|
|
569
|
+
(e) => ENTITY_VALUES.includes(e)
|
|
570
|
+
).slice(0, MIXPANEL_SETUP_MAX_ENTITIES);
|
|
571
|
+
const sections = ["## Mixpanel", ""];
|
|
572
|
+
for (const entity of selected) {
|
|
573
|
+
sections.push(`### ${ENTITY_LABELS[entity].en}`, "");
|
|
574
|
+
sections.push(ENTITY_DESCRIPTIONS[entity][rt.language], "");
|
|
575
|
+
if (entity === "events") {
|
|
576
|
+
const names = (await fetchEventNames(rt.params)).slice(
|
|
577
|
+
0,
|
|
578
|
+
MIXPANEL_SETUP_MAX_EVENTS
|
|
579
|
+
);
|
|
580
|
+
if (names.length > 0) {
|
|
581
|
+
sections.push("Event names:", "");
|
|
582
|
+
for (const name of names) {
|
|
583
|
+
sections.push(`- ${name}`);
|
|
584
|
+
}
|
|
585
|
+
sections.push("");
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
return sections.join("\n");
|
|
590
|
+
}
|
|
591
|
+
};
|
|
592
|
+
|
|
395
593
|
// ../connectors/src/connectors/mixpanel/tools/request.ts
|
|
396
594
|
import { z } from "zod";
|
|
397
595
|
var REQUEST_TIMEOUT_MS = 6e4;
|
|
@@ -649,7 +847,46 @@ export default async function handler(c: Context) {
|
|
|
649
847
|
|
|
650
848
|
\u91CD\u8981: Insights\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u306F\u3001Mixpanel UI\u306E\u65E2\u5B58\u30EC\u30DD\u30FC\u30C8\u306Ebookmark_id\u304C\u5FC5\u8981\u3067\u3059\u3002\u30A2\u30C9\u30DB\u30C3\u30AF\u306A\u30A4\u30D9\u30F3\u30C8\u5206\u6790\u306B\u306F\u3001Export API\u3067\u751F\u30A4\u30D9\u30F3\u30C8\u3092\u53D6\u5F97\u3057\u3001\u30B3\u30FC\u30C9\u4E0A\u3067\u96C6\u8A08\u3057\u3066\u304F\u3060\u3055\u3044\u3002Export API\u304C\u6700\u3082\u67D4\u8EDF\u3067\u5E83\u304F\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306A\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u3067\u3059\u3002`
|
|
651
849
|
},
|
|
652
|
-
tools
|
|
850
|
+
tools,
|
|
851
|
+
setup: (params, ctx, config) => runSetupFlow(mixpanelSetupFlow, params, ctx, config),
|
|
852
|
+
async checkConnection(params, _config) {
|
|
853
|
+
const username = params[parameters.serviceAccountUsername.slug];
|
|
854
|
+
const secret = params[parameters.serviceAccountSecret.slug];
|
|
855
|
+
const projectId = params[parameters.projectId.slug];
|
|
856
|
+
if (!username || !secret || !projectId) {
|
|
857
|
+
return {
|
|
858
|
+
success: false,
|
|
859
|
+
error: "Missing required parameters: service-account-username, service-account-secret, and project-id"
|
|
860
|
+
};
|
|
861
|
+
}
|
|
862
|
+
const region = params[parameters.region.slug];
|
|
863
|
+
const queryBase = region === "eu" ? "https://eu.mixpanel.com/api/query" : region === "in" ? "https://in.mixpanel.com/api/query" : "https://mixpanel.com/api/query";
|
|
864
|
+
try {
|
|
865
|
+
const res = await fetch(
|
|
866
|
+
`${queryBase}/events/names?project_id=${encodeURIComponent(projectId)}&type=general&limit=1`,
|
|
867
|
+
{
|
|
868
|
+
method: "GET",
|
|
869
|
+
headers: {
|
|
870
|
+
Authorization: `Basic ${btoa(`${username}:${secret}`)}`,
|
|
871
|
+
Accept: "application/json"
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
);
|
|
875
|
+
if (!res.ok) {
|
|
876
|
+
const errorText = await res.text().catch(() => res.statusText);
|
|
877
|
+
return {
|
|
878
|
+
success: false,
|
|
879
|
+
error: `Mixpanel API failed: HTTP ${res.status} ${errorText}`
|
|
880
|
+
};
|
|
881
|
+
}
|
|
882
|
+
return { success: true };
|
|
883
|
+
} catch (error) {
|
|
884
|
+
return {
|
|
885
|
+
success: false,
|
|
886
|
+
error: error instanceof Error ? error.message : String(error)
|
|
887
|
+
};
|
|
888
|
+
}
|
|
889
|
+
}
|
|
653
890
|
});
|
|
654
891
|
|
|
655
892
|
// src/connectors/create-connector-sdk.ts
|
|
@@ -678,6 +915,7 @@ function resolveEnvVarOptional(entry, key) {
|
|
|
678
915
|
import { getContext } from "hono/context-storage";
|
|
679
916
|
import { getCookie } from "hono/cookie";
|
|
680
917
|
var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
|
|
918
|
+
var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
|
|
681
919
|
function normalizeHeaders(input) {
|
|
682
920
|
const out = {};
|
|
683
921
|
if (!input) return out;
|
|
@@ -686,6 +924,11 @@ function normalizeHeaders(input) {
|
|
|
686
924
|
});
|
|
687
925
|
return out;
|
|
688
926
|
}
|
|
927
|
+
function extractInputUrl(input) {
|
|
928
|
+
if (typeof input === "string") return input;
|
|
929
|
+
if (input instanceof URL) return input.href;
|
|
930
|
+
return input.url;
|
|
931
|
+
}
|
|
689
932
|
function createSandboxProxyFetch(connectionId) {
|
|
690
933
|
return async (input, init) => {
|
|
691
934
|
const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
|
|
@@ -695,10 +938,17 @@ function createSandboxProxyFetch(connectionId) {
|
|
|
695
938
|
"Connection proxy is not configured. Please check your deployment settings."
|
|
696
939
|
);
|
|
697
940
|
}
|
|
698
|
-
const originalUrl =
|
|
941
|
+
const originalUrl = extractInputUrl(input);
|
|
942
|
+
const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
|
|
943
|
+
if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
|
|
944
|
+
const sessionUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
|
|
945
|
+
return fetch(sessionUrl, {
|
|
946
|
+
method: "POST",
|
|
947
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
948
|
+
});
|
|
949
|
+
}
|
|
699
950
|
const originalMethod = init?.method ?? "GET";
|
|
700
951
|
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
701
|
-
const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
|
|
702
952
|
const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
703
953
|
return fetch(proxyUrl, {
|
|
704
954
|
method: "POST",
|
|
@@ -724,10 +974,9 @@ function createDeployedAppProxyFetch(connectionId) {
|
|
|
724
974
|
}
|
|
725
975
|
const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
|
|
726
976
|
const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
977
|
+
const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
|
|
727
978
|
return async (input, init) => {
|
|
728
|
-
const originalUrl =
|
|
729
|
-
const originalMethod = init?.method ?? "GET";
|
|
730
|
-
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
979
|
+
const originalUrl = extractInputUrl(input);
|
|
731
980
|
const c = getContext();
|
|
732
981
|
const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
|
|
733
982
|
if (!appSession) {
|
|
@@ -735,6 +984,14 @@ function createDeployedAppProxyFetch(connectionId) {
|
|
|
735
984
|
"No authentication method available for connection proxy."
|
|
736
985
|
);
|
|
737
986
|
}
|
|
987
|
+
if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
|
|
988
|
+
return fetch(sessionUrl, {
|
|
989
|
+
method: "POST",
|
|
990
|
+
headers: { Authorization: `Bearer ${appSession}` }
|
|
991
|
+
});
|
|
992
|
+
}
|
|
993
|
+
const originalMethod = init?.method ?? "GET";
|
|
994
|
+
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
738
995
|
return fetch(proxyUrl, {
|
|
739
996
|
method: "POST",
|
|
740
997
|
headers: {
|