@squadbase/vite-server 0.1.12-dev.a9ac647 → 0.1.17-dev.24af54e

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 +12374 -883
  2. package/dist/connectors/airtable-oauth.js +257 -46
  3. package/dist/connectors/airtable.js +294 -51
  4. package/dist/connectors/amplitude.js +297 -47
  5. package/dist/connectors/anthropic.js +135 -47
  6. package/dist/connectors/asana.js +302 -49
  7. package/dist/connectors/attio.js +277 -49
  8. package/dist/connectors/aws-billing.js +262 -46
  9. package/dist/connectors/azure-sql.js +396 -102
  10. package/dist/connectors/backlog-api-key.js +292 -47
  11. package/dist/connectors/clickup.js +313 -49
  12. package/dist/connectors/cosmosdb.js +280 -50
  13. package/dist/connectors/customerio.js +294 -47
  14. package/dist/connectors/dbt.js +315 -47
  15. package/dist/connectors/freshdesk.js +317 -53
  16. package/dist/connectors/freshsales.js +308 -52
  17. package/dist/connectors/freshservice.js +336 -53
  18. package/dist/connectors/gamma.js +302 -52
  19. package/dist/connectors/gemini.js +134 -47
  20. package/dist/connectors/github.js +361 -49
  21. package/dist/connectors/gmail-oauth.js +179 -7
  22. package/dist/connectors/gmail.js +325 -47
  23. package/dist/connectors/google-ads.js +263 -46
  24. package/dist/connectors/google-analytics-oauth.js +285 -46
  25. package/dist/connectors/google-analytics.js +387 -49
  26. package/dist/connectors/google-audit-log.js +413 -47
  27. package/dist/connectors/google-calendar-oauth.js +234 -46
  28. package/dist/connectors/google-calendar.js +334 -47
  29. package/dist/connectors/google-docs.js +195 -6
  30. package/dist/connectors/google-drive.js +237 -5
  31. package/dist/connectors/google-search-console-oauth.js +231 -46
  32. package/dist/connectors/google-sheets.js +247 -47
  33. package/dist/connectors/google-slides.js +180 -6
  34. package/dist/connectors/grafana.js +307 -49
  35. package/dist/connectors/hubspot-oauth.js +183 -5
  36. package/dist/connectors/hubspot.js +281 -49
  37. package/dist/connectors/influxdb.js +391 -51
  38. package/dist/connectors/intercom-oauth.js +185 -5
  39. package/dist/connectors/intercom.js +277 -49
  40. package/dist/connectors/jdbc.js +737 -110
  41. package/dist/connectors/jira-api-key.js +301 -47
  42. package/dist/connectors/kintone-api-token.js +256 -47
  43. package/dist/connectors/kintone.js +303 -47
  44. package/dist/connectors/linear.js +305 -49
  45. package/dist/connectors/linkedin-ads.js +243 -50
  46. package/dist/connectors/mailchimp-oauth.js +243 -46
  47. package/dist/connectors/mailchimp.js +295 -49
  48. package/dist/connectors/meta-ads-oauth.js +248 -48
  49. package/dist/connectors/meta-ads.js +260 -50
  50. package/dist/connectors/mixpanel.js +313 -47
  51. package/dist/connectors/monday.js +335 -49
  52. package/dist/connectors/mongodb.js +294 -57
  53. package/dist/connectors/notion-oauth.js +206 -5
  54. package/dist/connectors/notion.js +298 -51
  55. package/dist/connectors/openai.js +134 -47
  56. package/dist/connectors/oracle.js +414 -103
  57. package/dist/connectors/outlook-oauth.js +179 -5
  58. package/dist/connectors/powerbi-oauth.js +226 -5
  59. package/dist/connectors/salesforce.js +359 -49
  60. package/dist/connectors/semrush.js +289 -49
  61. package/dist/connectors/sentry.js +264 -50
  62. package/dist/connectors/shopify-oauth.js +162 -5
  63. package/dist/connectors/shopify.js +332 -47
  64. package/dist/connectors/sqlserver.js +390 -102
  65. package/dist/connectors/stripe-api-key.js +244 -46
  66. package/dist/connectors/stripe-oauth.js +177 -5
  67. package/dist/connectors/supabase.js +278 -48
  68. package/dist/connectors/tableau.js +389 -184
  69. package/dist/connectors/tiktok-ads.js +254 -48
  70. package/dist/connectors/wix-store.js +295 -49
  71. package/dist/connectors/zendesk-oauth.js +214 -5
  72. package/dist/connectors/zendesk.js +333 -47
  73. package/dist/index.d.ts +149 -1
  74. package/dist/index.js +13677 -1969
  75. package/dist/main.js +13627 -1927
  76. package/dist/vite-plugin.js +12391 -890
  77. 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,51 @@ 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
