@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/airtable-oauth/parameters.ts
57
+ init_parameter_definition();
46
58
  var parameters = {
47
59
  baseId: new ParameterDefinition({
48
60
  slug: "base-id",
@@ -126,6 +138,28 @@ var ConnectorPlugin = class _ConnectorPlugin {
126
138
  tools;
127
139
  query;
128
140
  checkConnection;
141
+ /**
142
+ * SQPD-1212: Logic-based, rule-driven connection setup. Connectors that
143
+ * implement this expose a step-by-step exploration flow (database/schema/
144
+ * table/etc. discovery) that the dashboard backend drives via the
145
+ * `/connections/:connectionId/setup` endpoint. Implement by delegating to
146
+ * `runSetupFlow` from `setup-flow.ts`.
147
+ */
148
+ setup;
149
+ /**
150
+ * Opt-out of the default "verify before save" behavior on connection
151
+ * creation. The backend invokes `checkConnection` synchronously while
152
+ * creating the connection and aborts (no row inserted) if it fails — this
153
+ * flag disables that for connectors where the check cannot succeed pre-save:
154
+ *
155
+ * - `squadbase-db` populates `connection-url` only after Neon provisioning
156
+ * - OAuth connectors require an OAuth-aware proxyFetch keyed by the
157
+ * connectionId, which doesn't exist until the row is saved
158
+ *
159
+ * Exceptions are the explicit position; new credential-input connectors get
160
+ * the default verify-on-create behavior without opt-in.
161
+ */
162
+ skipConnectionCheckOnCreate;
129
163
  constructor(config) {
130
164
  this.slug = config.slug;
131
165
  this.authType = config.authType;
@@ -142,6 +176,8 @@ var ConnectorPlugin = class _ConnectorPlugin {
142
176
  this.tools = config.tools;
143
177
  this.query = config.query;
144
178
  this.checkConnection = config.checkConnection;
179
+ this.setup = config.setup;
180
+ this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
145
181
  }
146
182
  get connectorKey() {
147
183
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -206,6 +242,51 @@ var ConnectorPlugin = class _ConnectorPlugin {
206
242
  }
207
243
  };
208
244
 
245
+ // ../connectors/src/setup-flow.ts
246
+ async function runSetupFlow(flow, params, ctx, config) {
247
+ const runtime = {
248
+ params,
249
+ language: ctx.language,
250
+ config
251
+ };
252
+ let state = flow.initialState();
253
+ let answerIdx = 0;
254
+ for (const step of flow.steps) {
255
+ const ans = ctx.answers[answerIdx];
256
+ if (ans && ans.questionSlug === step.slug) {
257
+ state = step.applyAnswer(state, ans.answer);
258
+ answerIdx += 1;
259
+ continue;
260
+ }
261
+ if (step.type === "text") {
262
+ return {
263
+ type: "nextQuestion",
264
+ questionSlug: step.slug,
265
+ question: step.question[ctx.language],
266
+ questionType: "text"
267
+ };
268
+ }
269
+ const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
270
+ if (options.length === 0) {
271
+ continue;
272
+ }
273
+ return {
274
+ type: "nextQuestion",
275
+ questionSlug: step.slug,
276
+ question: step.question[ctx.language],
277
+ questionType: step.type,
278
+ options
279
+ };
280
+ }
281
+ const dataInvestigationResult = await flow.finalize(state, runtime);
282
+ return { type: "fulfilled", dataInvestigationResult };
283
+ }
284
+ async function resolveSetupSelection(params) {
285
+ const { selected, allSentinel, fetchAll, limit } = params;
286
+ const resolved = selected.includes(allSentinel) ? await fetchAll() : selected.filter((v) => v !== allSentinel);
287
+ return resolved.slice(0, limit);
288
+ }
289
+
209
290
  // ../connectors/src/auth-types.ts
210
291
  var AUTH_TYPES = {
211
292
  OAUTH: "oauth",
@@ -377,11 +458,120 @@ var airtableOauthOnboarding = new ConnectorOnboarding({
377
458
  }
378
459
  });
379
460
 
461
+ // ../connectors/src/connectors/airtable-oauth/utils.ts
462
+ var BASE_URL3 = "https://api.airtable.com/v0";
463
+ function apiFetch(proxyFetch, path2, init) {
464
+ const url = `${BASE_URL3}${path2.startsWith("/") ? "" : "/"}${path2}`;
465
+ return proxyFetch(url, init);
466
+ }
467
+
468
+ // ../connectors/src/connectors/airtable-oauth/setup-flow.ts
469
+ var ALL_TABLES = "__ALL_TABLES__";
470
+ var AIRTABLE_SETUP_MAX_TABLES = 20;
471
+ async function listBases(proxyFetch) {
472
+ const res = await apiFetch(proxyFetch, "/meta/bases");
473
+ if (!res.ok) {
474
+ const body = await res.text().catch(() => res.statusText);
475
+ throw new Error(
476
+ `airtable-oauth: listBases failed (${res.status}): ${body}`
477
+ );
478
+ }
479
+ const data = await res.json();
480
+ return data.bases ?? [];
481
+ }
482
+ async function listTables(proxyFetch, baseId) {
483
+ const res = await apiFetch(proxyFetch, `/meta/bases/${baseId}/tables`);
484
+ if (!res.ok) {
485
+ const body = await res.text().catch(() => res.statusText);
486
+ throw new Error(
487
+ `airtable-oauth: listTables failed (${res.status}): ${body}`
488
+ );
489
+ }
490
+ const data = await res.json();
491
+ return data.tables ?? [];
492
+ }
493
+ var airtableOauthSetupFlow = {
494
+ initialState: () => ({}),
495
+ steps: [
496
+ {
497
+ slug: "base",
498
+ type: "select",
499
+ question: {
500
+ ja: "\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u306B\u4F7F\u3046\u30D9\u30FC\u30B9\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044",
501
+ en: "Select the base to use for setup"
502
+ },
503
+ async fetchOptions(_state, rt) {
504
+ const bases = await listBases(rt.config.proxyFetch);
505
+ return bases.filter((b) => b.id && b.name).map((b) => ({ value: b.id, label: b.name }));
506
+ },
507
+ applyAnswer: (state, answer) => ({ ...state, base: answer[0] })
508
+ },
509
+ {
510
+ slug: "tables",
511
+ type: "multiSelect",
512
+ question: {
513
+ ja: "\u5BFE\u8C61\u30C6\u30FC\u30D6\u30EB\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
514
+ en: "Select target tables (multi-select allowed)"
515
+ },
516
+ async fetchOptions(state, rt) {
517
+ if (!state.base) return [];
518
+ const tables = await listTables(rt.config.proxyFetch, state.base);
519
+ const tableOptions = tables.filter((t) => t.name).map((t) => ({ value: t.name }));
520
+ return [
521
+ {
522
+ value: ALL_TABLES,
523
+ label: rt.language === "ja" ? "\u3059\u3079\u3066\u306E\u30C6\u30FC\u30D6\u30EB" : "All tables"
524
+ },
525
+ ...tableOptions
526
+ ];
527
+ },
528
+ applyAnswer: (state, answer) => ({ ...state, tables: answer })
529
+ }
530
+ ],
531
+ async finalize(state, rt) {
532
+ if (!state.base || !state.tables) {
533
+ throw new Error("Airtable setup: incomplete state on finalize");
534
+ }
535
+ const baseId = state.base;
536
+ const tables = await listTables(rt.config.proxyFetch, baseId);
537
+ const tableByName = new Map(tables.map((t) => [t.name, t]));
538
+ const targetTableNames = await resolveSetupSelection({
539
+ selected: state.tables,
540
+ allSentinel: ALL_TABLES,
541
+ fetchAll: async () => tables.map((t) => t.name).filter((n) => n),
542
+ limit: AIRTABLE_SETUP_MAX_TABLES
543
+ });
544
+ const sections = [
545
+ "## Airtable",
546
+ "",
547
+ `### Base: ${baseId}`,
548
+ ""
549
+ ];
550
+ for (const tableName of targetTableNames) {
551
+ const table = tableByName.get(tableName);
552
+ if (!table) {
553
+ sections.push(`#### Table: ${tableName}`, "", "_Not found._", "");
554
+ continue;
555
+ }
556
+ sections.push(`#### Table: ${table.name}`, "");
557
+ sections.push("| Field | Type | Description |");
558
+ sections.push("|-------|------|-------------|");
559
+ for (const f of table.fields ?? []) {
560
+ const description = (f.description ?? "").replace(/\|/g, "\\|");
561
+ sections.push(`| ${f.name} | ${f.type} | ${description || "-"} |`);
562
+ }
563
+ sections.push("");
564
+ }
565
+ return sections.join("\n");
566
+ }
567
+ };
568
+
380
569
  // ../connectors/src/connectors/airtable-oauth/index.ts
381
570
  var tools = { request: requestTool };
382
571
  var airtableOauthConnector = new ConnectorPlugin({
383
572
  slug: "airtable",
384
573
  authType: AUTH_TYPES.OAUTH,
574
+ skipConnectionCheckOnCreate: true,
385
575
  name: "Airtable",
386
576
  description: "Connect to Airtable for spreadsheet-database hybrid data management using OAuth.",
387
577
  iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/19JUphfOZjyjTK6Zg4NGCf/8c56227b088cada52d3a2d9385a3be97/airtable.svg",
@@ -496,6 +686,7 @@ const recordsData = await records.json();
496
686
  \`\`\``
497
687
  },
498
688
  tools,
689
+ setup: (params, ctx, config) => runSetupFlow(airtableOauthSetupFlow, params, ctx, config),
499
690
  async checkConnection(params, config) {
500
691
  const { proxyFetch } = config;
501
692
  const baseId = params[parameters.baseId.slug];
@@ -550,6 +741,7 @@ function resolveEnvVarOptional(entry, key) {
550
741
  import { getContext } from "hono/context-storage";
551
742
  import { getCookie } from "hono/cookie";
552
743
  var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
744
+ var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
553
745
  function normalizeHeaders(input) {
554
746
  const out = {};
555
747
  if (!input) return out;
@@ -558,6 +750,11 @@ function normalizeHeaders(input) {
558
750
  });
559
751
  return out;
560
752
  }
753
+ function extractInputUrl(input) {
754
+ if (typeof input === "string") return input;
755
+ if (input instanceof URL) return input.href;
756
+ return input.url;
757
+ }
561
758
  function createSandboxProxyFetch(connectionId) {
562
759
  return async (input, init) => {
563
760
  const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
@@ -567,10 +764,17 @@ function createSandboxProxyFetch(connectionId) {
567
764
  "Connection proxy is not configured. Please check your deployment settings."
568
765
  );
569
766
  }
570
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
767
+ const originalUrl = extractInputUrl(input);
768
+ const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
769
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
770
+ const sessionUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
771
+ return fetch(sessionUrl, {
772
+ method: "POST",
773
+ headers: { Authorization: `Bearer ${token}` }
774
+ });
775
+ }
571
776
  const originalMethod = init?.method ?? "GET";
572
777
  const originalBody = init?.body ? JSON.parse(init.body) : void 0;
573
- const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
574
778
  const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
575
779
  return fetch(proxyUrl, {
576
780
  method: "POST",
@@ -596,10 +800,9 @@ function createDeployedAppProxyFetch(connectionId) {
596
800
  }
597
801
  const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
598
802
  const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
803
+ const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
599
804
  return async (input, init) => {
600
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
601
- const originalMethod = init?.method ?? "GET";
602
- const originalBody = init?.body ? JSON.parse(init.body) : void 0;
805
+ const originalUrl = extractInputUrl(input);
603
806
  const c = getContext();
604
807
  const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
605
808
  if (!appSession) {
@@ -607,6 +810,14 @@ function createDeployedAppProxyFetch(connectionId) {
607
810
  "No authentication method available for connection proxy."
608
811
  );
609
812
  }
813
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
814
+ return fetch(sessionUrl, {
815
+ method: "POST",
816
+ headers: { Authorization: `Bearer ${appSession}` }
817
+ });
818
+ }
819
+ const originalMethod = init?.method ?? "GET";
820
+ const originalBody = init?.body ? JSON.parse(init.body) : void 0;
610
821
  return fetch(proxyUrl, {
611
822
  method: "POST",
612
823
  headers: {