@squadbase/vite-server 0.1.12-dev.93b8799 → 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 +12128 -934
  2. package/dist/connectors/airtable-oauth.js +248 -46
  3. package/dist/connectors/airtable.js +285 -51
  4. package/dist/connectors/amplitude.js +288 -47
  5. package/dist/connectors/anthropic.js +126 -47
  6. package/dist/connectors/asana.js +293 -49
  7. package/dist/connectors/attio.js +268 -49
  8. package/dist/connectors/aws-billing.js +253 -46
  9. package/dist/connectors/azure-sql.js +387 -102
  10. package/dist/connectors/backlog-api-key.js +283 -47
  11. package/dist/connectors/clickup.js +304 -49
  12. package/dist/connectors/cosmosdb.js +271 -50
  13. package/dist/connectors/customerio.js +285 -47
  14. package/dist/connectors/dbt.js +306 -47
  15. package/dist/connectors/freshdesk.js +308 -53
  16. package/dist/connectors/freshsales.js +299 -52
  17. package/dist/connectors/freshservice.js +327 -53
  18. package/dist/connectors/gamma.js +293 -52
  19. package/dist/connectors/gemini.js +125 -47
  20. package/dist/connectors/github.js +352 -49
  21. package/dist/connectors/gmail-oauth.js +170 -7
  22. package/dist/connectors/gmail.js +316 -47
  23. package/dist/connectors/google-ads.js +254 -46
  24. package/dist/connectors/google-analytics-oauth.js +276 -46
  25. package/dist/connectors/google-analytics.js +378 -49
  26. package/dist/connectors/google-audit-log.js +404 -47
  27. package/dist/connectors/google-calendar-oauth.js +225 -46
  28. package/dist/connectors/google-calendar.js +325 -47
  29. package/dist/connectors/google-docs.js +186 -6
  30. package/dist/connectors/google-drive.js +228 -5
  31. package/dist/connectors/google-search-console-oauth.js +222 -46
  32. package/dist/connectors/google-sheets.js +238 -47
  33. package/dist/connectors/google-slides.js +171 -6
  34. package/dist/connectors/grafana.js +298 -49
  35. package/dist/connectors/hubspot-oauth.js +174 -5
  36. package/dist/connectors/hubspot.js +272 -49
  37. package/dist/connectors/influxdb.js +382 -51
  38. package/dist/connectors/intercom-oauth.js +176 -5
  39. package/dist/connectors/intercom.js +268 -49
  40. package/dist/connectors/jdbc.js +728 -110
  41. package/dist/connectors/jira-api-key.js +292 -47
  42. package/dist/connectors/kintone-api-token.js +247 -47
  43. package/dist/connectors/kintone.js +294 -47
  44. package/dist/connectors/linear.js +296 -49
  45. package/dist/connectors/linkedin-ads.js +234 -50
  46. package/dist/connectors/mailchimp-oauth.js +234 -46
  47. package/dist/connectors/mailchimp.js +286 -49
  48. package/dist/connectors/meta-ads-oauth.js +239 -48
  49. package/dist/connectors/meta-ads.js +251 -50
  50. package/dist/connectors/mixpanel.js +304 -47
  51. package/dist/connectors/monday.js +326 -49
  52. package/dist/connectors/mongodb.js +285 -57
  53. package/dist/connectors/notion-oauth.js +197 -5
  54. package/dist/connectors/notion.js +289 -51
  55. package/dist/connectors/openai.js +125 -47
  56. package/dist/connectors/oracle.js +405 -103
  57. package/dist/connectors/outlook-oauth.js +170 -5
  58. package/dist/connectors/powerbi-oauth.js +217 -5
  59. package/dist/connectors/salesforce.js +350 -49
  60. package/dist/connectors/semrush.js +280 -49
  61. package/dist/connectors/sentry.js +255 -50
  62. package/dist/connectors/shopify-oauth.js +153 -5
  63. package/dist/connectors/shopify.js +323 -47
  64. package/dist/connectors/sqlserver.js +381 -102
  65. package/dist/connectors/stripe-api-key.js +235 -46
  66. package/dist/connectors/stripe-oauth.js +168 -5
  67. package/dist/connectors/supabase.js +269 -48
  68. package/dist/connectors/tableau.js +337 -206
  69. package/dist/connectors/tiktok-ads.js +245 -48
  70. package/dist/connectors/wix-store.js +286 -49
  71. package/dist/connectors/zendesk-oauth.js +205 -5
  72. package/dist/connectors/zendesk.js +324 -47
  73. package/dist/index.d.ts +149 -1
  74. package/dist/index.js +18297 -6886
  75. package/dist/main.js +12785 -1382
  76. package/dist/vite-plugin.js +12140 -936
  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",