+ for (const step of flow.steps) {
182
+ const ans = ctx.answers[answerIdx];
183
+ if (ans && ans.questionSlug === step.slug) {
184
+ state = step.applyAnswer(state, ans.answer);
185
+ answerIdx += 1;
186
+ continue;
187
+ }
188
+ if (step.type === "text") {
189
+ return {
190
+ type: "nextQuestion",
191
+ questionSlug: step.slug,
192
+ question: step.question[ctx.language],
193
+ questionType: "text"
194
+ };
195
+ }
196
+ const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
197
+ if (options.length === 0) {
198
+ continue;
199
+ }
200
+ return {
201
+ type: "nextQuestion",
202
+ questionSlug: step.slug,
203
+ question: step.question[ctx.language],
204
+ questionType: step.type,
205
+ options
206
+ };
207
+ }
208
+ const dataInvestigationResult = await flow.finalize(state, runtime);
209
+ return { type: "fulfilled", dataInvestigationResult };
210
+ }
211
+ async function resolveSetupSelection(params) {
212
+ const { selected, allSentinel, fetchAll, limit } = params;
213
+ const resolved = selected.includes(allSentinel) ? await fetchAll() : selected.filter((v) => v !== allSentinel);
214
+ return resolved.slice(0, limit);
215
+ }
216
+
148
217
  // ../connectors/src/auth-types.ts
149
218
  var AUTH_TYPES = {
150
219
  OAUTH: "oauth",
@@ -309,6 +378,124 @@ var zendeskOauthOnboarding = new ConnectorOnboarding({
309
378
  }
310
379
  });
311
380
 
381
+ // ../connectors/src/connectors/zendesk-oauth/utils.ts
382
+ function apiFetch(proxyFetch, path2, init) {
383
+ const url = path2.startsWith("/") ? path2 : `/${path2}`;
384
+ const headers = new Headers(init?.headers);
385
+ headers.set("Accept", "application/json");
386
+ return proxyFetch(url, { ...init, headers });
387
+ }
388
+
389
+ // ../connectors/src/connectors/zendesk-oauth/setup-flow.ts
390
+ var ZENDESK_SETUP_MAX_ENTITIES = 5;
391
+ var ZENDESK_ENTITIES = [
392
+ {
393
+ value: "tickets",
394
+ label: "Tickets",
395
+ countPath: "/api/v2/tickets.json?page[size]=1"
396
+ },
397
+ {
398
+ value: "users",
399
+ label: "Users",
400
+ countPath: "/api/v2/users.json?page[size]=1"
401
+ },
402
+ {
403
+ value: "organizations",
404
+ label: "Organizations",
405
+ countPath: "/api/v2/organizations.json?page[size]=1"
406
+ },
407
+ {
408
+ value: "groups",
409
+ label: "Groups",
410
+ countPath: "/api/v2/groups.json?page[size]=1"
411
+ },
412
+ {
413
+ value: "articles",
414
+ label: "Help Center articles",
415
+ countPath: "/api/v2/help_center/articles.json?page[size]=1"
416
+ }
417
+ ];
418
+ async function listBrands(proxyFetch) {
419
+ const res = await apiFetch(proxyFetch, "/api/v2/brands.json");
420
+ if (!res.ok) return [];
421
+ const data = await res.json();
422
+ return data.brands ?? [];
423
+ }
424
+ async function fetchCount(proxyFetch, path2) {
425
+ const res = await apiFetch(proxyFetch, path2);
426
+ if (!res.ok) return null;
427
+ const data = await res.json();
428
+ if (typeof data["count"] === "number") return data["count"];
429
+ return null;
430
+ }
431
+ var zendeskOauthSetupFlow = {
432
+ initialState: () => ({}),
433
+ steps: [
434
+ {
435
+ slug: "brand",
436
+ type: "select",
437
+ question: {
438
+ ja: "\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3067\u5BFE\u8C61\u3068\u3059\u308BZendesk\u30D6\u30E9\u30F3\u30C9\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044",
439
+ en: "Select the Zendesk brand to use for setup"
440
+ },
441
+ async fetchOptions(_state, rt) {
442
+ const brands = await listBrands(rt.config.proxyFetch);
443
+ const active = brands.filter((b) => b.active !== false && b.name);
444
+ if (active.length < 2) return [];
445
+ return active.map((b) => ({
446
+ value: String(b.subdomain ?? b.id ?? b.name),
447
+ label: String(b.name)
448
+ }));
449
+ },
450
+ applyAnswer: (state, answer) => ({ ...state, brand: answer[0] })
451
+ },
452
+ {
453
+ slug: "entities",
454
+ type: "multiSelect",
455
+ question: {
456
+ ja: "\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3067\u6982\u89B3\u3057\u305F\u3044\u30A8\u30F3\u30C6\u30A3\u30C6\u30A3\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
457
+ en: "Select the entities to include in setup (multi-select allowed)"
458
+ },
459
+ async fetchOptions(_state, _rt) {
460
+ return ZENDESK_ENTITIES.map((e) => ({ value: e.value, label: e.label }));
461
+ },
462
+ applyAnswer: (state, answer) => ({ ...state, entities: answer })
463
+ }
464
+ ],
465
+ async finalize(state, rt) {
466
+ if (!state.entities) {
467
+ throw new Error("Zendesk setup: incomplete state on finalize");
468
+ }
469
+ const targetEntities = await resolveSetupSelection({
470
+ selected: state.entities,
471
+ allSentinel: "__ALL__",
472
+ fetchAll: async () => ZENDESK_ENTITIES.map((e) => e.value),
473
+ limit: ZENDESK_SETUP_MAX_ENTITIES
474
+ });
475
+ const entityByValue = new Map(ZENDESK_ENTITIES.map((e) => [e.value, e]));
476
+ const sections = ["## Zendesk", ""];
477
+ if (state.brand) {
478
+ sections.push(`### Brand: ${state.brand}`, "");
479
+ }
480
+ sections.push("### Selected entities", "");
481
+ sections.push("| Entity | Count |");
482
+ sections.push("|--------|-------|");
483
+ for (const value of targetEntities) {
484
+ const entity = entityByValue.get(value);
485
+ if (!entity) {
486
+ sections.push(`| ${value} | _unknown_ |`);
487
+ continue;
488
+ }
489
+ const count = await fetchCount(rt.config.proxyFetch, entity.countPath);
490
+ sections.push(
491
+ `| ${entity.label} (${entity.value}) | ${count == null ? "-" : count} |`
492
+ );
493
+ }
494
+ sections.push("");
495
+ return sections.join("\n");
496
+ }
497
+ };
498
+
312
499
  // ../connectors/src/connectors/zendesk-oauth/parameters.ts
