@ai-sdk/provider-utils 3.0.24 → 3.0.26
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/CHANGELOG.md +29 -0
- package/dist/index.d.mts +61 -2
- package/dist/index.d.ts +61 -2
- package/dist/index.js +248 -145
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +245 -145
- package/dist/index.mjs.map +1 -1
- package/dist/test/index.js.map +1 -1
- package/dist/test/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -56,13 +56,16 @@ __export(index_exports, {
|
|
|
56
56
|
dynamicTool: () => dynamicTool,
|
|
57
57
|
executeTool: () => executeTool,
|
|
58
58
|
extractResponseHeaders: () => extractResponseHeaders,
|
|
59
|
+
fetchWithValidatedRedirects: () => fetchWithValidatedRedirects,
|
|
59
60
|
generateId: () => generateId,
|
|
60
61
|
getErrorMessage: () => getErrorMessage,
|
|
61
62
|
getFromApi: () => getFromApi,
|
|
62
63
|
getRuntimeEnvironmentUserAgent: () => getRuntimeEnvironmentUserAgent,
|
|
63
64
|
injectJsonInstructionIntoMessages: () => injectJsonInstructionIntoMessages,
|
|
64
65
|
isAbortError: () => isAbortError,
|
|
66
|
+
isBrowserRuntime: () => isBrowserRuntime,
|
|
65
67
|
isParsableJson: () => isParsableJson,
|
|
68
|
+
isSameOrigin: () => isSameOrigin,
|
|
66
69
|
isUrlSupported: () => isUrlSupported,
|
|
67
70
|
isValidator: () => isValidator,
|
|
68
71
|
jsonSchema: () => jsonSchema,
|
|
@@ -251,6 +254,191 @@ var DownloadError = class extends (_b = import_provider.AISDKError, _a = symbol,
|
|
|
251
254
|
}
|
|
252
255
|
};
|
|
253
256
|
|
|
257
|
+
// src/is-browser-runtime.ts
|
|
258
|
+
function isBrowserRuntime(globalThisAny = globalThis) {
|
|
259
|
+
return globalThisAny.window != null;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// src/validate-download-url.ts
|
|
263
|
+
function validateDownloadUrl(url) {
|
|
264
|
+
let parsed;
|
|
265
|
+
try {
|
|
266
|
+
parsed = new URL(url);
|
|
267
|
+
} catch (e) {
|
|
268
|
+
throw new DownloadError({
|
|
269
|
+
url,
|
|
270
|
+
message: `Invalid URL: ${url}`
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
if (parsed.protocol === "data:") {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
277
|
+
throw new DownloadError({
|
|
278
|
+
url,
|
|
279
|
+
message: `URL scheme must be http, https, or data, got ${parsed.protocol}`
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
const hostname = parsed.hostname.toLowerCase().replace(/\.+$/, "");
|
|
283
|
+
if (!hostname) {
|
|
284
|
+
throw new DownloadError({
|
|
285
|
+
url,
|
|
286
|
+
message: `URL must have a hostname`
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
if (hostname === "localhost" || hostname.endsWith(".local") || hostname.endsWith(".localhost")) {
|
|
290
|
+
throw new DownloadError({
|
|
291
|
+
url,
|
|
292
|
+
message: `URL with hostname ${hostname} is not allowed`
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
if (hostname.startsWith("[") && hostname.endsWith("]")) {
|
|
296
|
+
const ipv6 = hostname.slice(1, -1);
|
|
297
|
+
if (isPrivateIPv6(ipv6)) {
|
|
298
|
+
throw new DownloadError({
|
|
299
|
+
url,
|
|
300
|
+
message: `URL with IPv6 address ${hostname} is not allowed`
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
if (isIPv4(hostname)) {
|
|
306
|
+
if (isPrivateIPv4(hostname)) {
|
|
307
|
+
throw new DownloadError({
|
|
308
|
+
url,
|
|
309
|
+
message: `URL with IP address ${hostname} is not allowed`
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
function isIPv4(hostname) {
|
|
316
|
+
const parts = hostname.split(".");
|
|
317
|
+
if (parts.length !== 4) return false;
|
|
318
|
+
return parts.every((part) => {
|
|
319
|
+
const num = Number(part);
|
|
320
|
+
return Number.isInteger(num) && num >= 0 && num <= 255 && String(num) === part;
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
function isPrivateIPv4(ip) {
|
|
324
|
+
const parts = ip.split(".").map(Number);
|
|
325
|
+
const [a, b, c] = parts;
|
|
326
|
+
if (a === 0) return true;
|
|
327
|
+
if (a === 10) return true;
|
|
328
|
+
if (a === 100 && b >= 64 && b <= 127) return true;
|
|
329
|
+
if (a === 127) return true;
|
|
330
|
+
if (a === 169 && b === 254) return true;
|
|
331
|
+
if (a === 172 && b >= 16 && b <= 31) return true;
|
|
332
|
+
if (a === 192 && b === 0 && c === 0) return true;
|
|
333
|
+
if (a === 192 && b === 168) return true;
|
|
334
|
+
if (a === 198 && (b === 18 || b === 19)) return true;
|
|
335
|
+
if (a >= 240) return true;
|
|
336
|
+
return false;
|
|
337
|
+
}
|
|
338
|
+
function parseIPv6(ip) {
|
|
339
|
+
let address = ip.toLowerCase();
|
|
340
|
+
const zoneIndex = address.indexOf("%");
|
|
341
|
+
if (zoneIndex !== -1) {
|
|
342
|
+
address = address.slice(0, zoneIndex);
|
|
343
|
+
}
|
|
344
|
+
const halves = address.split("::");
|
|
345
|
+
if (halves.length > 2) return null;
|
|
346
|
+
const toGroups = (segment) => {
|
|
347
|
+
if (segment === "") return [];
|
|
348
|
+
const groups = [];
|
|
349
|
+
const parts = segment.split(":");
|
|
350
|
+
for (let i = 0; i < parts.length; i++) {
|
|
351
|
+
const part = parts[i];
|
|
352
|
+
if (part.includes(".")) {
|
|
353
|
+
if (i !== parts.length - 1 || !isIPv4(part)) return null;
|
|
354
|
+
const [a, b, c, d] = part.split(".").map(Number);
|
|
355
|
+
groups.push(a << 8 | b, c << 8 | d);
|
|
356
|
+
continue;
|
|
357
|
+
}
|
|
358
|
+
if (!/^[0-9a-f]{1,4}$/.test(part)) return null;
|
|
359
|
+
groups.push(parseInt(part, 16));
|
|
360
|
+
}
|
|
361
|
+
return groups;
|
|
362
|
+
};
|
|
363
|
+
const head = toGroups(halves[0]);
|
|
364
|
+
if (head === null) return null;
|
|
365
|
+
if (halves.length === 2) {
|
|
366
|
+
const tail = toGroups(halves[1]);
|
|
367
|
+
if (tail === null) return null;
|
|
368
|
+
const fill = 8 - head.length - tail.length;
|
|
369
|
+
if (fill < 0) return null;
|
|
370
|
+
return [...head, ...new Array(fill).fill(0), ...tail];
|
|
371
|
+
}
|
|
372
|
+
return head.length === 8 ? head : null;
|
|
373
|
+
}
|
|
374
|
+
function isPrivateIPv6(ip) {
|
|
375
|
+
const groups = parseIPv6(ip);
|
|
376
|
+
if (groups === null) return true;
|
|
377
|
+
const topZero = (count) => groups.slice(0, count).every((group) => group === 0);
|
|
378
|
+
if (topZero(7) && (groups[7] === 0 || groups[7] === 1)) return true;
|
|
379
|
+
if ((groups[0] & 65024) === 64512) return true;
|
|
380
|
+
if ((groups[0] & 65472) === 65152) return true;
|
|
381
|
+
if ((groups[0] & 65472) === 65216) return true;
|
|
382
|
+
if ((groups[0] & 65280) === 65280) return true;
|
|
383
|
+
const embedsIPv4 = (
|
|
384
|
+
// ::/96 — IPv4-compatible (deprecated)
|
|
385
|
+
topZero(6) || // ::ffff:0:0/96 — IPv4-mapped (ffff in group 5)
|
|
386
|
+
topZero(5) && groups[5] === 65535 || // ::ffff:0:0/96 — IPv4-translated form (ffff in group 4, group 5 zero)
|
|
387
|
+
topZero(4) && groups[4] === 65535 && groups[5] === 0 || // 64:ff9b::/96 — NAT64 well-known prefix
|
|
388
|
+
groups[0] === 100 && groups[1] === 65435 && groups[2] === 0 && groups[3] === 0 && groups[4] === 0 && groups[5] === 0 || // 64:ff9b:1::/48 — NAT64 local-use prefix
|
|
389
|
+
groups[0] === 100 && groups[1] === 65435 && groups[2] === 1
|
|
390
|
+
);
|
|
391
|
+
if (embedsIPv4) {
|
|
392
|
+
const a = groups[6] >> 8 & 255;
|
|
393
|
+
const b = groups[6] & 255;
|
|
394
|
+
const c = groups[7] >> 8 & 255;
|
|
395
|
+
const d = groups[7] & 255;
|
|
396
|
+
return isPrivateIPv4(`${a}.${b}.${c}.${d}`);
|
|
397
|
+
}
|
|
398
|
+
return false;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// src/fetch-with-validated-redirects.ts
|
|
402
|
+
var MAX_DOWNLOAD_REDIRECTS = 10;
|
|
403
|
+
async function fetchWithValidatedRedirects({
|
|
404
|
+
url,
|
|
405
|
+
headers,
|
|
406
|
+
abortSignal,
|
|
407
|
+
maxRedirects = MAX_DOWNLOAD_REDIRECTS
|
|
408
|
+
}) {
|
|
409
|
+
const baseInit = { signal: abortSignal };
|
|
410
|
+
if (headers !== void 0) {
|
|
411
|
+
baseInit.headers = headers;
|
|
412
|
+
}
|
|
413
|
+
let currentUrl = url;
|
|
414
|
+
for (let redirectCount = 0; redirectCount <= maxRedirects; redirectCount++) {
|
|
415
|
+
validateDownloadUrl(currentUrl);
|
|
416
|
+
const response = await fetch(currentUrl, {
|
|
417
|
+
...baseInit,
|
|
418
|
+
redirect: "manual"
|
|
419
|
+
});
|
|
420
|
+
if (response.type === "opaqueredirect") {
|
|
421
|
+
if (!isBrowserRuntime()) {
|
|
422
|
+
throw new DownloadError({
|
|
423
|
+
url,
|
|
424
|
+
message: `Redirect from ${currentUrl} could not be validated and was blocked`
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
return await fetch(currentUrl, { ...baseInit, redirect: "follow" });
|
|
428
|
+
}
|
|
429
|
+
const location = response.headers.get("location");
|
|
430
|
+
if (response.status >= 300 && response.status < 400 && location) {
|
|
431
|
+
currentUrl = new URL(location, currentUrl).toString();
|
|
432
|
+
continue;
|
|
433
|
+
}
|
|
434
|
+
return response;
|
|
435
|
+
}
|
|
436
|
+
throw new DownloadError({
|
|
437
|
+
url,
|
|
438
|
+
message: `Too many redirects (max ${maxRedirects})`
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
|
|
254
442
|
// src/read-response-with-size-limit.ts
|
|
255
443
|
var DEFAULT_MAX_DOWNLOAD_SIZE = 2 * 1024 * 1024 * 1024;
|
|
256
444
|
async function readResponseWithSizeLimit({
|
|
@@ -440,7 +628,7 @@ function withUserAgentSuffix(headers, ...userAgentSuffixParts) {
|
|
|
440
628
|
}
|
|
441
629
|
|
|
442
630
|
// src/version.ts
|
|
443
|
-
var VERSION = true ? "3.0.
|
|
631
|
+
var VERSION = true ? "3.0.26" : "0.0.0-test";
|
|
444
632
|
|
|
445
633
|
// src/get-from-api.ts
|
|
446
634
|
var getOriginalFetch = () => globalThis.fetch;
|
|
@@ -450,10 +638,10 @@ var getFromApi = async ({
|
|
|
450
638
|
successfulResponseHandler,
|
|
451
639
|
failedResponseHandler,
|
|
452
640
|
abortSignal,
|
|
453
|
-
fetch = getOriginalFetch()
|
|
641
|
+
fetch: fetch2 = getOriginalFetch()
|
|
454
642
|
}) => {
|
|
455
643
|
try {
|
|
456
|
-
const response = await
|
|
644
|
+
const response = await fetch2(url, {
|
|
457
645
|
method: "GET",
|
|
458
646
|
headers: withUserAgentSuffix(
|
|
459
647
|
headers,
|
|
@@ -551,6 +739,15 @@ function injectJsonInstructionIntoMessages({
|
|
|
551
739
|
];
|
|
552
740
|
}
|
|
553
741
|
|
|
742
|
+
// src/is-same-origin.ts
|
|
743
|
+
function isSameOrigin(url, baseUrl) {
|
|
744
|
+
try {
|
|
745
|
+
return new URL(url).origin === new URL(baseUrl).origin;
|
|
746
|
+
} catch (e) {
|
|
747
|
+
return false;
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
|
|
554
751
|
// src/is-url-supported.ts
|
|
555
752
|
function isUrlSupported({
|
|
556
753
|
mediaType,
|
|
@@ -890,7 +1087,7 @@ var postJsonToApi = async ({
|
|
|
890
1087
|
failedResponseHandler,
|
|
891
1088
|
successfulResponseHandler,
|
|
892
1089
|
abortSignal,
|
|
893
|
-
fetch
|
|
1090
|
+
fetch: fetch2
|
|
894
1091
|
}) => postToApi({
|
|
895
1092
|
url,
|
|
896
1093
|
headers: {
|
|
@@ -904,7 +1101,7 @@ var postJsonToApi = async ({
|
|
|
904
1101
|
failedResponseHandler,
|
|
905
1102
|
successfulResponseHandler,
|
|
906
1103
|
abortSignal,
|
|
907
|
-
fetch
|
|
1104
|
+
fetch: fetch2
|
|
908
1105
|
});
|
|
909
1106
|
var postFormDataToApi = async ({
|
|
910
1107
|
url,
|
|
@@ -913,7 +1110,7 @@ var postFormDataToApi = async ({
|
|
|
913
1110
|
failedResponseHandler,
|
|
914
1111
|
successfulResponseHandler,
|
|
915
1112
|
abortSignal,
|
|
916
|
-
fetch
|
|
1113
|
+
fetch: fetch2
|
|
917
1114
|
}) => postToApi({
|
|
918
1115
|
url,
|
|
919
1116
|
headers,
|
|
@@ -924,7 +1121,7 @@ var postFormDataToApi = async ({
|
|
|
924
1121
|
failedResponseHandler,
|
|
925
1122
|
successfulResponseHandler,
|
|
926
1123
|
abortSignal,
|
|
927
|
-
fetch
|
|
1124
|
+
fetch: fetch2
|
|
928
1125
|
});
|
|
929
1126
|
var postToApi = async ({
|
|
930
1127
|
url,
|
|
@@ -933,10 +1130,10 @@ var postToApi = async ({
|
|
|
933
1130
|
successfulResponseHandler,
|
|
934
1131
|
failedResponseHandler,
|
|
935
1132
|
abortSignal,
|
|
936
|
-
fetch = getOriginalFetch2()
|
|
1133
|
+
fetch: fetch2 = getOriginalFetch2()
|
|
937
1134
|
}) => {
|
|
938
1135
|
try {
|
|
939
|
-
const response = await
|
|
1136
|
+
const response = await fetch2(url, {
|
|
940
1137
|
method: "POST",
|
|
941
1138
|
headers: withUserAgentSuffix(
|
|
942
1139
|
headers,
|
|
@@ -1241,6 +1438,35 @@ var createStatusCodeErrorResponseHandler = () => async ({ response, url, request
|
|
|
1241
1438
|
};
|
|
1242
1439
|
};
|
|
1243
1440
|
|
|
1441
|
+
// src/schema.ts
|
|
1442
|
+
var schemaSymbol = /* @__PURE__ */ Symbol.for("vercel.ai.schema");
|
|
1443
|
+
function lazySchema(createSchema) {
|
|
1444
|
+
let schema;
|
|
1445
|
+
return () => {
|
|
1446
|
+
if (schema == null) {
|
|
1447
|
+
schema = createSchema();
|
|
1448
|
+
}
|
|
1449
|
+
return schema;
|
|
1450
|
+
};
|
|
1451
|
+
}
|
|
1452
|
+
function jsonSchema(jsonSchema2, {
|
|
1453
|
+
validate
|
|
1454
|
+
} = {}) {
|
|
1455
|
+
return {
|
|
1456
|
+
[schemaSymbol]: true,
|
|
1457
|
+
_type: void 0,
|
|
1458
|
+
// should never be used directly
|
|
1459
|
+
[validatorSymbol]: true,
|
|
1460
|
+
get jsonSchema() {
|
|
1461
|
+
if (typeof jsonSchema2 === "function") {
|
|
1462
|
+
jsonSchema2 = jsonSchema2();
|
|
1463
|
+
}
|
|
1464
|
+
return jsonSchema2;
|
|
1465
|
+
},
|
|
1466
|
+
validate
|
|
1467
|
+
};
|
|
1468
|
+
}
|
|
1469
|
+
|
|
1244
1470
|
// src/zod-schema.ts
|
|
1245
1471
|
var z4 = __toESM(require("zod/v4"));
|
|
1246
1472
|
|
|
@@ -1271,15 +1497,6 @@ function addAdditionalPropertiesToJsonSchema(jsonSchema2) {
|
|
|
1271
1497
|
return jsonSchema2;
|
|
1272
1498
|
}
|
|
1273
1499
|
|
|
1274
|
-
// src/zod-to-json-schema/get-relative-path.ts
|
|
1275
|
-
var getRelativePath = (pathA, pathB) => {
|
|
1276
|
-
let i = 0;
|
|
1277
|
-
for (; i < pathA.length && i < pathB.length; i++) {
|
|
1278
|
-
if (pathA[i] !== pathB[i]) break;
|
|
1279
|
-
}
|
|
1280
|
-
return [(pathA.length - i).toString(), ...pathB.slice(i)].join("/");
|
|
1281
|
-
};
|
|
1282
|
-
|
|
1283
1500
|
// src/zod-to-json-schema/options.ts
|
|
1284
1501
|
var ignoreOverride = /* @__PURE__ */ Symbol(
|
|
1285
1502
|
"Let zodToJsonSchema decide on which parser to use"
|
|
@@ -2311,6 +2528,15 @@ var selectParser = (def, typeName, refs) => {
|
|
|
2311
2528
|
}
|
|
2312
2529
|
};
|
|
2313
2530
|
|
|
2531
|
+
// src/zod-to-json-schema/get-relative-path.ts
|
|
2532
|
+
var getRelativePath = (pathA, pathB) => {
|
|
2533
|
+
let i = 0;
|
|
2534
|
+
for (; i < pathA.length && i < pathB.length; i++) {
|
|
2535
|
+
if (pathA[i] !== pathB[i]) break;
|
|
2536
|
+
}
|
|
2537
|
+
return [(pathA.length - i).toString(), ...pathB.slice(i)].join("/");
|
|
2538
|
+
};
|
|
2539
|
+
|
|
2314
2540
|
// src/zod-to-json-schema/parse-def.ts
|
|
2315
2541
|
function parseDef(def, refs, forceResolution = false) {
|
|
2316
2542
|
var _a2;
|
|
@@ -2500,34 +2726,7 @@ function zodSchema(zodSchema2, options) {
|
|
|
2500
2726
|
}
|
|
2501
2727
|
}
|
|
2502
2728
|
|
|
2503
|
-
// src/schema.ts
|
|
2504
|
-
var schemaSymbol = /* @__PURE__ */ Symbol.for("vercel.ai.schema");
|
|
2505
|
-
function lazySchema(createSchema) {
|
|
2506
|
-
let schema;
|
|
2507
|
-
return () => {
|
|
2508
|
-
if (schema == null) {
|
|
2509
|
-
schema = createSchema();
|
|
2510
|
-
}
|
|
2511
|
-
return schema;
|
|
2512
|
-
};
|
|
2513
|
-
}
|
|
2514
|
-
function jsonSchema(jsonSchema2, {
|
|
2515
|
-
validate
|
|
2516
|
-
} = {}) {
|
|
2517
|
-
return {
|
|
2518
|
-
[schemaSymbol]: true,
|
|
2519
|
-
_type: void 0,
|
|
2520
|
-
// should never be used directly
|
|
2521
|
-
[validatorSymbol]: true,
|
|
2522
|
-
get jsonSchema() {
|
|
2523
|
-
if (typeof jsonSchema2 === "function") {
|
|
2524
|
-
jsonSchema2 = jsonSchema2();
|
|
2525
|
-
}
|
|
2526
|
-
return jsonSchema2;
|
|
2527
|
-
},
|
|
2528
|
-
validate
|
|
2529
|
-
};
|
|
2530
|
-
}
|
|
2729
|
+
// src/as-schema.ts
|
|
2531
2730
|
function isSchema(value) {
|
|
2532
2731
|
return typeof value === "object" && value !== null && schemaSymbol in value && value[schemaSymbol] === true && "jsonSchema" in value && "validate" in value;
|
|
2533
2732
|
}
|
|
@@ -2556,105 +2755,6 @@ function convertToBase64(value) {
|
|
|
2556
2755
|
return value instanceof Uint8Array ? convertUint8ArrayToBase64(value) : value;
|
|
2557
2756
|
}
|
|
2558
2757
|
|
|
2559
|
-
// src/validate-download-url.ts
|
|
2560
|
-
function validateDownloadUrl(url) {
|
|
2561
|
-
let parsed;
|
|
2562
|
-
try {
|
|
2563
|
-
parsed = new URL(url);
|
|
2564
|
-
} catch (e) {
|
|
2565
|
-
throw new DownloadError({
|
|
2566
|
-
url,
|
|
2567
|
-
message: `Invalid URL: ${url}`
|
|
2568
|
-
});
|
|
2569
|
-
}
|
|
2570
|
-
if (parsed.protocol === "data:") {
|
|
2571
|
-
return;
|
|
2572
|
-
}
|
|
2573
|
-
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
2574
|
-
throw new DownloadError({
|
|
2575
|
-
url,
|
|
2576
|
-
message: `URL scheme must be http, https, or data, got ${parsed.protocol}`
|
|
2577
|
-
});
|
|
2578
|
-
}
|
|
2579
|
-
const hostname = parsed.hostname;
|
|
2580
|
-
if (!hostname) {
|
|
2581
|
-
throw new DownloadError({
|
|
2582
|
-
url,
|
|
2583
|
-
message: `URL must have a hostname`
|
|
2584
|
-
});
|
|
2585
|
-
}
|
|
2586
|
-
if (hostname === "localhost" || hostname.endsWith(".local") || hostname.endsWith(".localhost")) {
|
|
2587
|
-
throw new DownloadError({
|
|
2588
|
-
url,
|
|
2589
|
-
message: `URL with hostname ${hostname} is not allowed`
|
|
2590
|
-
});
|
|
2591
|
-
}
|
|
2592
|
-
if (hostname.startsWith("[") && hostname.endsWith("]")) {
|
|
2593
|
-
const ipv6 = hostname.slice(1, -1);
|
|
2594
|
-
if (isPrivateIPv6(ipv6)) {
|
|
2595
|
-
throw new DownloadError({
|
|
2596
|
-
url,
|
|
2597
|
-
message: `URL with IPv6 address ${hostname} is not allowed`
|
|
2598
|
-
});
|
|
2599
|
-
}
|
|
2600
|
-
return;
|
|
2601
|
-
}
|
|
2602
|
-
if (isIPv4(hostname)) {
|
|
2603
|
-
if (isPrivateIPv4(hostname)) {
|
|
2604
|
-
throw new DownloadError({
|
|
2605
|
-
url,
|
|
2606
|
-
message: `URL with IP address ${hostname} is not allowed`
|
|
2607
|
-
});
|
|
2608
|
-
}
|
|
2609
|
-
return;
|
|
2610
|
-
}
|
|
2611
|
-
}
|
|
2612
|
-
function isIPv4(hostname) {
|
|
2613
|
-
const parts = hostname.split(".");
|
|
2614
|
-
if (parts.length !== 4) return false;
|
|
2615
|
-
return parts.every((part) => {
|
|
2616
|
-
const num = Number(part);
|
|
2617
|
-
return Number.isInteger(num) && num >= 0 && num <= 255 && String(num) === part;
|
|
2618
|
-
});
|
|
2619
|
-
}
|
|
2620
|
-
function isPrivateIPv4(ip) {
|
|
2621
|
-
const parts = ip.split(".").map(Number);
|
|
2622
|
-
const [a, b] = parts;
|
|
2623
|
-
if (a === 0) return true;
|
|
2624
|
-
if (a === 10) return true;
|
|
2625
|
-
if (a === 127) return true;
|
|
2626
|
-
if (a === 169 && b === 254) return true;
|
|
2627
|
-
if (a === 172 && b >= 16 && b <= 31) return true;
|
|
2628
|
-
if (a === 192 && b === 168) return true;
|
|
2629
|
-
return false;
|
|
2630
|
-
}
|
|
2631
|
-
function isPrivateIPv6(ip) {
|
|
2632
|
-
const normalized = ip.toLowerCase();
|
|
2633
|
-
if (normalized === "::1") return true;
|
|
2634
|
-
if (normalized === "::") return true;
|
|
2635
|
-
if (normalized.startsWith("::ffff:")) {
|
|
2636
|
-
const mappedPart = normalized.slice(7);
|
|
2637
|
-
if (isIPv4(mappedPart)) {
|
|
2638
|
-
return isPrivateIPv4(mappedPart);
|
|
2639
|
-
}
|
|
2640
|
-
const hexParts = mappedPart.split(":");
|
|
2641
|
-
if (hexParts.length === 2) {
|
|
2642
|
-
const high = parseInt(hexParts[0], 16);
|
|
2643
|
-
const low = parseInt(hexParts[1], 16);
|
|
2644
|
-
if (!isNaN(high) && !isNaN(low)) {
|
|
2645
|
-
const a = high >> 8 & 255;
|
|
2646
|
-
const b = high & 255;
|
|
2647
|
-
const c = low >> 8 & 255;
|
|
2648
|
-
const d = low & 255;
|
|
2649
|
-
return isPrivateIPv4(`${a}.${b}.${c}.${d}`);
|
|
2650
|
-
}
|
|
2651
|
-
}
|
|
2652
|
-
}
|
|
2653
|
-
if (normalized.startsWith("fc") || normalized.startsWith("fd")) return true;
|
|
2654
|
-
if (normalized.startsWith("fe80")) return true;
|
|
2655
|
-
return false;
|
|
2656
|
-
}
|
|
2657
|
-
|
|
2658
2758
|
// src/without-trailing-slash.ts
|
|
2659
2759
|
function withoutTrailingSlash(url) {
|
|
2660
2760
|
return url == null ? void 0 : url.replace(/\/$/, "");
|
|
@@ -2714,13 +2814,16 @@ var import_stream2 = require("eventsource-parser/stream");
|
|
|
2714
2814
|
dynamicTool,
|
|
2715
2815
|
executeTool,
|
|
2716
2816
|
extractResponseHeaders,
|
|
2817
|
+
fetchWithValidatedRedirects,
|
|
2717
2818
|
generateId,
|
|
2718
2819
|
getErrorMessage,
|
|
2719
2820
|
getFromApi,
|
|
2720
2821
|
getRuntimeEnvironmentUserAgent,
|
|
2721
2822
|
injectJsonInstructionIntoMessages,
|
|
2722
2823
|
isAbortError,
|
|
2824
|
+
isBrowserRuntime,
|
|
2723
2825
|
isParsableJson,
|
|
2826
|
+
isSameOrigin,
|
|
2724
2827
|
isUrlSupported,
|
|
2725
2828
|
isValidator,
|
|
2726
2829
|
jsonSchema,
|