@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
@@ -185,6 +185,28 @@ var ConnectorPlugin = class _ConnectorPlugin {
185
185
  tools;
186
186
  query;
187
187
  checkConnection;
188
+ /**
189
+ * SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
190
+ * implement this expose a step-by-step exploration flow (database/schema/
191
+ * table/etc. discovery) that the dashboard backend drives via the
192
+ * `/connections/:connectionId/setup` endpoint. Implement by delegating to
193
+ * `runSetupFlow` from `setup-flow.ts`.
194
+ */
195
+ setup;
196
+ /**
197
+ * Opt-out of the default "verify before save" behavior on connection
198
+ * creation. The backend invokes `checkConnection` synchronously while
199
+ * creating the connection and aborts (no row inserted) if it fails — this
200
+ * flag disables that for connectors where the check cannot succeed pre-save:
201
+ *
202
+ * - `squadbase-db` populates `connection-url` only after Neon provisioning
203
+ * - OAuth connectors require an OAuth-aware proxyFetch keyed by the
204
+ * connectionId, which doesn't exist until the row is saved
205
+ *
206
+ * Exceptions are the explicit position; new credential-input connectors get
207
+ * the default verify-on-create behavior without opt-in.
208
+ */
209
+ skipConnectionCheckOnCreate;
188
210
  constructor(config) {
189
211
  this.slug = config.slug;
190
212
  this.authType = config.authType;
@@ -201,6 +223,8 @@ var ConnectorPlugin = class _ConnectorPlugin {
201
223
  this.tools = config.tools;
202
224
  this.query = config.query;
203
225
  this.checkConnection = config.checkConnection;
226
+ this.setup = config.setup;
227
+ this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
204
228
  }
205
229
  get connectorKey() {
206
230
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -265,6 +289,76 @@ var ConnectorPlugin = class _ConnectorPlugin {
265
289
  }
266
290
  };
267
291
 
292
+ // ../connectors/src/setup-flow.ts
293
+ async function runSetupFlow(flow, params, ctx, config) {
294
+ const runtime = {
295
+ params,
296
+ language: ctx.language,
297
+ config
298
+ };
299
+ let state = flow.initialState();
300
+ let answerIdx = 0;
301
+ const pendingParameterUpdates = [];
302
+ for (const step of flow.steps) {
303
+ const ans = ctx.answers[answerIdx];
304
+ if (ans && ans.questionSlug === step.slug) {
305
+ state = step.applyAnswer(state, ans.answer);
306
+ if (step.toParameterUpdates) {
307
+ pendingParameterUpdates.push(...step.toParameterUpdates(state));
308
+ }
309
+ answerIdx += 1;
310
+ continue;
311
+ }
312
+ const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
313
+ if (step.type === "text") {
314
+ if (step.fetchOptions) {
315
+ const options2 = await step.fetchOptions(state, runtime);
316
+ if (options2.length === 0) {
317
+ continue;
318
+ }
319
+ }
320
+ return {
321
+ type: "nextQuestion",
322
+ questionSlug: step.slug,
323
+ question: step.question[ctx.language],
324
+ questionType: "text",
325
+ allowFreeText: resolvedAllowFreeText,
326
+ ...pendingParameterUpdates.length > 0 && {
327
+ parameterUpdates: pendingParameterUpdates
328
+ }
329
+ };
330
+ }
331
+ const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
332
+ if (options.length === 0) {
333
+ continue;
334
+ }
335
+ return {
336
+ type: "nextQuestion",
337
+ questionSlug: step.slug,
338
+ question: step.question[ctx.language],
339
+ questionType: step.type,
340
+ options,
341
+ allowFreeText: resolvedAllowFreeText,
342
+ ...pendingParameterUpdates.length > 0 && {
343
+ parameterUpdates: pendingParameterUpdates
344
+ }
345
+ };
346
+ }
347
+ const dataInvestigationResult = await flow.finalize(state, runtime);
348
+ return {
349
+ type: "fulfilled",
350
+ dataInvestigationResult,
351
+ ...pendingParameterUpdates.length > 0 && {
352
+ parameterUpdates: pendingParameterUpdates
353
+ }
354
+ };
355
+ }
356
+ async function resolveSetupSelection(params) {
357
+ const { selected, allSentinel, fetchAll, limit } = params;
358
+ const resolved = selected.includes(allSentinel) ? await fetchAll() : selected.filter((v) => v !== allSentinel);
359
+ return resolved.slice(0, limit);
360
+ }
361
+
268
362
  // ../connectors/src/auth-types.ts
269
363
  var AUTH_TYPES = {
270
364
  OAUTH: "oauth",
@@ -463,6 +557,89 @@ Calendar
463
557
  }
464
558
  });
