@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/dbt/parameters.ts
57
+ init_parameter_definition();
46
58
  var parameters = {
47
59
  host: new ParameterDefinition({
48
60
  slug: "host",
@@ -376,6 +388,28 @@ var ConnectorPlugin = class _ConnectorPlugin {
376
388
  tools;
377
389
  query;
378
390
  checkConnection;
391
+ /**
392
+ * SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
393
+ * implement this expose a step-by-step exploration flow (database/schema/
394
+ * table/etc. discovery) that the dashboard backend drives via the
395
+ * `/connections/:connectionId/setup` endpoint. Implement by delegating to
396
+ * `runSetupFlow` from `setup-flow.ts`.
397
+ */
398
+ setup;
399
+ /**
400
+ * Opt-out of the default "verify before save" behavior on connection
401
+ * creation. The backend invokes `checkConnection` synchronously while
402
+ * creating the connection and aborts (no row inserted) if it fails — this
403
+ * flag disables that for connectors where the check cannot succeed pre-save:
404
+ *
405
+ * - `squadbase-db` populates `connection-url` only after Neon provisioning
406
+ * - OAuth connectors require an OAuth-aware proxyFetch keyed by the
407
+ * connectionId, which doesn't exist until the row is saved
408
+ *
409
+ * Exceptions are the explicit position; new credential-input connectors get
410
+ * the default verify-on-create behavior without opt-in.
411
+ */
412
+ skipConnectionCheckOnCreate;
379
413
  constructor(config) {
380
414
  this.slug = config.slug;
381
415
  this.authType = config.authType;
@@ -392,6 +426,8 @@ var ConnectorPlugin = class _ConnectorPlugin {
392
426
  this.tools = config.tools;
393
427
  this.query = config.query;
394
428
  this.checkConnection = config.checkConnection;
429
+ this.setup = config.setup;
430
+ this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
395
431
  }
396
432
  get connectorKey() {
397
433
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -456,6 +492,51 @@ var ConnectorPlugin = class _ConnectorPlugin {
456
492
  }
457
493
  };
458
494
 
495
+ // ../connectors/src/setup-flow.ts
496
+ async function runSetupFlow(flow, params, ctx, config) {
497
+ const runtime = {
498
+ params,
499
+ language: ctx.language,
500
+ config
501
+ };
502
+ let state = flow.initialState();
503
+ let answerIdx = 0;
504
+ for (const step of flow.steps) {
505
+ const ans = ctx.answers[answerIdx];
506
+ if (ans && ans.questionSlug === step.slug) {
507
+ state = step.applyAnswer(state, ans.answer);
508
+ answerIdx += 1;
509
+ continue;
510
+ }
511
+ if (step.type === "text") {
512
+ return {
513
+ type: "nextQuestion",
514
+ questionSlug: step.slug,
515
+ question: step.question[ctx.language],
516
+ questionType: "text"
517
+ };
518
+ }
519
+ const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
520
+ if (options.length === 0) {
521
+ continue;
522
+ }
523
+ return {
524
+ type: "nextQuestion",
525
+ questionSlug: step.slug,
526
+ question: step.question[ctx.language],
527
+ questionType: step.type,
528
+ options
529
+ };
530
+ }
531
+ const dataInvestigationResult = await flow.finalize(state, runtime);
532
+ return { type: "fulfilled", dataInvestigationResult };
533
+ }
534
+ async function resolveSetupSelection(params) {
535
+ const { selected, allSentinel, fetchAll, limit } = params;
536
+ const resolved = selected.includes(allSentinel) ? await fetchAll() : selected.filter((v) => v !== allSentinel);
537
+ return resolved.slice(0, limit);
538
+ }
539
+
459
540
  // ../connectors/src/auth-types.ts
460
541
  var AUTH_TYPES = {
461
542
  OAUTH: "oauth",
@@ -478,6 +559,132 @@ var dbtOnboarding = new ConnectorOnboarding({
478
559
  }
479
560
  });
480
561
 
562
+ // ../connectors/src/connectors/dbt/utils.ts
563
+ function adminApiBase(host) {
564
+ const trimmed = host.replace(/\/+$/, "");
565
+ if (trimmed.startsWith("http://") || trimmed.startsWith("https://")) {
566
+ return trimmed;
567
+ }
568
+ return `https://${trimmed}`;
569
+ }
570
+ function adminApiFetch(params, path2, init) {
571
+ const host = params[parameters.host.slug];
572
+ const token = params[parameters.token.slug];
573
+ if (!host) {
574
+ throw new Error(`dbt: missing required parameter: ${parameters.host.slug}`);
575
+ }
576
+ if (!token) {
577
+ throw new Error(`dbt: missing required parameter: ${parameters.token.slug}`);
578
+ }
579
+ const trimmedPath = path2.startsWith("/") ? path2 : `/${path2}`;
580
+ const headers = new Headers(init?.headers);
581
+ headers.set("Authorization", `Token ${token}`);
582
+ if (!headers.has("Accept")) headers.set("Accept", "application/json");
583
+ return fetch(`${adminApiBase(host)}${trimmedPath}`, { ...init, headers });
584
+ }
585
+
586
+ // ../connectors/src/connectors/dbt/setup-flow.ts
587
+ var ALL_PROJECTS = "__ALL_PROJECTS__";
588
+ var DBT_SETUP_MAX_PROJECTS = 10;
589
+ async function listAllProjects(params) {
590
+ const accountId = params[parameters.accountId.slug];
591
+ if (!accountId) {
592
+ throw new Error(
593
+ `dbt: missing required parameter: ${parameters.accountId.slug}`
594
+ );
595
+ }
596
+ const all = [];
597
+ const limit = 100;
598
+ let offset = 0;
599
+ while (all.length < 500) {
600
+ const res = await adminApiFetch(
601
+ params,
602
+ `/api/v2/accounts/${encodeURIComponent(accountId)}/projects/?limit=${limit}&offset=${offset}`
603
+ );
604
+ if (!res.ok) {
605
+ const body = await res.text().catch(() => res.statusText);
606
+ throw new Error(`dbt: listProjects failed (${res.status}): ${body}`);
607
+ }
608
+ const data = await res.json();
609
+ const batch = data.data ?? [];
610
+ all.push(...batch);
611
+ const total = data.extra?.pagination?.total_count ?? all.length;
612
+ if (!batch.length || all.length >= total) break;
613
+ offset += batch.length;
614
+ }
615
+ return all;
616
+ }
617
+ function repoLabel(p) {
618
+ const repo = p.repository;
619
+ if (!repo) return "-";
620
+ if (repo.remote_url) return repo.remote_url;
621
+ if (repo.name) return repo.name;
622
+ return "-";
623
+ }
624
+ var dbtSetupFlow = {
625
+ initialState: () => ({}),
626
+ steps: [
627
+ {
628
+ slug: "projects",
629
+ type: "multiSelect",
630
+ question: {
631
+ ja: "\u5BFE\u8C61\u306E dbt \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
632
+ en: "Select target dbt projects (multi-select allowed)"
633
+ },
634
+ async fetchOptions(_state, rt) {
635
+ const projects = await listAllProjects(rt.params);
636
+ const options = projects.filter((p) => p.id != null && p.name).map((p) => ({ value: String(p.id), label: p.name }));
637
+ if (options.length === 0) return [];
638
+ return [
639
+ {
640
+ value: ALL_PROJECTS,
641
+ label: rt.language === "ja" ? "\u3059\u3079\u3066\u306E\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8" : "All projects"
642
+ },
643
+ ...options
644
+ ];
645
+ },
646
+ applyAnswer: (state, answer) => ({ ...state, projects: answer })
647
+ }
648
+ ],
649
+ async finalize(state, rt) {
650
+ if (!state.projects) {
651
+ throw new Error("dbt setup: incomplete state on finalize");
652
+ }
653
+ const allProjects = await listAllProjects(rt.params);
654
+ const byId = new Map(allProjects.map((p) => [String(p.id), p]));
655
+ const targetIds = await resolveSetupSelection({
656
+ selected: state.projects,
657
+ allSentinel: ALL_PROJECTS,
658
+ fetchAll: async () => allProjects.map((p) => String(p.id)).filter((id) => id),
659
+ limit: DBT_SETUP_MAX_PROJECTS
660
+ });
661
+ const sections = ["## dbt Cloud", ""];
662
+ const accountId = rt.params[parameters.accountId.slug];
663
+ const prodEnvId = rt.params[parameters.prodEnvId.slug];
664
+ if (accountId) sections.push(`- Account: \`${accountId}\``);
665
+ if (prodEnvId) sections.push(`- Prod environment: \`${prodEnvId}\``);
666
+ sections.push("");
667
+ if (!targetIds.length) {
668
+ sections.push("_No projects selected._", "");
669
+ return sections.join("\n");
670
+ }
671
+ sections.push("| Project | Repository |");
672
+ sections.push("|---------|------------|");
673
+ for (const id of targetIds) {
674
+ const p = byId.get(id);
675
+ if (!p) {
676
+ sections.push(`| ${id} | - |`);
677
+ continue;
678
+ }
679
+ const name = (p.name ?? String(p.id)).replace(/\|/g, "\\|");
680
+ const repo = repoLabel(p).replace(/\|/g, "\\|");
681
+ sections.push(`| ${name} | ${repo} |`);
682
+ }
683
+ sections.push("");
684
+ return sections.join("\n");
685
+ }
686
+ };
687
+
481
688
  // ../connectors/src/connectors/dbt/tools/request.ts
482
689
  import { z } from "zod";
483
690
  var REQUEST_TIMEOUT_MS = 6e4;
@@ -795,7 +1002,48 @@ query($environmentId: BigInt!, $uniqueIds: [String!]!) {
795
1002
  - \`ancestors\` / \`children\` \u30D5\u30A3\u30FC\u30EB\u30C9\u3092\u4F7F\u7528\u3057\u3066\u95A2\u4FC2\u3092\u30C8\u30E9\u30D0\u30FC\u30B9\u3057\u307E\u3059
796
1003
  - node\u5185\u3067 \`ancestors { uniqueId name }\` \u307E\u305F\u306F \`children { uniqueId name }\` \u3092\u53D6\u5F97\u3057\u307E\u3059`
797
1004
  },
798
- tools
1005
+ tools,
1006
+ setup: (params, ctx, config) => runSetupFlow(dbtSetupFlow, params, ctx, config),
1007
+ async checkConnection(params, _config) {
1008
+ const host = params[parameters.host.slug];
1009
+ const token = params[parameters.token.slug];
1010
+ if (!host || !token) {
1011
+ return {
1012
+ success: false,
1013
+ error: `Missing required parameters: ${parameters.host.slug} and ${parameters.token.slug}`
1014
+ };
1015
+ }
1016
+ const normalizedHost = host.trim().replace(/\/+$/, "");
1017
+ const hostWithScheme = /^https?:\/\//i.test(normalizedHost) ? normalizedHost : `https://${normalizedHost}`;
1018
+ try {
1019
+ const res = await fetch(`${hostWithScheme}/api/v2/accounts/`, {
1020
+ method: "GET",
1021
+ headers: {
1022
+ Authorization: `Token ${token}`,
1023
+ Accept: "application/json"
1024
+ }
1025
+ });
1026
+ if (!res.ok) {
1027
+ if (res.status === 401) {
1028
+ return {
1029
+ success: false,
1030
+ error: "dbt Cloud API failed: HTTP 401 Unauthorized \u2014 invalid token"
1031
+ };
1032
+ }
1033
+ const errorText = await res.text().catch(() => res.statusText);
1034
+ return {
1035
+ success: false,
1036
+ error: `dbt Cloud API failed: HTTP ${res.status} ${errorText}`
1037
+ };
1038
+ }
1039
+ return { success: true };
1040
+ } catch (error) {
1041
+ return {
1042
+ success: false,
1043
+ error: error instanceof Error ? error.message : String(error)
1044
+ };
1045
+ }
1046
+ }
799
1047
  });
800
1048
 
801
1049
  // src/connectors/create-connector-sdk.ts
@@ -824,6 +1072,7 @@ function resolveEnvVarOptional(entry, key) {
824
1072
  import { getContext } from "hono/context-storage";
825
1073
  import { getCookie } from "hono/cookie";
826
1074
  var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
1075
+ var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
827
1076
  function normalizeHeaders(input) {
828
1077
  const out = {};
829
1078
  if (!input) return out;
@@ -832,6 +1081,11 @@ function normalizeHeaders(input) {
832
1081
  });
833
1082
  return out;
834
1083
  }
1084
+ function extractInputUrl(input) {
1085
+ if (typeof input === "string") return input;
1086
+ if (input instanceof URL) return input.href;
1087
+ return input.url;
1088
+ }
835
1089
  function createSandboxProxyFetch(connectionId) {
836
1090
  return async (input, init) => {
837
1091
  const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
@@ -841,10 +1095,17 @@ function createSandboxProxyFetch(connectionId) {
841
1095
  "Connection proxy is not configured. Please check your deployment settings."
842
1096
  );
843
1097
  }
844
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
1098
+ const originalUrl = extractInputUrl(input);
1099
+ const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
1100
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
1101
+ const sessionUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
1102
+ return fetch(sessionUrl, {
1103
+ method: "POST",
1104
+ headers: { Authorization: `Bearer ${token}` }
1105
+ });
1106
+ }
845
1107
  const originalMethod = init?.method ?? "GET";
846
1108
  const originalBody = init?.body ? JSON.parse(init.body) : void 0;
847
- const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
848
1109
  const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
849
1110
  return fetch(proxyUrl, {
850
1111
  method: "POST",
@@ -870,10 +1131,9 @@ function createDeployedAppProxyFetch(connectionId) {
870
1131
  }
871
1132
  const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
872
1133
  const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
1134
+ const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
873
1135
  return async (input, init) => {
874
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
875
- const originalMethod = init?.method ?? "GET";
876
- const originalBody = init?.body ? JSON.parse(init.body) : void 0;
1136
+ const originalUrl = extractInputUrl(input);
877
1137
  const c = getContext();
878
1138
  const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
879
1139
  if (!appSession) {
@@ -881,6 +1141,14 @@ function createDeployedAppProxyFetch(connectionId) {
881
1141
  "No authentication method available for connection proxy."
882
1142
  );
883
1143
  }
1144
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
1145
+ return fetch(sessionUrl, {
1146
+ method: "POST",
1147
+ headers: { Authorization: `Bearer ${appSession}` }
1148
+ });
1149
+ }
1150
+ const originalMethod = init?.method ?? "GET";
1151
+ const originalBody = init?.body ? JSON.parse(init.body) : void 0;
884
1152
  return fetch(proxyUrl, {
885
1153
  method: "POST",
886
1154
  headers: {