@shuffleio/shuffle-mcps 0.0.63 → 0.0.65
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/{appsCache-2UYFFT3V.mjs → appsCache-QAL2GC5W.mjs} +1 -2
- package/dist/{chunk-XNE7PKME.mjs → chunk-V3R4HDJT.mjs} +66 -17
- package/dist/index.d.mts +339 -325
- package/dist/index.d.ts +339 -325
- package/dist/index.js +11086 -68207
- package/dist/index.mjs +13271 -69522
- package/package.json +13 -3
- package/dist/analytics-JGBV375U.mjs +0 -20
- package/dist/auth-utils-HYVXQKTL.mjs +0 -12
- package/dist/chunk-2NCPSII6.mjs +0 -105
- package/dist/chunk-DSJHIKBO.mjs +0 -64
- package/dist/chunk-QC2DO6WV.mjs +0 -1208
- package/dist/chunk-TUSSDUVQ.mjs +0 -155
- package/dist/datastore-DRXSNIPR.mjs +0 -27
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shuffleio/shuffle-mcps",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.65",
|
|
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": {
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
"@emotion/styled": ">=11",
|
|
54
54
|
"lucide-react": ">=0.300.0",
|
|
55
55
|
"react-router-dom": ">=6",
|
|
56
|
+
"@shuffleio/shuffle-core": ">=0.0.1",
|
|
56
57
|
"@tanstack/react-query": ">=5"
|
|
57
58
|
},
|
|
58
59
|
"peerDependenciesMeta": {
|
|
@@ -71,9 +72,18 @@
|
|
|
71
72
|
"react18-json-view": "^0.2.9"
|
|
72
73
|
},
|
|
73
74
|
"devDependencies": {
|
|
74
|
-
"@
|
|
75
|
-
"@
|
|
75
|
+
"@emotion/react": "^11.11.0",
|
|
76
|
+
"@emotion/styled": "^11.11.0",
|
|
77
|
+
"@mui/icons-material": "^5.15.0",
|
|
78
|
+
"@mui/material": "^5.15.0",
|
|
76
79
|
"@tanstack/react-query": "^5.0.0",
|
|
80
|
+
"@types/node": "^20.0.0",
|
|
81
|
+
"@types/react": "^18.0.0",
|
|
82
|
+
"@types/react-dom": "^18.0.0",
|
|
83
|
+
"lucide-react": "^0.300.0",
|
|
84
|
+
"react": "^18.0.0",
|
|
85
|
+
"react-dom": "^18.0.0",
|
|
86
|
+
"react-router-dom": "^6.0.0",
|
|
77
87
|
"tsup": "^8.0.0",
|
|
78
88
|
"typescript": "^5.0.0"
|
|
79
89
|
}
|
|
@@ -1,20 +0,0 @@
|
|
|
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
|
-
};
|
package/dist/chunk-2NCPSII6.mjs
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
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
|
-
};
|
package/dist/chunk-DSJHIKBO.mjs
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
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
|
-
};
|