@@ -134,6 +146,20 @@ var ConnectorPlugin = class _ConnectorPlugin {
134
146
  * `runSetupFlow` from `setup-flow.ts`.
135
147
  */
136
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;
137
163
  constructor(config) {
138
164
  this.slug = config.slug;
139
165
  this.authType = config.authType;
@@ -151,6 +177,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
151
177
  this.query = config.query;
152
178
  this.checkConnection = config.checkConnection;
153
179
  this.setup = config.setup;
180
+ this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
154
181
  }
155
182
  get connectorKey() {
156
183
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -215,6 +242,51 @@ var ConnectorPlugin = class _ConnectorPlugin {
215
242
  }
216
243
  };
217
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
+
218
290
  // ../connectors/src/auth-types.ts
219
291
  var AUTH_TYPES = {
220
292
  OAUTH: "oauth",
@@ -386,11 +458,120 @@ var airtableOauthOnboarding = new ConnectorOnboarding({
386
458
  }
387
459
  });
388
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
+
389
569
  // ../connectors/src/connectors/airtable-oauth/index.ts
390
570
  var tools = { request: requestTool };
391
571
  var airtableOauthConnector = new ConnectorPlugin({
392
572
  slug: "airtable",
393
573
  authType: AUTH_TYPES.OAUTH,
574
+ skipConnectionCheckOnCreate: true,
394
575
  name: "Airtable",
395
576
  description: "Connect to Airtable for spreadsheet-database hybrid data management using OAuth.",
396
577
  iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/19JUphfOZjyjTK6Zg4NGCf/8c56227b088cada52d3a2d9385a3be97/airtable.svg",
@@ -505,6 +686,7 @@ const recordsData = await records.json();
505
686
  \`\`\``
506
687
  },
507
688
  tools,
689
+ setup: (params, ctx, config) => runSetupFlow(airtableOauthSetupFlow, params, ctx, config),
508
690
  async checkConnection(params, config) {
509
691
  const { proxyFetch } = config;
510
692
  const baseId = params[parameters.baseId.slug];
@@ -559,6 +741,7 @@ function resolveEnvVarOptional(entry, key) {
559
741
  import { getContext } from "hono/context-storage";
560
742
  import { getCookie } from "hono/cookie";
561
743
  var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
744
+ var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
562
745
  function normalizeHeaders(input) {
563
746
  const out = {};
564
747
  if (!input) return out;
@@ -567,6 +750,11 @@ function normalizeHeaders(input) {
567
750
  });
568
751
  return out;
569
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
+ }
570
758
  function createSandboxProxyFetch(connectionId) {
571
759
  return async (input, init) => {
572
760
  const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
@@ -576,10 +764,17 @@ function createSandboxProxyFetch(connectionId) {
576
764
  "Connection proxy is not configured. Please check your deployment settings."
577
765
  );
578
766
  }
579
- 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
+ }
580
776
  const originalMethod = init?.method ?? "GET";
581
777
  const originalBody = init?.body ? JSON.parse(init.body) : void 0;
582
- const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
583
778
  const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
584
779
  return fetch(proxyUrl, {
585
780
  method: "POST",
@@ -605,10 +800,9 @@ function createDeployedAppProxyFetch(connectionId) {
605
800
  }
606
801
  const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
607
802
  const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
803
+ const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
608
804
  return async (input, init) => {
609
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
610
- const originalMethod = init?.method ?? "GET";
611
- const originalBody = init?.body ? JSON.parse(init.body) : void 0;
805
+ const originalUrl = extractInputUrl(input);
612
806
  const c = getContext();
613
807
  const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
614
808
  if (!appSession) {
@@ -616,6 +810,14 @@ function createDeployedAppProxyFetch(connectionId) {
616
810
  "No authentication method available for connection proxy."
617
811
  );
618
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;
619
821
  return fetch(proxyUrl, {
620
822
  method: "POST",
621
823
  headers: {