@llmindset/hf-mcp 0.3.2 → 0.3.4

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.
Files changed (137) hide show
  1. package/dist/docs-search/doc-fetch.d.ts +1 -0
  2. package/dist/docs-search/doc-fetch.d.ts.map +1 -1
  3. package/dist/docs-search/doc-fetch.js +9 -12
  4. package/dist/docs-search/doc-fetch.js.map +1 -1
  5. package/dist/docs-search/doc-fetch.test.js +56 -11
  6. package/dist/docs-search/doc-fetch.test.js.map +1 -1
  7. package/dist/file-icons.d.ts +3 -0
  8. package/dist/file-icons.d.ts.map +1 -0
  9. package/dist/file-icons.js +38 -0
  10. package/dist/file-icons.js.map +1 -0
  11. package/dist/gradio-files.d.ts +0 -1
  12. package/dist/gradio-files.d.ts.map +1 -1
  13. package/dist/gradio-files.js +2 -35
  14. package/dist/gradio-files.js.map +1 -1
  15. package/dist/hf-api-call.d.ts.map +1 -1
  16. package/dist/hf-api-call.js +7 -7
  17. package/dist/hf-api-call.js.map +1 -1
  18. package/dist/index.browser.d.ts +48 -0
  19. package/dist/index.browser.d.ts.map +1 -0
  20. package/dist/index.browser.js +153 -0
  21. package/dist/index.browser.js.map +1 -0
  22. package/dist/index.d.ts +1 -0
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +1 -0
  25. package/dist/index.js.map +1 -1
  26. package/dist/jobs/commands/uv-utils.d.ts +0 -3
  27. package/dist/jobs/commands/uv-utils.d.ts.map +1 -1
  28. package/dist/jobs/commands/uv-utils.js +2 -2
  29. package/dist/jobs/commands/uv-utils.js.map +1 -1
  30. package/dist/jobs/jobs-tool.d.ts.map +1 -1
  31. package/dist/jobs/jobs-tool.js +11 -12
  32. package/dist/jobs/jobs-tool.js.map +1 -1
  33. package/dist/jobs/schema-help.d.ts +2 -9
  34. package/dist/jobs/schema-help.d.ts.map +1 -1
  35. package/dist/jobs/schema-help.js +3 -3
  36. package/dist/jobs/schema-help.js.map +1 -1
  37. package/dist/jobs/sse-handler.d.ts +3 -2
  38. package/dist/jobs/sse-handler.d.ts.map +1 -1
  39. package/dist/jobs/sse-handler.js +8 -4
  40. package/dist/jobs/sse-handler.js.map +1 -1
  41. package/dist/jobs/types.d.ts +1 -1
  42. package/dist/logger.d.ts +2 -2
  43. package/dist/logger.d.ts.map +1 -1
  44. package/dist/network/fetch-profile.d.ts +24 -0
  45. package/dist/network/fetch-profile.d.ts.map +1 -0
  46. package/dist/network/fetch-profile.js +80 -0
  47. package/dist/network/fetch-profile.js.map +1 -0
  48. package/dist/network/index.d.ts +5 -0
  49. package/dist/network/index.d.ts.map +1 -0
  50. package/dist/network/index.js +5 -0
  51. package/dist/network/index.js.map +1 -0
  52. package/dist/network/ip-policy.d.ts +6 -0
  53. package/dist/network/ip-policy.d.ts.map +1 -0
  54. package/dist/network/ip-policy.js +202 -0
  55. package/dist/network/ip-policy.js.map +1 -0
  56. package/dist/network/ip-policy.test.d.ts +2 -0
  57. package/dist/network/ip-policy.test.d.ts.map +1 -0
  58. package/dist/network/ip-policy.test.js +46 -0
  59. package/dist/network/ip-policy.test.js.map +1 -0
  60. package/dist/network/safe-fetch.d.ts +16 -0
  61. package/dist/network/safe-fetch.d.ts.map +1 -0
  62. package/dist/network/safe-fetch.js +124 -0
  63. package/dist/network/safe-fetch.js.map +1 -0
  64. package/dist/network/safe-fetch.test.d.ts +2 -0
  65. package/dist/network/safe-fetch.test.d.ts.map +1 -0
  66. package/dist/network/safe-fetch.test.js +136 -0
  67. package/dist/network/safe-fetch.test.js.map +1 -0
  68. package/dist/network/url-policy.d.ts +32 -0
  69. package/dist/network/url-policy.d.ts.map +1 -0
  70. package/dist/network/url-policy.js +230 -0
  71. package/dist/network/url-policy.js.map +1 -0
  72. package/dist/network/url-policy.test.d.ts +2 -0
  73. package/dist/network/url-policy.test.d.ts.map +1 -0
  74. package/dist/network/url-policy.test.js +57 -0
  75. package/dist/network/url-policy.test.js.map +1 -0
  76. package/dist/readme-utils.d.ts.map +1 -1
  77. package/dist/readme-utils.js +3 -4
  78. package/dist/readme-utils.js.map +1 -1
  79. package/dist/space/commands/discover.d.ts +0 -5
  80. package/dist/space/commands/discover.d.ts.map +1 -1
  81. package/dist/space/commands/discover.js +9 -2
  82. package/dist/space/commands/discover.js.map +1 -1
  83. package/dist/space/commands/invoke.js +1 -59
  84. package/dist/space/commands/invoke.js.map +1 -1
  85. package/dist/space/commands/view-parameters.d.ts.map +1 -1
  86. package/dist/space/commands/view-parameters.js +3 -98
  87. package/dist/space/commands/view-parameters.js.map +1 -1
  88. package/dist/space/dynamic-space-tool.d.ts.map +1 -1
  89. package/dist/space/dynamic-space-tool.js +5 -2
  90. package/dist/space/dynamic-space-tool.js.map +1 -1
  91. package/dist/space/utils/gradio-caller.d.ts.map +1 -1
  92. package/dist/space/utils/gradio-caller.js +13 -6
  93. package/dist/space/utils/gradio-caller.js.map +1 -1
  94. package/dist/space/utils/space-http.d.ts +8 -0
  95. package/dist/space/utils/space-http.d.ts.map +1 -0
  96. package/dist/space/utils/space-http.js +49 -0
  97. package/dist/space/utils/space-http.js.map +1 -0
  98. package/dist/space-files.d.ts +0 -1
  99. package/dist/space-files.d.ts.map +1 -1
  100. package/dist/space-files.js +3 -36
  101. package/dist/space-files.js.map +1 -1
  102. package/package.json +6 -2
  103. package/src/docs-search/doc-fetch.test.ts +98 -28
  104. package/src/docs-search/doc-fetch.ts +9 -16
  105. package/src/file-icons.ts +39 -0
  106. package/src/gradio-files.ts +2 -40
  107. package/src/hf-api-call.ts +8 -10
  108. package/src/index.browser.ts +183 -0
  109. package/src/index.ts +1 -0
  110. package/src/jobs/commands/uv-utils.ts +2 -2
  111. package/src/jobs/jobs-tool.ts +13 -12
  112. package/src/jobs/schema-help.ts +4 -4
  113. package/src/jobs/sse-handler.ts +12 -7
  114. package/src/logger.ts +2 -2
  115. package/src/network/fetch-profile.ts +112 -0
  116. package/src/network/index.ts +4 -0
  117. package/src/network/ip-policy.test.ts +58 -0
  118. package/src/network/ip-policy.ts +252 -0
  119. package/src/network/safe-fetch.test.ts +181 -0
  120. package/src/network/safe-fetch.ts +174 -0
  121. package/src/network/url-policy.test.ts +100 -0
  122. package/src/network/url-policy.ts +304 -0
  123. package/src/readme-utils.ts +11 -10
  124. package/src/space/commands/discover.ts +10 -2
  125. package/src/space/commands/invoke.ts +1 -88
  126. package/src/space/commands/view-parameters.ts +3 -136
  127. package/src/space/dynamic-space-tool.ts +6 -2
  128. package/src/space/utils/gradio-caller.ts +25 -12
  129. package/src/space/utils/space-http.ts +75 -0
  130. package/src/space-files.ts +3 -41
  131. package/test/fetch-guard.spec.ts +70 -0
  132. package/test/jobs/sse-handler.spec.ts +60 -0
  133. package/dist/space/utils/result-formatter.d.ts +0 -4
  134. package/dist/space/utils/result-formatter.d.ts.map +0 -1
  135. package/dist/space/utils/result-formatter.js +0 -146
  136. package/dist/space/utils/result-formatter.js.map +0 -1
  137. package/src/space/utils/result-formatter.ts +0 -226
