@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.
Files changed (77) hide show
  1. package/dist/cli/index.js +14375 -1652
  2. package/dist/connectors/airtable-oauth.js +282 -46
  3. package/dist/connectors/airtable.js +319 -51
  4. package/dist/connectors/amplitude.js +322 -47
  5. package/dist/connectors/anthropic.js +135 -47
  6. package/dist/connectors/asana.js +327 -49
  7. package/dist/connectors/attio.js +302 -49
  8. package/dist/connectors/aws-billing.js +287 -46
  9. package/dist/connectors/azure-sql.js +421 -102
  10. package/dist/connectors/backlog-api-key.js +317 -47
  11. package/dist/connectors/clickup.js +338 -49
  12. package/dist/connectors/cosmosdb.js +305 -50
  13. package/dist/connectors/customerio.js +319 -47
  14. package/dist/connectors/dbt.js +340 -47
  15. package/dist/connectors/freshdesk.js +342 -53
  16. package/dist/connectors/freshsales.js +333 -52
  17. package/dist/connectors/freshservice.js +361 -53
  18. package/dist/connectors/gamma.js +327 -52
  19. package/dist/connectors/gemini.js +134 -47
  20. package/dist/connectors/github.js +386 -49
  21. package/dist/connectors/gmail-oauth.js +204 -7
  22. package/dist/connectors/gmail.js +350 -47
  23. package/dist/connectors/google-ads.js +288 -46
  24. package/dist/connectors/google-analytics-oauth.js +310 -46
  25. package/dist/connectors/google-analytics.js +547 -87
  26. package/dist/connectors/google-audit-log.js +438 -47
  27. package/dist/connectors/google-calendar-oauth.js +259 -46
  28. package/dist/connectors/google-calendar.js +359 -47
  29. package/dist/connectors/google-docs.js +220 -6
  30. package/dist/connectors/google-drive.js +262 -5
  31. package/dist/connectors/google-search-console-oauth.js +256 -46
  32. package/dist/connectors/google-sheets.js +272 -47
  33. package/dist/connectors/google-slides.js +205 -6
  34. package/dist/connectors/grafana.js +332 -49
  35. package/dist/connectors/hubspot-oauth.js +208 -5
  36. package/dist/connectors/hubspot.js +306 -49
  37. package/dist/connectors/influxdb.js +416 -51
  38. package/dist/connectors/intercom-oauth.js +210 -5
  39. package/dist/connectors/intercom.js +302 -49
  40. package/dist/connectors/jdbc.js +762 -110
  41. package/dist/connectors/jira-api-key.js +326 -47
  42. package/dist/connectors/kintone-api-token.js +281 -47
  43. package/dist/connectors/kintone.js +328 -47
  44. package/dist/connectors/linear.js +330 -49
  45. package/dist/connectors/linkedin-ads.js +268 -50
  46. package/dist/connectors/mailchimp-oauth.js +268 -46
  47. package/dist/connectors/mailchimp.js +320 -49
  48. package/dist/connectors/meta-ads-oauth.js +273 -48
  49. package/dist/connectors/meta-ads.js +285 -50
  50. package/dist/connectors/mixpanel.js +338 -47
  51. package/dist/connectors/monday.js +360 -49
  52. package/dist/connectors/mongodb.js +319 -57
  53. package/dist/connectors/notion-oauth.js +231 -5
  54. package/dist/connectors/notion.js +323 -51
  55. package/dist/connectors/openai.js +134 -47
  56. package/dist/connectors/oracle.js +454 -103
  57. package/dist/connectors/outlook-oauth.js +204 -5
  58. package/dist/connectors/powerbi-oauth.js +498 -5
  59. package/dist/connectors/salesforce.js +384 -49
  60. package/dist/connectors/semrush.js +609 -49
  61. package/dist/connectors/sentry.js +289 -50
  62. package/dist/connectors/shopify-oauth.js +187 -5
  63. package/dist/connectors/shopify.js +357 -47
  64. package/dist/connectors/sqlserver.js +415 -102
  65. package/dist/connectors/stripe-api-key.js +269 -46
  66. package/dist/connectors/stripe-oauth.js +202 -5
  67. package/dist/connectors/supabase.js +303 -48
  68. package/dist/connectors/tableau.js +536 -163
  69. package/dist/connectors/tiktok-ads.js +279 -48
  70. package/dist/connectors/wix-store.js +320 -49
  71. package/dist/connectors/zendesk-oauth.js +239 -5
  72. package/dist/connectors/zendesk.js +358 -47
  73. package/dist/index.d.ts +149 -1
  74. package/dist/index.js +15057 -2117
  75. package/dist/main.js +15005 -2073
  76. package/dist/vite-plugin.js +14752 -2019
  77. 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 = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
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 = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
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: {