@shuffleio/shuffle-mcps 0.0.16 → 0.0.17

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.
package/dist/index.mjs CHANGED
@@ -4,13 +4,19 @@ import {
4
4
  fetchAppsViaApiConfig,
5
5
  getApiUrl,
6
6
  getAuthHeader,
7
+ getHostBaseUrl,
7
8
  getTrackedOrgId,
9
+ installFetchBreaker,
8
10
  invalidateAppsCache,
9
11
  isCloud,
10
12
  isCloudDomain,
11
13
  isOnprem,
14
+ registerProtectedOrigin,
15
+ resetRegionUrl,
16
+ setHostBaseUrl,
17
+ setRegionUrl,
12
18
  shuffleFetch
13
- } from "./chunk-FHIKSRCS.mjs";
19
+ } from "./chunk-R3YLER6P.mjs";
14
20
 
15
21
  // index.ts
16
22
  import "./shuffle-mcp-CN72CJJQ.css";
@@ -127,7 +133,7 @@ var ShuffleMcpThemeProvider = ({
127
133
  };
128
134
 
129
135
  // ShuffleMCP.tsx
130
- import React3, { useState as useState9, useEffect as useEffect7, useRef as useRef7, useCallback as useCallback7, useMemo as useMemo4, useImperativeHandle } from "react";
136
+ import React3, { useState as useState9, useEffect as useEffect8, useRef as useRef7, useCallback as useCallback7, useMemo as useMemo4, useImperativeHandle } from "react";
131
137
  import { algoliasearch } from "algoliasearch";
132
138
  import { Tooltip as Tooltip4 } from "@mui/material";
133
139
 
@@ -723,7 +729,7 @@ async function backfillAppImages(dedupedApps) {
723
729
  let missing = dedupedApps.filter((d) => !d.bestImage && !d.app.large_image);
724
730
  if (missing.length === 0) return dedupedApps;
725
731
  try {
726
- const { fetchAppsViaApiConfig: fetchAppsViaApiConfig2 } = await import("./appsCache-LOBSECTW.mjs");
732
+ const { fetchAppsViaApiConfig: fetchAppsViaApiConfig2 } = await import("./appsCache-CFCVTF7D.mjs");
727
733
  const apps = await fetchAppsViaApiConfig2().catch(() => []);
728
734
  if (Array.isArray(apps) && apps.length > 0) {
729
735
  const byName = /* @__PURE__ */ new Map();
@@ -5701,6 +5707,15 @@ function SegmentedControl({
5701
5707
  ) });
5702
5708
  }
5703
5709
 
5710
+ // useSyncHostBaseUrl.ts
5711
+ import { useEffect as useEffect7 } from "react";
5712
+ var useSyncHostBaseUrl = (globalUrl) => {
5713
+ useEffect7(() => {
5714
+ if (!globalUrl) return;
5715
+ setHostBaseUrl(globalUrl);
5716
+ }, [globalUrl]);
5717
+ };
5718
+
5704
5719
  // ShuffleMCP.tsx
5705
5720
  import { Fragment as Fragment5, jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
5706
5721
  var DEFAULT_ALGOLIA_APP_ID = "JNSS5CFDZZ";
@@ -5744,8 +5759,10 @@ var ShuffleMCP = React3.forwardRef(({
5744
5759
  renderLoadingState,
5745
5760
  onAppSelected,
5746
5761
  onSelectionChange,
5747
- onSearchChange
5762
+ onSearchChange,
5763
+ globalUrl
5748
5764
  }, ref) => {
5765
+ useSyncHostBaseUrl(globalUrl);
5749
5766
  const [query, setQuery] = useState9(initialQuery);
5750
5767
  const [results, setResults] = useState9([]);
5751
5768
  const [privateApps, setPrivateApps] = useState9([]);
@@ -5782,10 +5799,10 @@ var ShuffleMCP = React3.forwardRef(({
5782
5799
  console.error("Failed to fetch authenticated apps:", error);
5783
5800
  }
5784
5801
  }, [apiKey, apiBaseUrl, authPath, orgId]);
5785
- useEffect7(() => {
5802
+ useEffect8(() => {
5786
5803
  fetchAuthenticatedApps2();
5787
5804
  }, [fetchAuthenticatedApps2]);
5788
- useEffect7(() => {
5805
+ useEffect8(() => {
5789
5806
  if (disablePrivateApps) {
5790
5807
  setPrivateApps([]);
5791
5808
  return;
@@ -5825,7 +5842,7 @@ var ShuffleMCP = React3.forwardRef(({
5825
5842
  };
5826
5843
  fetchPrivateApps();
5827
5844
  }, [apiKey, apiBaseUrl, privateAppsPath, disablePrivateApps, orgId]);
5828
- useEffect7(() => {
5845
+ useEffect8(() => {
5829
5846
  if (authenticatedApps.length > 0 && results.length > 0) {
5830
5847
  const validatedApps = authenticatedApps.filter((auth) => auth.validation?.valid);
5831
5848
  const appsToAutoSelect = results.filter(
@@ -5845,12 +5862,12 @@ var ShuffleMCP = React3.forwardRef(({
5845
5862
  }
5846
5863
  }
5847
5864
  }, [authenticatedApps, results]);
5848
- useEffect7(() => {
5865
+ useEffect8(() => {
5849
5866
  if (externalAuthenticatedApps) {
5850
5867
  setAuthenticatedApps(externalAuthenticatedApps);
5851
5868
  }
5852
5869
  }, [externalAuthenticatedApps]);
5853
- useEffect7(() => {
5870
+ useEffect8(() => {
5854
5871
  searchClient.current = algoliasearch(algoliaAppId, algoliaApiKey);
5855
5872
  if (!hasInitialized.current) {
5856
5873
  hasInitialized.current = true;
@@ -5863,10 +5880,10 @@ var ShuffleMCP = React3.forwardRef(({
5863
5880
  }, 100);
5864
5881
  }
5865
5882
  }, []);
5866
- useEffect7(() => {
5883
+ useEffect8(() => {
5867
5884
  setInternalSelectedApps(selectedApps);
5868
5885
  }, [selectedApps]);
5869
- useEffect7(() => {
5886
+ useEffect8(() => {
5870
5887
  const handleClickOutside = (event) => {
5871
5888
  if (containerRef.current && !containerRef.current.contains(event.target)) {
5872
5889
  setIsOpen(false);
@@ -6240,7 +6257,7 @@ ShuffleMCP.displayName = "ShuffleMCP";
6240
6257
  var ShuffleMCP_default = ShuffleMCP;
6241
6258
 
6242
6259
  // AppSearchDrawer.tsx
6243
- import { useState as useState10, useEffect as useEffect8 } from "react";
6260
+ import { useState as useState10, useEffect as useEffect9 } from "react";
6244
6261
  import {
6245
6262
  X as CloseIcon3
6246
6263
  } from "lucide-react";
@@ -6349,7 +6366,7 @@ function AppSearchDrawer({
6349
6366
  const [detailAppName, setDetailAppName] = useState10(null);
6350
6367
  const [detailAppId, setDetailAppId] = useState10(null);
6351
6368
  const [highlightActive, setHighlightActive] = useState10(false);
6352
- useEffect8(() => {
6369
+ useEffect9(() => {
6353
6370
  setHighlightActive(false);
6354
6371
  if (!open || !highlightAppName) return;
6355
6372
  const t = setTimeout(() => setHighlightActive(true), highlightDelayMs);
@@ -6911,7 +6928,7 @@ function ShufflePipelinesBanner() {
6911
6928
  var ShufflePipelinesBanner_default = ShufflePipelinesBanner;
6912
6929
 
6913
6930
  // AgentUI.tsx
6914
- import { useCallback as useCallback8, useEffect as useEffect10, useMemo as useMemo6, useRef as useRef8, useState as useState12 } from "react";
6931
+ import { useCallback as useCallback8, useEffect as useEffect11, useMemo as useMemo6, useRef as useRef8, useState as useState12 } from "react";
6915
6932
  import {
6916
6933
  Plus as AddIcon3,
6917
6934
  Paperclip as AttachFileIcon,
@@ -7587,7 +7604,7 @@ var AgentDiagnosisCtas = ({ diagnosis, compact = false, tone = "medium" }) => {
7587
7604
  var AgentDiagnosisCtas_default = AgentDiagnosisCtas;
7588
7605
 
7589
7606
  // AgentRunDiagnosisBanner.tsx
7590
- import { useEffect as useEffect9, useMemo as useMemo5, useState as useState11 } from "react";
7607
+ import { useEffect as useEffect10, useMemo as useMemo5, useState as useState11 } from "react";
7591
7608
 
7592
7609
  // agentDiagnosis.ts
7593
7610
  var deepParseJsonStrings2 = (obj, depth = 0) => {
@@ -7970,7 +7987,7 @@ var AgentRunDiagnosisBanner = ({ run, sx, onJumpToEvidence, executionId }) => {
7970
7987
  return typeof fromRun === "string" && fromRun ? fromRun : null;
7971
7988
  }, [executionId, run]);
7972
7989
  const [dismissed, setDismissed] = useState11(() => readDismissed(dismissKey));
7973
- useEffect9(() => {
7990
+ useEffect10(() => {
7974
7991
  setDismissed(readDismissed(dismissKey));
7975
7992
  }, [dismissKey]);
7976
7993
  if (!run || dismissed) return null;
@@ -8764,14 +8781,14 @@ var AgentUI = ({
8764
8781
  stateRef.current.continuationText = continuationText;
8765
8782
  stateRef.current.localRunStart = localRunStart;
8766
8783
  stateRef.current.showStarter = showStarter;
8767
- useEffect10(() => {
8784
+ useEffect11(() => {
8768
8785
  if (execution?.execution_id || agentRequestLoading) {
8769
8786
  setLocalRunStart((prev) => prev ?? Math.floor(Date.now() / 1e3));
8770
8787
  } else {
8771
8788
  setLocalRunStart(null);
8772
8789
  }
8773
8790
  }, [execution?.execution_id, agentRequestLoading]);
8774
- useEffect10(() => {
8791
+ useEffect11(() => {
8775
8792
  const status = (execution?.status || agentData?.status || "").toUpperCase();
8776
8793
  const TERMINAL = ["FINISHED", "FAILURE", "ABORTED", "CANCELLED", "CANCELED"];
8777
8794
  if (TERMINAL.includes(status)) return;
@@ -8844,10 +8861,10 @@ var AgentUI = ({
8844
8861
  }
8845
8862
  return out;
8846
8863
  }, [agentData, appsById, isAppAuthenticated]);
8847
- useEffect10(() => {
8864
+ useEffect11(() => {
8848
8865
  if (apps) setChosenApps(apps);
8849
8866
  }, [apps]);
8850
- useEffect10(() => {
8867
+ useEffect11(() => {
8851
8868
  const decisions = agentData?.decisions || [];
8852
8869
  if (!Array.isArray(decisions) || decisions.length === 0) return;
8853
8870
  const norm4 = (s) => s.toLowerCase().replace(/[\s-]+/g, "_");
@@ -8895,7 +8912,7 @@ var AgentUI = ({
8895
8912
  cancelled = true;
8896
8913
  };
8897
8914
  }, [JSON.stringify(agentData?.decisions?.map((d) => [d?.details?.tool || d?.tool, extractAuthRequest(d)?.appName]) || []), appsById]);
8898
- useEffect10(() => {
8915
+ useEffect11(() => {
8899
8916
  const missing = chosenApps.filter((a) => !a.icon && a.name);
8900
8917
  if (missing.length === 0) return;
8901
8918
  let cancelled = false;
@@ -8953,7 +8970,7 @@ var AgentUI = ({
8953
8970
  cancelled = true;
8954
8971
  };
8955
8972
  }, [chosenApps, availableApps, resolveUrl2, resolveHeaders2]);
8956
- useEffect10(() => {
8973
+ useEffect11(() => {
8957
8974
  if (!autoLoadApps) return;
8958
8975
  if (apps || defaultApps) return;
8959
8976
  if (!hasApiKey) return;
@@ -8992,7 +9009,7 @@ var AgentUI = ({
8992
9009
  cancelled = true;
8993
9010
  };
8994
9011
  }, [autoLoadApps, apps, defaultApps, hasApiKey, resolveUrl2, resolveHeaders2]);
8995
- useEffect10(() => {
9012
+ useEffect11(() => {
8996
9013
  const raw = agentData?.allowed_actions;
8997
9014
  if (!Array.isArray(raw) || raw.length === 0) {
8998
9015
  setExecutionApps([]);
@@ -9136,7 +9153,7 @@ var AgentUI = ({
9136
9153
  setError(err instanceof Error ? err.message : "Network error.");
9137
9154
  }
9138
9155
  }, []);
9139
- useEffect10(() => {
9156
+ useEffect11(() => {
9140
9157
  let eid = null;
9141
9158
  let auth = null;
9142
9159
  if (executionId && authorization) {
@@ -9154,7 +9171,7 @@ var AgentUI = ({
9154
9171
  getExecution(eid, auth);
9155
9172
  }
9156
9173
  }, [readUrlParams, executionId, authorization, getExecution]);
9157
- useEffect10(() => {
9174
+ useEffect11(() => {
9158
9175
  if (!initialExecution || !initialExecution.execution_id) return;
9159
9176
  if (!userPickedStartRef.current) setShowStarter(false);
9160
9177
  activeExecutionIdRef.current = initialExecution.execution_id;
@@ -9187,7 +9204,7 @@ var AgentUI = ({
9187
9204
  getExecution(initialExecution.execution_id, initialExecution.authorization);
9188
9205
  }
9189
9206
  }, [initialExecution?.execution_id]);
9190
- useEffect10(() => {
9207
+ useEffect11(() => {
9191
9208
  if (!execution?.execution_id || !execution?.authorization) return;
9192
9209
  const status = (execution.status || "").toUpperCase();
9193
9210
  const TERMINAL = ["FINISHED", "FAILURE", "ABORTED", "CANCELLED", "CANCELED"];
@@ -9334,7 +9351,7 @@ var AgentUI = ({
9334
9351
  }
9335
9352
  }, [chosenApps, getExecution, onRun, attachedImages, readUrlParams, viewMode]);
9336
9353
  const autoSubmittedRef = useRef8(false);
9337
- useEffect10(() => {
9354
+ useEffect11(() => {
9338
9355
  if (autoSubmit && defaultInput && !autoSubmittedRef.current && !executionId) {
9339
9356
  autoSubmittedRef.current = true;
9340
9357
  submitInput(defaultInput);
@@ -9658,7 +9675,7 @@ var AgentUI = ({
9658
9675
  const activeTab = showStarter ? "start" : viewMode;
9659
9676
  const hasExecution = !!execution?.execution_id;
9660
9677
  const showRunSwitcher = hasExecution || agentRequestLoading;
9661
- useEffect10(() => {
9678
+ useEffect11(() => {
9662
9679
  onViewChange?.(activeTab);
9663
9680
  }, [activeTab, onViewChange]);
9664
9681
  const goToTab = (t) => {
@@ -9764,14 +9781,14 @@ var AgentUI = ({
9764
9781
  }, [agentData, execution?.status, showStarter]);
9765
9782
  const scheduleHint = useMemo6(() => parseScheduleHint(actionInput), [actionInput]);
9766
9783
  const lastAppliedHintRef = useRef8(null);
9767
- useEffect10(() => {
9784
+ useEffect11(() => {
9768
9785
  if (!scheduleHint) return;
9769
9786
  if (scheduleAnchor) return;
9770
9787
  if (lastAppliedHintRef.current === scheduleHint.cron) return;
9771
9788
  setScheduleCron(scheduleHint.cron);
9772
9789
  lastAppliedHintRef.current = scheduleHint.cron;
9773
9790
  }, [scheduleHint, scheduleAnchor]);
9774
- useEffect10(() => {
9791
+ useEffect11(() => {
9775
9792
  if (cronManualOverrideRef.current) return;
9776
9793
  const m = Math.max(0, Math.min(59, schedMinute));
9777
9794
  const h = Math.max(0, Math.min(23, schedHour));
@@ -11253,7 +11270,7 @@ var AgentUI = ({
11253
11270
  var AgentUI_default = AgentUI;
11254
11271
 
11255
11272
  // AgentRunDrawer.tsx
11256
- import { useEffect as useEffect11, useRef as useRef9, useState as useState13 } from "react";
11273
+ import { useEffect as useEffect12, useRef as useRef9, useState as useState13 } from "react";
11257
11274
  import {
11258
11275
  Box as Box15,
11259
11276
  Drawer as Drawer3,
@@ -11288,11 +11305,13 @@ var AgentRunDrawer = ({
11288
11305
  paperSx,
11289
11306
  headerSx,
11290
11307
  tabsSx,
11291
- bodySx
11308
+ bodySx,
11309
+ globalUrl
11292
11310
  }) => {
11311
+ useSyncHostBaseUrl(globalUrl);
11293
11312
  const [activeTab, setActiveTab] = useState13(initialTab);
11294
11313
  const prevOpenRef = useRef9(open);
11295
- useEffect11(() => {
11314
+ useEffect12(() => {
11296
11315
  if (open && !prevOpenRef.current) setActiveTab(initialTab);
11297
11316
  prevOpenRef.current = open;
11298
11317
  }, [open, initialTab]);
@@ -11435,6 +11454,7 @@ var AgentRunDrawer = ({
11435
11454
  hideHeroIcon: true,
11436
11455
  title: "",
11437
11456
  subtitle: null,
11457
+ apiBaseUrl: globalUrl,
11438
11458
  ...agentUIProps
11439
11459
  }
11440
11460
  ) }),
@@ -11448,7 +11468,7 @@ var AgentRunDrawer = ({
11448
11468
  var AgentRunDrawer_default = AgentRunDrawer;
11449
11469
 
11450
11470
  // AgentActivityList.tsx
11451
- import { useCallback as useCallback9, useEffect as useEffect12, useRef as useRef10, useState as useState14 } from "react";
11471
+ import { useCallback as useCallback9, useEffect as useEffect13, useRef as useRef10, useState as useState14 } from "react";
11452
11472
  import {
11453
11473
  Box as Box16,
11454
11474
  Button as Button9,
@@ -11943,7 +11963,7 @@ var AgentActivityList = ({
11943
11963
  if (debounceRef.current) clearTimeout(debounceRef.current);
11944
11964
  debounceRef.current = setTimeout(() => setDebouncedQuery(q), 350);
11945
11965
  }, []);
11946
- useEffect12(() => () => {
11966
+ useEffect13(() => () => {
11947
11967
  if (debounceRef.current) clearTimeout(debounceRef.current);
11948
11968
  }, []);
11949
11969
  const fetchRuns = useCallback9(
@@ -11975,10 +11995,10 @@ var AgentActivityList = ({
11975
11995
  },
11976
11996
  [statusFilter, limit, apiKey, apiBaseUrl, orgId, workflowFilter]
11977
11997
  );
11978
- useEffect12(() => {
11998
+ useEffect13(() => {
11979
11999
  fetchRuns(false, "");
11980
12000
  }, [statusFilter, apiKey, apiBaseUrl, orgId, workflowFilter]);
11981
- useEffect12(() => {
12001
+ useEffect13(() => {
11982
12002
  let cancelled = false;
11983
12003
  listAgentScheduleWorkflows({ apiKey, apiBaseUrl, orgId }).then((items) => {
11984
12004
  if (!cancelled) setAgentWorkflows(items);
@@ -12428,7 +12448,8 @@ var AgentExecutionDrawer_default = AgentExecutionDrawer;
12428
12448
  import { useCallback as useCallback10, useState as useState15 } from "react";
12429
12449
  import { Box as Box18, Stack, Typography as Typography17 } from "@mui/material";
12430
12450
  import { jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
12431
- var AgentsView = ({ onSchedule, maxWidth = 820 }) => {
12451
+ var AgentsView = ({ onSchedule, maxWidth = 820, globalUrl, isLoaded, isLoggedIn, userdata, serverside }) => {
12452
+ useSyncHostBaseUrl(globalUrl);
12432
12453
  const [selectedRun, setSelectedRun] = useState15(null);
12433
12454
  const [agentView, setAgentView] = useState15("start");
12434
12455
  const [prefill, setPrefill] = useState15({
@@ -12514,6 +12535,7 @@ var AgentsView = ({ onSchedule, maxWidth = 820 }) => {
12514
12535
  AgentUI_default,
12515
12536
  {
12516
12537
  maxWidth,
12538
+ apiBaseUrl: globalUrl,
12517
12539
  onViewChange: setAgentView,
12518
12540
  onSchedule,
12519
12541
  defaultInput: prefill.input,
@@ -12529,6 +12551,7 @@ var AgentsView = ({ onSchedule, maxWidth = 820 }) => {
12529
12551
  agentView === "start" && /* @__PURE__ */ jsx24(Box18, { sx: { pt: "12vh" }, children: /* @__PURE__ */ jsx24(
12530
12552
  AgentActivityList_default,
12531
12553
  {
12554
+ apiBaseUrl: globalUrl,
12532
12555
  onRunClick: setSelectedRun,
12533
12556
  onEditWorkflow: handleEditWorkflow
12534
12557
  }
@@ -12540,6 +12563,7 @@ var AgentsView = ({ onSchedule, maxWidth = 820 }) => {
12540
12563
  open: selectedRun !== null,
12541
12564
  onClose: () => setSelectedRun(null),
12542
12565
  run: selectedRun,
12566
+ apiBaseUrl: globalUrl,
12543
12567
  onSchedule
12544
12568
  }
12545
12569
  )
@@ -12548,7 +12572,7 @@ var AgentsView = ({ onSchedule, maxWidth = 820 }) => {
12548
12572
  var AgentsView_default = AgentsView;
12549
12573
 
12550
12574
  // useAppLookup.ts
12551
- import { useEffect as useEffect13, useMemo as useMemo7, useState as useState16 } from "react";
12575
+ import { useEffect as useEffect14, useMemo as useMemo7, useState as useState16 } from "react";
12552
12576
  var norm3 = (s) => s.toLowerCase().replace(/[\s_\-]+/g, "_");
12553
12577
  function useAppLookup(appName) {
12554
12578
  const [loading, setLoading] = useState16(false);
@@ -12562,7 +12586,7 @@ function useAppLookup(appName) {
12562
12586
  handleSaveAuth,
12563
12587
  refreshAuth
12564
12588
  } = useAppAuth();
12565
- useEffect13(() => {
12589
+ useEffect14(() => {
12566
12590
  if (!appName) {
12567
12591
  setInfo(null);
12568
12592
  setAlgoliaId(null);
@@ -12815,8 +12839,10 @@ export {
12815
12839
  getDatastoreItem,
12816
12840
  getDatastoreItemPublic,
12817
12841
  getFailureInfo,
12842
+ getHostBaseUrl,
12818
12843
  getIngestionCategory,
12819
12844
  hasOutputWarning,
12845
+ installFetchBreaker,
12820
12846
  invalidateAppsCache,
12821
12847
  invalidateResolvedApps,
12822
12848
  isCloud,
@@ -12830,12 +12856,16 @@ export {
12830
12856
  normalizeAppName,
12831
12857
  parseRunResult,
12832
12858
  refreshAllIntegrationStatus,
12859
+ registerProtectedOrigin,
12860
+ resetRegionUrl,
12833
12861
  resolveApp,
12834
12862
  resolveApps,
12835
12863
  searchAgentActivity,
12836
12864
  seedResolvedApp,
12837
12865
  setDatastoreItem,
12838
12866
  setDatastoreItems,
12867
+ setHostBaseUrl,
12868
+ setRegionUrl,
12839
12869
  setRuntimeOrgId,
12840
12870
  setToastImpl,
12841
12871
  shuffleFetch,
@@ -12843,5 +12873,6 @@ export {
12843
12873
  useAppAuth,
12844
12874
  useAppDetail,
12845
12875
  useAppDetailOptional,
12846
- useAppLookup
12876
+ useAppLookup,
12877
+ useSyncHostBaseUrl
12847
12878
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shuffleio/shuffle-mcps",
3
- "version": "0.0.16",
3
+ "version": "0.0.17",
4
4
  "description": "Turn 3,000+ SaaS tools into MCP servers your agents can use. Headless React component for search, selection, and OAuth handoff.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -1,149 +0,0 @@
1
- // api.ts
2
- var DEV_BACKEND = "https://tunnel.schemaless.org";
3
- var PROD_BACKEND = "https://shuffler.io";
4
- var CLOUD_DOMAINS = ["security.shuffler.io", "shutdown.no"];
5
- var getEnvVar = (key) => {
6
- try {
7
- const meta = new Function("try { return import.meta } catch { return undefined }")();
8
- return meta?.env?.[key];
9
- } catch {
10
- return void 0;
11
- }
12
- };
13
- var isDevEnvironment = () => {
14
- if (getEnvVar("VITE_SHUFFLE_API_URL")) return false;
15
- const hostname = typeof window !== "undefined" ? window.location.hostname : "";
16
- return hostname.includes("lovableproject.com") || hostname.includes("id-preview--");
17
- };
18
- var isCloudDomain = () => {
19
- const hostname = typeof window !== "undefined" ? window.location.hostname : "";
20
- return CLOUD_DOMAINS.includes(hostname);
21
- };
22
- var isCloud = () => isCloudDomain();
23
- var isOnprem = () => !isDevEnvironment() && !isCloudDomain();
24
- var getDefaultBaseUrl = () => {
25
- const envUrl = getEnvVar("VITE_SHUFFLE_API_URL");
26
- if (envUrl) {
27
- return envUrl;
28
- }
29
- if (isDevEnvironment()) return DEV_BACKEND;
30
- if (isCloudDomain()) return PROD_BACKEND;
31
- if (typeof window !== "undefined") {
32
- return window.location.origin;
33
- }
34
- return PROD_BACKEND;
35
- };
36
- var _regionUrl = null;
37
- var _trackedOrgId = null;
38
- var getTrackedOrgId = () => _trackedOrgId;
39
- var API_CONFIG = {
40
- // Shuffle backend URL - uses region URL if set, otherwise default
41
- get baseUrl() {
42
- return _regionUrl || getDefaultBaseUrl();
43
- },
44
- // API version
45
- version: "v1",
46
- // Get API key from localStorage (for local development)
47
- get apiKey() {
48
- return localStorage.getItem("shuffle_api_key");
49
- },
50
- // Set API key in localStorage
51
- setApiKey(key) {
52
- if (key) {
53
- localStorage.setItem("shuffle_api_key", key);
54
- } else {
55
- localStorage.removeItem("shuffle_api_key");
56
- }
57
- }
58
- };
59
- var getApiUrl = (endpoint) => {
60
- return `${API_CONFIG.baseUrl}${endpoint}`;
61
- };
62
- var shuffleFetch = (url, init) => {
63
- const { headers: extraHeaders, ...rest } = init || {};
64
- return fetch(url, {
65
- credentials: "include",
66
- ...rest,
67
- headers: {
68
- ...getAuthHeader(),
69
- ...extraHeaders
70
- }
71
- });
72
- };
73
- var getAuthHeader = (overrideOrgId) => {
74
- const headers = {};
75
- const apiKey = API_CONFIG.apiKey;
76
- if (apiKey) {
77
- headers["Authorization"] = `Bearer ${apiKey}`;
78
- }
79
- const orgId = overrideOrgId ?? _trackedOrgId;
80
- if (orgId) {
81
- headers["Org-Id"] = orgId;
82
- }
83
- return headers;
84
- };
85
-
86
- // appsCache.ts
87
- var TTL_MS = 3e4;
88
- var cache = /* @__PURE__ */ new Map();
89
- var cacheKey = (o) => `${o.baseUrl}|${o.path || "/api/v1/apps"}|${o.apiKey || ""}|${o.orgId || ""}`;
90
- var doFetch = async (o) => {
91
- const headers = {};
92
- if (o.apiKey) headers["Authorization"] = `Bearer ${o.apiKey}`;
93
- if (o.orgId) headers["Org-Id"] = o.orgId;
94
- const response = await fetch(`${o.baseUrl}${o.path || "/api/v1/apps"}`, {
95
- credentials: "include",
96
- headers
97
- });
98
- if (!response.ok) return [];
99
- const data = await response.json();
100
- if (Array.isArray(data)) return data;
101
- return Array.isArray(data?.data) ? data.data : [];
102
- };
103
- var fetchApps = (opts) => {
104
- const key = cacheKey(opts);
105
- const entry = cache.get(key) || {};
106
- if (entry.data && entry.fetchedAt && Date.now() - entry.fetchedAt < TTL_MS) {
107
- return Promise.resolve(entry.data);
108
- }
109
- if (entry.promise) return entry.promise;
110
- const promise = doFetch(opts).then((data) => {
111
- cache.set(key, { data, fetchedAt: Date.now() });
112
- return data;
113
- }).catch((err) => {
114
- cache.delete(key);
115
- throw err;
116
- });
117
- cache.set(key, { ...entry, promise });
118
- return promise;
119
- };
120
- var invalidateAppsCache = (opts) => {
121
- if (!opts) {
122
- cache.clear();
123
- return;
124
- }
125
- cache.delete(cacheKey(opts));
126
- };
127
- var fetchAppsViaApiConfig = () => {
128
- const headers = getAuthHeader();
129
- const orgId = headers["Org-Id"] || null;
130
- return fetchApps({
131
- baseUrl: API_CONFIG.baseUrl,
132
- apiKey: API_CONFIG.apiKey,
133
- orgId
134
- });
135
- };
136
-
137
- export {
138
- isCloudDomain,
139
- isCloud,
140
- isOnprem,
141
- getTrackedOrgId,
142
- API_CONFIG,
143
- getApiUrl,
144
- shuffleFetch,
145
- getAuthHeader,
146
- fetchApps,
147
- invalidateAppsCache,
148
- fetchAppsViaApiConfig
149
- };