@@ -0,0 +1,80 @@
1
+ import { safeFetch } from './safe-fetch.js';
2
+ import { createExternalHttpsPolicy, createGradioMcpHostPolicy, createGradioSchemaHostPolicy, createHfDocsPolicy, createHttpOrHttpsPolicy, createHuggingFaceHubPolicy, createLocalhostHttpPolicy, isLocalhostHostname, } from './url-policy.js';
3
+ const DEFAULT_TIMEOUT_MS = 12_500;
4
+ const DEFAULT_MAX_REDIRECTS = 3;
5
+ export async function fetchWithProfile(url, profile, options = {}) {
6
+ return safeFetch(url, {
7
+ urlPolicy: profile.urlPolicy,
8
+ timeoutMs: options.timeoutMs ?? profile.timeoutMs,
9
+ maxRedirects: profile.maxRedirects,
10
+ externalOnly: profile.externalOnly,
11
+ requestInit: options.requestInit,
12
+ });
13
+ }
14
+ export const NETWORK_FETCH_PROFILES = {
15
+ externalHttps() {
16
+ return {
17
+ urlPolicy: createExternalHttpsPolicy(),
18
+ timeoutMs: DEFAULT_TIMEOUT_MS,
19
+ maxRedirects: DEFAULT_MAX_REDIRECTS,
20
+ externalOnly: true,
21
+ };
22
+ },
23
+ httpOrHttpsPermissive() {
24
+ return {
25
+ urlPolicy: createHttpOrHttpsPolicy(),
26
+ timeoutMs: DEFAULT_TIMEOUT_MS,
27
+ maxRedirects: DEFAULT_MAX_REDIRECTS,
28
+ externalOnly: false,
29
+ };
30
+ },
31
+ streamableProxy() {
32
+ return {
33
+ urlPolicy: createHttpOrHttpsPolicy(),
34
+ timeoutMs: 0,
35
+ maxRedirects: DEFAULT_MAX_REDIRECTS,
36
+ externalOnly: false,
37
+ };
38
+ },
39
+ hfHub() {
40
+ return {
41
+ urlPolicy: createHuggingFaceHubPolicy(),
42
+ timeoutMs: DEFAULT_TIMEOUT_MS,
43
+ maxRedirects: DEFAULT_MAX_REDIRECTS,
44
+ externalOnly: true,
45
+ };
46
+ },
47
+ hfDocs() {
48
+ return {
49
+ urlPolicy: createHfDocsPolicy(),
50
+ timeoutMs: DEFAULT_TIMEOUT_MS,
51
+ maxRedirects: 5,
52
+ externalOnly: true,
53
+ };
54
+ },
55
+ localhostHttp() {
56
+ return {
57
+ urlPolicy: createLocalhostHttpPolicy(),
58
+ timeoutMs: DEFAULT_TIMEOUT_MS,
59
+ maxRedirects: 2,
60
+ externalOnly: false,
61
+ };
62
+ },
63
+ gradioSchemaHost(hostname) {
64
+ return {
65
+ urlPolicy: createGradioSchemaHostPolicy(hostname),
66
+ timeoutMs: 10_000,
67
+ maxRedirects: 2,
68
+ externalOnly: !isLocalhostHostname(hostname),
69
+ };
70
+ },
71
+ gradioMcpHost(hostname, allowedProtocol) {
72
+ return {
73
+ urlPolicy: createGradioMcpHostPolicy(hostname, allowedProtocol),
74
+ timeoutMs: 0,
75
+ maxRedirects: 0,
76
+ externalOnly: !isLocalhostHostname(hostname) && process.env.NODE_ENV !== 'test',
77
+ };
78
+ },
79
+ };
80
+ //# sourceMappingURL=fetch-profile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-profile.js","sourceRoot":"","sources":["../../src/network/fetch-profile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAwB,MAAM,iBAAiB,CAAC;AAClE,OAAO,EACN,yBAAyB,EACzB,yBAAyB,EACzB,4BAA4B,EAC5B,kBAAkB,EAClB,uBAAuB,EACvB,0BAA0B,EAC1B,yBAAyB,EACzB,mBAAmB,GAGnB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAClC,MAAM,qBAAqB,GAAG,CAAC,CAAC;AAchC,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACrC,GAAiB,EACjB,OAAyB,EACzB,UAAmC,EAAE;IAErC,OAAO,SAAS,CAAC,GAAG,EAAE;QACrB,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,SAAS;QACjD,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,WAAW,EAAE,OAAO,CAAC,WAAW;KAChC,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACrC,aAAa;QACZ,OAAO;YACN,SAAS,EAAE,yBAAyB,EAAE;YACtC,SAAS,EAAE,kBAAkB;YAC7B,YAAY,EAAE,qBAAqB;YACnC,YAAY,EAAE,IAAI;SAClB,CAAC;IACH,CAAC;IACD,qBAAqB;QACpB,OAAO;YACN,SAAS,EAAE,uBAAuB,EAAE;YACpC,SAAS,EAAE,kBAAkB;YAC7B,YAAY,EAAE,qBAAqB;YACnC,YAAY,EAAE,KAAK;SACnB,CAAC;IACH,CAAC;IACD,eAAe;QACd,OAAO;YACN,SAAS,EAAE,uBAAuB,EAAE;YACpC,SAAS,EAAE,CAAC;YACZ,YAAY,EAAE,qBAAqB;YACnC,YAAY,EAAE,KAAK;SACnB,CAAC;IACH,CAAC;IACD,KAAK;QACJ,OAAO;YACN,SAAS,EAAE,0BAA0B,EAAE;YACvC,SAAS,EAAE,kBAAkB;YAC7B,YAAY,EAAE,qBAAqB;YACnC,YAAY,EAAE,IAAI;SAClB,CAAC;IACH,CAAC;IACD,MAAM;QACL,OAAO;YACN,SAAS,EAAE,kBAAkB,EAAE;YAC/B,SAAS,EAAE,kBAAkB;YAC7B,YAAY,EAAE,CAAC;YACf,YAAY,EAAE,IAAI;SAClB,CAAC;IACH,CAAC;IACD,aAAa;QACZ,OAAO;YACN,SAAS,EAAE,yBAAyB,EAAE;YACtC,SAAS,EAAE,kBAAkB;YAC7B,YAAY,EAAE,CAAC;YACf,YAAY,EAAE,KAAK;SACnB,CAAC;IACH,CAAC;IACD,gBAAgB,CAAC,QAAgB;QAChC,OAAO;YACN,SAAS,EAAE,4BAA4B,CAAC,QAAQ,CAAC;YACjD,SAAS,EAAE,MAAM;YACjB,YAAY,EAAE,CAAC;YACf,YAAY,EAAE,CAAC,mBAAmB,CAAC,QAAQ,CAAC;SAC5C,CAAC;IACH,CAAC;IACD,aAAa,CACZ,QAAgB,EAChB,eAA4B;QAE5B,OAAO;YACN,SAAS,EAAE,yBAAyB,CAAC,QAAQ,EAAE,eAAe,CAAC;YAC/D,SAAS,EAAE,CAAC;YACZ,YAAY,EAAE,CAAC;YACf,YAAY,EAAE,CAAC,mBAAmB,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM;SAC/E,CAAC;IACH,CAAC;CACD,CAAC"}
@@ -0,0 +1,5 @@
1
+ export * from './url-policy.js';
2
+ export * from './ip-policy.js';
3
+ export * from './safe-fetch.js';
4
+ export * from './fetch-profile.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/network/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,5 @@
1
+ export * from './url-policy.js';
2
+ export * from './ip-policy.js';
3
+ export * from './safe-fetch.js';
4
+ export * from './fetch-profile.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/network/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,6 @@
1
+ export interface ExternalAddressOptions {
2
+ allowDnsRebindMitigation?: boolean;
3
+ }
4
+ export declare function isIpInternalOrReserved(ip: string): boolean;
5
+ export declare function assertExternalAddress(hostname: string, options?: ExternalAddressOptions): Promise<void>;
6
+ //# sourceMappingURL=ip-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ip-policy.d.ts","sourceRoot":"","sources":["../../src/network/ip-policy.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,sBAAsB;IACtC,wBAAwB,CAAC,EAAE,OAAO,CAAC;CACnC;AA+KD,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAY1D;AAwBD,wBAAsB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,sBAA2B,GAAG,OAAO,CAAC,IAAI,CAAC,CAsCjH"}
@@ -0,0 +1,202 @@
1
+ const INTERNAL_ADDRESS_HOST_ALLOWLIST_ENV = 'ALLOW_INTERNAL_ADDRESS_HOSTS';
2
+ function normalizeHostname(hostname) {
3
+ return hostname.trim().toLowerCase().replace(/\.+$/, '');
4
+ }
5
+ function getInternalAddressHostAllowlist() {
6
+ const raw = process.env[INTERNAL_ADDRESS_HOST_ALLOWLIST_ENV];
7
+ if (!raw) {
8
+ return [];
9
+ }
10
+ return raw
11
+ .split(',')
12
+ .map((entry) => normalizeHostname(entry))
13
+ .filter((entry) => entry.length > 0);
14
+ }
15
+ function hostnameMatchesPattern(hostname, pattern) {
16
+ if (pattern.startsWith('*.')) {
17
+ const baseDomain = pattern.slice(2);
18
+ if (!baseDomain) {
19
+ return false;
20
+ }
21
+ return hostname === baseDomain || hostname.endsWith(`.${baseDomain}`);
22
+ }
23
+ return hostname === pattern;
24
+ }
25
+ function isInternalAddressAllowedForHostname(hostname) {
26
+ const normalizedHostname = normalizeHostname(hostname);
27
+ if (!normalizedHostname) {
28
+ return false;
29
+ }
30
+ const allowlist = getInternalAddressHostAllowlist();
31
+ if (allowlist.length === 0) {
32
+ return false;
33
+ }
34
+ return allowlist.some((pattern) => hostnameMatchesPattern(normalizedHostname, pattern));
35
+ }
36
+ function normalizeIpLiteral(host) {
37
+ if (host.startsWith('[') && host.endsWith(']')) {
38
+ return host.slice(1, -1);
39
+ }
40
+ return host;
41
+ }
42
+ function parseIpv4ToInt(ip) {
43
+ const parts = ip.split('.').map((part) => Number.parseInt(part, 10));
44
+ if (parts.length !== 4 || parts.some((part) => Number.isNaN(part) || part < 0 || part > 255)) {
45
+ throw new Error(`Invalid IPv4 address: ${ip}`);
46
+ }
47
+ return parts.reduce((acc, part) => acc * 256 + part, 0);
48
+ }
49
+ function ipv4InRange(ipValue, start, end) {
50
+ const startValue = parseIpv4ToInt(start);
51
+ const endValue = parseIpv4ToInt(end);
52
+ return ipValue >= startValue && ipValue <= endValue;
53
+ }
54
+ function isIpv4InternalOrReserved(ip) {
55
+ const value = parseIpv4ToInt(ip);
56
+ return (ipv4InRange(value, '0.0.0.0', '0.255.255.255') ||
57
+ ipv4InRange(value, '10.0.0.0', '10.255.255.255') ||
58
+ ipv4InRange(value, '100.64.0.0', '100.127.255.255') ||
59
+ ipv4InRange(value, '127.0.0.0', '127.255.255.255') ||
60
+ ipv4InRange(value, '169.254.0.0', '169.254.255.255') ||
61
+ ipv4InRange(value, '172.16.0.0', '172.31.255.255') ||
62
+ ipv4InRange(value, '192.0.0.0', '192.0.0.255') ||
63
+ ipv4InRange(value, '192.0.2.0', '192.0.2.255') ||
64
+ ipv4InRange(value, '192.88.99.0', '192.88.99.255') ||
65
+ ipv4InRange(value, '192.168.0.0', '192.168.255.255') ||
66
+ ipv4InRange(value, '198.18.0.0', '198.19.255.255') ||
67
+ ipv4InRange(value, '198.51.100.0', '198.51.100.255') ||
68
+ ipv4InRange(value, '203.0.113.0', '203.0.113.255') ||
69
+ ipv4InRange(value, '224.0.0.0', '239.255.255.255') ||
70
+ ipv4InRange(value, '240.0.0.0', '255.255.255.255'));
71
+ }
72
+ function parseIpv6ToBigInt(ip) {
73
+ const zoneIndex = ip.indexOf('%');
74
+ const zoneStripped = zoneIndex >= 0 ? ip.slice(0, zoneIndex) : ip;
75
+ let working = zoneStripped;
76
+ if (working.includes('.')) {
77
+ const lastColon = working.lastIndexOf(':');
78
+ if (lastColon < 0) {
79
+ throw new Error(`Invalid IPv6 address: ${ip}`);
80
+ }
81
+ const ipv4Part = working.slice(lastColon + 1);
82
+ const ipv4Value = parseIpv4ToInt(ipv4Part);
83
+ const high = ((ipv4Value >>> 16) & 0xffff).toString(16);
84
+ const low = (ipv4Value & 0xffff).toString(16);
85
+ working = `${working.slice(0, lastColon)}:${high}:${low}`;
86
+ }
87
+ const split = working.split('::');
88
+ if (split.length > 2) {
89
+ throw new Error(`Invalid IPv6 address: ${ip}`);
90
+ }
91
+ const left = split[0] ? split[0].split(':').filter(Boolean) : [];
92
+ const right = split[1] ? split[1].split(':').filter(Boolean) : [];
93
+ const missingCount = 8 - (left.length + right.length);
94
+ if (split.length === 1 && missingCount !== 0) {
95
+ throw new Error(`Invalid IPv6 address: ${ip}`);
96
+ }
97
+ if (missingCount < 0) {
98
+ throw new Error(`Invalid IPv6 address: ${ip}`);
99
+ }
100
+ const full = [...left, ...Array.from({ length: missingCount }, () => '0'), ...right];
101
+ if (full.length !== 8) {
102
+ throw new Error(`Invalid IPv6 address: ${ip}`);
103
+ }
104
+ let value = 0n;
105
+ for (const part of full) {
106
+ const segment = Number.parseInt(part, 16);
107
+ if (Number.isNaN(segment) || segment < 0 || segment > 0xffff) {
108
+ throw new Error(`Invalid IPv6 address: ${ip}`);
109
+ }
110
+ value = (value << 16n) + BigInt(segment);
111
+ }
112
+ return value;
113
+ }
114
+ function isIpv6InCidr(ipValue, prefixValue, prefixLength) {
115
+ const hostBits = 128n - BigInt(prefixLength);
116
+ const mask = ((1n << BigInt(prefixLength)) - 1n) << hostBits;
117
+ return (ipValue & mask) === (prefixValue & mask);
118
+ }
119
+ function isIpv6InternalOrReserved(ip) {
120
+ const value = parseIpv6ToBigInt(ip);
121
+ if (value === 0n || value === 1n) {
122
+ return true;
123
+ }
124
+ if (value >> 32n === 0xffffn) {
125
+ const ipv4Value = Number(value & 0xffffffffn);
126
+ const octet1 = (ipv4Value >>> 24) & 0xff;
127
+ const octet2 = (ipv4Value >>> 16) & 0xff;
128
+ const octet3 = (ipv4Value >>> 8) & 0xff;
129
+ const octet4 = ipv4Value & 0xff;
130
+ return isIpv4InternalOrReserved(`${octet1.toString()}.${octet2.toString()}.${octet3.toString()}.${octet4.toString()}`);
131
+ }
132
+ return (isIpv6InCidr(value, 0xfc00n << 112n, 7) ||
133
+ isIpv6InCidr(value, 0xfe80n << 112n, 10) ||
134
+ isIpv6InCidr(value, 0xff00n << 112n, 8) ||
135
+ isIpv6InCidr(value, 0x20010db8n << 96n, 32) ||
136
+ isIpv6InCidr(value, 0x20010010n << 96n, 28));
137
+ }
138
+ export function isIpInternalOrReserved(ip) {
139
+ const normalizedIp = normalizeIpLiteral(ip);
140
+ const ipVersion = detectIpVersion(normalizedIp);
141
+ if (ipVersion === 0) {
142
+ throw new Error(`Invalid IP address: ${ip}`);
143
+ }
144
+ if (ipVersion === 4) {
145
+ return isIpv4InternalOrReserved(normalizedIp);
146
+ }
147
+ return isIpv6InternalOrReserved(normalizedIp);
148
+ }
149
+ async function lookupAll(hostname) {
150
+ const { lookup } = await import('node:dns/promises');
151
+ const results = await lookup(hostname, { all: true, verbatim: true });
152
+ return results.map((entry) => entry.address);
153
+ }
154
+ function detectIpVersion(candidate) {
155
+ try {
156
+ parseIpv4ToInt(candidate);
157
+ return 4;
158
+ }
159
+ catch {
160
+ }
161
+ try {
162
+ parseIpv6ToBigInt(candidate);
163
+ return 6;
164
+ }
165
+ catch {
166
+ return 0;
167
+ }
168
+ }
169
+ export async function assertExternalAddress(hostname, options = {}) {
170
+ const { allowDnsRebindMitigation = true } = options;
171
+ const normalized = normalizeHostname(hostname);
172
+ if (!normalized) {
173
+ throw new Error('Hostname is required for external address check');
174
+ }
175
+ const allowInternalAddress = isInternalAddressAllowedForHostname(normalized);
176
+ const ipLiteral = normalizeIpLiteral(normalized);
177
+ const ipVersion = detectIpVersion(ipLiteral);
178
+ if (ipVersion !== 0) {
179
+ if (isIpInternalOrReserved(ipLiteral)) {
180
+ throw new Error(`Blocked internal or reserved address: ${ipLiteral}`);
181
+ }
182
+ return;
183
+ }
184
+ const firstLookup = await lookupAll(normalized);
185
+ if (firstLookup.length === 0) {
186
+ throw new Error(`No DNS records found for hostname: ${normalized}`);
187
+ }
188
+ for (const address of firstLookup) {
189
+ if (isIpInternalOrReserved(address) && !allowInternalAddress) {
190
+ throw new Error(`Blocked internal or reserved address for hostname ${normalized}: ${address}`);
191
+ }
192
+ }
193
+ if (allowDnsRebindMitigation) {
194
+ const secondLookup = await lookupAll(normalized);
195
+ for (const address of secondLookup) {
196
+ if (isIpInternalOrReserved(address) && !allowInternalAddress) {
197
+ throw new Error(`Blocked internal or reserved address for hostname ${normalized}: ${address}`);
198
+ }
199
+ }
200
+ }
201
+ }
202
+ //# sourceMappingURL=ip-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ip-policy.js","sourceRoot":"","sources":["../../src/network/ip-policy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ip-policy.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ip-policy.test.d.ts","sourceRoot":"","sources":["../../src/network/ip-policy.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,46 @@
1
+ import { afterEach, describe, expect, it, vi } from 'vitest';
2
+ import { assertExternalAddress, isIpInternalOrReserved } from './ip-policy.js';
3
+ const { lookupMock } = vi.hoisted(() => ({
4
+ lookupMock: vi.fn(),
5
+ }));
6
+ vi.mock('node:dns/promises', () => ({
7
+ lookup: lookupMock,
8
+ }));
9
+ describe('ip-policy', () => {
10
+ afterEach(() => {
11
+ lookupMock.mockReset();
12
+ delete process.env.ALLOW_INTERNAL_ADDRESS_HOSTS;
13
+ });
14
+ it('classifies internal/reserved IPv4 ranges', () => {
15
+ expect(isIpInternalOrReserved('127.0.0.1')).toBe(true);
16
+ expect(isIpInternalOrReserved('10.1.2.3')).toBe(true);
17
+ expect(isIpInternalOrReserved('172.20.10.2')).toBe(true);
18
+ expect(isIpInternalOrReserved('192.168.1.1')).toBe(true);
19
+ expect(isIpInternalOrReserved('8.8.8.8')).toBe(false);
20
+ });
21
+ it('classifies internal/reserved IPv6 ranges', () => {
22
+ expect(isIpInternalOrReserved('::1')).toBe(true);
23
+ expect(isIpInternalOrReserved('fc00::1')).toBe(true);
24
+ expect(isIpInternalOrReserved('fe80::1')).toBe(true);
25
+ expect(isIpInternalOrReserved('2001:db8::1')).toBe(true);
26
+ expect(isIpInternalOrReserved('2607:f8b0:4005:80a::200e')).toBe(false);
27
+ });
28
+ it('blocks internal literal addresses in assertExternalAddress', async () => {
29
+ await expect(assertExternalAddress('127.0.0.1')).rejects.toThrow('Blocked internal or reserved address');
30
+ await expect(assertExternalAddress('::1')).rejects.toThrow('Blocked internal or reserved address');
31
+ });
32
+ it('allows external literal addresses in assertExternalAddress', async () => {
33
+ await expect(assertExternalAddress('8.8.8.8')).resolves.toBeUndefined();
34
+ });
35
+ it('blocks hostnames resolving to internal addresses by default', async () => {
36
+ lookupMock.mockResolvedValue([{ address: '10.0.246.93' }]);
37
+ await expect(assertExternalAddress('huggingface.co')).rejects.toThrow('Blocked internal or reserved address for hostname huggingface.co: 10.0.246.93');
38
+ });
39
+ it('allows allowlisted hostnames to resolve to internal addresses', async () => {
40
+ process.env.ALLOW_INTERNAL_ADDRESS_HOSTS = 'huggingface.co,*.hf.space';
41
+ lookupMock.mockResolvedValue([{ address: '10.0.246.93' }]);
42
+ await expect(assertExternalAddress('huggingface.co')).resolves.toBeUndefined();
43
+ await expect(assertExternalAddress('demo.hf.space')).resolves.toBeUndefined();
44
+ });
45
+ });
46
+ //# sourceMappingURL=ip-policy.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ip-policy.test.js","sourceRoot":"","sources":["../../src/network/ip-policy.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { type UrlPolicy } from './url-policy.js';
2
+ export interface SafeFetchOptions {
3
+ urlPolicy: UrlPolicy;
4
+ timeoutMs?: number;
5
+ maxRedirects?: number;
6
+ externalOnly?: boolean;
7
+ requestInit?: RequestInit;
8
+ stripSensitiveHeadersOnCrossHostRedirect?: boolean;
9
+ }
10
+ export interface SafeFetchResult {
11
+ response: Response;
12
+ finalUrl: URL;
13
+ redirectsFollowed: number;
14
+ }
15
+ export declare function safeFetch(url: string | URL, options: SafeFetchOptions): Promise<SafeFetchResult>;
16
+ //# sourceMappingURL=safe-fetch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safe-fetch.d.ts","sourceRoot":"","sources":["../../src/network/safe-fetch.ts"],"names":[],"mappings":"AACA,OAAO,EAAuB,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEtE,MAAM,WAAW,gBAAgB;IAChC,SAAS,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,wCAAwC,CAAC,EAAE,OAAO,CAAC;CACnD;AAED,MAAM,WAAW,eAAe;IAC/B,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,GAAG,CAAC;IACd,iBAAiB,EAAE,MAAM,CAAC;CAC1B;AA4ED,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAiFtG"}
@@ -0,0 +1,124 @@
1
+ import { assertExternalAddress } from './ip-policy.js';
2
+ import { parseAndValidateUrl } from './url-policy.js';
3
+ const DEFAULT_TIMEOUT_MS = 12500;
4
+ const DEFAULT_MAX_REDIRECTS = 5;
5
+ const REDIRECT_STATUSES = new Set([301, 302, 303, 307, 308]);
6
+ const SENSITIVE_HEADERS = new Set(['authorization', 'proxy-authorization', 'cookie', 'x-hf-authorization']);
7
+ function isRedirectStatus(status) {
8
+ return REDIRECT_STATUSES.has(status);
9
+ }
10
+ function dropSensitiveHeaders(headersInit) {
11
+ const headers = new Headers(headersInit);
12
+ for (const key of SENSITIVE_HEADERS) {
13
+ headers.delete(key);
14
+ }
15
+ return headers;
16
+ }
17
+ function withMethodAndBody(requestInit, method, body) {
18
+ const nextInit = {
19
+ ...requestInit,
20
+ method,
21
+ redirect: 'manual',
22
+ };
23
+ if (body !== undefined && body !== null && method !== 'GET' && method !== 'HEAD') {
24
+ nextInit.body = body;
25
+ }
26
+ else {
27
+ delete nextInit.body;
28
+ }
29
+ return nextInit;
30
+ }
31
+ async function fetchWithTimeout(url, requestInit, timeoutMs) {
32
+ if (timeoutMs <= 0) {
33
+ return fetch(url.toString(), {
34
+ ...requestInit,
35
+ redirect: 'manual',
36
+ });
37
+ }
38
+ const outerSignal = requestInit.signal;
39
+ if (outerSignal) {
40
+ if (outerSignal.aborted) {
41
+ throw new Error('Request was aborted');
42
+ }
43
+ }
44
+ const timeoutSignal = AbortSignal.timeout(timeoutMs);
45
+ const signal = outerSignal ? AbortSignal.any([outerSignal, timeoutSignal]) : timeoutSignal;
46
+ try {
47
+ return await fetch(url.toString(), {
48
+ ...requestInit,
49
+ signal,
50
+ redirect: 'manual',
51
+ });
52
+ }
53
+ catch (error) {
54
+ if (error instanceof Error && error.name === 'AbortError') {
55
+ if (outerSignal?.aborted) {
56
+ throw new Error('Request was aborted');
57
+ }
58
+ if (timeoutSignal.aborted) {
59
+ throw new Error(`Request timed out after ${timeoutMs.toString()}ms`);
60
+ }
61
+ throw new Error(`Request timed out after ${timeoutMs.toString()}ms`);
62
+ }
63
+ throw error;
64
+ }
65
+ }
66
+ export async function safeFetch(url, options) {
67
+ const { urlPolicy, timeoutMs = DEFAULT_TIMEOUT_MS, maxRedirects = DEFAULT_MAX_REDIRECTS, externalOnly = false, requestInit = {}, stripSensitiveHeadersOnCrossHostRedirect = true, } = options;
68
+ if (maxRedirects < 0) {
69
+ throw new Error('maxRedirects must be >= 0');
70
+ }
71
+ let currentUrl = parseAndValidateUrl(url, urlPolicy);
72
+ if (externalOnly) {
73
+ await assertExternalAddress(currentUrl.hostname);
74
+ }
75
+ const baseHeaders = new Headers(requestInit.headers);
76
+ let currentMethod = (requestInit.method || 'GET').toUpperCase();
77
+ let currentBody = requestInit.body;
78
+ let redirectsFollowed = 0;
79
+ while (true) {
80
+ const currentInit = withMethodAndBody({
81
+ ...requestInit,
82
+ headers: baseHeaders,
83
+ }, currentMethod, currentBody);
84
+ const response = await fetchWithTimeout(currentUrl, currentInit, timeoutMs);
85
+ if (!isRedirectStatus(response.status)) {
86
+ return {
87
+ response,
88
+ finalUrl: currentUrl,
89
+ redirectsFollowed,
90
+ };
91
+ }
92
+ if (redirectsFollowed >= maxRedirects) {
93
+ throw new Error(`Redirect limit exceeded (${maxRedirects.toString()})`);
94
+ }
95
+ const location = response.headers.get('location');
96
+ if (!location) {
97
+ throw new Error(`Redirect response missing Location header (status ${response.status.toString()})`);
98
+ }
99
+ const nextCandidate = new URL(location, currentUrl);
100
+ const nextUrl = parseAndValidateUrl(nextCandidate, urlPolicy);
101
+ if (externalOnly) {
102
+ await assertExternalAddress(nextUrl.hostname);
103
+ }
104
+ if (stripSensitiveHeadersOnCrossHostRedirect && currentUrl.origin !== nextUrl.origin) {
105
+ const filtered = dropSensitiveHeaders(baseHeaders);
106
+ baseHeaders.forEach((_, key) => {
107
+ baseHeaders.delete(key);
108
+ });
109
+ filtered.forEach((value, key) => {
110
+ baseHeaders.set(key, value);
111
+ });
112
+ }
113
+ if (response.status === 303 || ((response.status === 301 || response.status === 302) && currentMethod === 'POST')) {
114
+ currentMethod = 'GET';
115
+ currentBody = undefined;
116
+ baseHeaders.delete('content-length');
117
+ baseHeaders.delete('content-type');
118
+ }
119
+ redirectsFollowed += 1;
120
+ currentUrl = nextUrl;
121
+ await response.body?.cancel();
122
+ }
123
+ }
124
+ //# sourceMappingURL=safe-fetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safe-fetch.js","sourceRoot":"","sources":["../../src/network/safe-fetch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=safe-fetch.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safe-fetch.test.d.ts","sourceRoot":"","sources":["../../src/network/safe-fetch.test.ts"],"names":[],"mappings":""}