@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
package/dist/connectors/asana.js
CHANGED
|
@@ -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/asana/parameters.ts
|
|
57
|
+
init_parameter_definition();
|
|
46
58
|
var parameters = {
|
|
47
59
|
personalAccessToken: new ParameterDefinition({
|
|
48
60
|
slug: "personal-access-token",
|
|
@@ -261,6 +273,20 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
261
273
|
* `runSetupFlow` from `setup-flow.ts`.
|
|
262
274
|
*/
|
|
263
275
|
setup;
|
|
276
|
+
/**
|
|
277
|
+
* Opt-out of the default "verify before save" behavior on connection
|
|
278
|
+
* creation. The backend invokes `checkConnection` synchronously while
|
|
279
|
+
* creating the connection and aborts (no row inserted) if it fails — this
|
|
280
|
+
* flag disables that for connectors where the check cannot succeed pre-save:
|
|
281
|
+
*
|
|
282
|
+
* - `squadbase-db` populates `connection-url` only after Neon provisioning
|
|
283
|
+
* - OAuth connectors require an OAuth-aware proxyFetch keyed by the
|
|
284
|
+
* connectionId, which doesn't exist until the row is saved
|
|
285
|
+
*
|
|
286
|
+
* Exceptions are the explicit position; new credential-input connectors get
|
|
287
|
+
* the default verify-on-create behavior without opt-in.
|
|
288
|
+
*/
|
|
289
|
+
skipConnectionCheckOnCreate;
|
|
264
290
|
constructor(config) {
|
|
265
291
|
this.slug = config.slug;
|
|
266
292
|
this.authType = config.authType;
|
|
@@ -278,6 +304,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
278
304
|
this.query = config.query;
|
|
279
305
|
this.checkConnection = config.checkConnection;
|
|
280
306
|
this.setup = config.setup;
|
|
307
|
+
this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
|
|
281
308
|
}
|
|
282
309
|
get connectorKey() {
|
|
283
310
|
return _ConnectorPlugin.deriveKey(this.slug, this.authType);
|
|
@@ -342,6 +369,51 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
342
369
|
}
|
|
343
370
|
};
|
|
344
371
|
|
|
372
|
+
// ../connectors/src/setup-flow.ts
|
|
373
|
+
async function runSetupFlow(flow, params, ctx, config) {
|
|
374
|
+
const runtime = {
|
|
375
|
+
params,
|
|
376
|
+
language: ctx.language,
|
|
377
|
+
config
|
|
378
|
+
};
|
|
379
|
+
let state = flow.initialState();
|
|
380
|
+
let answerIdx = 0;
|
|
381
|
+
for (const step of flow.steps) {
|
|
382
|
+
const ans = ctx.answers[answerIdx];
|
|
383
|
+
if (ans && ans.questionSlug === step.slug) {
|
|
384
|
+
state = step.applyAnswer(state, ans.answer);
|
|
385
|
+
answerIdx += 1;
|
|
386
|
+
continue;
|
|
387
|
+
}
|
|
388
|
+
if (step.type === "text") {
|
|
389
|
+
return {
|
|
390
|
+
type: "nextQuestion",
|
|
391
|
+
questionSlug: step.slug,
|
|
392
|
+
question: step.question[ctx.language],
|
|
393
|
+
questionType: "text"
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
|
|
397
|
+
if (options.length === 0) {
|
|
398
|
+
continue;
|
|
399
|
+
}
|
|
400
|
+
return {
|
|
401
|
+
type: "nextQuestion",
|
|
402
|
+
questionSlug: step.slug,
|
|
403
|
+
question: step.question[ctx.language],
|
|
404
|
+
questionType: step.type,
|
|
405
|
+
options
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
const dataInvestigationResult = await flow.finalize(state, runtime);
|
|
409
|
+
return { type: "fulfilled", dataInvestigationResult };
|
|
410
|
+
}
|
|
411
|
+
async function resolveSetupSelection(params) {
|
|
412
|
+
const { selected, allSentinel, fetchAll, limit } = params;
|
|
413
|
+
const resolved = selected.includes(allSentinel) ? await fetchAll() : selected.filter((v) => v !== allSentinel);
|
|
414
|
+
return resolved.slice(0, limit);
|
|
415
|
+
}
|
|
416
|
+
|
|
345
417
|
// ../connectors/src/auth-types.ts
|
|
346
418
|
var AUTH_TYPES = {
|
|
347
419
|
OAUTH: "oauth",
|
|
@@ -376,11 +448,131 @@ var asanaOnboarding = new ConnectorOnboarding({
|
|
|
376
448
|
}
|
|
377
449
|
});
|
|
378
450
|
|
|
451
|
+
// ../connectors/src/connectors/asana/utils.ts
|
|
452
|
+
var BASE_URL2 = "https://app.asana.com/api/1.0";
|
|
453
|
+
async function apiFetch(params, path2, init) {
|
|
454
|
+
const token = params[parameters.personalAccessToken.slug];
|
|
455
|
+
if (!token) {
|
|
456
|
+
throw new Error("asana: missing required parameter: personal-access-token");
|
|
457
|
+
}
|
|
458
|
+
const url = `${BASE_URL2}${path2.startsWith("/") ? "" : "/"}${path2}`;
|
|
459
|
+
const headers = new Headers(init?.headers);
|
|
460
|
+
headers.set("Authorization", `Bearer ${token}`);
|
|
461
|
+
if (!headers.has("Accept")) headers.set("Accept", "application/json");
|
|
462
|
+
return fetch(url, { ...init, headers });
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// ../connectors/src/connectors/asana/setup-flow.ts
|
|
466
|
+
var ALL_PROJECTS = "__ALL_PROJECTS__";
|
|
467
|
+
var ASANA_SETUP_MAX_PROJECTS = 20;
|
|
468
|
+
async function listWorkspaces(params) {
|
|
469
|
+
const res = await apiFetch(params, "/workspaces?limit=100");
|
|
470
|
+
if (!res.ok) {
|
|
471
|
+
const body = await res.text().catch(() => res.statusText);
|
|
472
|
+
throw new Error(`asana: listWorkspaces failed (${res.status}): ${body}`);
|
|
473
|
+
}
|
|
474
|
+
const data = await res.json();
|
|
475
|
+
return data.data ?? [];
|
|
476
|
+
}
|
|
477
|
+
async function listProjects(params, workspaceGid) {
|
|
478
|
+
const all = [];
|
|
479
|
+
const fields = encodeURIComponent("name,team.name,current_status");
|
|
480
|
+
let offset;
|
|
481
|
+
while (all.length < 500) {
|
|
482
|
+
const query = `workspace=${encodeURIComponent(workspaceGid)}&limit=100&opt_fields=${fields}${offset ? `&offset=${encodeURIComponent(offset)}` : ""}`;
|
|
483
|
+
const res = await apiFetch(params, `/projects?${query}`);
|
|
484
|
+
if (!res.ok) {
|
|
485
|
+
const body = await res.text().catch(() => res.statusText);
|
|
486
|
+
throw new Error(`asana: listProjects failed (${res.status}): ${body}`);
|
|
487
|
+
}
|
|
488
|
+
const data = await res.json();
|
|
489
|
+
const batch = data.data ?? [];
|
|
490
|
+
all.push(...batch);
|
|
491
|
+
const next = data.next_page?.offset;
|
|
492
|
+
if (!next || batch.length === 0) break;
|
|
493
|
+
offset = next;
|
|
494
|
+
}
|
|
495
|
+
return all;
|
|
496
|
+
}
|
|
497
|
+
var asanaSetupFlow = {
|
|
498
|
+
initialState: () => ({}),
|
|
499
|
+
steps: [
|
|
500
|
+
{
|
|
501
|
+
slug: "workspace",
|
|
502
|
+
type: "select",
|
|
503
|
+
question: {
|
|
504
|
+
ja: "\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u306B\u4F7F\u3046\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044",
|
|
505
|
+
en: "Select the workspace to use for setup"
|
|
506
|
+
},
|
|
507
|
+
async fetchOptions(_state, rt) {
|
|
508
|
+
const workspaces = await listWorkspaces(rt.params);
|
|
509
|
+
return workspaces.filter((w) => w.gid && w.name).map((w) => ({ value: w.gid, label: w.name }));
|
|
510
|
+
},
|
|
511
|
+
applyAnswer: (state, answer) => ({ ...state, workspace: answer[0] })
|
|
512
|
+
},
|
|
513
|
+
{
|
|
514
|
+
slug: "projects",
|
|
515
|
+
type: "multiSelect",
|
|
516
|
+
question: {
|
|
517
|
+
ja: "\u5BFE\u8C61\u306E\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
|
|
518
|
+
en: "Select target projects (multi-select allowed)"
|
|
519
|
+
},
|
|
520
|
+
async fetchOptions(state, rt) {
|
|
521
|
+
if (!state.workspace) return [];
|
|
522
|
+
const projects = await listProjects(rt.params, state.workspace);
|
|
523
|
+
const projectOptions = projects.filter((p) => p.gid && p.name).map((p) => ({ value: p.gid, label: p.name }));
|
|
524
|
+
return [
|
|
525
|
+
{
|
|
526
|
+
value: ALL_PROJECTS,
|
|
527
|
+
label: rt.language === "ja" ? "\u3059\u3079\u3066\u306E\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8" : "All projects"
|
|
528
|
+
},
|
|
529
|
+
...projectOptions
|
|
530
|
+
];
|
|
531
|
+
},
|
|
532
|
+
applyAnswer: (state, answer) => ({ ...state, projects: answer })
|
|
533
|
+
}
|
|
534
|
+
],
|
|
535
|
+
async finalize(state, rt) {
|
|
536
|
+
if (!state.workspace || !state.projects) {
|
|
537
|
+
throw new Error("Asana setup: incomplete state on finalize");
|
|
538
|
+
}
|
|
539
|
+
const workspaceGid = state.workspace;
|
|
540
|
+
const projects = await listProjects(rt.params, workspaceGid);
|
|
541
|
+
const projectByGid = new Map(projects.map((p) => [p.gid, p]));
|
|
542
|
+
const targetGids = await resolveSetupSelection({
|
|
543
|
+
selected: state.projects,
|
|
544
|
+
allSentinel: ALL_PROJECTS,
|
|
545
|
+
fetchAll: async () => projects.map((p) => p.gid).filter((g) => g),
|
|
546
|
+
limit: ASANA_SETUP_MAX_PROJECTS
|
|
547
|
+
});
|
|
548
|
+
const sections = [
|
|
549
|
+
"## Asana",
|
|
550
|
+
"",
|
|
551
|
+
`### Workspace: ${workspaceGid}`,
|
|
552
|
+
""
|
|
553
|
+
];
|
|
554
|
+
for (const gid of targetGids) {
|
|
555
|
+
const project = projectByGid.get(gid);
|
|
556
|
+
if (!project) {
|
|
557
|
+
sections.push(`#### Project: ${gid}`, "", "_Not found._", "");
|
|
558
|
+
continue;
|
|
559
|
+
}
|
|
560
|
+
sections.push(`#### Project: ${project.name}`, "");
|
|
561
|
+
const team = project.team?.name ?? "-";
|
|
562
|
+
const status = project.current_status?.title ?? project.current_status?.text ?? "-";
|
|
563
|
+
sections.push(`- Team: ${team}`);
|
|
564
|
+
sections.push(`- Current status: ${status}`);
|
|
565
|
+
sections.push("");
|
|
566
|
+
}
|
|
567
|
+
return sections.join("\n");
|
|
568
|
+
}
|
|
569
|
+
};
|
|
570
|
+
|
|
379
571
|
// ../connectors/src/connectors/asana/tools/request.ts
|
|
380
572
|
import { z } from "zod";
|
|
381
573
|
var BASE_HOST = "https://app.asana.com";
|
|
382
574
|
var BASE_PATH_SEGMENT = "/api/1.0";
|
|
383
|
-
var
|
|
575
|
+
var BASE_URL3 = `${BASE_HOST}${BASE_PATH_SEGMENT}`;
|
|
384
576
|
var REQUEST_TIMEOUT_MS = 6e4;
|
|
385
577
|
var inputSchema = z.object({
|
|
386
578
|
toolUseIntent: z.string().optional().describe(
|
|
@@ -445,7 +637,7 @@ Pagination: Use limit (1-100) and offset query parameters. The response includes
|
|
|
445
637
|
try {
|
|
446
638
|
const token = parameters.personalAccessToken.getValue(connection2);
|
|
447
639
|
const normalizedPath = normalizeRequestPath(path2, BASE_PATH_SEGMENT);
|
|
448
|
-
const url = `${
|
|
640
|
+
const url = `${BASE_URL3}${normalizedPath}`;
|
|
449
641
|
const controller = new AbortController();
|
|
450
642
|
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
451
643
|
try {
|
|
@@ -664,7 +856,39 @@ export default async function handler(c: Context) {
|
|
|
664
856
|
- \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8: name, archived, created_at, modified_at, owner, owner.name, team, team.name, members
|
|
665
857
|
- \u30E6\u30FC\u30B6\u30FC: name, email, photo`
|
|
666
858
|
},
|
|
667
|
-
tools
|
|
859
|
+
tools,
|
|
860
|
+
setup: (params, ctx, config) => runSetupFlow(asanaSetupFlow, params, ctx, config),
|
|
861
|
+
async checkConnection(params, _config) {
|
|
862
|
+
try {
|
|
863
|
+
const pat = params[parameters.personalAccessToken.slug];
|
|
864
|
+
if (!pat) {
|
|
865
|
+
return {
|
|
866
|
+
success: false,
|
|
867
|
+
error: "Missing required parameter: personal-access-token"
|
|
868
|
+
};
|
|
869
|
+
}
|
|
870
|
+
const res = await fetch("https://app.asana.com/api/1.0/users/me", {
|
|
871
|
+
method: "GET",
|
|
872
|
+
headers: {
|
|
873
|
+
Authorization: `Bearer ${pat}`,
|
|
874
|
+
Accept: "application/json"
|
|
875
|
+
}
|
|
876
|
+
});
|
|
877
|
+
if (!res.ok) {
|
|
878
|
+
const errorText = await res.text().catch(() => res.statusText);
|
|
879
|
+
return {
|
|
880
|
+
success: false,
|
|
881
|
+
error: `Asana API failed: HTTP ${res.status} ${errorText}`
|
|
882
|
+
};
|
|
883
|
+
}
|
|
884
|
+
return { success: true };
|
|
885
|
+
} catch (error) {
|
|
886
|
+
return {
|
|
887
|
+
success: false,
|
|
888
|
+
error: error instanceof Error ? error.message : String(error)
|
|
889
|
+
};
|
|
890
|
+
}
|
|
891
|
+
}
|
|
668
892
|
});
|
|
669
893
|
|
|
670
894
|
// src/connectors/create-connector-sdk.ts
|
|
@@ -693,6 +917,7 @@ function resolveEnvVarOptional(entry, key) {
|
|
|
693
917
|
import { getContext } from "hono/context-storage";
|
|
694
918
|
import { getCookie } from "hono/cookie";
|
|
695
919
|
var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
|
|
920
|
+
var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
|
|
696
921
|
function normalizeHeaders(input) {
|
|
697
922
|
const out = {};
|
|
698
923
|
if (!input) return out;
|
|
@@ -701,6 +926,11 @@ function normalizeHeaders(input) {
|
|
|
701
926
|
});
|
|
702
927
|
return out;
|
|
703
928
|
}
|
|
929
|
+
function extractInputUrl(input) {
|
|
930
|
+
if (typeof input === "string") return input;
|
|
931
|
+
if (input instanceof URL) return input.href;
|
|
932
|
+
return input.url;
|
|
933
|
+
}
|
|
704
934
|
function createSandboxProxyFetch(connectionId) {
|
|
705
935
|
return async (input, init) => {
|
|
706
936
|
const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
|
|
@@ -710,10 +940,17 @@ function createSandboxProxyFetch(connectionId) {
|
|
|
710
940
|
"Connection proxy is not configured. Please check your deployment settings."
|
|
711
941
|
);
|
|
712
942
|
}
|
|
713
|
-
const originalUrl =
|
|
943
|
+
const originalUrl = extractInputUrl(input);
|
|
944
|
+
const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
|
|
945
|
+
if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
|
|
946
|
+
const sessionUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
|
|
947
|
+
return fetch(sessionUrl, {
|
|
948
|
+
method: "POST",
|
|
949
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
950
|
+
});
|
|
951
|
+
}
|
|
714
952
|
const originalMethod = init?.method ?? "GET";
|
|
715
953
|
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
716
|
-
const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
|
|
717
954
|
const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
718
955
|
return fetch(proxyUrl, {
|
|
719
956
|
method: "POST",
|
|
@@ -739,10 +976,9 @@ function createDeployedAppProxyFetch(connectionId) {
|
|
|
739
976
|
}
|
|
740
977
|
const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
|
|
741
978
|
const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
979
|
+
const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
|
|
742
980
|
return async (input, init) => {
|
|
743
|
-
const originalUrl =
|
|
744
|
-
const originalMethod = init?.method ?? "GET";
|
|
745
|
-
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
981
|
+
const originalUrl = extractInputUrl(input);
|
|
746
982
|
const c = getContext();
|
|
747
983
|
const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
|
|
748
984
|
if (!appSession) {
|
|
@@ -750,6 +986,14 @@ function createDeployedAppProxyFetch(connectionId) {
|
|
|
750
986
|
"No authentication method available for connection proxy."
|
|
751
987
|
);
|
|
752
988
|
}
|
|
989
|
+
if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
|
|
990
|
+
return fetch(sessionUrl, {
|
|
991
|
+
method: "POST",
|
|
992
|
+
headers: { Authorization: `Bearer ${appSession}` }
|
|
993
|
+
});
|
|
994
|
+
}
|
|
995
|
+
const originalMethod = init?.method ?? "GET";
|
|
996
|
+
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
753
997
|
return fetch(proxyUrl, {
|
|
754
998
|
method: "POST",
|
|
755
999
|
headers: {
|