@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/google-ads/constants.ts
46
57
  var VERSION_FALLBACK_ORDER = ["v22", "v23", "v24"];
@@ -76,6 +87,7 @@ async function fetchGoogleAdsWithVersionFallback(attempt) {
76
87
  }
77
88
 
78
89
  // ../connectors/src/connectors/google-ads/parameters.ts
90
+ init_parameter_definition();
79
91
  var parameters = {
80
92
  customerId: new ParameterDefinition({
81
93
  slug: "customer-id",
@@ -213,6 +225,28 @@ var ConnectorPlugin = class _ConnectorPlugin {
213
225
  tools;
214
226
  query;
215
227
  checkConnection;
228
+ /**
229
+ * SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
230
+ * implement this expose a step-by-step exploration flow (database/schema/
231
+ * table/etc. discovery) that the dashboard backend drives via the
232
+ * `/connections/:connectionId/setup` endpoint. Implement by delegating to
233
+ * `runSetupFlow` from `setup-flow.ts`.
234
+ */
235
+ setup;
236
+ /**
237
+ * Opt-out of the default "verify before save" behavior on connection
238
+ * creation. The backend invokes `checkConnection` synchronously while
239
+ * creating the connection and aborts (no row inserted) if it fails — this
240
+ * flag disables that for connectors where the check cannot succeed pre-save:
241
+ *
242
+ * - `squadbase-db` populates `connection-url` only after Neon provisioning
243
+ * - OAuth connectors require an OAuth-aware proxyFetch keyed by the
244
+ * connectionId, which doesn't exist until the row is saved
245
+ *
246
+ * Exceptions are the explicit position; new credential-input connectors get
247
+ * the default verify-on-create behavior without opt-in.
248
+ */
249
+ skipConnectionCheckOnCreate;
216
250
  constructor(config) {
217
251
  this.slug = config.slug;
218
252
  this.authType = config.authType;
@@ -229,6 +263,8 @@ var ConnectorPlugin = class _ConnectorPlugin {
229
263
  this.tools = config.tools;
230
264
  this.query = config.query;
231
265
  this.checkConnection = config.checkConnection;
266
+ this.setup = config.setup;
267
+ this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
232
268
  }
233
269
  get connectorKey() {
234
270
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -293,6 +329,76 @@ var ConnectorPlugin = class _ConnectorPlugin {
293
329
  }
294
330
  };
295
331
 
332
+ // ../connectors/src/setup-flow.ts
333
+ async function runSetupFlow(flow, params, ctx, config) {
334
+ const runtime = {
335
+ params,
336
+ language: ctx.language,
337
+ config
338
+ };
339
+ let state = flow.initialState();
340
+ let answerIdx = 0;
341
+ const pendingParameterUpdates = [];
342
+ for (const step of flow.steps) {
343
+ const ans = ctx.answers[answerIdx];
344
+ if (ans && ans.questionSlug === step.slug) {
345
+ state = step.applyAnswer(state, ans.answer);
346
+ if (step.toParameterUpdates) {
347
+ pendingParameterUpdates.push(...step.toParameterUpdates(state));
348
+ }
349
+ answerIdx += 1;
350
+ continue;
351
+ }
352
+ const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
353
+ if (step.type === "text") {
354
+ if (step.fetchOptions) {
355
+ const options2 = await step.fetchOptions(state, runtime);
356
+ if (options2.length === 0) {
357
+ continue;
358
+ }
359
+ }
360
+ return {
361
+ type: "nextQuestion",
362
+ questionSlug: step.slug,
363
+ question: step.question[ctx.language],
364
+ questionType: "text",
365
+ allowFreeText: resolvedAllowFreeText,
366
+ ...pendingParameterUpdates.length > 0 && {
367
+ parameterUpdates: pendingParameterUpdates
368
+ }
369
+ };
370
+ }
371
+ const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
372
+ if (options.length === 0) {
373
+ continue;
374
+ }
375
+ return {
376
+ type: "nextQuestion",
377
+ questionSlug: step.slug,
378
+ question: step.question[ctx.language],
379
+ questionType: step.type,
380
+ options,
381
+ allowFreeText: resolvedAllowFreeText,
382
+ ...pendingParameterUpdates.length > 0 && {
383
+ parameterUpdates: pendingParameterUpdates
384
+ }
385
+ };
386
+ }
387
+ const dataInvestigationResult = await flow.finalize(state, runtime);
388
+ return {
389
+ type: "fulfilled",
390
+ dataInvestigationResult,
391
+ ...pendingParameterUpdates.length > 0 && {
392
+ parameterUpdates: pendingParameterUpdates
393
+ }
394
+ };
395
+ }
396
+ async function resolveSetupSelection(params) {
397
+ const { selected, allSentinel, fetchAll, limit } = params;
398
+ const resolved = selected.includes(allSentinel) ? await fetchAll() : selected.filter((v) => v !== allSentinel);
399
+ return resolved.slice(0, limit);
400
+ }
401
+
296
402
  // ../connectors/src/auth-types.ts
297
403
  var AUTH_TYPES = {
298
404
  OAUTH: "oauth",
@@ -561,6 +667,120 @@ var googleAdsOnboarding = new ConnectorOnboarding({
561
667
  }
562
668
  });
563
669
 
670
+ // ../connectors/src/connectors/google-ads/setup-flow.ts
671
+ var ALL_CUSTOMERS = "__ALL_CUSTOMERS__";
672
+ var GOOGLE_ADS_SETUP_MAX_CUSTOMERS = 10;
673
+ async function listAccessibleCustomerIds(proxyFetch) {
674
+ const res = await fetchGoogleAdsWithVersionFallback(
675
+ (baseUrl) => proxyFetch(`${baseUrl}customers:listAccessibleCustomers`, {
676
+ method: "GET"
677
+ })
678
+ );
679
+ if (!res.ok) {
680
+ const body = await res.text().catch(() => res.statusText);
681
+ throw new Error(
682
+ `google-ads: listAccessibleCustomers failed (${res.status}): ${body}`
683
+ );
684
+ }
685
+ const data = await res.json();
686
+ return (data.resourceNames ?? []).map(
687
+ (rn) => rn.replace(/^customers\//, "")
688
+ );
689
+ }
690
+ async function fetchCustomerInfo(proxyFetch, customerId) {
691
+ try {
692
+ const res = await fetchGoogleAdsWithVersionFallback(
693
+ (baseUrl) => proxyFetch(`${baseUrl}customers/${customerId}/googleAds:searchStream`, {
694
+ method: "POST",
695
+ headers: {
696
+ "Content-Type": "application/json",
697
+ "login-customer-id": customerId
698
+ },
699
+ body: JSON.stringify({
700
+ query: "SELECT customer.id, customer.descriptive_name, customer.currency_code, customer.time_zone FROM customer LIMIT 1"
701
+ })
702
+ })
703
+ );
704
+ if (!res.ok) {
705
+ return {
706
+ customerId,
707
+ descriptiveName: customerId,
708
+ currencyCode: "-",
709
+ timeZone: "-"
710
+ };
711
+ }
712
+ const data = await res.json();
713
+ const customer = data?.[0]?.results?.[0]?.customer;
714
+ return {
715
+ customerId,
716
+ descriptiveName: customer?.descriptiveName ?? customerId,
717
+ currencyCode: customer?.currencyCode ?? "-",
718
+ timeZone: customer?.timeZone ?? "-"
719
+ };
720
+ } catch {
721
+ return {
722
+ customerId,
723
+ descriptiveName: customerId,
724
+ currencyCode: "-",
725
+ timeZone: "-"
726
+ };
727
+ }
728
+ }
729
+ var googleAdsSetupFlow = {
730
+ initialState: () => ({}),
731
+ steps: [
732
+ {
733
+ slug: "customers",
734
+ type: "multiSelect",
735
+ question: {
736
+ ja: "\u5BFE\u8C61\u306E Google Ads \u30A2\u30AB\u30A6\u30F3\u30C8\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
737
+ en: "Select target Google Ads accounts (multi-select allowed)"
738
+ },
739
+ async fetchOptions(_state, rt) {
740
+ const customerIds = await listAccessibleCustomerIds(
741
+ rt.config.proxyFetch
742
+ );
743
+ if (customerIds.length === 0) return [];
744
+ return [
745
+ {
746
+ value: ALL_CUSTOMERS,
747
+ label: rt.language === "ja" ? "\u3059\u3079\u3066\u306E\u30A2\u30AB\u30A6\u30F3\u30C8" : "All accounts"
748
+ },
749
+ ...customerIds.map((id) => ({ value: id }))
750
+ ];
751
+ },
752
+ applyAnswer: (state, answer) => ({ ...state, customers: answer })
753
+ }
754
+ ],
755
+ async finalize(state, rt) {
756
+ if (!state.customers) {
757
+ throw new Error("Google Ads setup: incomplete state on finalize");
758
+ }
759
+ const targetCustomerIds = await resolveSetupSelection({
760
+ selected: state.customers,
761
+ allSentinel: ALL_CUSTOMERS,
762
+ fetchAll: async () => listAccessibleCustomerIds(rt.config.proxyFetch),
763
+ limit: GOOGLE_ADS_SETUP_MAX_CUSTOMERS
764
+ });
765
+ const sections = ["## Google Ads", ""];
766
+ if (targetCustomerIds.length === 0) {
767
+ sections.push("_No customer accounts selected._", "");
768
+ return sections.join("\n");
769
+ }
770
+ sections.push("| Customer ID | Name | Currency | Time Zone |");
771
+ sections.push("|-------------|------|----------|-----------|");
772
+ for (const customerId of targetCustomerIds) {
773
+ const info = await fetchCustomerInfo(rt.config.proxyFetch, customerId);
774
+ const name = info.descriptiveName.replace(/\|/g, "\\|");
775
+ sections.push(
776
+ `| ${info.customerId} | ${name} | ${info.currencyCode} | ${info.timeZone} |`
777
+ );
778
+ }
779
+ sections.push("");
780
+ return sections.join("\n");
781
+ }
782
+ };
783
+
564
784
  // ../connectors/src/connectors/google-ads/tools/request.ts
565
785
  import { z as z2 } from "zod";
566
786
  var REQUEST_TIMEOUT_MS2 = 6e4;
@@ -695,6 +915,7 @@ var tools = {
695
915
  var googleAdsConnector = new ConnectorPlugin({
696
916
  slug: "google-ads",
697
917
  authType: AUTH_TYPES.OAUTH,
918
+ skipConnectionCheckOnCreate: true,
698
919
  name: "Google Ads",
699
920
  description: "Connect to Google Ads for advertising campaign data and reporting using OAuth.",
700
921
  iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/1NGvmgvCxX7Tn11EST2N3N/a745fe7c63d360ed40a27ddaad3af168/google-ads.svg",
@@ -837,6 +1058,7 @@ const customerIds = await ads.listAccessibleCustomers();
837
1058
  \`\`\``
838
1059
  },
839
1060
  tools,
1061
+ setup: (params, ctx, config) => runSetupFlow(googleAdsSetupFlow, params, ctx, config),
840
1062
  async checkConnection(params, config) {
841
1063
  const { proxyFetch } = config;
842
1064
  const rawCustomerId = params[parameters.customerId.slug];
@@ -903,6 +1125,7 @@ function resolveEnvVarOptional(entry, key) {
903
1125
  import { getContext } from "hono/context-storage";
904
1126
  import { getCookie } from "hono/cookie";
905
1127
  var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
1128
+ var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
906
1129
  function normalizeHeaders(input) {
907
1130
  const out = {};
908
1131
  if (!input) return out;
@@ -911,6 +1134,11 @@ function normalizeHeaders(input) {
911
1134
  });
912
1135
  return out;
913
1136
  }
1137
+ function extractInputUrl(input) {
1138
+ if (typeof input === "string") return input;
1139
+ if (input instanceof URL) return input.href;
1140
+ return input.url;
1141
+ }
914
1142
  function createSandboxProxyFetch(connectionId) {
915
1143
  return async (input, init) => {
916
1144
  const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
@@ -920,10 +1148,17 @@ function createSandboxProxyFetch(connectionId) {
920
1148
  "Connection proxy is not configured. Please check your deployment settings."
921
1149
  );
922
1150
  }
923
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
1151
+ const originalUrl = extractInputUrl(input);
1152
+ const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
1153
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
1154
+ const sessionUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
1155
+ return fetch(sessionUrl, {
1156
+ method: "POST",
1157
+ headers: { Authorization: `Bearer ${token}` }
1158
+ });
1159
+ }
924
1160
  const originalMethod = init?.method ?? "GET";
925
1161
  const originalBody = init?.body ? JSON.parse(init.body) : void 0;
926
- const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
927
1162
  const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
928
1163
  return fetch(proxyUrl, {
929
1164
  method: "POST",
@@ -949,10 +1184,9 @@ function createDeployedAppProxyFetch(connectionId) {
949
1184
  }
950
1185
  const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
951
1186
  const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
1187
+ const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
952
1188
  return async (input, init) => {
953
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
954
- const originalMethod = init?.method ?? "GET";
955
- const originalBody = init?.body ? JSON.parse(init.body) : void 0;
1189
+ const originalUrl = extractInputUrl(input);
956
1190
  const c = getContext();
957
1191
  const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
958
1192
  if (!appSession) {
@@ -960,6 +1194,14 @@ function createDeployedAppProxyFetch(connectionId) {
960
1194
  "No authentication method available for connection proxy."
961
1195
  );
962
1196
  }
1197
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
1198
+ return fetch(sessionUrl, {
1199
+ method: "POST",
1200
+ headers: { Authorization: `Bearer ${appSession}` }
1201
+ });
1202
+ }
1203
+ const originalMethod = init?.method ?? "GET";
1204
+ const originalBody = init?.body ? JSON.parse(init.body) : void 0;
963
1205
  return fetch(proxyUrl, {
964
1206
  method: "POST",
965
1207
  headers: {