@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
|
@@ -65,6 +65,28 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
65
65
|
tools;
|
|
66
66
|
query;
|
|
67
67
|
checkConnection;
|
|
68
|
+
/**
|
|
69
|
+
* SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
|
|
70
|
+
* implement this expose a step-by-step exploration flow (database/schema/
|
|
71
|
+
* table/etc. discovery) that the dashboard backend drives via the
|
|
72
|
+
* `/connections/:connectionId/setup` endpoint. Implement by delegating to
|
|
73
|
+
* `runSetupFlow` from `setup-flow.ts`.
|
|
74
|
+
*/
|
|
75
|
+
setup;
|
|
76
|
+
/**
|
|
77
|
+
* Opt-out of the default "verify before save" behavior on connection
|
|
78
|
+
* creation. The backend invokes `checkConnection` synchronously while
|
|
79
|
+
* creating the connection and aborts (no row inserted) if it fails — this
|
|
80
|
+
* flag disables that for connectors where the check cannot succeed pre-save:
|
|
81
|
+
*
|
|
82
|
+
* - `squadbase-db` populates `connection-url` only after Neon provisioning
|
|
83
|
+
* - OAuth connectors require an OAuth-aware proxyFetch keyed by the
|
|
84
|
+
* connectionId, which doesn't exist until the row is saved
|
|
85
|
+
*
|
|
86
|
+
* Exceptions are the explicit position; new credential-input connectors get
|
|
87
|
+
* the default verify-on-create behavior without opt-in.
|
|
88
|
+
*/
|
|
89
|
+
skipConnectionCheckOnCreate;
|
|
68
90
|
constructor(config) {
|
|
69
91
|
this.slug = config.slug;
|
|
70
92
|
this.authType = config.authType;
|
|
@@ -81,6 +103,8 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
81
103
|
this.tools = config.tools;
|
|
82
104
|
this.query = config.query;
|
|
83
105
|
this.checkConnection = config.checkConnection;
|
|
106
|
+
this.setup = config.setup;
|
|
107
|
+
this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
|
|
84
108
|
}
|
|
85
109
|
get connectorKey() {
|
|
86
110
|
return _ConnectorPlugin.deriveKey(this.slug, this.authType);
|
|
@@ -145,6 +169,71 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
145
169
|
}
|
|
146
170
|
};
|
|
147
171
|
|
|
172
|
+
// ../connectors/src/setup-flow.ts
|
|
173
|
+
async function runSetupFlow(flow, params, ctx, config) {
|
|
174
|
+
const runtime = {
|
|
175
|
+
params,
|
|
176
|
+
language: ctx.language,
|
|
177
|
+
config
|
|
178
|
+
};
|
|
179
|
+
let state = flow.initialState();
|
|
180
|
+
let answerIdx = 0;
|
|
181
|
+
const pendingParameterUpdates = [];
|
|
182
|
+
for (const step of flow.steps) {
|
|
183
|
+
const ans = ctx.answers[answerIdx];
|
|
184
|
+
if (ans && ans.questionSlug === step.slug) {
|
|
185
|
+
state = step.applyAnswer(state, ans.answer);
|
|
186
|
+
if (step.toParameterUpdates) {
|
|
187
|
+
pendingParameterUpdates.push(...step.toParameterUpdates(state));
|
|
188
|
+
}
|
|
189
|
+
answerIdx += 1;
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
|
|
193
|
+
if (step.type === "text") {
|
|
194
|
+
if (step.fetchOptions) {
|
|
195
|
+
const options2 = await step.fetchOptions(state, runtime);
|
|
196
|
+
if (options2.length === 0) {
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return {
|
|
201
|
+
type: "nextQuestion",
|
|
202
|
+
questionSlug: step.slug,
|
|
203
|
+
question: step.question[ctx.language],
|
|
204
|
+
questionType: "text",
|
|
205
|
+
allowFreeText: resolvedAllowFreeText,
|
|
206
|
+
...pendingParameterUpdates.length > 0 && {
|
|
207
|
+
parameterUpdates: pendingParameterUpdates
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
|
|
212
|
+
if (options.length === 0) {
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
return {
|
|
216
|
+
type: "nextQuestion",
|
|
217
|
+
questionSlug: step.slug,
|
|
218
|
+
question: step.question[ctx.language],
|
|
219
|
+
questionType: step.type,
|
|
220
|
+
options,
|
|
221
|
+
allowFreeText: resolvedAllowFreeText,
|
|
222
|
+
...pendingParameterUpdates.length > 0 && {
|
|
223
|
+
parameterUpdates: pendingParameterUpdates
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
const dataInvestigationResult = await flow.finalize(state, runtime);
|
|
228
|
+
return {
|
|
229
|
+
type: "fulfilled",
|
|
230
|
+
dataInvestigationResult,
|
|
231
|
+
...pendingParameterUpdates.length > 0 && {
|
|
232
|
+
parameterUpdates: pendingParameterUpdates
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
|
|
148
237
|
// ../connectors/src/auth-types.ts
|
|
149
238
|
var AUTH_TYPES = {
|
|
150
239
|
OAUTH: "oauth",
|
|
@@ -307,11 +396,83 @@ var shopifyOauthOnboarding = new ConnectorOnboarding({
|
|
|
307
396
|
// ../connectors/src/connectors/shopify-oauth/parameters.ts
|
|
308
397
|
var parameters = {};
|
|
309
398
|
|
|
399
|
+
// ../connectors/src/connectors/shopify-oauth/setup-flow.ts
|
|
400
|
+
var SHOPIFY_API_VERSION = "2024-10";
|
|
401
|
+
var SHOPIFY_OAUTH_SETUP_MAX_ENTITIES = 10;
|
|
402
|
+
var ENTITY_LABELS = {
|
|
403
|
+
products: { en: "Products", ja: "Products (\u5546\u54C1)" },
|
|
404
|
+
orders: { en: "Orders", ja: "Orders (\u6CE8\u6587)" },
|
|
405
|
+
customers: { en: "Customers", ja: "Customers (\u9867\u5BA2)" },
|
|
406
|
+
collections: { en: "Collections", ja: "Collections (\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3)" },
|
|
407
|
+
inventory: { en: "Inventory items", ja: "Inventory items (\u5728\u5EAB)" },
|
|
408
|
+
discounts: { en: "Discounts", ja: "Discounts (\u5272\u5F15)" }
|
|
409
|
+
};
|
|
410
|
+
var ENTITY_VALUES = [
|
|
411
|
+
"products",
|
|
412
|
+
"orders",
|
|
413
|
+
"customers",
|
|
414
|
+
"collections",
|
|
415
|
+
"inventory",
|
|
416
|
+
"discounts"
|
|
417
|
+
];
|
|
418
|
+
var COUNT_PATHS = {
|
|
419
|
+
products: `/admin/api/${SHOPIFY_API_VERSION}/products/count.json`,
|
|
420
|
+
orders: `/admin/api/${SHOPIFY_API_VERSION}/orders/count.json?status=any`,
|
|
421
|
+
customers: `/admin/api/${SHOPIFY_API_VERSION}/customers/count.json`,
|
|
422
|
+
collections: `/admin/api/${SHOPIFY_API_VERSION}/custom_collections/count.json`,
|
|
423
|
+
inventory: null,
|
|
424
|
+
discounts: `/admin/api/${SHOPIFY_API_VERSION}/price_rules/count.json`
|
|
425
|
+
};
|
|
426
|
+
var shopifyOauthSetupFlow = {
|
|
427
|
+
initialState: () => ({}),
|
|
428
|
+
steps: [
|
|
429
|
+
{
|
|
430
|
+
slug: "entities",
|
|
431
|
+
type: "multiSelect",
|
|
432
|
+
question: {
|
|
433
|
+
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",
|
|
434
|
+
en: "Select target entities (multi-select allowed)"
|
|
435
|
+
},
|
|
436
|
+
async fetchOptions(_state, rt) {
|
|
437
|
+
return ENTITY_VALUES.map((value) => ({
|
|
438
|
+
value,
|
|
439
|
+
label: ENTITY_LABELS[value][rt.language]
|
|
440
|
+
}));
|
|
441
|
+
},
|
|
442
|
+
applyAnswer: (state, answer) => ({ ...state, entities: answer })
|
|
443
|
+
}
|
|
444
|
+
],
|
|
445
|
+
async finalize(state, rt) {
|
|
446
|
+
if (!state.entities) {
|
|
447
|
+
throw new Error("Shopify setup: incomplete state on finalize");
|
|
448
|
+
}
|
|
449
|
+
const selected = state.entities.filter(
|
|
450
|
+
(e) => ENTITY_VALUES.includes(e)
|
|
451
|
+
).slice(0, SHOPIFY_OAUTH_SETUP_MAX_ENTITIES);
|
|
452
|
+
const sections = ["## Shopify", ""];
|
|
453
|
+
for (const entity of selected) {
|
|
454
|
+
const path2 = COUNT_PATHS[entity];
|
|
455
|
+
let count = "available";
|
|
456
|
+
if (path2) {
|
|
457
|
+
const res = await rt.config.proxyFetch(path2, { method: "GET" });
|
|
458
|
+
if (res.ok) {
|
|
459
|
+
const data = await res.json();
|
|
460
|
+
if (typeof data.count === "number") count = String(data.count);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
sections.push(`### ${ENTITY_LABELS[entity].en}`, "");
|
|
464
|
+
sections.push(`Count: ${count}`, "");
|
|
465
|
+
}
|
|
466
|
+
return sections.join("\n");
|
|
467
|
+
}
|
|
468
|
+
};
|
|
469
|
+
|
|
310
470
|
// ../connectors/src/connectors/shopify-oauth/index.ts
|
|
311
471
|
var tools = { request: requestTool };
|
|
312
472
|
var shopifyOauthConnector = new ConnectorPlugin({
|
|
313
473
|
slug: "shopify",
|
|
314
474
|
authType: AUTH_TYPES.OAUTH,
|
|
475
|
+
skipConnectionCheckOnCreate: true,
|
|
315
476
|
name: "Shopify",
|
|
316
477
|
description: "Connect to Shopify for e-commerce data including products, orders, and customers using OAuth.",
|
|
317
478
|
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/57KEjZCBskKgSxgKyU4Sm0/117d681a410f48dc36f97cdd9c0593c5/shopify-icon.svg",
|
|
@@ -424,6 +585,7 @@ const data = await res.json();
|
|
|
424
585
|
\`\`\``
|
|
425
586
|
},
|
|
426
587
|
tools,
|
|
588
|
+
setup: (params, ctx, config) => runSetupFlow(shopifyOauthSetupFlow, params, ctx, config),
|
|
427
589
|
async checkConnection(_params, config) {
|
|
428
590
|
const { proxyFetch } = config;
|
|
429
591
|
try {
|
|
@@ -473,6 +635,7 @@ function resolveEnvVarOptional(entry, key) {
|
|
|
473
635
|
import { getContext } from "hono/context-storage";
|
|
474
636
|
import { getCookie } from "hono/cookie";
|
|
475
637
|
var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
|
|
638
|
+
var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
|
|
476
639
|
function normalizeHeaders(input) {
|
|
477
640
|
const out = {};
|
|
478
641
|
if (!input) return out;
|
|
@@ -481,6 +644,11 @@ function normalizeHeaders(input) {
|
|
|
481
644
|
});
|
|
482
645
|
return out;
|
|
483
646
|
}
|
|
647
|
+
function extractInputUrl(input) {
|
|
648
|
+
if (typeof input === "string") return input;
|
|
649
|
+
if (input instanceof URL) return input.href;
|
|
650
|
+
return input.url;
|
|
651
|
+
}
|
|
484
652
|
function createSandboxProxyFetch(connectionId) {
|
|
485
653
|
return async (input, init) => {
|
|
486
654
|
const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
|
|
@@ -490,10 +658,17 @@ function createSandboxProxyFetch(connectionId) {
|
|
|
490
658
|
"Connection proxy is not configured. Please check your deployment settings."
|
|
491
659
|
);
|
|
492
660
|
}
|
|
493
|
-
const originalUrl =
|
|
661
|
+
const originalUrl = extractInputUrl(input);
|
|
662
|
+
const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
|
|
663
|
+
if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
|
|
664
|
+
const sessionUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
|
|
665
|
+
return fetch(sessionUrl, {
|
|
666
|
+
method: "POST",
|
|
667
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
668
|
+
});
|
|
669
|
+
}
|
|
494
670
|
const originalMethod = init?.method ?? "GET";
|
|
495
671
|
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
496
|
-
const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
|
|
497
672
|
const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
498
673
|
return fetch(proxyUrl, {
|
|
499
674
|
method: "POST",
|
|
@@ -519,10 +694,9 @@ function createDeployedAppProxyFetch(connectionId) {
|
|
|
519
694
|
}
|
|
520
695
|
const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
|
|
521
696
|
const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
|
|
697
|
+
const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
|
|
522
698
|
return async (input, init) => {
|
|
523
|
-
const originalUrl =
|
|
524
|
-
const originalMethod = init?.method ?? "GET";
|
|
525
|
-
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
699
|
+
const originalUrl = extractInputUrl(input);
|
|
526
700
|
const c = getContext();
|
|
527
701
|
const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
|
|
528
702
|
if (!appSession) {
|
|
@@ -530,6 +704,14 @@ function createDeployedAppProxyFetch(connectionId) {
|
|
|
530
704
|
"No authentication method available for connection proxy."
|
|
531
705
|
);
|
|
532
706
|
}
|
|
707
|
+
if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
|
|
708
|
+
return fetch(sessionUrl, {
|
|
709
|
+
method: "POST",
|
|
710
|
+
headers: { Authorization: `Bearer ${appSession}` }
|
|
711
|
+
});
|
|
712
|
+
}
|
|
713
|
+
const originalMethod = init?.method ?? "GET";
|
|
714
|
+
const originalBody = init?.body ? JSON.parse(init.body) : void 0;
|
|
533
715
|
return fetch(proxyUrl, {
|
|
534
716
|
method: "POST",
|
|
535
717
|
headers: {
|