@apify/actors-mcp-server 0.11.7-beta.0 → 0.11.7-beta.1
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/const.d.ts +5 -5
- package/dist/const.d.ts.map +1 -1
- package/dist/const.js +5 -5
- package/dist/const.js.map +1 -1
- package/dist/mcp/server.d.ts +13 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +20 -7
- package/dist/mcp/server.js.map +1 -1
- package/dist/resources/api_resources.d.ts +37 -0
- package/dist/resources/api_resources.d.ts.map +1 -0
- package/dist/resources/api_resources.js +255 -0
- package/dist/resources/api_resources.js.map +1 -0
- package/dist/resources/resource_service.d.ts +4 -3
- package/dist/resources/resource_service.d.ts.map +1 -1
- package/dist/resources/resource_service.js +52 -7
- package/dist/resources/resource_service.js.map +1 -1
- package/dist/tools/storage/get_key_value_store_record.d.ts.map +1 -1
- package/dist/tools/storage/get_key_value_store_record.js +9 -7
- package/dist/tools/storage/get_key_value_store_record.js.map +1 -1
- package/dist/tools/storage/storage_helpers.d.ts +27 -0
- package/dist/tools/storage/storage_helpers.d.ts.map +1 -1
- package/dist/tools/storage/storage_helpers.js +21 -1
- package/dist/tools/storage/storage_helpers.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/mcp.d.ts +6 -0
- package/dist/utils/mcp.d.ts.map +1 -1
- package/dist/utils/mcp.js +15 -8
- package/dist/utils/mcp.js.map +1 -1
- package/dist/utils/server-instructions/index.d.ts.map +1 -1
- package/dist/utils/server-instructions/index.js +10 -0
- package/dist/utils/server-instructions/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
import { isAxiosError } from 'axios';
|
|
3
|
+
import { getApifyAPIBaseUrl } from '../apify_client.js';
|
|
4
|
+
import { MAX_INLINE_BYTES } from '../const.js';
|
|
5
|
+
import { parseBaseMimeType } from '../tools/storage/storage_helpers.js';
|
|
6
|
+
import { getHttpStatusCode, logHttpError } from '../utils/logging.js';
|
|
7
|
+
import { getHttpErrorHint } from '../utils/mcp.js';
|
|
8
|
+
const TEXT_MIME_TYPE = 'text/plain';
|
|
9
|
+
/** Textual base MIME types (returned as `text`); everything else becomes a base64 `blob`. */
|
|
10
|
+
function isTextualMimeType(baseMimeType) {
|
|
11
|
+
if (!baseMimeType)
|
|
12
|
+
return false;
|
|
13
|
+
return (baseMimeType.startsWith('text/') ||
|
|
14
|
+
baseMimeType === 'application/json' ||
|
|
15
|
+
baseMimeType.endsWith('+json') ||
|
|
16
|
+
baseMimeType === 'application/xml' ||
|
|
17
|
+
baseMimeType.endsWith('+xml') ||
|
|
18
|
+
baseMimeType === 'application/javascript');
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Maps a failed read's HTTP status to a JSON-RPC error code:
|
|
22
|
+
* - 3xx/4xx except 429 → `InvalidParams` (the request/resource is the problem — bad URI, missing/invalid
|
|
23
|
+
* token, private resource, or a resource that does not exist; SEP-2164 remaps "nonexistent" here too).
|
|
24
|
+
* - 429, 5xx, or no status (network failure) → `InternalError` (transient or upstream).
|
|
25
|
+
*/
|
|
26
|
+
function getErrorCodeForStatus(status) {
|
|
27
|
+
if (status !== undefined && status < 500 && status !== 429)
|
|
28
|
+
return ErrorCode.InvalidParams;
|
|
29
|
+
return ErrorCode.InternalError;
|
|
30
|
+
}
|
|
31
|
+
/** Throw the standard resources/read failure McpError. Callers log the error first — the log source differs by site. */
|
|
32
|
+
function throwReadFailure(uri, status, message) {
|
|
33
|
+
const hint = getHttpErrorHint(status);
|
|
34
|
+
throw new McpError(getErrorCodeForStatus(status), `Failed to read ${uri}: ${status ? `HTTP ${status}: ` : ''}${message}${hint ? `. ${hint}` : ''}`, { uri });
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* True when the URI is an Apify API URL (same origin as the configured API base).
|
|
38
|
+
*
|
|
39
|
+
* This is the security gate for the generic read proxy: the apify-client attaches the
|
|
40
|
+
* session token as an `Authorization` header to every outbound request, so we must only
|
|
41
|
+
* hand it Apify API URLs — never an arbitrary host. Userinfo-bearing URLs
|
|
42
|
+
* (`user@api.apify.com`) are rejected even when the host is genuinely ours: axios drops
|
|
43
|
+
* the default `Authorization` header for credentials-bearing URLs, so the read would
|
|
44
|
+
* silently run unauthenticated.
|
|
45
|
+
*/
|
|
46
|
+
export function isApifyApiUri(uri) {
|
|
47
|
+
try {
|
|
48
|
+
const url = new URL(uri);
|
|
49
|
+
if (url.username || url.password)
|
|
50
|
+
return false;
|
|
51
|
+
return url.origin === new URL(getApifyAPIBaseUrl()).origin;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Matches an Apify key-value-store record path, capturing the store id and the record key.
|
|
59
|
+
* Both groups exclude `/?#` so a trailing query or fragment can't leak into the captured key.
|
|
60
|
+
*/
|
|
61
|
+
const KV_RECORD_PATH_RE = /^\/v2\/key-value-stores\/([^/?#]+)\/records\/([^/?#]+)$/;
|
|
62
|
+
/** `decodeURIComponent` that returns the input unchanged on malformed percent-encoding instead of throwing. */
|
|
63
|
+
function safeDecodeURIComponent(segment) {
|
|
64
|
+
try {
|
|
65
|
+
return decodeURIComponent(segment);
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return segment;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Download URL for a body too large to inline. For a key-value-store record URI, returns the
|
|
73
|
+
* store's signed `recordPublicUrl` — fetchable without an API token when the client can read the
|
|
74
|
+
* store's URL signing key. Falls back to the original API URL for any other endpoint, or if minting
|
|
75
|
+
* the signed URL fails (fetching that link then needs a token).
|
|
76
|
+
*/
|
|
77
|
+
async function fetchRecordDownloadUrl(uri, apifyClient) {
|
|
78
|
+
let pathname;
|
|
79
|
+
try {
|
|
80
|
+
pathname = new URL(uri).pathname;
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return uri;
|
|
84
|
+
}
|
|
85
|
+
const match = KV_RECORD_PATH_RE.exec(pathname);
|
|
86
|
+
if (!match)
|
|
87
|
+
return uri;
|
|
88
|
+
try {
|
|
89
|
+
const store = apifyClient.keyValueStore(safeDecodeURIComponent(match[1]));
|
|
90
|
+
return await store.getRecordPublicUrl(safeDecodeURIComponent(match[2]));
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
logHttpError(err, `Failed to mint signed download URL for ${uri}; falling back to API URL`);
|
|
94
|
+
return uri;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/** Single text-contents result; pass `mimeType` to preserve a body's declared Content-Type. */
|
|
98
|
+
function buildTextResult(uri, text, mimeType = TEXT_MIME_TYPE) {
|
|
99
|
+
return { contents: [{ uri, mimeType, text }] };
|
|
100
|
+
}
|
|
101
|
+
/** True when the URI is a key-value-store record path (a single record, not a pageable list). */
|
|
102
|
+
function isKvRecordUri(uri) {
|
|
103
|
+
try {
|
|
104
|
+
return KV_RECORD_PATH_RE.test(new URL(uri).pathname);
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/** Body too large to inline: a download-pointer text result. NOT a failure — the resource is readable, just not inline. */
|
|
111
|
+
async function buildLinkOutResult(uri, apifyClient) {
|
|
112
|
+
const downloadUrl = await fetchRecordDownloadUrl(uri, apifyClient);
|
|
113
|
+
// A KVS record is a single object with no paging; only a dataset/list can shrink via limit/offset.
|
|
114
|
+
const pagingHint = isKvRecordUri(uri) ? '' : ' For a dataset/list, re-read with a smaller limit/offset range.';
|
|
115
|
+
return buildTextResult(uri, `Response body exceeds the ${MAX_INLINE_BYTES}-byte inline limit. Download it from ${downloadUrl} ` +
|
|
116
|
+
`(may require your Apify API token).${pagingHint}`);
|
|
117
|
+
}
|
|
118
|
+
/** The mid-consumption abort axios raises when a streamed body crosses `maxContentLength`. */
|
|
119
|
+
function isMaxContentLengthAbort(err) {
|
|
120
|
+
return isAxiosError(err) && err.code === 'ERR_BAD_RESPONSE' && err.message.includes('maxContentLength');
|
|
121
|
+
}
|
|
122
|
+
/** `charset` parameter of a Content-Type header, lowercased; `undefined` when absent. */
|
|
123
|
+
function parseCharset(contentType) {
|
|
124
|
+
const match = /;\s*charset\s*=\s*"?([^";]+)"?/i.exec(contentType !== null && contentType !== void 0 ? contentType : '');
|
|
125
|
+
return match === null || match === void 0 ? void 0 : match[1].trim().toLowerCase();
|
|
126
|
+
}
|
|
127
|
+
/** Drain a response stream into one Buffer. Chunks are Buffers (`objectMode: false`). */
|
|
128
|
+
async function collectStream(data) {
|
|
129
|
+
const chunks = [];
|
|
130
|
+
for await (const chunk of data) {
|
|
131
|
+
chunks.push(Buffer.from(chunk));
|
|
132
|
+
}
|
|
133
|
+
return Buffer.concat(chunks);
|
|
134
|
+
}
|
|
135
|
+
/** `error.message` from an Apify API error body, or `undefined` when the body isn't that shape. */
|
|
136
|
+
function parseApiErrorMessage(body) {
|
|
137
|
+
var _a;
|
|
138
|
+
if (!body || body.length === 0)
|
|
139
|
+
return undefined;
|
|
140
|
+
try {
|
|
141
|
+
const parsed = JSON.parse(body.toString('utf-8'));
|
|
142
|
+
return typeof ((_a = parsed === null || parsed === void 0 ? void 0 : parsed.error) === null || _a === void 0 ? void 0 : _a.message) === 'string' ? parsed.error.message : undefined;
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
return undefined;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Read any Apify API GET endpoint as an MCP resource.
|
|
150
|
+
*
|
|
151
|
+
* A thin streaming proxy: the apify-client injects the session token (and the MCP-origin header),
|
|
152
|
+
* the body streams in verbatim and is returned by its declared Content-Type — textual types
|
|
153
|
+
* (text/*, JSON, XML) as `text`, anything else as a base64 `blob`. The body is never parsed, so
|
|
154
|
+
* JSON primitives, formatting, and bytes round-trip exactly.
|
|
155
|
+
*
|
|
156
|
+
* Genuine failures (no token, bad origin, a missing resource, a bad token, a 5xx, a network error)
|
|
157
|
+
* throw an `McpError` so the SDK returns a JSON-RPC error rather than success-shaped content for an
|
|
158
|
+
* unreadable resource (see SEP-2164). A body over `MAX_INLINE_BYTES` is NOT a failure — it is a
|
|
159
|
+
* successful read returning a download pointer.
|
|
160
|
+
*
|
|
161
|
+
* The request goes straight through `apifyClient.httpClient.axios` (the same axios instance
|
|
162
|
+
* apify-client builds internally, so token/origin headers still apply) instead of
|
|
163
|
+
* `httpClient.call()`: with `responseType: 'stream'`, a non-2xx reaches `call()` as an unconsumed
|
|
164
|
+
* stream — its `ApifyApiError` message degrades to junk and each retry attempt strands an unread
|
|
165
|
+
* socket. One attempt, no retries. `maxContentLength` is enforced by axios itself mid-consumption
|
|
166
|
+
* (verified in axios@1.16.1: the adapter wraps streamed responses in a byte-counting generator
|
|
167
|
+
* that throws `ERR_BAD_RESPONSE` when the decoded size crosses the limit), so an oversized body
|
|
168
|
+
* is aborted at ~`MAX_INLINE_BYTES`, never buffered whole.
|
|
169
|
+
*/
|
|
170
|
+
export async function readApiResource(uri, apifyClient) {
|
|
171
|
+
var _a, _b;
|
|
172
|
+
if (!isApifyApiUri(uri)) {
|
|
173
|
+
throw new McpError(ErrorCode.InvalidParams, `Failed to read ${uri}: only Apify API URLs (${getApifyAPIBaseUrl()}) are readable as resources.`, { uri });
|
|
174
|
+
}
|
|
175
|
+
if (!apifyClient) {
|
|
176
|
+
throw new McpError(ErrorCode.InvalidParams, `Failed to read ${uri}: no Apify token in this session.`, {
|
|
177
|
+
uri,
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
let response;
|
|
181
|
+
try {
|
|
182
|
+
// The raw axios instance skips `httpClient.call()` → `ensureNodeInit()`, so reads do NOT honor
|
|
183
|
+
// `HTTPS_PROXY` (auth + MCP-origin headers are instance defaults and still apply — not a leak).
|
|
184
|
+
// Fine for direct egress; a proxy-mandatory deployment needs an apify-client init hook.
|
|
185
|
+
response = await apifyClient.httpClient.axios.request({
|
|
186
|
+
url: uri,
|
|
187
|
+
method: 'GET',
|
|
188
|
+
responseType: 'stream',
|
|
189
|
+
maxContentLength: MAX_INLINE_BYTES,
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
catch (err) {
|
|
193
|
+
logHttpError(err, `resources/read request failed`, { uri });
|
|
194
|
+
throwReadFailure(uri, getHttpStatusCode(err), err instanceof Error ? err.message : String(err));
|
|
195
|
+
}
|
|
196
|
+
let body;
|
|
197
|
+
let overLimit = false;
|
|
198
|
+
try {
|
|
199
|
+
body = await collectStream(response.data);
|
|
200
|
+
}
|
|
201
|
+
catch (err) {
|
|
202
|
+
if (isMaxContentLengthAbort(err)) {
|
|
203
|
+
overLimit = true;
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
// A drop mid-body (reset, truncation, bad gzip). Never return partial content.
|
|
207
|
+
logHttpError(err, `resources/read response interrupted`, { uri });
|
|
208
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
209
|
+
throw new McpError(ErrorCode.InternalError, `Failed to read ${uri}: response interrupted: ${message}`, {
|
|
210
|
+
uri,
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
// `validateStatus: null` on this axios instance resolves non-2xx responses instead of throwing,
|
|
215
|
+
// so a failed request is checked here. The error body was just collected above (Apify API error
|
|
216
|
+
// bodies are small JSON; if one somehow crossed the limit, fall back to the status text).
|
|
217
|
+
if (response.status >= 300) {
|
|
218
|
+
const message = (_a = parseApiErrorMessage(body)) !== null && _a !== void 0 ? _a : response.statusText;
|
|
219
|
+
logHttpError(Object.assign(new Error(message), { statusCode: response.status }), `resources/read failed`, {
|
|
220
|
+
uri,
|
|
221
|
+
});
|
|
222
|
+
throwReadFailure(uri, response.status, message);
|
|
223
|
+
}
|
|
224
|
+
// Second clause is runtime-redundant (undefined ⟺ overLimit) but narrows `body` to Buffer below.
|
|
225
|
+
if (overLimit || body === undefined) {
|
|
226
|
+
return buildLinkOutResult(uri, apifyClient);
|
|
227
|
+
}
|
|
228
|
+
const contentTypeHeader = response.headers['content-type'];
|
|
229
|
+
const contentType = typeof contentTypeHeader === 'string' ? contentTypeHeader : undefined;
|
|
230
|
+
// Empty body → empty text preserving the declared Content-Type, matching get-key-value-store-record
|
|
231
|
+
// (even for a binary type: an empty blob carries no bytes).
|
|
232
|
+
if (body.length === 0) {
|
|
233
|
+
return buildTextResult(uri, '', contentType);
|
|
234
|
+
}
|
|
235
|
+
const baseMimeType = parseBaseMimeType(contentType);
|
|
236
|
+
const charset = (_b = parseCharset(contentType)) !== null && _b !== void 0 ? _b : 'utf-8';
|
|
237
|
+
// Decode with the DECLARED charset, not hardcoded UTF-8 — latin1 bytes decoded as UTF-8 mangle
|
|
238
|
+
// irreversibly to U+FFFD. A charset Node cannot decode falls through to the blob branch (lossless
|
|
239
|
+
// base64 beats text in a wrong encoding), the same rule as apify-client's body_parser. The full
|
|
240
|
+
// Content-Type — charset included — rides along on the text result.
|
|
241
|
+
if (isTextualMimeType(baseMimeType) && Buffer.isEncoding(charset)) {
|
|
242
|
+
return buildTextResult(uri, body.toString(charset), contentType);
|
|
243
|
+
}
|
|
244
|
+
// Binary or undecodable text: base MIME type only (parameters are meaningless for a blob).
|
|
245
|
+
return {
|
|
246
|
+
contents: [
|
|
247
|
+
{
|
|
248
|
+
uri,
|
|
249
|
+
...(baseMimeType && { mimeType: baseMimeType }),
|
|
250
|
+
blob: body.toString('base64'),
|
|
251
|
+
},
|
|
252
|
+
],
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
//# sourceMappingURL=api_resources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api_resources.js","sourceRoot":"","sources":["../../src/resources/api_resources.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type { ListResourcesResult, ListResourceTemplatesResult, ReadResourceResult, TextResourceContents } from '@modelcontextprotocol/sdk/types.js';
|
|
1
|
+
import type { BlobResourceContents, ListResourcesResult, ListResourceTemplatesResult, ReadResourceResult, TextResourceContents } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
import type { ApifyClient } from '../apify_client.js';
|
|
2
3
|
import type { PaymentProvider } from '../payments/types.js';
|
|
3
4
|
import { SERVER_MODE } from '../types.js';
|
|
4
5
|
import type { AvailableWidget } from './widgets.js';
|
|
5
|
-
type ExtendedResourceContents = TextResourceContents & {
|
|
6
|
+
type ExtendedResourceContents = (TextResourceContents | BlobResourceContents) & {
|
|
6
7
|
html?: string;
|
|
7
8
|
_meta?: AvailableWidget['meta'];
|
|
8
9
|
};
|
|
@@ -11,7 +12,7 @@ type ExtendedReadResourceResult = Omit<ReadResourceResult, 'contents'> & {
|
|
|
11
12
|
};
|
|
12
13
|
type ResourceService = {
|
|
13
14
|
listResources: () => Promise<ListResourcesResult>;
|
|
14
|
-
readResource: (uri: string) => Promise<ExtendedReadResourceResult>;
|
|
15
|
+
readResource: (uri: string, apifyClient?: ApifyClient) => Promise<ExtendedReadResourceResult>;
|
|
15
16
|
listResourceTemplates: () => Promise<ListResourceTemplatesResult>;
|
|
16
17
|
};
|
|
17
18
|
type ResourceServiceOptions = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource_service.d.ts","sourceRoot":"","sources":["../../src/resources/resource_service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACR,mBAAmB,EACnB,2BAA2B,EAC3B,kBAAkB,EAElB,oBAAoB,EACvB,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"resource_service.d.ts","sourceRoot":"","sources":["../../src/resources/resource_service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACR,oBAAoB,EACpB,mBAAmB,EACnB,2BAA2B,EAC3B,kBAAkB,EAElB,oBAAoB,EACvB,MAAM,oCAAoC,CAAC;AAK5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAIpD,KAAK,wBAAwB,GAAG,CAAC,oBAAoB,GAAG,oBAAoB,CAAC,GAAG;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;CACnC,CAAC;AAEF,KAAK,0BAA0B,GAAG,IAAI,CAAC,kBAAkB,EAAE,UAAU,CAAC,GAAG;IACrE,QAAQ,EAAE,wBAAwB,EAAE,CAAC;CACxC,CAAC;AAEF,KAAK,eAAe,GAAG;IACnB,aAAa,EAAE,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAClD,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAC9F,qBAAqB,EAAE,MAAM,OAAO,CAAC,2BAA2B,CAAC,CAAC;CACrE,CAAC;AAEF,KAAK,sBAAsB,GAAG;IAC1B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC;;;;;;OAMG;IACH,OAAO,EAAE,MAAM,WAAW,CAAC;IAC3B,mBAAmB,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC3D,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,sBAAsB,GAAG,eAAe,CA0KtF"}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js';
|
|
2
3
|
import log from '@apify/log';
|
|
4
|
+
import { getApifyAPIBaseUrl } from '../apify_client.js';
|
|
3
5
|
import { SERVER_MODE } from '../types.js';
|
|
6
|
+
import { readApiResource } from './api_resources.js';
|
|
4
7
|
import { RESOURCE_MIME_TYPE } from './widgets.js';
|
|
5
8
|
export function createResourceService(options) {
|
|
6
9
|
const { paymentProvider, getMode, getAvailableWidgets } = options;
|
|
@@ -32,8 +35,14 @@ export function createResourceService(options) {
|
|
|
32
35
|
}
|
|
33
36
|
return { resources };
|
|
34
37
|
};
|
|
35
|
-
const readResource = async (uri) => {
|
|
38
|
+
const readResource = async (uri, apifyClient) => {
|
|
36
39
|
var _a;
|
|
40
|
+
// Route every http(s) URI to the API proxy — it owns the single origin gate, so a
|
|
41
|
+
// non-Apify URL gets the explanatory origin refusal instead of the generic fallback.
|
|
42
|
+
if (/^https?:\/\//i.test(uri)) {
|
|
43
|
+
// API contents carry no widget `_meta`/`html`; the extended shape only adds optional fields.
|
|
44
|
+
return (await readApiResource(uri, apifyClient));
|
|
45
|
+
}
|
|
37
46
|
const usageGuide = (_a = paymentProvider === null || paymentProvider === void 0 ? void 0 : paymentProvider.getUsageGuide) === null || _a === void 0 ? void 0 : _a.call(paymentProvider);
|
|
38
47
|
if (usageGuide && uri === 'file://readme.md') {
|
|
39
48
|
return {
|
|
@@ -98,19 +107,55 @@ export function createResourceService(options) {
|
|
|
98
107
|
};
|
|
99
108
|
}
|
|
100
109
|
}
|
|
110
|
+
// A URI that is neither an http(s) URL, the usage guide, nor a served widget is not a
|
|
111
|
+
// readable resource — throw so the SDK returns a JSON-RPC error instead of success-shaped
|
|
112
|
+
// "not found" content (see SEP-2164 and src/resources/AGENTS.md).
|
|
113
|
+
throw new McpError(ErrorCode.InvalidParams, `Failed to read ${uri}: not a readable resource.`, { uri });
|
|
114
|
+
};
|
|
115
|
+
// Advertise the common URL shapes so clients that never surface the server instructions can
|
|
116
|
+
// still discover the read proxy and its paging parameters (RFC 6570 `{?var}` = query params).
|
|
117
|
+
// Advertisement only, NOT a route table: the read path stays a generic proxy, and any other
|
|
118
|
+
// Apify API GET URL is readable the same way.
|
|
119
|
+
const listResourceTemplates = async () => {
|
|
120
|
+
const api = getApifyAPIBaseUrl();
|
|
101
121
|
return {
|
|
102
|
-
|
|
122
|
+
resourceTemplates: [
|
|
103
123
|
{
|
|
104
|
-
|
|
124
|
+
uriTemplate: `${api}/v2/datasets/{datasetId}/items{?limit,offset,clean,fields,format}`,
|
|
125
|
+
name: 'dataset-items',
|
|
126
|
+
// No mimeType: `format` selects among 7 response types (json/jsonl/xml/html/csv/xlsx/rss),
|
|
127
|
+
// and the spec allows a template mimeType only when all matching resources share one.
|
|
128
|
+
description: 'Items of a dataset, read via resources/read (the server injects the Apify token). ' +
|
|
129
|
+
'Page with limit/offset; format defaults to JSON — responses inline up to 256 KB, ' +
|
|
130
|
+
'larger ones return a download URL.',
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
uriTemplate: `${api}/v2/key-value-stores/{storeId}/records/{recordKey}`,
|
|
134
|
+
name: 'key-value-store-record',
|
|
135
|
+
description: 'A single record, returned whole in its stored Content-Type via resources/read. ' +
|
|
136
|
+
'Not pageable — a record over 256 KB returns a download URL instead.',
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
uriTemplate: `${api}/v2/key-value-stores/{storeId}/keys{?limit,exclusiveStartKey}`,
|
|
140
|
+
name: 'key-value-store-keys',
|
|
141
|
+
description: 'Keys of a key-value store. Page with limit/exclusiveStartKey (not offset).',
|
|
142
|
+
mimeType: 'application/json',
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
uriTemplate: `${api}/v2/actor-runs/{runId}`,
|
|
146
|
+
name: 'actor-run',
|
|
147
|
+
description: 'Metadata of an Actor run: status, storage IDs, usage.',
|
|
148
|
+
mimeType: 'application/json',
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
uriTemplate: `${api}/v2/logs/{runId}`,
|
|
152
|
+
name: 'actor-run-log',
|
|
153
|
+
description: 'Log of an Actor run. Inlines up to 256 KB, larger returns a download URL.',
|
|
105
154
|
mimeType: 'text/plain',
|
|
106
|
-
text: `Resource ${uri} not found`,
|
|
107
155
|
},
|
|
108
156
|
],
|
|
109
157
|
};
|
|
110
158
|
};
|
|
111
|
-
const listResourceTemplates = async () => ({
|
|
112
|
-
resourceTemplates: [],
|
|
113
|
-
});
|
|
114
159
|
return {
|
|
115
160
|
listResources,
|
|
116
161
|
readResource,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource_service.js","sourceRoot":"","sources":["../../src/resources/resource_service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAUvC,OAAO,GAAG,MAAM,YAAY,CAAC;AAG7B,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"resource_service.js","sourceRoot":"","sources":["../../src/resources/resource_service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get_key_value_store_record.d.ts","sourceRoot":"","sources":["../../../src/tools/storage/get_key_value_store_record.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAoB,SAAS,EAAmB,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"get_key_value_store_record.d.ts","sourceRoot":"","sources":["../../../src/tools/storage/get_key_value_store_record.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAoB,SAAS,EAAmB,MAAM,gBAAgB,CAAC;AAmBnF;;GAEG;AACH,eAAO,MAAM,sBAAsB,EAAE,SA6H1B,CAAC"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import dedent from 'dedent';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
import { HELPER_TOOLS
|
|
3
|
+
import { HELPER_TOOLS } from '../../const.js';
|
|
4
4
|
import { TOOL_TYPE } from '../../types.js';
|
|
5
5
|
import { compileSchema } from '../../utils/ajv.js';
|
|
6
6
|
import { buildConsoleKeyValueStoreUrl, getConsoleLinkContext } from '../../utils/console_link.js';
|
|
7
7
|
import { computeValueBytes, stripQuoteWrappers } from '../../utils/generic.js';
|
|
8
8
|
import { respondRaw, respondUserError } from '../../utils/mcp.js';
|
|
9
9
|
import { keyValueStoreRecordOutputSchema } from '../structured_output_schemas.js';
|
|
10
|
-
import { buildConsoleLinkContent, buildStorageResponse, normalizeRecordKey } from './storage_helpers.js';
|
|
10
|
+
import { buildBinaryRecordDisposition, buildConsoleLinkContent, buildStorageResponse, normalizeRecordKey, } from './storage_helpers.js';
|
|
11
11
|
const getKeyValueStoreRecordArgs = z.object({
|
|
12
12
|
keyValueStoreId: z.string().min(1).describe('Key-value store ID or username~store-name'),
|
|
13
13
|
recordKey: z.string().min(1).describe('Key of the record to retrieve.'),
|
|
@@ -72,8 +72,10 @@ export const getKeyValueStoreRecord = Object.freeze({
|
|
|
72
72
|
// structuredContent — so emit a minimal schema-conforming descriptor alongside the block.
|
|
73
73
|
// The Console link (Console UI token sessions) rides as a trailing text block.
|
|
74
74
|
if (Buffer.isBuffer(value)) {
|
|
75
|
-
//
|
|
76
|
-
|
|
75
|
+
// Normalizes the MIME type (so the image/audio checks below don't miss `Image/PNG`) and
|
|
76
|
+
// decides inline-vs-link-out at the same MAX_INLINE_BYTES threshold the API-resource proxy uses.
|
|
77
|
+
const disposition = buildBinaryRecordDisposition(contentType, value);
|
|
78
|
+
const { mimeType } = disposition;
|
|
77
79
|
const structuredContent = {
|
|
78
80
|
keyValueStoreId,
|
|
79
81
|
key: record.key,
|
|
@@ -82,7 +84,7 @@ export const getKeyValueStoreRecord = Object.freeze({
|
|
|
82
84
|
summary,
|
|
83
85
|
};
|
|
84
86
|
const consoleLinkContent = buildConsoleLinkContent(apifyConsoleUrl);
|
|
85
|
-
if (
|
|
87
|
+
if (disposition.kind === 'linkOut') {
|
|
86
88
|
// base64-inlining a large binary would blow up the context window; return a link instead.
|
|
87
89
|
const uri = await store.getRecordPublicUrl(recordKey);
|
|
88
90
|
return respondRaw({
|
|
@@ -92,14 +94,14 @@ export const getKeyValueStoreRecord = Object.freeze({
|
|
|
92
94
|
type: 'resource_link',
|
|
93
95
|
uri,
|
|
94
96
|
name: recordKey,
|
|
95
|
-
size:
|
|
97
|
+
size: disposition.bytes,
|
|
96
98
|
...(mimeType && { mimeType }),
|
|
97
99
|
},
|
|
98
100
|
...consoleLinkContent,
|
|
99
101
|
],
|
|
100
102
|
});
|
|
101
103
|
}
|
|
102
|
-
const data =
|
|
104
|
+
const data = disposition.base64;
|
|
103
105
|
if (mimeType === null || mimeType === void 0 ? void 0 : mimeType.startsWith('image/')) {
|
|
104
106
|
return respondRaw({
|
|
105
107
|
structuredContent,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get_key_value_store_record.js","sourceRoot":"","sources":["../../../src/tools/storage/get_key_value_store_record.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"get_key_value_store_record.js","sourceRoot":"","sources":["../../../src/tools/storage/get_key_value_store_record.ts"],"names":[],"mappings":"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"}
|
|
@@ -84,4 +84,31 @@ export declare function buildKvsKeysSummaryNextStep(params: {
|
|
|
84
84
|
nextStep: string;
|
|
85
85
|
};
|
|
86
86
|
export declare function normalizeRecordKey(key: string): string;
|
|
87
|
+
/**
|
|
88
|
+
* How to surface a binary key-value-store record value: inline as base64 below
|
|
89
|
+
* `MAX_INLINE_BYTES`, otherwise link out (inlining a multi-MB blob would blow up the
|
|
90
|
+
* client's context). `mimeType` is the Content-Type with parameters stripped and lowercased
|
|
91
|
+
* (`Image/PNG; charset=…` → `image/png`), or `undefined` when no Content-Type was declared.
|
|
92
|
+
*/
|
|
93
|
+
export type BinaryRecordDisposition = {
|
|
94
|
+
kind: 'inline';
|
|
95
|
+
mimeType?: string;
|
|
96
|
+
base64: string;
|
|
97
|
+
} | {
|
|
98
|
+
kind: 'linkOut';
|
|
99
|
+
mimeType?: string;
|
|
100
|
+
bytes: number;
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Base MIME type of a Content-Type header: parameters stripped, lowercased
|
|
104
|
+
* (`Image/PNG; charset=…` → `image/png`), `undefined` when no header was declared.
|
|
105
|
+
* Shared by the get-key-value-store-record tool and the API-resource proxy.
|
|
106
|
+
*/
|
|
107
|
+
export declare function parseBaseMimeType(contentType: string | undefined): string | undefined;
|
|
108
|
+
/**
|
|
109
|
+
* Build the transport disposition for a binary record value: normalize the MIME type, decide
|
|
110
|
+
* inline-vs-link-out at the byte threshold, base64-encode when inlining. It does NOT mint the
|
|
111
|
+
* link-out URL — the caller handles `linkOut` by minting its own URL via async calls.
|
|
112
|
+
*/
|
|
113
|
+
export declare function buildBinaryRecordDisposition(contentType: string | undefined, value: Buffer): BinaryRecordDisposition;
|
|
87
114
|
//# sourceMappingURL=storage_helpers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage_helpers.d.ts","sourceRoot":"","sources":["../../../src/tools/storage/storage_helpers.ts"],"names":[],"mappings":"AAMA;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAS7E;AAMD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,eAAe,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAE5F;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,eAAe,EAAE,MAAM,GAAG,SAAS,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,CAG7G;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE;IACzC,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qGAAqG;IACrG,eAAe,CAAC,EAAE,MAAM,CAAC;CAC5B,6CAQA;AAED;;;GAGG;AACH,wBAAgB,+BAA+B,CAAC,MAAM,EAAE;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACvB,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CASxC;AAED;;;GAGG;AACH,wBAAgB,gCAAgC,CAAC,MAAM,EAAE;IACrD,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,oFAAoF;IACpF,eAAe,EAAE,MAAM,EAAE,CAAC;CAC7B,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAkBxC;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE;IAChD,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,OAAO,CAAC;IACrB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAgBxC;AAWD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEtD"}
|
|
1
|
+
{"version":3,"file":"storage_helpers.d.ts","sourceRoot":"","sources":["../../../src/tools/storage/storage_helpers.ts"],"names":[],"mappings":"AAMA;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAS7E;AAMD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,eAAe,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAE5F;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,eAAe,EAAE,MAAM,GAAG,SAAS,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,CAG7G;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE;IACzC,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qGAAqG;IACrG,eAAe,CAAC,EAAE,MAAM,CAAC;CAC5B,6CAQA;AAED;;;GAGG;AACH,wBAAgB,+BAA+B,CAAC,MAAM,EAAE;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACvB,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CASxC;AAED;;;GAGG;AACH,wBAAgB,gCAAgC,CAAC,MAAM,EAAE;IACrD,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,oFAAoF;IACpF,eAAe,EAAE,MAAM,EAAE,CAAC;CAC7B,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAkBxC;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE;IAChD,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,OAAO,CAAC;IACrB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAgBxC;AAWD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;GAKG;AACH,MAAM,MAAM,uBAAuB,GAC7B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACrD;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5D;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAErF;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,uBAAuB,CAMpH"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HELPER_TOOLS, HTTP_NOT_FOUND } from '../../const.js';
|
|
1
|
+
import { HELPER_TOOLS, HTTP_NOT_FOUND, MAX_INLINE_BYTES } from '../../const.js';
|
|
2
2
|
import { VERBATIM_LINKS_NUDGE } from '../../utils/console_link.js';
|
|
3
3
|
import { QUOTE_WRAPPER_CHARS } from '../../utils/generic.js';
|
|
4
4
|
import { getHttpStatusCode } from '../../utils/logging.js';
|
|
@@ -129,4 +129,24 @@ const NORMALIZE_RECORD_KEY_REGEX = new RegExp(`^[${QUOTE_WRAPPER_CHARS}]+|[${QUO
|
|
|
129
129
|
export function normalizeRecordKey(key) {
|
|
130
130
|
return key.trim().replace(NORMALIZE_RECORD_KEY_REGEX, '').trim();
|
|
131
131
|
}
|
|
132
|
+
/**
|
|
133
|
+
* Base MIME type of a Content-Type header: parameters stripped, lowercased
|
|
134
|
+
* (`Image/PNG; charset=…` → `image/png`), `undefined` when no header was declared.
|
|
135
|
+
* Shared by the get-key-value-store-record tool and the API-resource proxy.
|
|
136
|
+
*/
|
|
137
|
+
export function parseBaseMimeType(contentType) {
|
|
138
|
+
return contentType === null || contentType === void 0 ? void 0 : contentType.split(';')[0].trim().toLowerCase();
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Build the transport disposition for a binary record value: normalize the MIME type, decide
|
|
142
|
+
* inline-vs-link-out at the byte threshold, base64-encode when inlining. It does NOT mint the
|
|
143
|
+
* link-out URL — the caller handles `linkOut` by minting its own URL via async calls.
|
|
144
|
+
*/
|
|
145
|
+
export function buildBinaryRecordDisposition(contentType, value) {
|
|
146
|
+
const mimeType = parseBaseMimeType(contentType);
|
|
147
|
+
if (value.length > MAX_INLINE_BYTES) {
|
|
148
|
+
return { kind: 'linkOut', ...(mimeType !== undefined && { mimeType }), bytes: value.length };
|
|
149
|
+
}
|
|
150
|
+
return { kind: 'inline', ...(mimeType !== undefined && { mimeType }), base64: value.toString('base64') };
|
|
151
|
+
}
|
|
132
152
|
//# sourceMappingURL=storage_helpers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage_helpers.js","sourceRoot":"","sources":["../../../src/tools/storage/storage_helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"storage_helpers.js","sourceRoot":"","sources":["../../../src/tools/storage/storage_helpers.ts"],"names":[],"mappings":"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"}
|