@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
@@ -1,46 +1,57 @@
1
+ var __getOwnPropNames = Object.getOwnPropertyNames;
2
+ var __esm = (fn, res) => function __init() {
3
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
4
+ };
5
+
1
6
  // ../connectors/src/parameter-definition.ts
2
- var ParameterDefinition = class {
3
- slug;
4
- name;
5
- description;
6
- envVarBaseKey;
7
- type;
8
- secret;
9
- required;
10
- constructor(config) {
11
- this.slug = config.slug;
12
- this.name = config.name;
13
- this.description = config.description;
14
- this.envVarBaseKey = config.envVarBaseKey;
15
- this.type = config.type;
16
- this.secret = config.secret;
17
- this.required = config.required;
18
- }
19
- /**
20
- * Get the parameter value from a ConnectorConnectionObject.
21
- */
22
- getValue(connection2) {
23
- const param = connection2.parameters.find(
24
- (p) => p.parameterSlug === this.slug
25
- );
26
- if (!param || param.value == null) {
27
- throw new Error(
28
- `Parameter "${this.slug}" not found or has no value in connection "${connection2.id}"`
29
- );
30
- }
31
- return param.value;
32
- }
33
- /**
34
- * Try to get the parameter value. Returns undefined if not found (for optional params).
35
- */
36
- tryGetValue(connection2) {
37
- const param = connection2.parameters.find(
38
- (p) => p.parameterSlug === this.slug
39
- );
40
- if (!param || param.value == null) return void 0;
41
- return param.value;
7
+ var ParameterDefinition;
8
+ var init_parameter_definition = __esm({
9
+ "../connectors/src/parameter-definition.ts"() {
10
+ "use strict";
11
+ ParameterDefinition = class {
12
+ slug;
13
+ name;
14
+ description;
15
+ envVarBaseKey;
16
+ type;
17
+ secret;
18
+ required;
19
+ constructor(config) {
20
+ this.slug = config.slug;
21
+ this.name = config.name;
22
+ this.description = config.description;
23
+ this.envVarBaseKey = config.envVarBaseKey;
24
+ this.type = config.type;
25
+ this.secret = config.secret;
26
+ this.required = config.required;
27
+ }
28
+ /**
29
+ * Get the parameter value from a ConnectorConnectionObject.
30
+ */
31
+ getValue(connection2) {
32
+ const param = connection2.parameters.find(
33
+ (p) => p.parameterSlug === this.slug
34
+ );
35
+ if (!param || param.value == null) {
36
+ throw new Error(
37
+ `Parameter "${this.slug}" not found or has no value in connection "${connection2.id}"`
38
+ );
39
+ }
40
+ return param.value;
41
+ }
42
+ /**
43
+ * Try to get the parameter value. Returns undefined if not found (for optional params).
44
+ */
45
+ tryGetValue(connection2) {
46
+ const param = connection2.parameters.find(
47
+ (p) => p.parameterSlug === this.slug
48
+ );
49
+ if (!param || param.value == null) return void 0;
50
+ return param.value;
51
+ }
52
+ };
42
53
  }
43
- };
54
+ });
44
55
 
45
56
  // ../connectors/src/connectors/mailchimp-oauth/sdk/index.ts
46
57
  function createClient(params, fetchFn = fetch) {
@@ -117,6 +128,28 @@ var ConnectorPlugin = class _ConnectorPlugin {
117
128
  tools;
118
129
  query;
119
130
  checkConnection;
131
+ /**
132
+ * SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
133
+ * implement this expose a step-by-step exploration flow (database/schema/
134
+ * table/etc. discovery) that the dashboard backend drives via the
135
+ * `/connections/:connectionId/setup` endpoint. Implement by delegating to
136
+ * `runSetupFlow` from `setup-flow.ts`.
137
+ */
138
+ setup;
139
+ /**
140
+ * Opt-out of the default "verify before save" behavior on connection
141
+ * creation. The backend invokes `checkConnection` synchronously while
142
+ * creating the connection and aborts (no row inserted) if it fails — this
143
+ * flag disables that for connectors where the check cannot succeed pre-save:
144
+ *
145
+ * - `squadbase-db` populates `connection-url` only after Neon provisioning
146
+ * - OAuth connectors require an OAuth-aware proxyFetch keyed by the
147
+ * connectionId, which doesn't exist until the row is saved
148
+ *
149
+ * Exceptions are the explicit position; new credential-input connectors get
150
+ * the default verify-on-create behavior without opt-in.
151
+ */
152
+ skipConnectionCheckOnCreate;
120
153
  constructor(config) {
121
154
  this.slug = config.slug;
122
155
  this.authType = config.authType;
@@ -133,6 +166,8 @@ var ConnectorPlugin = class _ConnectorPlugin {
133
166
  this.tools = config.tools;
134
167
  this.query = config.query;
135
168
  this.checkConnection = config.checkConnection;
169
+ this.setup = config.setup;
170
+ this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
136
171
  }
137
172
  get connectorKey() {
138
173
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -197,6 +232,76 @@ var ConnectorPlugin = class _ConnectorPlugin {
197
232
  }
198
233
  };
199
234
 
235
+ // ../connectors/src/setup-flow.ts
236
+ async function runSetupFlow(flow, params, ctx, config) {
237
+ const runtime = {
238
+ params,
239
+ language: ctx.language,
240
+ config
241
+ };
242
+ let state = flow.initialState();
243
+ let answerIdx = 0;
244
+ const pendingParameterUpdates = [];
245
+ for (const step of flow.steps) {
246
+ const ans = ctx.answers[answerIdx];
247
+ if (ans && ans.questionSlug === step.slug) {
248
+ state = step.applyAnswer(state, ans.answer);
249
+ if (step.toParameterUpdates) {
250
+ pendingParameterUpdates.push(...step.toParameterUpdates(state));
251
+ }
252
+ answerIdx += 1;
253
+ continue;
254
+ }
255
+ const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
256
+ if (step.type === "text") {
257
+ if (step.fetchOptions) {
258
+ const options2 = await step.fetchOptions(state, runtime);
259
+ if (options2.length === 0) {
260
+ continue;
261
+ }
262
+ }
263
+ return {
264
+ type: "nextQuestion",
265
+ questionSlug: step.slug,
266
+ question: step.question[ctx.language],
267
+ questionType: "text",
268
+ allowFreeText: resolvedAllowFreeText,
269
+ ...pendingParameterUpdates.length > 0 && {
270
+ parameterUpdates: pendingParameterUpdates
271
+ }
272
+ };
273
+ }
274
+ const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
275
+ if (options.length === 0) {
276
+ continue;
277
+ }
278
+ return {
279
+ type: "nextQuestion",
280
+ questionSlug: step.slug,
281
+ question: step.question[ctx.language],
282
+ questionType: step.type,
283
+ options,
284
+ allowFreeText: resolvedAllowFreeText,
285
+ ...pendingParameterUpdates.length > 0 && {
286
+ parameterUpdates: pendingParameterUpdates
287
+ }
288
+ };
289
+ }
290
+ const dataInvestigationResult = await flow.finalize(state, runtime);
291
+ return {
292
+ type: "fulfilled",
293
+ dataInvestigationResult,
294
+ ...pendingParameterUpdates.length > 0 && {
295
+ parameterUpdates: pendingParameterUpdates
296
+ }
297
+ };
298
+ }
299
+ async function resolveSetupSelection(params) {
300
+ const { selected, allSentinel, fetchAll, limit } = params;
301
+ const resolved = selected.includes(allSentinel) ? await fetchAll() : selected.filter((v) => v !== allSentinel);
302
+ return resolved.slice(0, limit);
303
+ }
304
+
200
305
  // ../connectors/src/auth-types.ts
201
306
  var AUTH_TYPES = {
202
307
  OAUTH: "oauth",
@@ -222,6 +327,7 @@ var mailchimpOauthOnboarding = new ConnectorOnboarding({
222
327
  });
223
328
 
224
329
  // ../connectors/src/connectors/mailchimp-oauth/parameters.ts
330
+ init_parameter_definition();
225
331
  var parameters = {
226
332
  serverPrefix: new ParameterDefinition({
227
333
  slug: "server-prefix",
@@ -234,6 +340,100 @@ var parameters = {
234
340
  })
235
341
  };
236
342
 
343
+ // ../connectors/src/connectors/mailchimp-oauth/utils.ts
344
+ function apiFetch(params, proxyFetch, path2, init) {
345
+ const serverPrefix = params[parameters.serverPrefix.slug];
346
+ if (!serverPrefix) {
347
+ throw new Error(
348
+ "mailchimp-oauth: missing required parameter: server-prefix"
349
+ );
350
+ }
351
+ const baseUrl = `https://${serverPrefix}.api.mailchimp.com/3.0`;
352
+ const url = `${baseUrl}${path2.startsWith("/") ? "" : "/"}${path2}`;
353
+ return proxyFetch(url, init);
354
+ }
355
+
356
+ // ../connectors/src/connectors/mailchimp-oauth/setup-flow.ts
357
+ var ALL_AUDIENCES = "__ALL_AUDIENCES__";
358
+ var MAILCHIMP_SETUP_MAX_AUDIENCES = 10;
359
+ async function listAudiences(params, proxyFetch) {
360
+ const res = await apiFetch(
361
+ params,
362
+ proxyFetch,
363
+ "/lists?count=1000&fields=lists.id,lists.name,lists.stats"
364
+ );
365
+ if (!res.ok) {
366
+ const body = await res.text().catch(() => res.statusText);
367
+ throw new Error(
368
+ `mailchimp-oauth: listAudiences failed (${res.status}): ${body}`
369
+ );
370
+ }
371
+ const data = await res.json();
372
+ return data.lists ?? [];
373
+ }
374
+ var mailchimpOauthSetupFlow = {
375
+ initialState: () => ({}),
376
+ steps: [
377
+ {
378
+ slug: "audiences",
379
+ type: "multiSelect",
380
+ question: {
381
+ ja: "\u5BFE\u8C61\u30AA\u30FC\u30C7\u30A3\u30A8\u30F3\u30B9\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
382
+ en: "Select target audiences (multi-select allowed)"
383
+ },
384
+ async fetchOptions(_state, rt) {
385
+ const lists = await listAudiences(rt.params, rt.config.proxyFetch);
386
+ const opts = lists.filter((l) => l.id && l.name).map((l) => ({ value: l.id, label: l.name }));
387
+ if (opts.length === 0) return [];
388
+ return [
389
+ {
390
+ value: ALL_AUDIENCES,
391
+ label: rt.language === "ja" ? "\u3059\u3079\u3066\u306E\u30AA\u30FC\u30C7\u30A3\u30A8\u30F3\u30B9" : "All audiences"
392
+ },
393
+ ...opts
394
+ ];
395
+ },
396
+ applyAnswer: (state, answer) => ({ ...state, audiences: answer })
397
+ }
398
+ ],
399
+ async finalize(state, rt) {
400
+ if (!state.audiences) {
401
+ throw new Error("Mailchimp setup: incomplete state on finalize");
402
+ }
403
+ const lists = await listAudiences(rt.params, rt.config.proxyFetch);
404
+ const listById = new Map(lists.map((l) => [l.id, l]));
405
+ const targetIds = await resolveSetupSelection({
406
+ selected: state.audiences,
407
+ allSentinel: ALL_AUDIENCES,
408
+ fetchAll: async () => lists.map((l) => l.id).filter((id) => id),
409
+ limit: MAILCHIMP_SETUP_MAX_AUDIENCES
410
+ });
411
+ const sections = ["## Mailchimp", ""];
412
+ for (const id of targetIds) {
413
+ const list = listById.get(id);
414
+ if (!list) {
415
+ sections.push(`### Audience: ${id}`, "", "_Not found._", "");
416
+ continue;
417
+ }
418
+ const stats = list.stats ?? {};
419
+ sections.push(`### Audience: ${list.name}`, "");
420
+ sections.push("| Metric | Value |");
421
+ sections.push("|--------|-------|");
422
+ sections.push(`| Members | ${stats.member_count ?? "-"} |`);
423
+ sections.push(`| Unsubscribed | ${stats.unsubscribe_count ?? "-"} |`);
424
+ sections.push(`| Cleaned | ${stats.cleaned_count ?? "-"} |`);
425
+ sections.push(
426
+ `| Open rate | ${stats.open_rate != null ? stats.open_rate : "-"} |`
427
+ );
428
+ sections.push(
429
+ `| Click rate | ${stats.click_rate != null ? stats.click_rate : "-"} |`
430
+ );
431
+ sections.push("");
432
+ }
433
+ return sections.join("\n");
434
+ }
435
+ };
436
+
237
437
  // ../connectors/src/connectors/mailchimp-oauth/tools/request.ts
238
438
  import { z } from "zod";
239
439
  var REQUEST_TIMEOUT_MS = 6e4;
@@ -355,6 +555,7 @@ var tools = { request: requestTool };
355
555
  var mailchimpOauthConnector = new ConnectorPlugin({
356
556
  slug: "mailchimp",
357
557
  authType: AUTH_TYPES.OAUTH,
558
+ skipConnectionCheckOnCreate: true,
358
559
  name: "Mailchimp (OAuth)",
359
560
  description: "Connect to Mailchimp for email marketing, audiences, campaigns, and analytics using OAuth.",
360
561
  iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/19Rac6B8eGiLpQb4lKMbG3/10f567f85572aeb16f2ee6aaa6602987/mailchimp.png",
@@ -489,6 +690,7 @@ const data = await res.json();
489
690
  \`\`\``
490
691
  },
491
692
  tools,
693
+ setup: (params, ctx, config) => runSetupFlow(mailchimpOauthSetupFlow, params, ctx, config),
492
694
  async checkConnection(params, config) {
493
695
  const { proxyFetch } = config;
494
696
  const serverPrefix = params["server-prefix"];
@@ -540,6 +742,7 @@ function resolveEnvVarOptional(entry, key) {
540
742
  import { getContext } from "hono/context-storage";
541
743
  import { getCookie } from "hono/cookie";
542
744
  var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
745
+ var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
543
746
  function normalizeHeaders(input) {
544
747
  const out = {};
545
748
  if (!input) return out;
@@ -548,6 +751,11 @@ function normalizeHeaders(input) {
548
751
  });
549
752
  return out;
550
753
  }
754
+ function extractInputUrl(input) {
755
+ if (typeof input === "string") return input;
756
+ if (input instanceof URL) return input.href;
757
+ return input.url;
758
+ }
551
759
  function createSandboxProxyFetch(connectionId) {
552
760
  return async (input, init) => {
553
761
  const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
@@ -557,10 +765,17 @@ function createSandboxProxyFetch(connectionId) {
557
765
  "Connection proxy is not configured. Please check your deployment settings."
558
766
  );
559
767
  }
560
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
768
+ const originalUrl = extractInputUrl(input);
769
+ const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
770
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
771
+ const sessionUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
772
+ return fetch(sessionUrl, {
773
+ method: "POST",
774
+ headers: { Authorization: `Bearer ${token}` }
775
+ });
776
+ }
561
777
  const originalMethod = init?.method ?? "GET";
562
778
  const originalBody = init?.body ? JSON.parse(init.body) : void 0;
563
- const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
564
779
  const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
565
780
  return fetch(proxyUrl, {
566
781
  method: "POST",
@@ -586,10 +801,9 @@ function createDeployedAppProxyFetch(connectionId) {
586
801
  }
587
802
  const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
588
803
  const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
804
+ const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
589
805
  return async (input, init) => {
590
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
591
- const originalMethod = init?.method ?? "GET";
592
- const originalBody = init?.body ? JSON.parse(init.body) : void 0;
806
+ const originalUrl = extractInputUrl(input);
593
807
  const c = getContext();
594
808
  const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
595
809
  if (!appSession) {
@@ -597,6 +811,14 @@ function createDeployedAppProxyFetch(connectionId) {
597
811
  "No authentication method available for connection proxy."
598
812
  );
599
813
  }
814
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
815
+ return fetch(sessionUrl, {
816
+ method: "POST",
817
+ headers: { Authorization: `Bearer ${appSession}` }
818
+ });
819
+ }
820
+ const originalMethod = init?.method ?? "GET";
821
+ const originalBody = init?.body ? JSON.parse(init.body) : void 0;
600
822
  return fetch(proxyUrl, {
601
823
  method: "POST",
602
824
  headers: {