@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",
@@ -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 = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
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 = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
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: {