@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
|
@@ -67,6 +67,28 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
67
67
|
tools;
|
|
68
68
|
query;
|
|
69
69
|
checkConnection;
|
|
70
|
+
/**
|
|
71
|
+
* SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
|
|
72
|
+
* implement this expose a step-by-step exploration flow (database/schema/
|
|
73
|
+
* table/etc. discovery) that the dashboard backend drives via the
|
|
74
|
+
* `/connections/:connectionId/setup` endpoint. Implement by delegating to
|
|
75
|
+
* `runSetupFlow` from `setup-flow.ts`.
|
|
76
|
+
*/
|
|
77
|
+
setup;
|
|
78
|
+
/**
|
|
79
|
+
* Opt-out of the default "verify before save" behavior on connection
|
|
80
|
+
* creation. The backend invokes `checkConnection` synchronously while
|
|
81
|
+
* creating the connection and aborts (no row inserted) if it fails — this
|
|
82
|
+
* flag disables that for connectors where the check cannot succeed pre-save:
|
|
83
|
+
*
|
|
84
|
+
* - `squadbase-db` populates `connection-url` only after Neon provisioning
|
|
85
|
+
* - OAuth connectors require an OAuth-aware proxyFetch keyed by the
|
|
86
|
+
* connectionId, which doesn't exist until the row is saved
|
|
87
|
+
*
|
|
88
|
+
* Exceptions are the explicit position; new credential-input connectors get
|
|
89
|
+
* the default verify-on-create behavior without opt-in.
|
|
90
|
+
*/
|
|
91
|
+
skipConnectionCheckOnCreate;
|
|
70
92
|
constructor(config) {
|
|
71
93
|
this.slug = config.slug;
|
|
72
94
|
this.authType = config.authType;
|
|
@@ -83,6 +105,8 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
83
105
|
this.tools = config.tools;
|
|
84
106
|
this.query = config.query;
|
|
85
107
|
this.checkConnection = config.checkConnection;
|
|
108
|
+
this.setup = config.setup;
|
|
109
|
+
this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
|
|
86
110
|
}
|
|
87
111
|
get connectorKey() {
|
|
88
112
|
return _ConnectorPlugin.deriveKey(this.slug, this.authType);
|
|
@@ -147,6 +171,76 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
147
171
|
}
|
|
148
172
|
};
|
|
149
173
|
|
|
174
|
+
// ../connectors/src/setup-flow.ts
|
|
175
|
+
async function runSetupFlow(flow, params, ctx, config) {
|
|
176
|
+
const runtime = {
|
|
177
|
+
params,
|
|
178
|
+
language: ctx.language,
|
|
179
|
+
config
|
|
180
|
+
};
|
|
181
|
+
let state = flow.initialState();
|
|
182
|
+
let answerIdx = 0;
|
|
183
|
+
const pendingParameterUpdates = [];
|
|
184
|
+
for (const step of flow.steps) {
|
|
185
|
+
const ans = ctx.answers[answerIdx];
|
|
186
|
+
if (ans && ans.questionSlug === step.slug) {
|
|
187
|
+
state = step.applyAnswer(state, ans.answer);
|
|
188
|
+
if (step.toParameterUpdates) {
|
|
189
|
+
pendingParameterUpdates.push(...step.toParameterUpdates(state));
|
|
190
|
+
}
|
|
191
|
+
answerIdx += 1;
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
|
|
195
|
+
if (step.type === "text") {
|
|
196
|
+
if (step.fetchOptions) {
|
|
197
|
+
const options2 = await step.fetchOptions(state, runtime);
|
|
198
|
+
if (options2.length === 0) {
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return {
|
|
203
|
+
type: "nextQuestion",
|
|
204
|
+
questionSlug: step.slug,
|
|
205
|
+
question: step.question[ctx.language],
|
|
206
|
+
questionType: "text",
|
|
207
|
+
allowFreeText: resolvedAllowFreeText,
|
|
208
|
+
...pendingParameterUpdates.length > 0 && {
|
|
209
|
+
parameterUpdates: pendingParameterUpdates
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
|
|
214
|
+
if (options.length === 0) {
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
return {
|
|
218
|
+
type: "nextQuestion",
|
|
219
|
+
questionSlug: step.slug,
|
|
220
|
+
question: step.question[ctx.language],
|
|
221
|
+
questionType: step.type,
|
|
222
|
+
options,
|
|
223
|
+
allowFreeText: resolvedAllowFreeText,
|
|
224
|
+
...pendingParameterUpdates.length > 0 && {
|
|
225
|
+
parameterUpdates: pendingParameterUpdates
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
const dataInvestigationResult = await flow.finalize(state, runtime);
|
|
230
|
+
return {
|
|
231
|
+
type: "fulfilled",
|
|
232
|
+
dataInvestigationResult,
|
|
233
|
+
...pendingParameterUpdates.length > 0 && {
|
|
234
|
+
parameterUpdates: pendingParameterUpdates
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
async function resolveSetupSelection(params) {
|
|
239
|
+
const { selected, allSentinel, fetchAll, limit } = params;
|
|
240
|
+
const resolved = selected.includes(allSentinel) ? await fetchAll() : selected.filter((v) => v !== allSentinel);
|
|
241
|
+
return resolved.slice(0, limit);
|
|
242
|
+
}
|
|
243
|
+
|
|
150
244
|
// ../connectors/src/auth-types.ts
|
|
151
245
|
var AUTH_TYPES = {
|
|
152
246
|
OAUTH: "oauth",
|
|
@@ -314,6 +408,95 @@ var intercomOauthOnboarding = new ConnectorOnboarding({
|
|
|
314
408
|
}
|
|
315
409
|
});
|
|
316
410
|
|
|
411
|
+
// ../connectors/src/connectors/intercom-oauth/utils.ts
|
|
412
|
+
var BASE_URL3 = "https://api.intercom.io";
|
|
413
|
+
var INTERCOM_VERSION = "2.11";
|
|
414
|
+
function apiFetch(proxyFetch, path2, init) {
|
|
415
|
+
const url = `${BASE_URL3}${path2.startsWith("/") ? "" : "/"}${path2}`;
|
|
416
|
+
const headers = new Headers(init?.headers);
|
|
417
|
+
headers.set("Accept", "application/json");
|
|
418
|
+
headers.set("Intercom-Version", INTERCOM_VERSION);
|
|
419
|
+
return proxyFetch(url, { ...init, headers });
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
// ../connectors/src/connectors/intercom-oauth/setup-flow.ts
|
|
423
|
+
var INTERCOM_SETUP_MAX_SCOPES = 10;
|
|
424
|
+
var INTERCOM_SCOPES = [
|
|
425
|
+
{ value: "contacts", label: "Contacts", countPath: "/contacts?per_page=1" },
|
|
426
|
+
{ value: "companies", label: "Companies", countPath: "/companies?per_page=1" },
|
|
427
|
+
{
|
|
428
|
+
value: "conversations",
|
|
429
|
+
label: "Conversations",
|
|
430
|
+
countPath: "/conversations?per_page=1"
|
|
431
|
+
},
|
|
432
|
+
{ value: "articles", label: "Articles", countPath: "/articles?per_page=1" },
|
|
433
|
+
{ value: "teams", label: "Teams", countPath: "/teams" }
|
|
434
|
+
];
|
|
435
|
+
async function fetchCount(proxyFetch, path2) {
|
|
436
|
+
const res = await apiFetch(proxyFetch, path2);
|
|
437
|
+
if (!res.ok) {
|
|
438
|
+
return null;
|
|
439
|
+
}
|
|
440
|
+
const data = await res.json();
|
|
441
|
+
if (typeof data.total_count === "number") return data.total_count;
|
|
442
|
+
if (Array.isArray(data.teams)) return data.teams.length;
|
|
443
|
+
if (Array.isArray(data.data)) return data.data.length;
|
|
444
|
+
return null;
|
|
445
|
+
}
|
|
446
|
+
var intercomOauthSetupFlow = {
|
|
447
|
+
initialState: () => ({}),
|
|
448
|
+
steps: [
|
|
449
|
+
{
|
|
450
|
+
slug: "scopes",
|
|
451
|
+
type: "multiSelect",
|
|
452
|
+
question: {
|
|
453
|
+
ja: "\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3067\u6982\u89B3\u3057\u305F\u3044Intercom\u30C7\u30FC\u30BF\u30B9\u30B3\u30FC\u30D7\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
|
|
454
|
+
en: "Select the Intercom data scopes to include in setup (multi-select allowed)"
|
|
455
|
+
},
|
|
456
|
+
async fetchOptions(_state, _rt) {
|
|
457
|
+
return INTERCOM_SCOPES.map((s) => ({
|
|
458
|
+
value: s.value,
|
|
459
|
+
label: s.label
|
|
460
|
+
}));
|
|
461
|
+
},
|
|
462
|
+
applyAnswer: (state, answer) => ({ ...state, scopes: answer })
|
|
463
|
+
}
|
|
464
|
+
],
|
|
465
|
+
async finalize(state, rt) {
|
|
466
|
+
if (!state.scopes) {
|
|
467
|
+
throw new Error("Intercom setup: incomplete state on finalize");
|
|
468
|
+
}
|
|
469
|
+
const targetScopes = await resolveSetupSelection({
|
|
470
|
+
selected: state.scopes,
|
|
471
|
+
allSentinel: "__ALL__",
|
|
472
|
+
fetchAll: async () => INTERCOM_SCOPES.map((s) => s.value),
|
|
473
|
+
limit: INTERCOM_SETUP_MAX_SCOPES
|
|
474
|
+
});
|
|
475
|
+
const scopeByValue = new Map(INTERCOM_SCOPES.map((s) => [s.value, s]));
|
|
476
|
+
const sections = [
|
|
477
|
+
"## Intercom",
|
|
478
|
+
"",
|
|
479
|
+
"### Selected scopes",
|
|
480
|
+
"",
|
|
481
|
+
"| Scope | Count |",
|
|
482
|
+
"|-------|-------|"
|
|
483
|
+
];
|
|
484
|
+
for (const value of targetScopes) {
|
|
485
|
+
const scope = scopeByValue.get(value);
|
|
486
|
+
if (!scope) {
|
|
487
|
+
sections.push(`| ${value} | _unknown_ |`);
|
|
488
|
+
continue;
|
|
489
|
+
}
|
|
490
|
+
const count = await fetchCount(rt.config.proxyFetch, scope.countPath);
|
|
491
|
+
sections.push(
|
|
492
|
+
`| ${scope.label} (${scope.value}) | ${count == null ? "-" : count} |`
|
|
493
|
+
);
|
|
494
|
+
}
|
|
495
|
+
sections.push("");
|
|
496
|
+
return sections.join("\n");
|
|
497
|
+
}
|
|
498
|
+
};
|
|
499
|
+
|
|
317
500
|
// ../connectors/src/connectors/intercom-oauth/parameters.ts
|
|
318
501
|
var parameters = {};
|
|
319
502
|
|
|
@@ -322,6 +505,7 @@ var tools = { request: requestTool };
|
|
|
322
505
|
var intercomOauthConnector = new ConnectorPlugin({
|
|
323
506
|
slug: "intercom",
|
|
324
507
|
authType: AUTH_TYPES.OAUTH,
|
|
508
|
+
skipConnectionCheckOnCreate: true,
|
|
325
509
|
name: "Intercom",
|
|
326
510
|
description: "Connect to Intercom for contacts, conversations, companies, and customer engagement data using OAuth.",
|
|
327
511
|
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/sb2cRMGClpId0LKiSqsok/ae90a0849f21ffe3faf73e04a5676b45/intercom.svg",
|
|
@@ -456,6 +640,7 @@ const data = await res.json();
|
|
|
456
640
|
\`\`\``
|
|
457
641
|
},
|
|
458
642
|
tools,
|
|
643
|
+
setup: (params, ctx, config) => runSetupFlow(intercomOauthSetupFlow, params, ctx, config),
|
|
459
644
|
async checkConnection(_params, config) {
|
|
460
645
|
const { proxyFetch } = config;
|
|
461
646
|
try {
|
|
@@ -505,6 +690,7 @@ function resolveEnvVarOptional(entry, key) {
|
|
|
505
690
|
import { getContext } from "hono/context-storage";
|
|
506
691
|
import { getCookie } from "hono/cookie";
|
|
507
692
|
var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
|
|
693
|
+
var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
|
|
508
694
|
function normalizeHeaders(input) {
|
|
509
695
|
const out = {};
|
|
510
696
|
if (!input) return out;
|
|
@@ -513,6 +699,11 @@ function normalizeHeaders(input) {
|
|
|
513
699
|
});
|
|
514
700
|
return out;
|
|
515
701
|
}
|
|
702
|
+
function extractInputUrl(input) {
|
|
703
|
+
if (typeof input === "string") return input;
|
|
704
|
+
if (input instanceof URL) return input.href;
|
|
705
|
+
return input.url;
|
|
706
|
+
}
|
|
516
707
|
function createSandboxProxyFetch(connectionId) {
|
|
517
708
|
return async (input, init) => {
|
|
518
709
|
const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
|
|
@@ -522,10 +713,17 @@ function createSandboxProxyFetch(connectionId) {
|
|
|
522
713
|
"Connection proxy is not configured. Please check your deployment settings."
|
|
523
714
|
);
|
|
524
715
|
}
|
|
525
|
-
const originalUrl =
|
|
716
|
+
const originalUrl = extractInputUrl(input);
|
|
717
|
+
const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
|
|
718
|
+
if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
|
|
719
|
+
const sessionUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
|
|
720
|
+
return fetch(sessionUrl, {
|
|
721
|
+
method: "POST",
|
|
722
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
723
|
+
});
|
|
724
|
+
}
|
|
526
725
|
const originalMethod = init?.method ?? "GET";
|
|
527
726
|
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
528
|
-
const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
|
|
529
727
|
const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
530
728
|
return fetch(proxyUrl, {
|
|
531
729
|
method: "POST",
|
|
@@ -551,10 +749,9 @@ function createDeployedAppProxyFetch(connectionId) {
|
|
|
551
749
|
}
|
|
552
750
|
const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
|
|
553
751
|
const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
752
|
+
const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
|
|
554
753
|
return async (input, init) => {
|
|
555
|
-
const originalUrl =
|
|
556
|
-
const originalMethod = init?.method ?? "GET";
|
|
557
|
-
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
754
|
+
const originalUrl = extractInputUrl(input);
|
|
558
755
|
const c = getContext();
|
|
559
756
|
const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
|
|
560
757
|
if (!appSession) {
|
|
@@ -562,6 +759,14 @@ function createDeployedAppProxyFetch(connectionId) {
|
|
|
562
759
|
"No authentication method available for connection proxy."
|
|
563
760
|
);
|
|
564
761
|
}
|
|
762
|
+
if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
|
|
763
|
+
return fetch(sessionUrl, {
|
|
764
|
+
method: "POST",
|
|
765
|
+
headers: { Authorization: `Bearer ${appSession}` }
|
|
766
|
+
});
|
|
767
|
+
}
|
|
768
|
+
const originalMethod = init?.method ?? "GET";
|
|
769
|
+
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
565
770
|
return fetch(proxyUrl, {
|
|
566
771
|
method: "POST",
|
|
567
772
|
headers: {
|