465
559
 
560
+ // ../connectors/src/connectors/outlook-oauth/utils.ts
561
+ async function graphApiFetch(config, url) {
562
+ const res = await config.proxyFetch(url, { method: "GET" });
563
+ if (!res.ok) {
564
+ const text = await res.text().catch(() => res.statusText);
565
+ throw new Error(`Microsoft Graph ${url} failed: HTTP ${res.status} ${text}`);
566
+ }
567
+ return await res.json();
568
+ }
569
+
570
+ // ../connectors/src/connectors/outlook-oauth/setup-flow.ts
571
+ var ALL_FOLDERS = "__ALL_FOLDERS__";
572
+ var OUTLOOK_SETUP_MAX_FOLDERS = 20;
573
+ async function listMailFolders(config) {
574
+ const url = "https://graph.microsoft.com/v1.0/me/mailFolders?$top=100&$select=id,displayName,parentFolderId,childFolderCount,unreadItemCount,totalItemCount";
575
+ const data = await graphApiFetch(config, url);
576
+ return data.value ?? [];
577
+ }
578
+ var outlookOauthSetupFlow = {
579
+ initialState: () => ({}),
580
+ steps: [
581
+ {
582
+ slug: "folders",
583
+ type: "multiSelect",
584
+ question: {
585
+ ja: "\u5BFE\u8C61\u306E\u30E1\u30FC\u30EB\u30D5\u30A9\u30EB\u30C0\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
586
+ en: "Select target mail folders (multi-select allowed)"
587
+ },
588
+ async fetchOptions(_state, rt) {
589
+ const folders = await listMailFolders(rt.config);
590
+ return [
591
+ {
592
+ value: ALL_FOLDERS,
593
+ label: rt.language === "ja" ? "\u3059\u3079\u3066\u306E\u30D5\u30A9\u30EB\u30C0" : "All folders"
594
+ },
595
+ ...folders.map((f) => ({
596
+ value: f.id,
597
+ label: f.displayName ?? f.id
598
+ }))
599
+ ];
600
+ },
601
+ applyAnswer: (state, answer) => ({ ...state, folders: answer })
602
+ }
603
+ ],
604
+ async finalize(state, rt) {
605
+ if (!state.folders) {
606
+ throw new Error("Outlook setup: incomplete state on finalize");
607
+ }
608
+ const folders = await listMailFolders(rt.config);
609
+ const byId = new Map(folders.map((f) => [f.id, f]));
610
+ const targetIds = await resolveSetupSelection({
611
+ selected: state.folders,
612
+ allSentinel: ALL_FOLDERS,
613
+ fetchAll: async () => folders.map((f) => f.id),
614
+ limit: OUTLOOK_SETUP_MAX_FOLDERS
615
+ });
616
+ const sections = ["## Outlook", ""];
617
+ if (targetIds.length === 0) {
618
+ sections.push(
619
+ rt.language === "ja" ? "\u5BFE\u8C61\u306E\u30D5\u30A9\u30EB\u30C0\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002" : "No folders selected."
620
+ );
621
+ return sections.join("\n");
622
+ }
623
+ sections.push("| Folder | Total | Unread | Sub-folders |");
624
+ sections.push("|--------|-------|--------|-------------|");
625
+ for (const id of targetIds) {
626
+ const f = byId.get(id);
627
+ if (!f) {
628
+ sections.push(`| ${id} | - | - | - |`);
629
+ continue;
630
+ }
631
+ const total = f.totalItemCount ?? "-";
632
+ const unread = f.unreadItemCount ?? "-";
633
+ const subs = f.childFolderCount ?? 0;
634
+ sections.push(
635
+ `| ${f.displayName ?? id} | ${total} | ${unread} | ${subs} |`
636
+ );
637
+ }
638
+ sections.push("");
639
+ return sections.join("\n");
640
+ }
641
+ };
642
+
466
643
  // ../connectors/src/connectors/outlook-oauth/parameters.ts
