@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/github/parameters.ts
|
|
57
|
+
init_parameter_definition();
|
|
46
58
|
var parameters = {
|
|
47
59
|
personalAccessToken: new ParameterDefinition({
|
|
48
60
|
slug: "personal-access-token",
|
|
@@ -351,6 +363,20 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
351
363
|
* `runSetupFlow` from `setup-flow.ts`.
|
|
352
364
|
*/
|
|
353
365
|
setup;
|
|
366
|
+
/**
|
|
367
|
+
* Opt-out of the default "verify before save" behavior on connection
|
|
368
|
+
* creation. The backend invokes `checkConnection` synchronously while
|
|
369
|
+
* creating the connection and aborts (no row inserted) if it fails — this
|
|
370
|
+
* flag disables that for connectors where the check cannot succeed pre-save:
|
|
371
|
+
*
|
|
372
|
+
* - `squadbase-db` populates `connection-url` only after Neon provisioning
|
|
373
|
+
* - OAuth connectors require an OAuth-aware proxyFetch keyed by the
|
|
374
|
+
* connectionId, which doesn't exist until the row is saved
|
|
375
|
+
*
|
|
376
|
+
* Exceptions are the explicit position; new credential-input connectors get
|
|
377
|
+
* the default verify-on-create behavior without opt-in.
|
|
378
|
+
*/
|
|
379
|
+
skipConnectionCheckOnCreate;
|
|
354
380
|
constructor(config) {
|
|
355
381
|
this.slug = config.slug;
|
|
356
382
|
this.authType = config.authType;
|
|
@@ -368,6 +394,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
368
394
|
this.query = config.query;
|
|
369
395
|
this.checkConnection = config.checkConnection;
|
|
370
396
|
this.setup = config.setup;
|
|
397
|
+
this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
|
|
371
398
|
}
|
|
372
399
|
get connectorKey() {
|
|
373
400
|
return _ConnectorPlugin.deriveKey(this.slug, this.authType);
|
|
@@ -432,6 +459,51 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
432
459
|
}
|
|
433
460
|
};
|
|
434
461
|
|
|
462
|
+
// ../connectors/src/setup-flow.ts
|
|
463
|
+
async function runSetupFlow(flow, params, ctx, config) {
|
|
464
|
+
const runtime = {
|
|
465
|
+
params,
|
|
466
|
+
language: ctx.language,
|
|
467
|
+
config
|
|
468
|
+
};
|
|
469
|
+
let state = flow.initialState();
|
|
470
|
+
let answerIdx = 0;
|
|
471
|
+
for (const step of flow.steps) {
|
|
472
|
+
const ans = ctx.answers[answerIdx];
|
|
473
|
+
if (ans && ans.questionSlug === step.slug) {
|
|
474
|
+
state = step.applyAnswer(state, ans.answer);
|
|
475
|
+
answerIdx += 1;
|
|
476
|
+
continue;
|
|
477
|
+
}
|
|
478
|
+
if (step.type === "text") {
|
|
479
|
+
return {
|
|
480
|
+
type: "nextQuestion",
|
|
481
|
+
questionSlug: step.slug,
|
|
482
|
+
question: step.question[ctx.language],
|
|
483
|
+
questionType: "text"
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
|
|
487
|
+
if (options.length === 0) {
|
|
488
|
+
continue;
|
|
489
|
+
}
|
|
490
|
+
return {
|
|
491
|
+
type: "nextQuestion",
|
|
492
|
+
questionSlug: step.slug,
|
|
493
|
+
question: step.question[ctx.language],
|
|
494
|
+
questionType: step.type,
|
|
495
|
+
options
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
const dataInvestigationResult = await flow.finalize(state, runtime);
|
|
499
|
+
return { type: "fulfilled", dataInvestigationResult };
|
|
500
|
+
}
|
|
501
|
+
async function resolveSetupSelection(params) {
|
|
502
|
+
const { selected, allSentinel, fetchAll, limit } = params;
|
|
503
|
+
const resolved = selected.includes(allSentinel) ? await fetchAll() : selected.filter((v) => v !== allSentinel);
|
|
504
|
+
return resolved.slice(0, limit);
|
|
505
|
+
}
|
|
506
|
+
|
|
435
507
|
// ../connectors/src/auth-types.ts
|
|
436
508
|
var AUTH_TYPES = {
|
|
437
509
|
OAUTH: "oauth",
|
|
@@ -464,10 +536,185 @@ var githubOnboarding = new ConnectorOnboarding({
|
|
|
464
536
|
}
|
|
465
537
|
});
|
|
466
538
|
|
|
539
|
+
// ../connectors/src/connectors/github/utils.ts
|
|
540
|
+
function resolveBaseUrl(connectionBaseUrl) {
|
|
541
|
+
const trimmed = connectionBaseUrl?.trim();
|
|
542
|
+
return trimmed && trimmed.replace(/\/+$/, "") || DEFAULT_BASE_URL;
|
|
543
|
+
}
|
|
544
|
+
async function apiFetch(params, path2, init) {
|
|
545
|
+
const token = params[parameters.personalAccessToken.slug];
|
|
546
|
+
if (!token) {
|
|
547
|
+
throw new Error(
|
|
548
|
+
"github: missing required parameter: personal-access-token"
|
|
549
|
+
);
|
|
550
|
+
}
|
|
551
|
+
const baseUrl = resolveBaseUrl(params[parameters.baseUrl.slug]);
|
|
552
|
+
const trimmedPath = path2.replace(/^\/+/, "/");
|
|
553
|
+
const url = `${baseUrl}${trimmedPath.startsWith("/") ? "" : "/"}${trimmedPath}`;
|
|
554
|
+
const headers = new Headers(init?.headers);
|
|
555
|
+
headers.set("Authorization", `Bearer ${token}`);
|
|
556
|
+
if (!headers.has("Accept")) {
|
|
557
|
+
headers.set("Accept", "application/vnd.github+json");
|
|
558
|
+
}
|
|
559
|
+
if (!headers.has("X-GitHub-Api-Version")) {
|
|
560
|
+
headers.set("X-GitHub-Api-Version", "2022-11-28");
|
|
561
|
+
}
|
|
562
|
+
if (!headers.has("User-Agent")) {
|
|
563
|
+
headers.set("User-Agent", "squadbase-connectors-github");
|
|
564
|
+
}
|
|
565
|
+
return fetch(url, { ...init, headers });
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
// ../connectors/src/connectors/github/setup-flow.ts
|
|
569
|
+
var ALL_REPOS = "__ALL_REPOS__";
|
|
570
|
+
var GITHUB_SETUP_MAX_REPOS = 20;
|
|
571
|
+
var USER_OWNER = "__USER__";
|
|
572
|
+
async function getAuthenticatedUser(params) {
|
|
573
|
+
const res = await apiFetch(params, "/user");
|
|
574
|
+
if (!res.ok) return null;
|
|
575
|
+
return await res.json();
|
|
576
|
+
}
|
|
577
|
+
async function listOrgs(params) {
|
|
578
|
+
const res = await apiFetch(params, "/user/orgs?per_page=100");
|
|
579
|
+
if (!res.ok) {
|
|
580
|
+
const body = await res.text().catch(() => res.statusText);
|
|
581
|
+
throw new Error(`github: listOrgs failed (${res.status}): ${body}`);
|
|
582
|
+
}
|
|
583
|
+
return await res.json();
|
|
584
|
+
}
|
|
585
|
+
async function listReposPaged(params, pathBase) {
|
|
586
|
+
const all = [];
|
|
587
|
+
let page = 1;
|
|
588
|
+
const perPage = 100;
|
|
589
|
+
while (all.length < 500) {
|
|
590
|
+
const sep = pathBase.includes("?") ? "&" : "?";
|
|
591
|
+
const res = await apiFetch(
|
|
592
|
+
params,
|
|
593
|
+
`${pathBase}${sep}per_page=${perPage}&page=${page}`
|
|
594
|
+
);
|
|
595
|
+
if (!res.ok) {
|
|
596
|
+
const body = await res.text().catch(() => res.statusText);
|
|
597
|
+
throw new Error(`github: listRepos failed (${res.status}): ${body}`);
|
|
598
|
+
}
|
|
599
|
+
const batch = await res.json();
|
|
600
|
+
if (!Array.isArray(batch) || batch.length === 0) break;
|
|
601
|
+
all.push(...batch);
|
|
602
|
+
if (batch.length < perPage) break;
|
|
603
|
+
page += 1;
|
|
604
|
+
}
|
|
605
|
+
return all;
|
|
606
|
+
}
|
|
607
|
+
async function listOrgRepos(params, org) {
|
|
608
|
+
return listReposPaged(
|
|
609
|
+
params,
|
|
610
|
+
`/orgs/${encodeURIComponent(org)}/repos?sort=updated`
|
|
611
|
+
);
|
|
612
|
+
}
|
|
613
|
+
async function listUserRepos(params) {
|
|
614
|
+
return listReposPaged(params, `/user/repos?sort=updated&affiliation=owner`);
|
|
615
|
+
}
|
|
616
|
+
async function getRepoLanguages(params, fullName) {
|
|
617
|
+
const res = await apiFetch(params, `/repos/${fullName}/languages`);
|
|
618
|
+
if (!res.ok) return {};
|
|
619
|
+
return await res.json();
|
|
620
|
+
}
|
|
621
|
+
var githubSetupFlow = {
|
|
622
|
+
initialState: () => ({}),
|
|
623
|
+
steps: [
|
|
624
|
+
{
|
|
625
|
+
slug: "owner",
|
|
626
|
+
type: "select",
|
|
627
|
+
question: {
|
|
628
|
+
ja: "\u5BFE\u8C61\u306E\u30AA\u30FC\u30CA\u30FC\uFF08\u7D44\u7E54\u307E\u305F\u306F\u81EA\u5206\u81EA\u8EAB\uFF09\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044",
|
|
629
|
+
en: "Select the owner (organization or yourself)"
|
|
630
|
+
},
|
|
631
|
+
async fetchOptions(_state, rt) {
|
|
632
|
+
const [user, orgs] = await Promise.all([
|
|
633
|
+
getAuthenticatedUser(rt.params).catch(() => null),
|
|
634
|
+
listOrgs(rt.params).catch(() => [])
|
|
635
|
+
]);
|
|
636
|
+
const options = [];
|
|
637
|
+
if (user?.login) {
|
|
638
|
+
options.push({
|
|
639
|
+
value: USER_OWNER,
|
|
640
|
+
label: rt.language === "ja" ? `\u81EA\u5206 (${user.login})` : `Myself (${user.login})`
|
|
641
|
+
});
|
|
642
|
+
}
|
|
643
|
+
for (const org of orgs) {
|
|
644
|
+
if (org.login) {
|
|
645
|
+
options.push({ value: org.login, label: org.login });
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
return options;
|
|
649
|
+
},
|
|
650
|
+
applyAnswer: (state, answer) => ({ ...state, owner: answer[0] })
|
|
651
|
+
},
|
|
652
|
+
{
|
|
653
|
+
slug: "repos",
|
|
654
|
+
type: "multiSelect",
|
|
655
|
+
question: {
|
|
656
|
+
ja: "\u5BFE\u8C61\u306E\u30EA\u30DD\u30B8\u30C8\u30EA\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
|
|
657
|
+
en: "Select target repositories (multi-select allowed)"
|
|
658
|
+
},
|
|
659
|
+
async fetchOptions(state, rt) {
|
|
660
|
+
if (!state.owner) return [];
|
|
661
|
+
const repos = state.owner === USER_OWNER ? await listUserRepos(rt.params) : await listOrgRepos(rt.params, state.owner);
|
|
662
|
+
const repoOptions = repos.filter((r) => r.full_name).map((r) => ({ value: r.full_name, label: r.full_name }));
|
|
663
|
+
return [
|
|
664
|
+
{
|
|
665
|
+
value: ALL_REPOS,
|
|
666
|
+
label: rt.language === "ja" ? "\u3059\u3079\u3066\u306E\u30EA\u30DD\u30B8\u30C8\u30EA" : "All repositories"
|
|
667
|
+
},
|
|
668
|
+
...repoOptions
|
|
669
|
+
];
|
|
670
|
+
},
|
|
671
|
+
applyAnswer: (state, answer) => ({ ...state, repos: answer })
|
|
672
|
+
}
|
|
673
|
+
],
|
|
674
|
+
async finalize(state, rt) {
|
|
675
|
+
if (!state.owner || !state.repos) {
|
|
676
|
+
throw new Error("GitHub setup: incomplete state on finalize");
|
|
677
|
+
}
|
|
678
|
+
const repos = state.owner === USER_OWNER ? await listUserRepos(rt.params) : await listOrgRepos(rt.params, state.owner);
|
|
679
|
+
const repoByFullName = new Map(repos.map((r) => [r.full_name, r]));
|
|
680
|
+
const targetFullNames = await resolveSetupSelection({
|
|
681
|
+
selected: state.repos,
|
|
682
|
+
allSentinel: ALL_REPOS,
|
|
683
|
+
fetchAll: async () => repos.map((r) => r.full_name).filter((n) => n),
|
|
684
|
+
limit: GITHUB_SETUP_MAX_REPOS
|
|
685
|
+
});
|
|
686
|
+
const ownerLabel = state.owner === USER_OWNER ? "self" : state.owner;
|
|
687
|
+
const sections = [
|
|
688
|
+
"## GitHub",
|
|
689
|
+
"",
|
|
690
|
+
`### Owner: ${ownerLabel}`,
|
|
691
|
+
""
|
|
692
|
+
];
|
|
693
|
+
for (const fullName of targetFullNames) {
|
|
694
|
+
const repo = repoByFullName.get(fullName);
|
|
695
|
+
if (!repo) {
|
|
696
|
+
sections.push(`#### Repository: ${fullName}`, "", "_Not found._", "");
|
|
697
|
+
continue;
|
|
698
|
+
}
|
|
699
|
+
sections.push(`#### Repository: ${repo.full_name}`, "");
|
|
700
|
+
sections.push(`- Description: ${repo.description ?? "-"}`);
|
|
701
|
+
sections.push(`- Default branch: ${repo.default_branch ?? "-"}`);
|
|
702
|
+
sections.push(`- Visibility: ${repo.private ? "private" : "public"}`);
|
|
703
|
+
const languages = await getRepoLanguages(rt.params, repo.full_name);
|
|
704
|
+
const names = Object.keys(languages);
|
|
705
|
+
sections.push(
|
|
706
|
+
`- Languages: ${names.length > 0 ? names.join(", ") : "-"}`
|
|
707
|
+
);
|
|
708
|
+
sections.push("");
|
|
709
|
+
}
|
|
710
|
+
return sections.join("\n");
|
|
711
|
+
}
|
|
712
|
+
};
|
|
713
|
+
|
|
467
714
|
// ../connectors/src/connectors/github/tools/request.ts
|
|
468
715
|
import { z } from "zod";
|
|
469
716
|
var REQUEST_TIMEOUT_MS = 6e4;
|
|
470
|
-
function
|
|
717
|
+
function resolveBaseUrl2(connectionBaseUrl) {
|
|
471
718
|
const trimmed = connectionBaseUrl?.trim();
|
|
472
719
|
return trimmed && trimmed.replace(/\/+$/, "") || DEFAULT_BASE_URL;
|
|
473
720
|
}
|
|
@@ -553,7 +800,7 @@ Rate limits: 5,000 req/hr on REST endpoints, 30 req/min on /search/*. Inspect \`
|
|
|
553
800
|
);
|
|
554
801
|
try {
|
|
555
802
|
const token = parameters.personalAccessToken.getValue(connection2);
|
|
556
|
-
const baseUrl =
|
|
803
|
+
const baseUrl = resolveBaseUrl2(parameters.baseUrl.tryGetValue(connection2));
|
|
557
804
|
const trimmedPath = path2.trim().replace(/^\/+/, "/");
|
|
558
805
|
const url = `${baseUrl}${trimmedPath.startsWith("/") ? "" : "/"}${trimmedPath}`;
|
|
559
806
|
const controller = new AbortController();
|
|
@@ -820,7 +1067,43 @@ export default async function handler(c: Context) {
|
|
|
820
1067
|
**\u30AF\u30A9\u30FC\u30BF**
|
|
821
1068
|
- GET \`/rate_limit\` \u2014 REST / GraphQL / search \u306E\u6B8B\u30EC\u30FC\u30C8\u78BA\u8A8D`
|
|
822
1069
|
},
|
|
823
|
-
tools
|
|
1070
|
+
tools,
|
|
1071
|
+
setup: (params, ctx, config) => runSetupFlow(githubSetupFlow, params, ctx, config),
|
|
1072
|
+
async checkConnection(params, _config) {
|
|
1073
|
+
const token = params[parameters.personalAccessToken.slug];
|
|
1074
|
+
if (!token) {
|
|
1075
|
+
return {
|
|
1076
|
+
success: false,
|
|
1077
|
+
error: `Missing required parameter: ${parameters.personalAccessToken.slug}`
|
|
1078
|
+
};
|
|
1079
|
+
}
|
|
1080
|
+
const rawBaseUrl = params[parameters.baseUrl.slug]?.trim();
|
|
1081
|
+
const baseUrl = rawBaseUrl && rawBaseUrl.replace(/\/+$/, "") || DEFAULT_BASE_URL;
|
|
1082
|
+
try {
|
|
1083
|
+
const res = await fetch(`${baseUrl}/user`, {
|
|
1084
|
+
method: "GET",
|
|
1085
|
+
headers: {
|
|
1086
|
+
Authorization: `Bearer ${token}`,
|
|
1087
|
+
Accept: "application/vnd.github+json",
|
|
1088
|
+
"X-GitHub-Api-Version": "2022-11-28",
|
|
1089
|
+
"User-Agent": "squadbase-connector"
|
|
1090
|
+
}
|
|
1091
|
+
});
|
|
1092
|
+
if (!res.ok) {
|
|
1093
|
+
const errorText = await res.text().catch(() => res.statusText);
|
|
1094
|
+
return {
|
|
1095
|
+
success: false,
|
|
1096
|
+
error: `GitHub API failed: HTTP ${res.status} ${errorText}`
|
|
1097
|
+
};
|
|
1098
|
+
}
|
|
1099
|
+
return { success: true };
|
|
1100
|
+
} catch (error) {
|
|
1101
|
+
return {
|
|
1102
|
+
success: false,
|
|
1103
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1104
|
+
};
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
824
1107
|
});
|
|
825
1108
|
|
|
826
1109
|
// src/connectors/create-connector-sdk.ts
|
|
@@ -849,6 +1132,7 @@ function resolveEnvVarOptional(entry, key) {
|
|
|
849
1132
|
import { getContext } from "hono/context-storage";
|
|
850
1133
|
import { getCookie } from "hono/cookie";
|
|
851
1134
|
var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
|
|
1135
|
+
var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
|
|
852
1136
|
function normalizeHeaders(input) {
|
|
853
1137
|
const out = {};
|
|
854
1138
|
if (!input) return out;
|
|
@@ -857,6 +1141,11 @@ function normalizeHeaders(input) {
|
|
|
857
1141
|
});
|
|
858
1142
|
return out;
|
|
859
1143
|
}
|
|
1144
|
+
function extractInputUrl(input) {
|
|
1145
|
+
if (typeof input === "string") return input;
|
|
1146
|
+
if (input instanceof URL) return input.href;
|
|
1147
|
+
return input.url;
|
|
1148
|
+
}
|
|
860
1149
|
function createSandboxProxyFetch(connectionId) {
|
|
861
1150
|
return async (input, init) => {
|
|
862
1151
|
const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
|
|
@@ -866,10 +1155,17 @@ function createSandboxProxyFetch(connectionId) {
|
|
|
866
1155
|
"Connection proxy is not configured. Please check your deployment settings."
|
|
867
1156
|
);
|
|
868
1157
|
}
|
|
869
|
-
const originalUrl =
|
|
1158
|
+
const originalUrl = extractInputUrl(input);
|
|
1159
|
+
const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
|
|
1160
|
+
if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
|
|
1161
|
+
const sessionUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
|
|
1162
|
+
return fetch(sessionUrl, {
|
|
1163
|
+
method: "POST",
|
|
1164
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
1165
|
+
});
|
|
1166
|
+
}
|
|
870
1167
|
const originalMethod = init?.method ?? "GET";
|
|
871
1168
|
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
872
|
-
const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
|
|
873
1169
|
const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
874
1170
|
return fetch(proxyUrl, {
|
|
875
1171
|
method: "POST",
|
|
@@ -895,10 +1191,9 @@ function createDeployedAppProxyFetch(connectionId) {
|
|
|
895
1191
|
}
|
|
896
1192
|
const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
|
|
897
1193
|
const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
1194
|
+
const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
|
|
898
1195
|
return async (input, init) => {
|
|
899
|
-
const originalUrl =
|
|
900
|
-
const originalMethod = init?.method ?? "GET";
|
|
901
|
-
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
1196
|
+
const originalUrl = extractInputUrl(input);
|
|
902
1197
|
const c = getContext();
|
|
903
1198
|
const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
|
|
904
1199
|
if (!appSession) {
|
|
@@ -906,6 +1201,14 @@ function createDeployedAppProxyFetch(connectionId) {
|
|
|
906
1201
|
"No authentication method available for connection proxy."
|
|
907
1202
|
);
|
|
908
1203
|
}
|
|
1204
|
+
if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
|
|
1205
|
+
return fetch(sessionUrl, {
|
|
1206
|
+
method: "POST",
|
|
1207
|
+
headers: { Authorization: `Bearer ${appSession}` }
|
|
1208
|
+
});
|
|
1209
|
+
}
|
|
1210
|
+
const originalMethod = init?.method ?? "GET";
|
|
1211
|
+
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
909
1212
|
return fetch(proxyUrl, {
|
|
910
1213
|
method: "POST",
|
|
911
1214
|
headers: {
|