@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/asana/parameters.ts
57
+ init_parameter_definition();
46
58
  var parameters = {
47
59
  personalAccessToken: new ParameterDefinition({
48
60
  slug: "personal-access-token",
@@ -261,6 +273,20 @@ var ConnectorPlugin = class _ConnectorPlugin {
261
273
  * `runSetupFlow` from `setup-flow.ts`.
262
274
  */
263
275
  setup;
276
+ /**
277
+ * Opt-out of the default "verify before save" behavior on connection
278
+ * creation. The backend invokes `checkConnection` synchronously while
279
+ * creating the connection and aborts (no row inserted) if it fails — this
280
+ * flag disables that for connectors where the check cannot succeed pre-save:
281
+ *
282
+ * - `squadbase-db` populates `connection-url` only after Neon provisioning
283
+ * - OAuth connectors require an OAuth-aware proxyFetch keyed by the
284
+ * connectionId, which doesn't exist until the row is saved
285
+ *
286
+ * Exceptions are the explicit position; new credential-input connectors get
287
+ * the default verify-on-create behavior without opt-in.
288
+ */
289
+ skipConnectionCheckOnCreate;
264
290
  constructor(config) {
265
291
  this.slug = config.slug;
266
292
  this.authType = config.authType;
@@ -278,6 +304,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
278
304
  this.query = config.query;
279
305
  this.checkConnection = config.checkConnection;
280
306
  this.setup = config.setup;
307
+ this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
281
308
  }
282
309
  get connectorKey() {
283
310
  return _ConnectorPlugin.deriveKey(this.slug, this.authType);
@@ -342,6 +369,51 @@ var ConnectorPlugin = class _ConnectorPlugin {
342
369
  }
343
370
  };
344
371
 
372
+ // ../connectors/src/setup-flow.ts
373
+ async function runSetupFlow(flow, params, ctx, config) {
374
+ const runtime = {
375
+ params,
376
+ language: ctx.language,
377
+ config
378
+ };
379
+ let state = flow.initialState();
380
+ let answerIdx = 0;
381
+ for (const step of flow.steps) {
382
+ const ans = ctx.answers[answerIdx];
383
+ if (ans && ans.questionSlug === step.slug) {
384
+ state = step.applyAnswer(state, ans.answer);
385
+ answerIdx += 1;
386
+ continue;
387
+ }
388
+ if (step.type === "text") {
389
+ return {
390
+ type: "nextQuestion",
391
+ questionSlug: step.slug,
392
+ question: step.question[ctx.language],
393
+ questionType: "text"
394
+ };
395
+ }
396
+ const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
397
+ if (options.length === 0) {
398
+ continue;
399
+ }
400
+ return {
401
+ type: "nextQuestion",
402
+ questionSlug: step.slug,
403
+ question: step.question[ctx.language],
404
+ questionType: step.type,
405
+ options
406
+ };
407
+ }
408
+ const dataInvestigationResult = await flow.finalize(state, runtime);
409
+ return { type: "fulfilled", dataInvestigationResult };
410
+ }
411
+ async function resolveSetupSelection(params) {
412
+ const { selected, allSentinel, fetchAll, limit } = params;
413
+ const resolved = selected.includes(allSentinel) ? await fetchAll() : selected.filter((v) => v !== allSentinel);
414
+ return resolved.slice(0, limit);
415
+ }
416
+
345
417
  // ../connectors/src/auth-types.ts
346
418
  var AUTH_TYPES = {
347
419
  OAUTH: "oauth",
@@ -376,11 +448,131 @@ var asanaOnboarding = new ConnectorOnboarding({
376
448
  }
377
449
  });
378
450
 
451
+ // ../connectors/src/connectors/asana/utils.ts
452
+ var BASE_URL2 = "https://app.asana.com/api/1.0";
453
+ async function apiFetch(params, path2, init) {
454
+ const token = params[parameters.personalAccessToken.slug];
455
+ if (!token) {
456
+ throw new Error("asana: missing required parameter: personal-access-token");
457
+ }
458
+ const url = `${BASE_URL2}${path2.startsWith("/") ? "" : "/"}${path2}`;
459
+ const headers = new Headers(init?.headers);
460
+ headers.set("Authorization", `Bearer ${token}`);
461
+ if (!headers.has("Accept")) headers.set("Accept", "application/json");
462
+ return fetch(url, { ...init, headers });
463
+ }
464
+
465
+ // ../connectors/src/connectors/asana/setup-flow.ts
466
+ var ALL_PROJECTS = "__ALL_PROJECTS__";
467
+ var ASANA_SETUP_MAX_PROJECTS = 20;
468
+ async function listWorkspaces(params) {
469
+ const res = await apiFetch(params, "/workspaces?limit=100");
470
+ if (!res.ok) {
471
+ const body = await res.text().catch(() => res.statusText);
472
+ throw new Error(`asana: listWorkspaces failed (${res.status}): ${body}`);
473
+ }
474
+ const data = await res.json();
475
+ return data.data ?? [];
476
+ }
477
+ async function listProjects(params, workspaceGid) {
478
+ const all = [];
479
+ const fields = encodeURIComponent("name,team.name,current_status");
480
+ let offset;
481
+ while (all.length < 500) {
482
+ const query = `workspace=${encodeURIComponent(workspaceGid)}&limit=100&opt_fields=${fields}${offset ? `&offset=${encodeURIComponent(offset)}` : ""}`;
483
+ const res = await apiFetch(params, `/projects?${query}`);
484
+ if (!res.ok) {
485
+ const body = await res.text().catch(() => res.statusText);
486
+ throw new Error(`asana: listProjects failed (${res.status}): ${body}`);
487
+ }
488
+ const data = await res.json();
489
+ const batch = data.data ?? [];
490
+ all.push(...batch);
491
+ const next = data.next_page?.offset;
492
+ if (!next || batch.length === 0) break;
493
+ offset = next;
494
+ }
495
+ return all;
496
+ }
497
+ var asanaSetupFlow = {
498
+ initialState: () => ({}),
499
+ steps: [
500
+ {
501
+ slug: "workspace",
502
+ type: "select",
503
+ question: {
504
+ ja: "\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u306B\u4F7F\u3046\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044",
505
+ en: "Select the workspace to use for setup"
506
+ },
507
+ async fetchOptions(_state, rt) {
508
+ const workspaces = await listWorkspaces(rt.params);
509
+ return workspaces.filter((w) => w.gid && w.name).map((w) => ({ value: w.gid, label: w.name }));
510
+ },
511
+ applyAnswer: (state, answer) => ({ ...state, workspace: answer[0] })
512
+ },
513
+ {
514
+ slug: "projects",
515
+ type: "multiSelect",
516
+ question: {
517
+ ja: "\u5BFE\u8C61\u306E\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
518
+ en: "Select target projects (multi-select allowed)"
519
+ },
520
+ async fetchOptions(state, rt) {
521
+ if (!state.workspace) return [];
522
+ const projects = await listProjects(rt.params, state.workspace);
523
+ const projectOptions = projects.filter((p) => p.gid && p.name).map((p) => ({ value: p.gid, label: p.name }));
524
+ return [
525
+ {
526
+ value: ALL_PROJECTS,
527
+ label: rt.language === "ja" ? "\u3059\u3079\u3066\u306E\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8" : "All projects"
528
+ },
529
+ ...projectOptions
530
+ ];
531
+ },
532
+ applyAnswer: (state, answer) => ({ ...state, projects: answer })
533
+ }
534
+ ],
535
+ async finalize(state, rt) {
536
+ if (!state.workspace || !state.projects) {
537
+ throw new Error("Asana setup: incomplete state on finalize");
538
+ }
539
+ const workspaceGid = state.workspace;
540
+ const projects = await listProjects(rt.params, workspaceGid);
541
+ const projectByGid = new Map(projects.map((p) => [p.gid, p]));
542
+ const targetGids = await resolveSetupSelection({
543
+ selected: state.projects,
544
+ allSentinel: ALL_PROJECTS,
545
+ fetchAll: async () => projects.map((p) => p.gid).filter((g) => g),
546
+ limit: ASANA_SETUP_MAX_PROJECTS
547
+ });
548
+ const sections = [
549
+ "## Asana",
550
+ "",
551
+ `### Workspace: ${workspaceGid}`,
552
+ ""
553
+ ];
554
+ for (const gid of targetGids) {
555
+ const project = projectByGid.get(gid);
556
+ if (!project) {
557
+ sections.push(`#### Project: ${gid}`, "", "_Not found._", "");
558
+ continue;
559
+ }
560
+ sections.push(`#### Project: ${project.name}`, "");
561
+ const team = project.team?.name ?? "-";
562
+ const status = project.current_status?.title ?? project.current_status?.text ?? "-";
563
+ sections.push(`- Team: ${team}`);
564
+ sections.push(`- Current status: ${status}`);
565
+ sections.push("");
566
+ }
567
+ return sections.join("\n");
568
+ }
569
+ };
570
+
379
571
  // ../connectors/src/connectors/asana/tools/request.ts
380
572
  import { z } from "zod";
381
573
  var BASE_HOST = "https://app.asana.com";
382
574
  var BASE_PATH_SEGMENT = "/api/1.0";
383
- var BASE_URL2 = `${BASE_HOST}${BASE_PATH_SEGMENT}`;
575
+ var BASE_URL3 = `${BASE_HOST}${BASE_PATH_SEGMENT}`;
384
576
  var REQUEST_TIMEOUT_MS = 6e4;
385
577
  var inputSchema = z.object({
386
578
  toolUseIntent: z.string().optional().describe(
@@ -445,7 +637,7 @@ Pagination: Use limit (1-100) and offset query parameters. The response includes
445
637
  try {
446
638
  const token = parameters.personalAccessToken.getValue(connection2);
447
639
  const normalizedPath = normalizeRequestPath(path2, BASE_PATH_SEGMENT);
448
- const url = `${BASE_URL2}${normalizedPath}`;
640
+ const url = `${BASE_URL3}${normalizedPath}`;
449
641
  const controller = new AbortController();
450
642
  const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
451
643
  try {
@@ -664,7 +856,39 @@ export default async function handler(c: Context) {
664
856
  - \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8: name, archived, created_at, modified_at, owner, owner.name, team, team.name, members
665
857
  - \u30E6\u30FC\u30B6\u30FC: name, email, photo`
666
858
  },
667
- tools
859
+ tools,
860
+ setup: (params, ctx, config) => runSetupFlow(asanaSetupFlow, params, ctx, config),
861
+ async checkConnection(params, _config) {
862
+ try {
863
+ const pat = params[parameters.personalAccessToken.slug];
864
+ if (!pat) {
865
+ return {
866
+ success: false,
867
+ error: "Missing required parameter: personal-access-token"
868
+ };
869
+ }
870
+ const res = await fetch("https://app.asana.com/api/1.0/users/me", {
871
+ method: "GET",
872
+ headers: {
873
+ Authorization: `Bearer ${pat}`,
874
+ Accept: "application/json"
875
+ }
876
+ });
877
+ if (!res.ok) {
878
+ const errorText = await res.text().catch(() => res.statusText);
879
+ return {
880
+ success: false,
881
+ error: `Asana API failed: HTTP ${res.status} ${errorText}`
882
+ };
883
+ }
884
+ return { success: true };
885
+ } catch (error) {
886
+ return {
887
+ success: false,
888
+ error: error instanceof Error ? error.message : String(error)
889
+ };
890
+ }
891
+ }
668
892
  });
669
893
 
670
894
  // src/connectors/create-connector-sdk.ts
@@ -693,6 +917,7 @@ function resolveEnvVarOptional(entry, key) {
693
917
  import { getContext } from "hono/context-storage";
694
918
  import { getCookie } from "hono/cookie";
695
919
  var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
920
+ var TABLEAU_SESSION_SENTINEL_URL = "squadbase://tableau-session/";
696
921
  function normalizeHeaders(input) {
697
922
  const out = {};
698
923
  if (!input) return out;
@@ -701,6 +926,11 @@ function normalizeHeaders(input) {
701
926
  });
702
927
  return out;
703
928
  }
929
+ function extractInputUrl(input) {
930
+ if (typeof input === "string") return input;
931
+ if (input instanceof URL) return input.href;
932
+ return input.url;
933
+ }
704
934
  function createSandboxProxyFetch(connectionId) {
705
935
  return async (input, init) => {
706
936
  const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
@@ -710,10 +940,17 @@ function createSandboxProxyFetch(connectionId) {
710
940
  "Connection proxy is not configured. Please check your deployment settings."
711
941
  );
712
942
  }
713
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
943
+ const originalUrl = extractInputUrl(input);
944
+ const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
945
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
946
+ const sessionUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
947
+ return fetch(sessionUrl, {
948
+ method: "POST",
949
+ headers: { Authorization: `Bearer ${token}` }
950
+ });
951
+ }
714
952
  const originalMethod = init?.method ?? "GET";
715
953
  const originalBody = init?.body ? JSON.parse(init.body) : void 0;
716
- const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
717
954
  const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
718
955
  return fetch(proxyUrl, {
719
956
  method: "POST",
@@ -739,10 +976,9 @@ function createDeployedAppProxyFetch(connectionId) {
739
976
  }
740
977
  const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
741
978
  const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
979
+ const sessionUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/tableau-session`;
742
980
  return async (input, init) => {
743
- const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
744
- const originalMethod = init?.method ?? "GET";
745
- const originalBody = init?.body ? JSON.parse(init.body) : void 0;
981
+ const originalUrl = extractInputUrl(input);
746
982
  const c = getContext();
747
983
  const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
748
984
  if (!appSession) {
@@ -750,6 +986,14 @@ function createDeployedAppProxyFetch(connectionId) {
750
986
  "No authentication method available for connection proxy."
751
987
  );
752
988
  }
989
+ if (originalUrl === TABLEAU_SESSION_SENTINEL_URL) {
990
+ return fetch(sessionUrl, {
991
+ method: "POST",
992
+ headers: { Authorization: `Bearer ${appSession}` }
993
+ });
994
+ }
995
+ const originalMethod = init?.method ?? "GET";
996
+ const originalBody = init?.body ? JSON.parse(init.body) : void 0;
753
997
  return fetch(proxyUrl, {
754
998
  method: "POST",
755
999
  headers: {