@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/shopify/parameters.ts
|
|
57
|
+
init_parameter_definition();
|
|
46
58
|
var parameters = {
|
|
47
59
|
storeDomain: new ParameterDefinition({
|
|
48
60
|
slug: "store-domain",
|
|
@@ -348,6 +360,20 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
348
360
|
* `runSetupFlow` from `setup-flow.ts`.
|
|
349
361
|
*/
|
|
350
362
|
setup;
|
|
363
|
+
/**
|
|
364
|
+
* Opt-out of the default "verify before save" behavior on connection
|
|
365
|
+
* creation. The backend invokes `checkConnection` synchronously while
|
|
366
|
+
* creating the connection and aborts (no row inserted) if it fails — this
|
|
367
|
+
* flag disables that for connectors where the check cannot succeed pre-save:
|
|
368
|
+
*
|
|
369
|
+
* - `squadbase-db` populates `connection-url` only after Neon provisioning
|
|
370
|
+
* - OAuth connectors require an OAuth-aware proxyFetch keyed by the
|
|
371
|
+
* connectionId, which doesn't exist until the row is saved
|
|
372
|
+
*
|
|
373
|
+
* Exceptions are the explicit position; new credential-input connectors get
|
|
374
|
+
* the default verify-on-create behavior without opt-in.
|
|
375
|
+
*/
|
|
376
|
+
skipConnectionCheckOnCreate;
|
|
351
377
|
constructor(config) {
|
|
352
378
|
this.slug = config.slug;
|
|
353
379
|
this.authType = config.authType;
|
|
@@ -365,6 +391,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
365
391
|
this.query = config.query;
|
|
366
392
|
this.checkConnection = config.checkConnection;
|
|
367
393
|
this.setup = config.setup;
|
|
394
|
+
this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
|
|
368
395
|
}
|
|
369
396
|
get connectorKey() {
|
|
370
397
|
return _ConnectorPlugin.deriveKey(this.slug, this.authType);
|
|
@@ -429,6 +456,46 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
429
456
|
}
|
|
430
457
|
};
|
|
431
458
|
|
|
459
|
+
// ../connectors/src/setup-flow.ts
|
|
460
|
+
async function runSetupFlow(flow, params, ctx, config) {
|
|
461
|
+
const runtime = {
|
|
462
|
+
params,
|
|
463
|
+
language: ctx.language,
|
|
464
|
+
config
|
|
465
|
+
};
|
|
466
|
+
let state = flow.initialState();
|
|
467
|
+
let answerIdx = 0;
|
|
468
|
+
for (const step of flow.steps) {
|
|
469
|
+
const ans = ctx.answers[answerIdx];
|
|
470
|
+
if (ans && ans.questionSlug === step.slug) {
|
|
471
|
+
state = step.applyAnswer(state, ans.answer);
|
|
472
|
+
answerIdx += 1;
|
|
473
|
+
continue;
|
|
474
|
+
}
|
|
475
|
+
if (step.type === "text") {
|
|
476
|
+
return {
|
|
477
|
+
type: "nextQuestion",
|
|
478
|
+
questionSlug: step.slug,
|
|
479
|
+
question: step.question[ctx.language],
|
|
480
|
+
questionType: "text"
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
|
|
484
|
+
if (options.length === 0) {
|
|
485
|
+
continue;
|
|
486
|
+
}
|
|
487
|
+
return {
|
|
488
|
+
type: "nextQuestion",
|
|
489
|
+
questionSlug: step.slug,
|
|
490
|
+
question: step.question[ctx.language],
|
|
491
|
+
questionType: step.type,
|
|
492
|
+
options
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
const dataInvestigationResult = await flow.finalize(state, runtime);
|
|
496
|
+
return { type: "fulfilled", dataInvestigationResult };
|
|
497
|
+
}
|
|
498
|
+
|
|
432
499
|
// ../connectors/src/auth-types.ts
|
|
433
500
|
var AUTH_TYPES = {
|
|
434
501
|
OAUTH: "oauth",
|
|
@@ -451,6 +518,133 @@ var shopifyOnboarding = new ConnectorOnboarding({
|
|
|
451
518
|
}
|
|
452
519
|
});
|
|
453
520
|
|
|
521
|
+
// ../connectors/src/connectors/shopify/utils.ts
|
|
522
|
+
var SHOPIFY_API_VERSION = "2024-10";
|
|
523
|
+
function getStoreBaseUrl(params) {
|
|
524
|
+
const storeDomain = params[parameters.storeDomain.slug];
|
|
525
|
+
if (!storeDomain) {
|
|
526
|
+
throw new Error("shopify: missing required parameter: store-domain");
|
|
527
|
+
}
|
|
528
|
+
const host = storeDomain.includes(".") ? storeDomain : `${storeDomain}.myshopify.com`;
|
|
529
|
+
return `https://${host}`;
|
|
530
|
+
}
|
|
531
|
+
async function getAccessToken(params) {
|
|
532
|
+
const clientId = params[parameters.clientId.slug];
|
|
533
|
+
const clientSecret = params[parameters.clientSecret.slug];
|
|
534
|
+
if (!clientId || !clientSecret) {
|
|
535
|
+
throw new Error(
|
|
536
|
+
"shopify: missing required parameters: client-id and client-secret"
|
|
537
|
+
);
|
|
538
|
+
}
|
|
539
|
+
const base = getStoreBaseUrl(params);
|
|
540
|
+
const res = await fetch(`${base}/admin/oauth/access_token`, {
|
|
541
|
+
method: "POST",
|
|
542
|
+
headers: { "Content-Type": "application/json" },
|
|
543
|
+
body: JSON.stringify({
|
|
544
|
+
grant_type: "client_credentials",
|
|
545
|
+
client_id: clientId,
|
|
546
|
+
client_secret: clientSecret
|
|
547
|
+
})
|
|
548
|
+
});
|
|
549
|
+
if (!res.ok) {
|
|
550
|
+
const body = await res.text().catch(() => res.statusText);
|
|
551
|
+
throw new Error(
|
|
552
|
+
`shopify: failed to obtain access token (${res.status}): ${body}`
|
|
553
|
+
);
|
|
554
|
+
}
|
|
555
|
+
const data = await res.json();
|
|
556
|
+
if (!data.access_token) {
|
|
557
|
+
throw new Error("shopify: access_token missing in token response");
|
|
558
|
+
}
|
|
559
|
+
return data.access_token;
|
|
560
|
+
}
|
|
561
|
+
async function apiFetch(params, path2, init) {
|
|
562
|
+
const token = await getAccessToken(params);
|
|
563
|
+
const url = `${getStoreBaseUrl(params)}${path2.startsWith("/") ? "" : "/"}${path2}`;
|
|
564
|
+
const headers = new Headers(init?.headers);
|
|
565
|
+
headers.set("X-Shopify-Access-Token", token);
|
|
566
|
+
if (!headers.has("Content-Type")) {
|
|
567
|
+
headers.set("Content-Type", "application/json");
|
|
568
|
+
}
|
|
569
|
+
return fetch(url, { ...init, headers });
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
// ../connectors/src/connectors/shopify/setup-flow.ts
|
|
573
|
+
var SHOPIFY_SETUP_MAX_ENTITIES = 10;
|
|
574
|
+
var ENTITY_LABELS = {
|
|
575
|
+
products: { en: "Products", ja: "Products (\u5546\u54C1)" },
|
|
576
|
+
orders: { en: "Orders", ja: "Orders (\u6CE8\u6587)" },
|
|
577
|
+
customers: { en: "Customers", ja: "Customers (\u9867\u5BA2)" },
|
|
578
|
+
collections: { en: "Collections", ja: "Collections (\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3)" },
|
|
579
|
+
inventory: { en: "Inventory items", ja: "Inventory items (\u5728\u5EAB)" },
|
|
580
|
+
discounts: { en: "Discounts", ja: "Discounts (\u5272\u5F15)" }
|
|
581
|
+
};
|
|
582
|
+
var ENTITY_VALUES = [
|
|
583
|
+
"products",
|
|
584
|
+
"orders",
|
|
585
|
+
"customers",
|
|
586
|
+
"collections",
|
|
587
|
+
"inventory",
|
|
588
|
+
"discounts"
|
|
589
|
+
];
|
|
590
|
+
var COUNT_PATHS = {
|
|
591
|
+
products: `/admin/api/${SHOPIFY_API_VERSION}/products/count.json`,
|
|
592
|
+
orders: `/admin/api/${SHOPIFY_API_VERSION}/orders/count.json?status=any`,
|
|
593
|
+
customers: `/admin/api/${SHOPIFY_API_VERSION}/customers/count.json`,
|
|
594
|
+
collections: `/admin/api/${SHOPIFY_API_VERSION}/custom_collections/count.json`,
|
|
595
|
+
inventory: null,
|
|
596
|
+
discounts: `/admin/api/${SHOPIFY_API_VERSION}/price_rules/count.json`
|
|
597
|
+
};
|
|
598
|
+
async function defaultFetchCount(params, path2) {
|
|
599
|
+
return apiFetch(params, path2);
|
|
600
|
+
}
|
|
601
|
+
function createShopifySetupFlow(fetchCount = defaultFetchCount, labelPrefix = "Shopify") {
|
|
602
|
+
return {
|
|
603
|
+
initialState: () => ({}),
|
|
604
|
+
steps: [
|
|
605
|
+
{
|
|
606
|
+
slug: "entities",
|
|
607
|
+
type: "multiSelect",
|
|
608
|
+
question: {
|
|
609
|
+
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",
|
|
610
|
+
en: "Select target entities (multi-select allowed)"
|
|
611
|
+
},
|
|
612
|
+
async fetchOptions(_state, rt) {
|
|
613
|
+
return ENTITY_VALUES.map((value) => ({
|
|
614
|
+
value,
|
|
615
|
+
label: ENTITY_LABELS[value][rt.language]
|
|
616
|
+
}));
|
|
617
|
+
},
|
|
618
|
+
applyAnswer: (state, answer) => ({ ...state, entities: answer })
|
|
619
|
+
}
|
|
620
|
+
],
|
|
621
|
+
async finalize(state, rt) {
|
|
622
|
+
if (!state.entities) {
|
|
623
|
+
throw new Error("Shopify setup: incomplete state on finalize");
|
|
624
|
+
}
|
|
625
|
+
const selected = state.entities.filter(
|
|
626
|
+
(e) => ENTITY_VALUES.includes(e)
|
|
627
|
+
).slice(0, SHOPIFY_SETUP_MAX_ENTITIES);
|
|
628
|
+
const sections = [`## ${labelPrefix}`, ""];
|
|
629
|
+
for (const entity of selected) {
|
|
630
|
+
const path2 = COUNT_PATHS[entity];
|
|
631
|
+
let count = "available";
|
|
632
|
+
if (path2) {
|
|
633
|
+
const res = await fetchCount(rt.params, path2);
|
|
634
|
+
if (res.ok) {
|
|
635
|
+
const data = await res.json();
|
|
636
|
+
if (typeof data.count === "number") count = String(data.count);
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
sections.push(`### ${ENTITY_LABELS[entity].en}`, "");
|
|
640
|
+
sections.push(`Count: ${count}`, "");
|
|
641
|
+
}
|
|
642
|
+
return sections.join("\n");
|
|
643
|
+
}
|
|
644
|
+
};
|
|
645
|
+
}
|
|
646
|
+
var shopifySetupFlow = createShopifySetupFlow();
|
|
647
|
+
|
|
454
648
|
// ../connectors/src/connectors/shopify/tools/request.ts
|
|
455
649
|
import { z } from "zod";
|
|
456
650
|
var REQUEST_TIMEOUT_MS = 6e4;
|
|
@@ -714,7 +908,69 @@ export default async function handler(c: Context) {
|
|
|
714
908
|
- \`updated_at_min\`, \`updated_at_max\` \u2014 \u66F4\u65B0\u65E5\u30D5\u30A3\u30EB\u30BF\u30FC\uFF08ISO 8601\uFF09
|
|
715
909
|
- \`status\` \u2014 \u30B9\u30C6\u30FC\u30BF\u30B9\u3067\u30D5\u30A3\u30EB\u30BF\u30FC\uFF08\u4F8B: \u5546\u54C1\u306E\u5834\u5408 active, draft, archived\u3001\u6CE8\u6587\u306E\u5834\u5408 open, closed, cancelled, any\uFF09`
|
|
716
910
|
},
|
|
717
|
-
tools
|
|
911
|
+
tools,
|
|
912
|
+
setup: (params, ctx, config) => runSetupFlow(shopifySetupFlow, params, ctx, config),
|
|
913
|
+
async checkConnection(params, _config) {
|
|
914
|
+
const storeDomain = params[parameters.storeDomain.slug];
|
|
915
|
+
const clientId = params[parameters.clientId.slug];
|
|
916
|
+
const clientSecret = params[parameters.clientSecret.slug];
|
|
917
|
+
if (!storeDomain || !clientId || !clientSecret) {
|
|
918
|
+
return {
|
|
919
|
+
success: false,
|
|
920
|
+
error: "Missing required parameters: store-domain, client-id, and client-secret"
|
|
921
|
+
};
|
|
922
|
+
}
|
|
923
|
+
const host = storeDomain.includes(".") ? storeDomain : `${storeDomain}.myshopify.com`;
|
|
924
|
+
const base = `https://${host}`;
|
|
925
|
+
try {
|
|
926
|
+
const tokenRes = await fetch(`${base}/admin/oauth/access_token`, {
|
|
927
|
+
method: "POST",
|
|
928
|
+
headers: { "Content-Type": "application/json" },
|
|
929
|
+
body: JSON.stringify({
|
|
930
|
+
grant_type: "client_credentials",
|
|
931
|
+
client_id: clientId,
|
|
932
|
+
client_secret: clientSecret
|
|
933
|
+
})
|
|
934
|
+
});
|
|
935
|
+
if (!tokenRes.ok) {
|
|
936
|
+
const errorText = await tokenRes.text().catch(() => tokenRes.statusText);
|
|
937
|
+
return {
|
|
938
|
+
success: false,
|
|
939
|
+
error: `Shopify token request failed: HTTP ${tokenRes.status} ${errorText}`
|
|
940
|
+
};
|
|
941
|
+
}
|
|
942
|
+
const tokenData = await tokenRes.json();
|
|
943
|
+
if (!tokenData.access_token) {
|
|
944
|
+
return {
|
|
945
|
+
success: false,
|
|
946
|
+
error: "Shopify token response missing access_token"
|
|
947
|
+
};
|
|
948
|
+
}
|
|
949
|
+
const shopRes = await fetch(
|
|
950
|
+
`${base}/admin/api/${SHOPIFY_API_VERSION}/shop.json`,
|
|
951
|
+
{
|
|
952
|
+
method: "GET",
|
|
953
|
+
headers: {
|
|
954
|
+
"X-Shopify-Access-Token": tokenData.access_token,
|
|
955
|
+
Accept: "application/json"
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
);
|
|
959
|
+
if (!shopRes.ok) {
|
|
960
|
+
const errorText = await shopRes.text().catch(() => shopRes.statusText);
|
|
961
|
+
return {
|
|
962
|
+
success: false,
|
|
963
|
+
error: `Shopify API failed: HTTP ${shopRes.status} ${errorText}`
|
|
964
|
+
};
|
|
965
|
+
}
|
|
966
|
+
return { success: true };
|
|
967
|
+
} catch (error) {
|
|
968
|
+
return {
|
|
969
|
+
success: false,
|
|
970
|
+
error: error instanceof Error ? error.message : String(error)
|
|
971
|
+
};
|
|
972
|
+
}
|
|
973
|
+
}
|
|
718
974
|
});
|
|
719
975
|
|
|
720
976
|
// src/connectors/create-connector-sdk.ts
|
|
@@ -743,6 +999,7 @@ function resolveEnvVarOptional(entry, key) {
|
|
|
743
999
|
import { getContext } from "hono/context-storage";
|
|
744
1000
|
import { getCookie } from "hono/cookie";
|
|
745
1001
|
var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
|
|
1002
|
+
var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
|
|
746
1003
|
function normalizeHeaders(input) {
|
|
747
1004
|
const out = {};
|
|
748
1005
|
if (!input) return out;
|
|
@@ -751,6 +1008,11 @@ function normalizeHeaders(input) {
|
|
|
751
1008
|
});
|
|
752
1009
|
return out;
|
|
753
1010
|
}
|
|
1011
|
+
function extractInputUrl(input) {
|
|
1012
|
+
if (typeof input === "string") return input;
|
|
1013
|
+
if (input instanceof URL) return input.href;
|
|
1014
|
+
return input.url;
|
|
1015
|
+
}
|
|
754
1016
|
function createSandboxProxyFetch(connectionId) {
|
|
755
1017
|
return async (input, init) => {
|
|
756
1018
|
const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
|
|
@@ -760,10 +1022,17 @@ function createSandboxProxyFetch(connectionId) {
|
|
|
760
1022
|
"Connection proxy is not configured. Please check your deployment settings."
|
|
761
1023
|
);
|
|
762
1024
|
}
|
|
763
|
-
const originalUrl =
|
|
1025
|
+
const originalUrl = extractInputUrl(input);
|
|
1026
|
+
const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
|
|
1027
|
+
if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
|
|
1028
|
+
const sessionUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
|
|
1029
|
+
return fetch(sessionUrl, {
|
|
1030
|
+
method: "POST",
|
|
1031
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
1032
|
+
});
|
|
1033
|
+
}
|
|
764
1034
|
const originalMethod = init?.method ?? "GET";
|
|
765
1035
|
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
766
|
-
const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
|
|
767
1036
|
const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
768
1037
|
return fetch(proxyUrl, {
|
|
769
1038
|
method: "POST",
|
|
@@ -789,10 +1058,9 @@ function createDeployedAppProxyFetch(connectionId) {
|
|
|
789
1058
|
}
|
|
790
1059
|
const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
|
|
791
1060
|
const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
1061
|
+
const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
|
|
792
1062
|
return async (input, init) => {
|
|
793
|
-
const originalUrl =
|
|
794
|
-
const originalMethod = init?.method ?? "GET";
|
|
795
|
-
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
1063
|
+
const originalUrl = extractInputUrl(input);
|
|
796
1064
|
const c = getContext();
|
|
797
1065
|
const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
|
|
798
1066
|
if (!appSession) {
|
|
@@ -800,6 +1068,14 @@ function createDeployedAppProxyFetch(connectionId) {
|
|
|
800
1068
|
"No authentication method available for connection proxy."
|
|
801
1069
|
);
|
|
802
1070
|
}
|
|
1071
|
+
if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
|
|
1072
|
+
return fetch(sessionUrl, {
|
|
1073
|
+
method: "POST",
|
|
1074
|
+
headers: { Authorization: `Bearer ${appSession}` }
|
|
1075
|
+
});
|
|
1076
|
+
}
|
|
1077
|
+
const originalMethod = init?.method ?? "GET";
|
|
1078
|
+
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
803
1079
|
return fetch(proxyUrl, {
|
|
804
1080
|
method: "POST",
|
|
805
1081
|
headers: {
|