@shuffleio/shuffle-mcps 0.0.59 → 0.0.63

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.
@@ -0,0 +1,20 @@
1
+ import {
2
+ GA_EVENTS,
3
+ initAnalytics,
4
+ trackCTA,
5
+ trackEvent,
6
+ trackOnboardingStep,
7
+ trackPageView,
8
+ trackPredefinedEvent,
9
+ trackReferralParams
10
+ } from "./chunk-TUSSDUVQ.mjs";
11
+ export {
12
+ GA_EVENTS,
13
+ initAnalytics,
14
+ trackCTA,
15
+ trackEvent,
16
+ trackOnboardingStep,
17
+ trackPageView,
18
+ trackPredefinedEvent,
19
+ trackReferralParams
20
+ };
@@ -2,7 +2,8 @@ import {
2
2
  fetchApps,
3
3
  fetchAppsViaApiConfig,
4
4
  invalidateAppsCache
5
- } from "./chunk-7HRNENGV.mjs";
5
+ } from "./chunk-DSJHIKBO.mjs";
6
+ import "./chunk-XNE7PKME.mjs";
6
7
  export {
7
8
  fetchApps,
8
9
  fetchAppsViaApiConfig,
@@ -0,0 +1,12 @@
1
+ import {
2
+ backfillAppImages,
3
+ deduplicateAuthApps,
4
+ isValidationFresh,
5
+ seedImageCache
6
+ } from "./chunk-2NCPSII6.mjs";
7
+ export {
8
+ backfillAppImages,
9
+ deduplicateAuthApps,
10
+ isValidationFresh,
11
+ seedImageCache
12
+ };
@@ -0,0 +1,105 @@
1
+ // ../Shuffle-Core/auth-utils.ts
2
+ var THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1e3;
3
+ function isValidationFresh(validation) {
4
+ if (validation?.valid !== true) return false;
5
+ if (!validation.last_valid) return true;
6
+ const cutoff = Date.now() - THIRTY_DAYS_MS;
7
+ const lastValidMs = validation.last_valid > 1e12 ? validation.last_valid : validation.last_valid * 1e3;
8
+ return lastValidMs >= cutoff;
9
+ }
10
+ function deduplicateAuthApps(apps) {
11
+ const appMap = /* @__PURE__ */ new Map();
12
+ apps.forEach((auth) => {
13
+ if (!auth.app?.name) return;
14
+ if (!auth.active && !isValidationFresh(auth.validation)) return;
15
+ const normalizedName = auth.app.name.toLowerCase().trim().replace(/[\s_\-]+/g, "_");
16
+ const existing = appMap.get(normalizedName);
17
+ const isValidated = isValidationFresh(auth.validation);
18
+ const entryImage = auth.app.large_image || "";
19
+ const instance = {
20
+ label: auth.label || auth.id || "Default",
21
+ isValidated
22
+ };
23
+ if (!existing) {
24
+ appMap.set(normalizedName, {
25
+ app: auth.app,
26
+ hasValidAuth: isValidated,
27
+ bestImage: entryImage,
28
+ instances: [instance]
29
+ });
30
+ } else {
31
+ existing.instances.push(instance);
32
+ if (isValidated) existing.hasValidAuth = true;
33
+ if (!existing.bestImage && entryImage) existing.bestImage = entryImage;
34
+ if (isValidated && !existing.app.large_image && entryImage) {
35
+ existing.app = { ...existing.app, large_image: entryImage };
36
+ }
37
+ }
38
+ });
39
+ return Array.from(appMap.values());
40
+ }
41
+ var _imageCache = /* @__PURE__ */ new Map();
42
+ var _pendingLookups = /* @__PURE__ */ new Map();
43
+ var _normalize = (n) => n.toLowerCase().replace(/[\s_\-]+/g, "_");
44
+ function seedImageCache(appName, imageUrl) {
45
+ if (appName && imageUrl) _imageCache.set(_normalize(appName), imageUrl);
46
+ }
47
+ async function backfillAppImages(dedupedApps) {
48
+ for (const d of dedupedApps) {
49
+ const norm = _normalize(d.app.name);
50
+ const existingImg = d.bestImage || d.app.large_image;
51
+ if (existingImg) {
52
+ _imageCache.set(norm, existingImg);
53
+ } else if (_imageCache.has(norm)) {
54
+ const cached = _imageCache.get(norm);
55
+ if (cached) {
56
+ d.bestImage = cached;
57
+ d.app = { ...d.app, large_image: cached };
58
+ }
59
+ }
60
+ }
61
+ const missing = dedupedApps.filter((d) => !d.bestImage && !d.app.large_image && !_imageCache.has(_normalize(d.app.name)));
62
+ if (missing.length === 0) return dedupedApps;
63
+ try {
64
+ const { algoliasearch } = await import("algoliasearch");
65
+ const client = algoliasearch("JNSS5CFDZZ", "33e4e3564f4f060e96e0531957bed552");
66
+ await Promise.all(missing.map(async (entry) => {
67
+ const norm = _normalize(entry.app.name);
68
+ if (!_pendingLookups.has(norm)) {
69
+ _pendingLookups.set(norm, (async () => {
70
+ try {
71
+ const result = await client.searchSingleIndex({
72
+ indexName: "appsearch",
73
+ searchParams: { query: entry.app.name, hitsPerPage: 3 }
74
+ });
75
+ const match = result.hits.find(
76
+ (h) => _normalize(h.name || "") === norm
77
+ );
78
+ const url2 = match?.image_url || "";
79
+ _imageCache.set(norm, url2);
80
+ return url2;
81
+ } catch {
82
+ _imageCache.set(norm, "");
83
+ return null;
84
+ } finally {
85
+ _pendingLookups.delete(norm);
86
+ }
87
+ })());
88
+ }
89
+ const url = await _pendingLookups.get(norm);
90
+ if (url) {
91
+ entry.bestImage = url;
92
+ entry.app = { ...entry.app, large_image: url };
93
+ }
94
+ }));
95
+ } catch {
96
+ }
97
+ return dedupedApps;
98
+ }
99
+
100
+ export {
101
+ isValidationFresh,
102
+ deduplicateAuthApps,
103
+ seedImageCache,
104
+ backfillAppImages
105
+ };
@@ -0,0 +1,64 @@
1
+ import {
2
+ API_CONFIG,
3
+ getAuthHeader
4
+ } from "./chunk-XNE7PKME.mjs";
5
+
6
+ // appsCache.ts
7
+ var TTL_MS = 3e4;
8
+ var ERROR_TTL_MS = 3e4;
9
+ var cache = /* @__PURE__ */ new Map();
10
+ var cacheKey = (o) => `${o.baseUrl}|${o.path || "/api/v1/apps"}|${o.apiKey || ""}|${o.orgId || ""}`;
11
+ var doFetch = async (o) => {
12
+ const headers = {
13
+ ...getAuthHeader(o.orgId || void 0)
14
+ };
15
+ if (o.apiKey) headers["Authorization"] = `Bearer ${o.apiKey}`;
16
+ if (o.orgId) headers["Org-Id"] = o.orgId;
17
+ const response = await fetch(`${o.baseUrl}${o.path || "/api/v1/apps"}`, {
18
+ credentials: "include",
19
+ headers
20
+ });
21
+ if (!response.ok) return [];
22
+ const data = await response.json();
23
+ if (Array.isArray(data)) return data;
24
+ return Array.isArray(data?.data) ? data.data : [];
25
+ };
26
+ var fetchApps = (opts) => {
27
+ const key = cacheKey(opts);
28
+ const entry = cache.get(key) || {};
29
+ if (entry.data && entry.fetchedAt && Date.now() - entry.fetchedAt < TTL_MS) {
30
+ return Promise.resolve(entry.data);
31
+ }
32
+ if (entry.promise) return entry.promise;
33
+ const promise = doFetch(opts).then((data) => {
34
+ cache.set(key, { data, fetchedAt: Date.now() });
35
+ return data;
36
+ }).catch(() => {
37
+ cache.set(key, { data: [], fetchedAt: Date.now() - (TTL_MS - ERROR_TTL_MS) });
38
+ return [];
39
+ });
40
+ cache.set(key, { ...entry, promise });
41
+ return promise;
42
+ };
43
+ var invalidateAppsCache = (opts) => {
44
+ if (!opts) {
45
+ cache.clear();
46
+ return;
47
+ }
48
+ cache.delete(cacheKey(opts));
49
+ };
50
+ var fetchAppsViaApiConfig = () => {
51
+ const headers = getAuthHeader();
52
+ const orgId = headers["Org-Id"] || null;
53
+ return fetchApps({
54
+ baseUrl: API_CONFIG.baseUrl,
55
+ apiKey: API_CONFIG.apiKey,
56
+ orgId
57
+ });
58
+ };
59
+
60
+ export {
61
+ fetchApps,
62
+ invalidateAppsCache,
63
+ fetchAppsViaApiConfig
64
+ };