313
500
  var parameters = {};
314
501
 
@@ -317,6 +504,7 @@ var tools = { request: requestTool };
317
504
  var zendeskOauthConnector = new ConnectorPlugin({
318
505
  slug: "zendesk",
319
506
  authType: AUTH_TYPES.OAUTH,
507
+ skipConnectionCheckOnCreate: true,
320
508
  name: "Zendesk",
321
509
  description: "Connect to Zendesk Support for tickets, users, organizations, and customer service data using OAuth.",
322
510
  iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/7e9Q7PwV6MJRJMj543m2gl/55385fae903ccfa1599e35be9d3516aa/zendesk-icon.svg",
@@ -451,6 +639,7 @@ const data = await res.json();
451
639
  \`\`\``
452
640
  },
453
641
  tools,
642
+ setup: (params, ctx, config) => runSetupFlow(zendeskOauthSetupFlow, params, ctx, config),
454
643
  async checkConnection(_params, config) {
455
644
  const { proxyFetch } = config;
456
645
  try {
@@ -500,6 +689,7 @@ function resolveEnvVarOptional(entry, key) {
500
689
  import { getContext } from "hono/context-storage";
501
690
  import { getCookie } from "hono/cookie";
502
691
  var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
692
+ var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
503
693
  function normalizeHeaders(input) {
504
694
  const out = {};
505
695
  if (!input) return out;
@@ -508,6 +698,11 @@ function normalizeHeaders(input) {
508
698
  });
509
699
  return out;
510
700
  }
701
+ function extractInputUrl(input) {
702
+ if (typeof input === "string") return input;
703
+ if (input instanceof URL) return input.href;
704
+ return input.url;
705
+ }
511
706
  function createSandboxProxyFetch(connectionId) {
512
707
  return async (input, init) => {
513
708
  const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
@@ -517,10 +712,17 @@ function createSandboxProxyFetch(connectionId) {
517
712
  "Connection proxy is not configured. Please check your deployment settings."
518
713
  );
519
714
  }
520
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
715
+ const originalUrl = extractInputUrl(input);
716
+ const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
717
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
718
+ const sessionUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
719
+ return fetch(sessionUrl, {
720
+ method: "POST",
721
+ headers: { Authorization: `Bearer ${token}` }
722
+ });
723
+ }
521
724
  const originalMethod = init?.method ?? "GET";
522
725
  const originalBody = init?.body ? JSON.parse(init.body) : void 0;
523
- const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
524
726
  const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
525
727
  return fetch(proxyUrl, {
526
728
  method: "POST",
@@ -546,10 +748,9 @@ function createDeployedAppProxyFetch(connectionId) {
546
748
  }
547
749
  const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
548
750
  const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
751
+ const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
549
752
  return async (input, init) => {
550
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
551
- const originalMethod = init?.method ?? "GET";
552
- const originalBody = init?.body ? JSON.parse(init.body) : void 0;
753
+ const originalUrl = extractInputUrl(input);
553
754
  const c = getContext();
554
755
  const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
555
756
  if (!appSession) {
@@ -557,6 +758,14 @@ function createDeployedAppProxyFetch(connectionId) {
557
758
  "No authentication method available for connection proxy."
558
759
  );
559
760
  }
761
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
762
+ return fetch(sessionUrl, {
763
+ method: "POST",
764
+ headers: { Authorization: `Bearer ${appSession}` }
765
+ });
766
+ }
767
+ const originalMethod = init?.method ?? "GET";
768
+ const originalBody = init?.body ? JSON.parse(init.body) : void 0;
560
769
  return fetch(proxyUrl, {
561
770
  method: "POST",
562
771
  headers: {