@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",
|
|
@@ -307,6 +401,93 @@ var hubspotOnboarding = new ConnectorOnboarding({
|
|
|
307
401
|
}
|
|
308
402
|
});
|
|
309
403
|
|
|
404
|
+
// ../connectors/src/connectors/hubspot-oauth/utils.ts
|
|
405
|
+
var BASE_URL3 = "https://api.hubapi.com";
|
|
406
|
+
function apiFetch(proxyFetch, path2, init) {
|
|
407
|
+
const url = `${BASE_URL3}${path2.startsWith("/") ? "" : "/"}${path2}`;
|
|
408
|
+
return proxyFetch(url, init);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// ../connectors/src/connectors/hubspot-oauth/setup-flow.ts
|
|
412
|
+
var HUBSPOT_SETUP_MAX_OBJECT_TYPES = 10;
|
|
413
|
+
var HUBSPOT_SETUP_MAX_PROPERTIES = 50;
|
|
414
|
+
var HUBSPOT_OBJECT_TYPES = [
|
|
415
|
+
{ value: "contacts", label: "Contacts" },
|
|
416
|
+
{ value: "companies", label: "Companies" },
|
|
417
|
+
{ value: "deals", label: "Deals" },
|
|
418
|
+
{ value: "tickets", label: "Tickets" },
|
|
419
|
+
{ value: "products", label: "Products" },
|
|
420
|
+
{ value: "notes", label: "Notes" },
|
|
421
|
+
{ value: "calls", label: "Calls" },
|
|
422
|
+
{ value: "emails", label: "Emails" },
|
|
423
|
+
{ value: "meetings", label: "Meetings" },
|
|
424
|
+
{ value: "tasks", label: "Tasks" }
|
|
425
|
+
];
|
|
426
|
+
async function listProperties(proxyFetch, objectType) {
|
|
427
|
+
const res = await apiFetch(proxyFetch, `/crm/v3/properties/${objectType}`);
|
|
428
|
+
if (!res.ok) {
|
|
429
|
+
const body = await res.text().catch(() => res.statusText);
|
|
430
|
+
throw new Error(
|
|
431
|
+
`hubspot-oauth: listProperties(${objectType}) failed (${res.status}): ${body}`
|
|
432
|
+
);
|
|
433
|
+
}
|
|
434
|
+
const data = await res.json();
|
|
435
|
+
return data.results ?? [];
|
|
436
|
+
}
|
|
437
|
+
var hubspotOauthSetupFlow = {
|
|
438
|
+
initialState: () => ({}),
|
|
439
|
+
steps: [
|
|
440
|
+
{
|
|
441
|
+
slug: "objectTypes",
|
|
442
|
+
type: "multiSelect",
|
|
443
|
+
question: {
|
|
444
|
+
ja: "\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3067\u6982\u89B3\u3057\u305F\u3044CRM\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
|
|
445
|
+
en: "Select the CRM object types to include in setup (multi-select allowed)"
|
|
446
|
+
},
|
|
447
|
+
async fetchOptions(_state, _rt) {
|
|
448
|
+
return HUBSPOT_OBJECT_TYPES.map((o) => ({
|
|
449
|
+
value: o.value,
|
|
450
|
+
label: o.label
|
|
451
|
+
}));
|
|
452
|
+
},
|
|
453
|
+
applyAnswer: (state, answer) => ({ ...state, objectTypes: answer })
|
|
454
|
+
}
|
|
455
|
+
],
|
|
456
|
+
async finalize(state, rt) {
|
|
457
|
+
if (!state.objectTypes) {
|
|
458
|
+
throw new Error("HubSpot setup: incomplete state on finalize");
|
|
459
|
+
}
|
|
460
|
+
const targetObjectTypes = await resolveSetupSelection({
|
|
461
|
+
selected: state.objectTypes,
|
|
462
|
+
allSentinel: "__ALL__",
|
|
463
|
+
fetchAll: async () => HUBSPOT_OBJECT_TYPES.map((o) => o.value),
|
|
464
|
+
limit: HUBSPOT_SETUP_MAX_OBJECT_TYPES
|
|
465
|
+
});
|
|
466
|
+
const sections = ["## HubSpot", ""];
|
|
467
|
+
for (const objectType of targetObjectTypes) {
|
|
468
|
+
sections.push(`### Object: ${objectType}`, "");
|
|
469
|
+
const props = await listProperties(rt.config.proxyFetch, objectType);
|
|
470
|
+
const limited = props.slice(0, HUBSPOT_SETUP_MAX_PROPERTIES);
|
|
471
|
+
sections.push("| Property | Type | Label |");
|
|
472
|
+
sections.push("|----------|------|-------|");
|
|
473
|
+
for (const p of limited) {
|
|
474
|
+
const name = (p.name ?? "").replace(/\|/g, "\\|");
|
|
475
|
+
const type = (p.type ?? "").replace(/\|/g, "\\|");
|
|
476
|
+
const label = (p.label ?? "").replace(/\|/g, "\\|");
|
|
477
|
+
sections.push(`| ${name} | ${type} | ${label || "-"} |`);
|
|
478
|
+
}
|
|
479
|
+
if (props.length > HUBSPOT_SETUP_MAX_PROPERTIES) {
|
|
480
|
+
sections.push(
|
|
481
|
+
"",
|
|
482
|
+
`_Showing first ${HUBSPOT_SETUP_MAX_PROPERTIES} of ${props.length} properties._`
|
|
483
|
+
);
|
|
484
|
+
}
|
|
485
|
+
sections.push("");
|
|
486
|
+
}
|
|
487
|
+
return sections.join("\n");
|
|
488
|
+
}
|
|
489
|
+
};
|
|
490
|
+
|
|
310
491
|
// ../connectors/src/connectors/hubspot-oauth/parameters.ts
|
|
311
492
|
var parameters = {};
|
|
312
493
|
|
|
@@ -315,6 +496,7 @@ var tools = { request: requestTool };
|
|
|
315
496
|
var hubspotOauthConnector = new ConnectorPlugin({
|
|
316
497
|
slug: "hubspot",
|
|
317
498
|
authType: AUTH_TYPES.OAUTH,
|
|
499
|
+
skipConnectionCheckOnCreate: true,
|
|
318
500
|
name: "HubSpot",
|
|
319
501
|
description: "Connect to HubSpot CRM for contacts, deals, companies, and marketing data using OAuth.",
|
|
320
502
|
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/5UcSkKkzhUMA4RsM45ynuo/43b967e36915ca0fc5d277684b204320/hubspot.svg",
|
|
@@ -423,6 +605,7 @@ const data = await res.json();
|
|
|
423
605
|
\`\`\``
|
|
424
606
|
},
|
|
425
607
|
tools,
|
|
608
|
+
setup: (params, ctx, config) => runSetupFlow(hubspotOauthSetupFlow, params, ctx, config),
|
|
426
609
|
async checkConnection(_params, config) {
|
|
427
610
|
const { proxyFetch } = config;
|
|
428
611
|
try {
|
|
@@ -473,6 +656,7 @@ function resolveEnvVarOptional(entry, key) {
|
|
|
473
656
|
import { getContext } from "hono/context-storage";
|
|
474
657
|
import { getCookie } from "hono/cookie";
|
|
475
658
|
var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
|
|
659
|
+
var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
|
|
476
660
|
function normalizeHeaders(input) {
|
|
477
661
|
const out = {};
|
|
478
662
|
if (!input) return out;
|
|
@@ -481,6 +665,11 @@ function normalizeHeaders(input) {
|
|
|
481
665
|
});
|
|
482
666
|
return out;
|
|
483
667
|
}
|
|
668
|
+
function extractInputUrl(input) {
|
|
669
|
+
if (typeof input === "string") return input;
|
|
670
|
+
if (input instanceof URL) return input.href;
|
|
671
|
+
return input.url;
|
|
672
|
+
}
|
|
484
673
|
function createSandboxProxyFetch(connectionId) {
|
|
485
674
|
return async (input, init) => {
|
|
486
675
|
const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
|
|
@@ -490,10 +679,17 @@ function createSandboxProxyFetch(connectionId) {
|
|
|
490
679
|
"Connection proxy is not configured. Please check your deployment settings."
|
|
491
680
|
);
|
|
492
681
|
}
|
|
493
|
-
const originalUrl =
|
|
682
|
+
const originalUrl = extractInputUrl(input);
|
|
683
|
+
const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
|
|
684
|
+
if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
|
|
685
|
+
const sessionUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
|
|
686
|
+
return fetch(sessionUrl, {
|
|
687
|
+
method: "POST",
|
|
688
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
689
|
+
});
|
|
690
|
+
}
|
|
494
691
|
const originalMethod = init?.method ?? "GET";
|
|
495
692
|
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
496
|
-
const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
|
|
497
693
|
const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
498
694
|
return fetch(proxyUrl, {
|
|
499
695
|
method: "POST",
|
|
@@ -519,10 +715,9 @@ function createDeployedAppProxyFetch(connectionId) {
|
|
|
519
715
|
}
|
|
520
716
|
const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
|
|
521
717
|
const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
718
|
+
const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
|
|
522
719
|
return async (input, init) => {
|
|
523
|
-
const originalUrl =
|
|
524
|
-
const originalMethod = init?.method ?? "GET";
|
|
525
|
-
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
720
|
+
const originalUrl = extractInputUrl(input);
|
|
526
721
|
const c = getContext();
|
|
527
722
|
const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
|
|
528
723
|
if (!appSession) {
|
|
@@ -530,6 +725,14 @@ function createDeployedAppProxyFetch(connectionId) {
|
|
|
530
725
|
"No authentication method available for connection proxy."
|
|
531
726
|
);
|
|
532
727
|
}
|
|
728
|
+
if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
|
|
729
|
+
return fetch(sessionUrl, {
|
|
730
|
+
method: "POST",
|
|
731
|
+
headers: { Authorization: `Bearer ${appSession}` }
|
|
732
|
+
});
|
|
733
|
+
}
|
|
734
|
+
const originalMethod = init?.method ?? "GET";
|
|
735
|
+
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
533
736
|
return fetch(proxyUrl, {
|
|
534
737
|
method: "POST",
|
|
535
738
|
headers: {
|