@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
@@ -1,48 +1,60 @@
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/google-analytics-oauth/parameters.ts
57
+ init_parameter_definition();
46
58
  var parameters = {
47
59
  propertyId: new ParameterDefinition({
48
60
  slug: "property-id",
@@ -194,6 +206,28 @@ var ConnectorPlugin = class _ConnectorPlugin {
194
206
  tools;
195
207
  query;
196
208
  checkConnection;
209
+ /**
210
+ * SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
211
+ * implement this expose a step-by-step exploration flow (database/schema/
212
+ * table/etc. discovery) that the dashboard backend drives via the
213
+ * `/connections/:connectionId/setup` endpoint. Implement by delegating to
214
+ * `runSetupFlow` from `setup-flow.ts`.
215
+ */
216
+ setup;
217
+ /**
218
+ * Opt-out of the default "verify before save" behavior on connection
219
+ * creation. The backend invokes `checkConnection` synchronously while
220
+ * creating the connection and aborts (no row inserted) if it fails — this
221
+ * flag disables that for connectors where the check cannot succeed pre-save:
222
+ *
223
+ * - `squadbase-db` populates `connection-url` only after Neon provisioning
224
+ * - OAuth connectors require an OAuth-aware proxyFetch keyed by the
225
+ * connectionId, which doesn't exist until the row is saved
226
+ *
227
+ * Exceptions are the explicit position; new credential-input connectors get
228
+ * the default verify-on-create behavior without opt-in.
229
+ */
230
+ skipConnectionCheckOnCreate;
197
231
  constructor(config) {
198
232
  this.slug = config.slug;
199
233
  this.authType = config.authType;
@@ -210,6 +244,8 @@ var ConnectorPlugin = class _ConnectorPlugin {
210
244
  this.tools = config.tools;
211
245
  this.query = config.query;
212
246
  this.checkConnection = config.checkConnection;
247
+ this.setup = config.setup;
248
+ this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
213
249
  }
214
250
  get connectorKey() {
215
251
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -274,6 +310,51 @@ var ConnectorPlugin = class _ConnectorPlugin {
274
310
  }
275
311
  };
276
312
 
313
+ // ../connectors/src/setup-flow.ts
314
+ async function runSetupFlow(flow, params, ctx, config) {
315
+ const runtime = {
316
+ params,
317
+ language: ctx.language,
318
+ config
319
+ };
320
+ let state = flow.initialState();
321
+ let answerIdx = 0;
322
+ for (const step of flow.steps) {
323
+ const ans = ctx.answers[answerIdx];
324
+ if (ans && ans.questionSlug === step.slug) {
325
+ state = step.applyAnswer(state, ans.answer);
326
+ answerIdx += 1;
327
+ continue;
328
+ }
329
+ if (step.type === "text") {
330
+ return {
331
+ type: "nextQuestion",
332
+ questionSlug: step.slug,
333
+ question: step.question[ctx.language],
334
+ questionType: "text"
335
+ };
336
+ }
337
+ const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
338
+ if (options.length === 0) {
339
+ continue;
340
+ }
341
+ return {
342
+ type: "nextQuestion",
343
+ questionSlug: step.slug,
344
+ question: step.question[ctx.language],
345
+ questionType: step.type,
346
+ options
347
+ };
348
+ }
349
+ const dataInvestigationResult = await flow.finalize(state, runtime);
350
+ return { type: "fulfilled", dataInvestigationResult };
351
+ }
352
+ async function resolveSetupSelection(params) {
353
+ const { selected, allSentinel, fetchAll, limit } = params;
354
+ const resolved = selected.includes(allSentinel) ? await fetchAll() : selected.filter((v) => v !== allSentinel);
355
+ return resolved.slice(0, limit);
356
+ }
357
+
277
358
  // ../connectors/src/auth-types.ts
278
359
  var AUTH_TYPES = {
279
360
  OAUTH: "oauth",
@@ -564,6 +645,142 @@ var googleAnalyticsOauthOnboarding = new ConnectorOnboarding({
564
645
  }
565
646
  });
566
647
 
648
+ // ../connectors/src/connectors/google-analytics-oauth/setup-flow.ts
649
+ var ADMIN_BASE_URL3 = "https://analyticsadmin.googleapis.com/v1beta";
650
+ var ALL_PROPERTIES = "__ALL_PROPERTIES__";
651
+ var GOOGLE_ANALYTICS_OAUTH_SETUP_MAX_PROPERTIES = 20;
652
+ async function listAccountSummaries(proxyFetch) {
653
+ const summaries = [];
654
+ let pageToken;
655
+ do {
656
+ const url = pageToken ? `${ADMIN_BASE_URL3}/accountSummaries?pageToken=${encodeURIComponent(pageToken)}` : `${ADMIN_BASE_URL3}/accountSummaries`;
657
+ const res = await proxyFetch(url, { method: "GET" });
658
+ if (!res.ok) {
659
+ const body = await res.text().catch(() => res.statusText);
660
+ throw new Error(
661
+ `google-analytics-oauth: accountSummaries failed (${res.status}): ${body}`
662
+ );
663
+ }
664
+ const data = await res.json();
665
+ summaries.push(...data.accountSummaries ?? []);
666
+ pageToken = data.nextPageToken;
667
+ } while (pageToken);
668
+ return summaries;
669
+ }
670
+ function propertyIdFromResource(resource) {
671
+ return (resource ?? "").replace(/^properties\//, "");
672
+ }
673
+ async function getProperty(proxyFetch, propertyId) {
674
+ const res = await proxyFetch(`${ADMIN_BASE_URL3}/properties/${propertyId}`, {
675
+ method: "GET"
676
+ });
677
+ if (!res.ok) return null;
678
+ return await res.json();
679
+ }
680
+ var googleAnalyticsOauthSetupFlow = {
681
+ initialState: () => ({}),
682
+ steps: [
683
+ {
684
+ slug: "account",
685
+ type: "select",
686
+ question: {
687
+ ja: "Google Analytics \u30A2\u30AB\u30A6\u30F3\u30C8\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044",
688
+ en: "Select a Google Analytics account"
689
+ },
690
+ async fetchOptions(_state, rt) {
691
+ const summaries = await listAccountSummaries(rt.config.proxyFetch);
692
+ return summaries.map((s) => {
693
+ const accountResource = s.account ?? s.name ?? "";
694
+ if (!accountResource) return null;
695
+ return {
696
+ value: accountResource,
697
+ label: s.displayName ?? accountResource
698
+ };
699
+ }).filter((v) => v != null);
700
+ },
701
+ applyAnswer: (state, answer) => ({ ...state, account: answer[0] })
702
+ },
703
+ {
704
+ slug: "properties",
705
+ type: "multiSelect",
706
+ question: {
707
+ ja: "\u5BFE\u8C61\u306E GA4 \u30D7\u30ED\u30D1\u30C6\u30A3\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
708
+ en: "Select target GA4 properties (multi-select allowed)"
709
+ },
710
+ async fetchOptions(state, rt) {
711
+ if (!state.account) return [];
712
+ const summaries = await listAccountSummaries(rt.config.proxyFetch);
713
+ const account = summaries.find(
714
+ (s) => (s.account ?? s.name) === state.account
715
+ );
716
+ const props = (account?.propertySummaries ?? []).map((p) => {
717
+ const id = propertyIdFromResource(p.property);
718
+ if (!id) return null;
719
+ return {
720
+ value: id,
721
+ label: p.displayName ? `${p.displayName} (${id})` : id
722
+ };
723
+ }).filter((v) => v != null);
724
+ if (props.length === 0) return [];
725
+ return [
726
+ {
727
+ value: ALL_PROPERTIES,
728
+ label: rt.language === "ja" ? "\u3059\u3079\u3066\u306E\u30D7\u30ED\u30D1\u30C6\u30A3" : "All properties"
729
+ },
730
+ ...props
731
+ ];
732
+ },
733
+ applyAnswer: (state, answer) => ({ ...state, properties: answer })
734
+ }
735
+ ],
736
+ async finalize(state, rt) {
737
+ if (!state.account || !state.properties) {
738
+ throw new Error(
739
+ "Google Analytics OAuth setup: incomplete state on finalize"
740
+ );
741
+ }
742
+ const summaries = await listAccountSummaries(rt.config.proxyFetch);
743
+ const account = summaries.find(
744
+ (s) => (s.account ?? s.name) === state.account
745
+ );
746
+ const accountLabel = account?.displayName ?? state.account.replace(/^accounts\//, "");
747
+ const targetPropertyIds = await resolveSetupSelection({
748
+ selected: state.properties,
749
+ allSentinel: ALL_PROPERTIES,
750
+ fetchAll: async () => (account?.propertySummaries ?? []).map((p) => propertyIdFromResource(p.property)).filter((v) => v),
751
+ limit: GOOGLE_ANALYTICS_OAUTH_SETUP_MAX_PROPERTIES
752
+ });
753
+ const sections = [
754
+ "## Google Analytics",
755
+ "",
756
+ `### Account: ${accountLabel}`,
757
+ ""
758
+ ];
759
+ if (targetPropertyIds.length === 0) {
760
+ sections.push("_No properties selected._", "");
761
+ return sections.join("\n");
762
+ }
763
+ sections.push(
764
+ "| Property ID | Display Name | Time Zone | Currency | Industry |"
765
+ );
766
+ sections.push(
767
+ "|-------------|--------------|-----------|----------|----------|"
768
+ );
769
+ for (const propertyId of targetPropertyIds) {
770
+ const prop = await getProperty(rt.config.proxyFetch, propertyId);
771
+ const displayName = (prop?.displayName ?? "-").replace(/\|/g, "\\|");
772
+ const timeZone = prop?.timeZone ?? "-";
773
+ const currency = prop?.currencyCode ?? "-";
774
+ const industry = (prop?.industryCategory ?? "-").replace(/\|/g, "\\|");
775
+ sections.push(
776
+ `| ${propertyId} | ${displayName} | ${timeZone} | ${currency} | ${industry} |`
777
+ );
778
+ }
779
+ sections.push("");
780
+ return sections.join("\n");
781
+ }
782
+ };
783
+
567
784
  // ../connectors/src/connectors/google-analytics-oauth/tools/request.ts
568
785
  import { z as z3 } from "zod";
569
786
  var BASE_URL2 = "https://analyticsdata.googleapis.com/v1beta/";
@@ -689,6 +906,7 @@ var tools = {
689
906
  var googleAnalyticsOauthConnector = new ConnectorPlugin({
690
907
  slug: "google-analytics",
691
908
  authType: AUTH_TYPES.OAUTH,
909
+ skipConnectionCheckOnCreate: true,
692
910
  name: "Google Analytics",
693
911
  description: "Connect to Google Analytics for web analytics and reporting using OAuth.",
694
912
  iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/7fs0ipzxuD9mACDzBATtxX/3c53ed90d15c96483e4f78cb29dab5e9/google-analytics.svg",
@@ -855,6 +1073,7 @@ const realtime = await ga.runRealtimeReport({
855
1073
  \`\`\``
856
1074
  },
857
1075
  tools,
1076
+ setup: (params, ctx, config) => runSetupFlow(googleAnalyticsOauthSetupFlow, params, ctx, config),
858
1077
  async checkConnection(params, config) {
859
1078
  const { proxyFetch } = config;
860
1079
  const propertyId = params[parameters.propertyId.slug];
@@ -907,6 +1126,7 @@ function resolveEnvVarOptional(entry, key) {
907
1126
  import { getContext } from "hono/context-storage";
908
1127
  import { getCookie } from "hono/cookie";
909
1128
  var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
1129
+ var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
910
1130
  function normalizeHeaders(input) {
911
1131
  const out = {};
912
1132
  if (!input) return out;
@@ -915,6 +1135,11 @@ function normalizeHeaders(input) {
915
1135
  });
916
1136
  return out;
917
1137
  }
1138
+ function extractInputUrl(input) {
1139
+ if (typeof input === "string") return input;
1140
+ if (input instanceof URL) return input.href;
1141
+ return input.url;
1142
+ }
918
1143
  function createSandboxProxyFetch(connectionId) {
919
1144
  return async (input, init) => {
920
1145
  const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
@@ -924,10 +1149,17 @@ function createSandboxProxyFetch(connectionId) {
924
1149
  "Connection proxy is not configured. Please check your deployment settings."
925
1150
  );
926
1151
  }
927
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
1152
+ const originalUrl = extractInputUrl(input);
1153
+ const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
1154
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
1155
+ const sessionUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
1156
+ return fetch(sessionUrl, {
1157
+ method: "POST",
1158
+ headers: { Authorization: `Bearer ${token}` }
1159
+ });
1160
+ }
928
1161
  const originalMethod = init?.method ?? "GET";
929
1162
  const originalBody = init?.body ? JSON.parse(init.body) : void 0;
930
- const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
931
1163
  const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
932
1164
  return fetch(proxyUrl, {
933
1165
  method: "POST",
@@ -953,10 +1185,9 @@ function createDeployedAppProxyFetch(connectionId) {
953
1185
  }
954
1186
  const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
955
1187
  const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
1188
+ const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
956
1189
  return async (input, init) => {
957
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
958
- const originalMethod = init?.method ?? "GET";
959
- const originalBody = init?.body ? JSON.parse(init.body) : void 0;
1190
+ const originalUrl = extractInputUrl(input);
960
1191
  const c = getContext();
961
1192
  const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
962
1193
  if (!appSession) {
@@ -964,6 +1195,14 @@ function createDeployedAppProxyFetch(connectionId) {
964
1195
  "No authentication method available for connection proxy."
965
1196
  );
966
1197
  }
1198
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
1199
+ return fetch(sessionUrl, {
1200
+ method: "POST",
1201
+ headers: { Authorization: `Bearer ${appSession}` }
1202
+ });
1203
+ }
1204
+ const originalMethod = init?.method ?? "GET";
1205
+ const originalBody = init?.body ? JSON.parse(init.body) : void 0;
967
1206
  return fetch(proxyUrl, {
968
1207
  method: "POST",
969
1208
  headers: {