@ai-sdk/provider-utils 4.0.18 → 4.0.19

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
@@ -288,9 +288,106 @@ async function readResponseWithSizeLimit({
288
288
  return result;
289
289
  }
290
290
 
291
+ // src/validate-download-url.ts
292
+ function validateDownloadUrl(url) {
293
+ let parsed;
294
+ try {
295
+ parsed = new URL(url);
296
+ } catch (e) {
297
+ throw new DownloadError({
298
+ url,
299
+ message: `Invalid URL: ${url}`
300
+ });
301
+ }
302
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
303
+ throw new DownloadError({
304
+ url,
305
+ message: `URL scheme must be http or https, got ${parsed.protocol}`
306
+ });
307
+ }
308
+ const hostname = parsed.hostname;
309
+ if (!hostname) {
310
+ throw new DownloadError({
311
+ url,
312
+ message: `URL must have a hostname`
313
+ });
314
+ }
315
+ if (hostname === "localhost" || hostname.endsWith(".local") || hostname.endsWith(".localhost")) {
316
+ throw new DownloadError({
317
+ url,
318
+ message: `URL with hostname ${hostname} is not allowed`
319
+ });
320
+ }
321
+ if (hostname.startsWith("[") && hostname.endsWith("]")) {
322
+ const ipv6 = hostname.slice(1, -1);
323
+ if (isPrivateIPv6(ipv6)) {
324
+ throw new DownloadError({
325
+ url,
326
+ message: `URL with IPv6 address ${hostname} is not allowed`
327
+ });
328
+ }
329
+ return;
330
+ }
331
+ if (isIPv4(hostname)) {
332
+ if (isPrivateIPv4(hostname)) {
333
+ throw new DownloadError({
334
+ url,
335
+ message: `URL with IP address ${hostname} is not allowed`
336
+ });
337
+ }
338
+ return;
339
+ }
340
+ }
341
+ function isIPv4(hostname) {
342
+ const parts = hostname.split(".");
343
+ if (parts.length !== 4) return false;
344
+ return parts.every((part) => {
345
+ const num = Number(part);
346
+ return Number.isInteger(num) && num >= 0 && num <= 255 && String(num) === part;
347
+ });
348
+ }
349
+ function isPrivateIPv4(ip) {
350
+ const parts = ip.split(".").map(Number);
351
+ const [a, b] = parts;
352
+ if (a === 0) return true;
353
+ if (a === 10) return true;
354
+ if (a === 127) return true;
355
+ if (a === 169 && b === 254) return true;
356
+ if (a === 172 && b >= 16 && b <= 31) return true;
357
+ if (a === 192 && b === 168) return true;
358
+ return false;
359
+ }
360
+ function isPrivateIPv6(ip) {
361
+ const normalized = ip.toLowerCase();
362
+ if (normalized === "::1") return true;
363
+ if (normalized === "::") return true;
364
+ if (normalized.startsWith("::ffff:")) {
365
+ const mappedPart = normalized.slice(7);
366
+ if (isIPv4(mappedPart)) {
367
+ return isPrivateIPv4(mappedPart);
368
+ }
369
+ const hexParts = mappedPart.split(":");
370
+ if (hexParts.length === 2) {
371
+ const high = parseInt(hexParts[0], 16);
372
+ const low = parseInt(hexParts[1], 16);
373
+ if (!isNaN(high) && !isNaN(low)) {
374
+ const a = high >> 8 & 255;
375
+ const b = high & 255;
376
+ const c = low >> 8 & 255;
377
+ const d = low & 255;
378
+ return isPrivateIPv4(`${a}.${b}.${c}.${d}`);
379
+ }
380
+ }
381
+ }
382
+ if (normalized.startsWith("fc") || normalized.startsWith("fd")) return true;
383
+ if (normalized.startsWith("fe80")) return true;
384
+ return false;
385
+ }
386
+
291
387
  // src/download-blob.ts
292
388
  async function downloadBlob(url, options) {
293
389
  var _a2, _b2;
390
+ validateDownloadUrl(url);
294
391
  try {
295
392
  const response = await fetch(url, {
296
393
  signal: options == null ? void 0 : options.abortSignal
@@ -479,7 +576,7 @@ function withUserAgentSuffix(headers, ...userAgentSuffixParts) {
479
576
  }
480
577
 
481
578
  // src/version.ts
482
- var VERSION = true ? "4.0.18" : "0.0.0-test";
579
+ var VERSION = true ? "4.0.19" : "0.0.0-test";
483
580
 
484
581
  // src/get-from-api.ts
485
582
  var getOriginalFetch = () => globalThis.fetch;
@@ -2650,6 +2747,7 @@ export {
2650
2747
  safeValidateTypes,
2651
2748
  stripFileExtension,
2652
2749
  tool,
2750
+ validateDownloadUrl,
2653
2751
  validateTypes,
2654
2752
  withUserAgentSuffix,
2655
2753
  withoutTrailingSlash,