467
644
  var parameters = {};
468
645
 
@@ -471,6 +648,7 @@ var tools = { request: requestTool };
471
648
  var outlookOauthConnector = new ConnectorPlugin({
472
649
  slug: "outlook",
473
650
  authType: AUTH_TYPES.OAUTH,
651
+ skipConnectionCheckOnCreate: true,
474
652
  name: "Outlook",
475
653
  description: "Connect to Microsoft Outlook (Mail + Calendar) via Microsoft Graph using OAuth. Read-only access to the user's mailbox, mail folders, messages, attachments, calendars, and events.",
476
654
  iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/1J1FrRTYJjOh3CcSIqsz3I/6a467b4d926075ff99dc60820e0ae4b1/Microsoft_Outlook_Icon__2025%C3%A2__present_.svg",
@@ -755,6 +933,7 @@ events.value.forEach(e => console.log(e.start.dateTime, e.subject));
755
933
  \`\`\``
756
934
  },
757
935
  tools,
936
+ setup: (params, ctx, config) => runSetupFlow(outlookOauthSetupFlow, params, ctx, config),
758
937
  async checkConnection(_params, config) {
759
938
  const { proxyFetch } = config;
760
939
  const url = "https://graph.microsoft.com/v1.0/me";
@@ -803,6 +982,7 @@ function resolveEnvVarOptional(entry, key) {
803
982
  import { getContext } from "hono/context-storage";
804
983
  import { getCookie } from "hono/cookie";
805
984
  var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
985
+ var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
806
986
  function normalizeHeaders(input) {
807
987
  const out = {};
808
988
  if (!input) return out;
@@ -811,6 +991,11 @@ function normalizeHeaders(input) {
811
991
  });
812
992
  return out;
813
993
  }
994
+ function extractInputUrl(input) {
995
+ if (typeof input === "string") return input;
996
+ if (input instanceof URL) return input.href;
997
+ return input.url;
998
+ }
814
999
  function createSandboxProxyFetch(connectionId) {
815
1000
  return async (input, init) => {
816
1001
  const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
@@ -820,10 +1005,17 @@ function createSandboxProxyFetch(connectionId) {
820
1005
  "Connection proxy is not configured. Please check your deployment settings."
821
1006
  );
822
1007
  }
823
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
1008
+ const originalUrl = extractInputUrl(input);
1009
+ const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
1010
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
1011
+ const sessionUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
1012
+ return fetch(sessionUrl, {
1013
+ method: "POST",
1014
+ headers: { Authorization: `Bearer ${token}` }
1015
+ });
1016
+ }
824
1017
  const originalMethod = init?.method ?? "GET";
825
1018
  const originalBody = init?.body ? JSON.parse(init.body) : void 0;
826
- const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
827
1019
  const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
828
1020
  return fetch(proxyUrl, {
829
1021
  method: "POST",
@@ -849,10 +1041,9 @@ function createDeployedAppProxyFetch(connectionId) {
849
1041
  }
850
1042
  const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
851
1043
  const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
1044
+ const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
852
1045
  return async (input, init) => {
853
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
854
- const originalMethod = init?.method ?? "GET";
855
- const originalBody = init?.body ? JSON.parse(init.body) : void 0;
1046
+ const originalUrl = extractInputUrl(input);
856
1047
  const c = getContext();
857
1048
  const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
858
1049
  if (!appSession) {
@@ -860,6 +1051,14 @@ function createDeployedAppProxyFetch(connectionId) {
860
1051
  "No authentication method available for connection proxy."
861
1052
  );
862
1053
  }
1054
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
1055
+ return fetch(sessionUrl, {
1056
+ method: "POST",
1057
+ headers: { Authorization: `Bearer ${appSession}` }
1058
+ });
1059
+ }
1060
+ const originalMethod = init?.method ?? "GET";
1061
+ const originalBody = init?.body ? JSON.parse(init.body) : void 0;
863
1062
  return fetch(proxyUrl, {
864
1063
  method: "POST",
865
1064
  headers: {