@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/parameters.ts
57
+ init_parameter_definition();
46
58
  var parameters = {
47
59
  baseId: new ParameterDefinition({
48
60
  slug: "base-id",
@@ -176,7 +188,7 @@ function createClient(params) {
176
188
  }
177
189
  return await response.json();
178
190
  }
179
- async function listTables() {
191
+ async function listTables2() {
180
192
  const path2 = `/meta/bases/${baseId}/tables`;
181
193
  const response = await request(path2);
182
194
  if (!response.ok) {
@@ -193,7 +205,7 @@ function createClient(params) {
193
205
  getRecord,
194
206
  createRecords,
195
207
  updateRecords,
196
- listTables
208
+ listTables: listTables2
197
209
  };
198
210
  }
199
211
 
@@ -264,6 +276,20 @@ var ConnectorPlugin = class _ConnectorPlugin {
264
276
  * `runSetupFlow` from `setup-flow.ts`.
265
277
  */
266
278
  setup;
279
+ /**
280
+ * Opt-out of the default "verify before save" behavior on connection
281
+ * creation. The backend invokes `checkConnection` synchronously while
282
+ * creating the connection and aborts (no row inserted) if it fails — this
283
+ * flag disables that for connectors where the check cannot succeed pre-save:
284
+ *
285
+ * - `squadbase-db` populates `connection-url` only after Neon provisioning
286
+ * - OAuth connectors require an OAuth-aware proxyFetch keyed by the
287
+ * connectionId, which doesn't exist until the row is saved
288
+ *
289
+ * Exceptions are the explicit position; new credential-input connectors get
290
+ * the default verify-on-create behavior without opt-in.
291
+ */
292
+ skipConnectionCheckOnCreate;
267
293
  constructor(config) {
268
294
  this.slug = config.slug;
269
295
  this.authType = config.authType;
@@ -281,6 +307,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
281
307
  this.query = config.query;
282
308
  this.checkConnection = config.checkConnection;
283
309
  this.setup = config.setup;
310
+ this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
284
311
  }
285
312
  get connectorKey() {
286
313
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -345,6 +372,51 @@ var ConnectorPlugin = class _ConnectorPlugin {
345
372
  }
346
373
  };
347
374
 
375
+ // ../connectors/src/setup-flow.ts
376
+ async function runSetupFlow(flow, params, ctx, config) {
377
+ const runtime = {
378
+ params,
379
+ language: ctx.language,
380
+ config
381
+ };
382
+ let state = flow.initialState();
383
+ let answerIdx = 0;
384
+ for (const step of flow.steps) {
385
+ const ans = ctx.answers[answerIdx];
386
+ if (ans && ans.questionSlug === step.slug) {
387
+ state = step.applyAnswer(state, ans.answer);
388
+ answerIdx += 1;
389
+ continue;
390
+ }
391
+ if (step.type === "text") {
392
+ return {
393
+ type: "nextQuestion",
394
+ questionSlug: step.slug,
395
+ question: step.question[ctx.language],
396
+ questionType: "text"
397
+ };
398
+ }
399
+ const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
400
+ if (options.length === 0) {
401
+ continue;
402
+ }
403
+ return {
404
+ type: "nextQuestion",
405
+ questionSlug: step.slug,
406
+ question: step.question[ctx.language],
407
+ questionType: step.type,
408
+ options
409
+ };
410
+ }
411
+ const dataInvestigationResult = await flow.finalize(state, runtime);
412
+ return { type: "fulfilled", dataInvestigationResult };
413
+ }
414
+ async function resolveSetupSelection(params) {
415
+ const { selected, allSentinel, fetchAll, limit } = params;
416
+ const resolved = selected.includes(allSentinel) ? await fetchAll() : selected.filter((v) => v !== allSentinel);
417
+ return resolved.slice(0, limit);
418
+ }
419
+
348
420
  // ../connectors/src/auth-types.ts
349
421
  var AUTH_TYPES = {
350
422
  OAUTH: "oauth",
@@ -365,9 +437,119 @@ var airtableOnboarding = new ConnectorOnboarding({
365
437
  }
366
438
  });
367
439
 
440
+ // ../connectors/src/connectors/airtable/utils.ts
441
+ var BASE_URL2 = "https://api.airtable.com/v0";
442
+ async function apiFetch(params, path2, init) {
443
+ const apiKey = params[parameters.apiKey.slug];
444
+ if (!apiKey) {
445
+ throw new Error("airtable: missing required parameter: api-key");
446
+ }
447
+ const url = `${BASE_URL2}${path2.startsWith("/") ? "" : "/"}${path2}`;
448
+ const headers = new Headers(init?.headers);
449
+ headers.set("Authorization", `Bearer ${apiKey}`);
450
+ return fetch(url, { ...init, headers });
451
+ }
452
+
453
+ // ../connectors/src/connectors/airtable/setup-flow.ts
454
+ var ALL_TABLES = "__ALL_TABLES__";
455
+ var AIRTABLE_SETUP_MAX_TABLES = 20;
456
+ async function listBases(params) {
457
+ const res = await apiFetch(params, "/meta/bases");
458
+ if (!res.ok) {
459
+ const body = await res.text().catch(() => res.statusText);
460
+ throw new Error(`airtable: listBases failed (${res.status}): ${body}`);
461
+ }
462
+ const data = await res.json();
463
+ return data.bases ?? [];
464
+ }
465
+ async function listTables(params, baseId) {
466
+ const res = await apiFetch(params, `/meta/bases/${baseId}/tables`);
467
+ if (!res.ok) {
468
+ const body = await res.text().catch(() => res.statusText);
469
+ throw new Error(`airtable: listTables failed (${res.status}): ${body}`);
470
+ }
471
+ const data = await res.json();
472
+ return data.tables ?? [];
473
+ }
474
+ var airtableSetupFlow = {
475
+ initialState: () => ({}),
476
+ steps: [
477
+ {
478
+ slug: "base",
479
+ type: "select",
480
+ question: {
481
+ ja: "\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u306B\u4F7F\u3046\u30D9\u30FC\u30B9\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044",
482
+ en: "Select the base to use for setup"
483
+ },
484
+ async fetchOptions(_state, rt) {
485
+ const bases = await listBases(rt.params);
486
+ return bases.filter((b) => b.id && b.name).map((b) => ({ value: b.id, label: b.name }));
487
+ },
488
+ applyAnswer: (state, answer) => ({ ...state, base: answer[0] })
489
+ },
490
+ {
491
+ slug: "tables",
492
+ type: "multiSelect",
493
+ question: {
494
+ ja: "\u5BFE\u8C61\u30C6\u30FC\u30D6\u30EB\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
495
+ en: "Select target tables (multi-select allowed)"
496
+ },
497
+ async fetchOptions(state, rt) {
498
+ if (!state.base) return [];
499
+ const tables = await listTables(rt.params, state.base);
500
+ const tableOptions = tables.filter((t) => t.name).map((t) => ({ value: t.name }));
501
+ return [
502
+ {
503
+ value: ALL_TABLES,
504
+ label: rt.language === "ja" ? "\u3059\u3079\u3066\u306E\u30C6\u30FC\u30D6\u30EB" : "All tables"
505
+ },
506
+ ...tableOptions
507
+ ];
508
+ },
509
+ applyAnswer: (state, answer) => ({ ...state, tables: answer })
510
+ }
511
+ ],
512
+ async finalize(state, rt) {
513
+ if (!state.base || !state.tables) {
514
+ throw new Error("Airtable setup: incomplete state on finalize");
515
+ }
516
+ const baseId = state.base;
517
+ const tables = await listTables(rt.params, baseId);
518
+ const tableByName = new Map(tables.map((t) => [t.name, t]));
519
+ const targetTableNames = await resolveSetupSelection({
520
+ selected: state.tables,
521
+ allSentinel: ALL_TABLES,
522
+ fetchAll: async () => tables.map((t) => t.name).filter((n) => n),
523
+ limit: AIRTABLE_SETUP_MAX_TABLES
524
+ });
525
+ const sections = [
526
+ "## Airtable",
527
+ "",
528
+ `### Base: ${baseId}`,
529
+ ""
530
+ ];
531
+ for (const tableName of targetTableNames) {
532
+ const table = tableByName.get(tableName);
533
+ if (!table) {
534
+ sections.push(`#### Table: ${tableName}`, "", "_Not found._", "");
535
+ continue;
536
+ }
537
+ sections.push(`#### Table: ${table.name}`, "");
538
+ sections.push("| Field | Type | Description |");
539
+ sections.push("|-------|------|-------------|");
540
+ for (const f of table.fields ?? []) {
541
+ const description = (f.description ?? "").replace(/\|/g, "\\|");
542
+ sections.push(`| ${f.name} | ${f.type} | ${description || "-"} |`);
543
+ }
544
+ sections.push("");
545
+ }
546
+ return sections.join("\n");
547
+ }
548
+ };
549
+
368
550
  // ../connectors/src/connectors/airtable/tools/request.ts
369
551
  import { z } from "zod";
370
- var BASE_URL2 = "https://api.airtable.com/v0/";
552
+ var BASE_URL3 = "https://api.airtable.com/v0/";
371
553
  var REQUEST_TIMEOUT_MS = 6e4;
372
554
  var inputSchema = z.object({
373
555
  toolUseIntent: z.string().optional().describe("Brief description of what you intend to accomplish with this tool call"),
@@ -404,7 +586,7 @@ Authentication is handled automatically using the API Key.
404
586
  const apiKey = parameters.apiKey.getValue(connection2);
405
587
  const baseId = parameters.baseId.getValue(connection2);
406
588
  const resolvedPath = path2.replace(/\{baseId\}/g, baseId);
407
- const url = `${BASE_URL2}${resolvedPath}`;
589
+ const url = `${BASE_URL3}${resolvedPath}`;
408
590
  const controller = new AbortController();
409
591
  const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
410
592
  try {
@@ -568,7 +750,39 @@ export default async function handler(c: Context) {
568
750
  #### \u30DA\u30FC\u30B8\u30CD\u30FC\u30B7\u30E7\u30F3
569
751
  - \u30EC\u30B9\u30DD\u30F3\u30B9\u306B \`offset\` \u304C\u542B\u307E\u308C\u308B\u5834\u5408\u3001\u6B21\u306E\u30EA\u30AF\u30A8\u30B9\u30C8\u306B \`?offset={offset}\` \u3092\u8FFD\u52A0\u3057\u3066\u6B21\u306E\u30DA\u30FC\u30B8\u3092\u53D6\u5F97\u3057\u307E\u3059`
570
752
  },
571
- tools
753
+ tools,
754
+ setup: (params, ctx, config) => runSetupFlow(airtableSetupFlow, params, ctx, config),
755
+ async checkConnection(params, _config) {
756
+ const apiKey = params[parameters.apiKey.slug];
757
+ if (!apiKey) {
758
+ return {
759
+ success: false,
760
+ error: `Missing required parameter: ${parameters.apiKey.slug}`
761
+ };
762
+ }
763
+ try {
764
+ const res = await fetch("https://api.airtable.com/v0/meta/whoami", {
765
+ method: "GET",
766
+ headers: {
767
+ Authorization: `Bearer ${apiKey}`,
768
+ Accept: "application/json"
769
+ }
770
+ });
771
+ if (!res.ok) {
772
+ const errorText = await res.text().catch(() => res.statusText);
773
+ return {
774
+ success: false,
775
+ error: `Airtable API failed: HTTP ${res.status} ${errorText}`
776
+ };
777
+ }
778
+ return { success: true };
779
+ } catch (error) {
780
+ return {
781
+ success: false,
782
+ error: error instanceof Error ? error.message : String(error)
783
+ };
784
+ }
785
+ }
572
786
  });
573
787
 
574
788
  // src/connectors/create-connector-sdk.ts
@@ -597,6 +811,7 @@ function resolveEnvVarOptional(entry, key) {
597
811
  import { getContext } from "hono/context-storage";
598
812
  import { getCookie } from "hono/cookie";
599
813
  var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
814
+ var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
600
815
  function normalizeHeaders(input) {
601
816
  const out = {};
602
817
  if (!input) return out;
@@ -605,6 +820,11 @@ function normalizeHeaders(input) {
605
820
  });
606
821
  return out;
607
822
  }
823
+ function extractInputUrl(input) {
824
+ if (typeof input === "string") return input;
825
+ if (input instanceof URL) return input.href;
826
+ return input.url;
827
+ }
608
828
  function createSandboxProxyFetch(connectionId) {
609
829
  return async (input, init) => {
610
830
  const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
@@ -614,10 +834,17 @@ function createSandboxProxyFetch(connectionId) {
614
834
  "Connection proxy is not configured. Please check your deployment settings."
615
835
  );
616
836
  }
617
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
837
+ const originalUrl = extractInputUrl(input);
838
+ const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
839
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
840
+ const sessionUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
841
+ return fetch(sessionUrl, {
842
+ method: "POST",
843
+ headers: { Authorization: `Bearer ${token}` }
844
+ });
845
+ }
618
846
  const originalMethod = init?.method ?? "GET";
619
847
  const originalBody = init?.body ? JSON.parse(init.body) : void 0;
620
- const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
621
848
  const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
622
849
  return fetch(proxyUrl, {
623
850
  method: "POST",
@@ -643,10 +870,9 @@ function createDeployedAppProxyFetch(connectionId) {
643
870
  }
644
871
  const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
645
872
  const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
873
+ const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
646
874
  return async (input, init) => {
647
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
648
- const originalMethod = init?.method ?? "GET";
649
- const originalBody = init?.body ? JSON.parse(init.body) : void 0;
875
+ const originalUrl = extractInputUrl(input);
650
876
  const c = getContext();
651
877
  const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
652
878
  if (!appSession) {
@@ -654,6 +880,14 @@ function createDeployedAppProxyFetch(connectionId) {
654
880
  "No authentication method available for connection proxy."
655
881
  );
656
882
  }
883
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
884
+ return fetch(sessionUrl, {
885
+ method: "POST",
886
+ headers: { Authorization: `Bearer ${appSession}` }
887
+ });
888
+ }
889
+ const originalMethod = init?.method ?? "GET";
890
+ const originalBody = init?.body ? JSON.parse(init.body) : void 0;
657
891
  return fetch(proxyUrl, {
658
892
  method: "POST",
659
893
  headers: {