@j0hanz/fetch-url-mcp 1.12.3 → 1.12.5

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 (65) hide show
  1. package/dist/http/auth.d.ts.map +1 -1
  2. package/dist/http/auth.js +44 -29
  3. package/dist/http/helpers.d.ts.map +1 -1
  4. package/dist/http/helpers.js +22 -12
  5. package/dist/http/native.d.ts.map +1 -1
  6. package/dist/http/native.js +30 -29
  7. package/dist/http/rate-limit.d.ts.map +1 -1
  8. package/dist/http/rate-limit.js +5 -3
  9. package/dist/index.js +3 -2
  10. package/dist/lib/config.d.ts.map +1 -1
  11. package/dist/lib/config.js +11 -7
  12. package/dist/lib/core.d.ts.map +1 -1
  13. package/dist/lib/core.js +12 -9
  14. package/dist/lib/error-codes.d.ts +11 -0
  15. package/dist/lib/error-codes.d.ts.map +1 -0
  16. package/dist/lib/error-codes.js +15 -0
  17. package/dist/lib/error-messages.d.ts +13 -0
  18. package/dist/lib/error-messages.d.ts.map +1 -0
  19. package/dist/lib/error-messages.js +51 -0
  20. package/dist/lib/fetch-pipeline.d.ts.map +1 -1
  21. package/dist/lib/fetch-pipeline.js +5 -4
  22. package/dist/lib/http.d.ts.map +1 -1
  23. package/dist/lib/http.js +80 -41
  24. package/dist/lib/logger-names.d.ts +14 -0
  25. package/dist/lib/logger-names.d.ts.map +1 -0
  26. package/dist/lib/logger-names.js +13 -0
  27. package/dist/lib/mcp-interop.d.ts +1 -11
  28. package/dist/lib/mcp-interop.d.ts.map +1 -1
  29. package/dist/lib/mcp-interop.js +10 -73
  30. package/dist/lib/session.d.ts.map +1 -1
  31. package/dist/lib/session.js +2 -1
  32. package/dist/lib/tool-errors.d.ts +39 -0
  33. package/dist/lib/tool-errors.d.ts.map +1 -0
  34. package/dist/lib/tool-errors.js +252 -0
  35. package/dist/lib/url.d.ts.map +1 -1
  36. package/dist/lib/url.js +18 -15
  37. package/dist/lib/utils.d.ts +4 -1
  38. package/dist/lib/utils.d.ts.map +1 -1
  39. package/dist/lib/utils.js +18 -9
  40. package/dist/schemas.d.ts.map +1 -1
  41. package/dist/schemas.js +3 -3
  42. package/dist/server.d.ts.map +1 -1
  43. package/dist/server.js +7 -6
  44. package/dist/tasks/call-contract.d.ts.map +1 -1
  45. package/dist/tasks/call-contract.js +9 -11
  46. package/dist/tasks/execution.d.ts.map +1 -1
  47. package/dist/tasks/execution.js +17 -14
  48. package/dist/tasks/handlers.d.ts.map +1 -1
  49. package/dist/tasks/handlers.js +9 -8
  50. package/dist/tasks/manager.d.ts.map +1 -1
  51. package/dist/tasks/manager.js +14 -13
  52. package/dist/tasks/owner.d.ts +0 -1
  53. package/dist/tasks/owner.d.ts.map +1 -1
  54. package/dist/tasks/owner.js +0 -25
  55. package/dist/tools/fetch-url.d.ts.map +1 -1
  56. package/dist/tools/fetch-url.js +15 -27
  57. package/dist/transform/dom-prep.d.ts.map +1 -1
  58. package/dist/transform/dom-prep.js +10 -8
  59. package/dist/transform/shared.d.ts.map +1 -1
  60. package/dist/transform/shared.js +2 -1
  61. package/dist/transform/transform.d.ts.map +1 -1
  62. package/dist/transform/transform.js +29 -21
  63. package/dist/transform/worker-pool.d.ts.map +1 -1
  64. package/dist/transform/worker-pool.js +16 -12
  65. package/package.json +1 -1
@@ -16,16 +16,16 @@ function hasPackageJsonVersion(value) {
16
16
  function readServerVersion(moduleUrl) {
17
17
  const packageJsonPath = findPackageJSON(moduleUrl);
18
18
  if (!packageJsonPath)
19
- throw new Error('package.json not found');
19
+ throw Error('package.json not found');
20
20
  let packageJson;
21
21
  try {
22
22
  packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
23
23
  }
24
24
  catch (error) {
25
- throw new Error(`Failed to parse package.json at ${packageJsonPath}: ${getErrorMessage(error)}`, { cause: error });
25
+ throw Error(`Failed to parse package.json at ${packageJsonPath}: ${getErrorMessage(error)}`, { cause: error });
26
26
  }
27
27
  if (!hasPackageJsonVersion(packageJson)) {
28
- throw new Error(`package.json version is missing at ${packageJsonPath}`);
28
+ throw Error(`package.json version is missing at ${packageJsonPath}`);
29
29
  }
30
30
  return packageJson.version;
31
31
  }
@@ -184,14 +184,17 @@ const EnvParser = {
184
184
  if (!value)
185
185
  return undefined;
186
186
  const parsed = URL.parse(value);
187
- if (!parsed)
188
- throw new ConfigError(`Invalid ${name} value: ${value}`);
187
+ if (!parsed) {
188
+ const error = new ConfigError(`Invalid ${name} value: ${value}`);
189
+ throw error;
190
+ }
189
191
  return parsed;
190
192
  },
191
193
  allowedHosts(envValue) {
192
- return new Set(EnvParser.list(envValue)
194
+ const hosts = new Set(EnvParser.list(envValue)
193
195
  .map((h) => EnvParser.normalizeHostValue(h))
194
196
  .filter((h) => h !== null));
197
+ return hosts;
195
198
  },
196
199
  optionalFilePath(value) {
197
200
  const trimmed = value?.trim();
@@ -303,7 +306,8 @@ function buildHttpsConfig() {
303
306
  const certFile = EnvParser.optionalFilePath(env['SERVER_TLS_CERT_FILE']);
304
307
  const caFile = EnvParser.optionalFilePath(env['SERVER_TLS_CA_FILE']);
305
308
  if ((keyFile && !certFile) || (!keyFile && certFile)) {
306
- throw new ConfigError('Both SERVER_TLS_KEY_FILE and SERVER_TLS_CERT_FILE must be set together');
309
+ const error = new ConfigError('Both SERVER_TLS_KEY_FILE and SERVER_TLS_CERT_FILE must be set together');
310
+ throw error;
307
311
  }
308
312
  return {
309
313
  enabled: Boolean(keyFile && certFile),
@@ -1 +1 @@
1
- {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/lib/core.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/lib/core.ts"],"names":[],"mappings":"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"}
package/dist/lib/core.js CHANGED
@@ -3,6 +3,7 @@ import process from 'node:process';
3
3
  import { getSystemErrorMessage, inspect, stripVTControlCharacters, } from 'node:util';
4
4
  import {} from '@modelcontextprotocol/sdk/server/mcp.js';
5
5
  import { config } from './config.js';
6
+ import { LOG_SESSION } from './logger-names.js';
6
7
  import { getErrorMessage, isAbortError, startAbortableIntervalLoop, } from './utils.js';
7
8
  export { config, enableHttpMode, serverVersion } from './config.js';
8
9
  const requestContext = new AsyncLocalStorage({
@@ -225,7 +226,8 @@ function formatMetadata(meta) {
225
226
  return ` ${inspect(merged, { breakLength: Infinity, colors: false, compact: true, sorted: true })}`;
226
227
  }
227
228
  function createTimestamp() {
228
- return new Date().toISOString();
229
+ const now = new Date();
230
+ return now.toISOString();
229
231
  }
230
232
  function formatLogEntry(level, message, meta, logger) {
231
233
  if (config.logging.format === 'json') {
@@ -511,12 +513,12 @@ function getCleanupIntervalMs(sessionTtlMs) {
511
513
  function handleSessionCleanupError(error) {
512
514
  if (isAbortError(error))
513
515
  return;
514
- logWarn('Session cleanup loop failed', { error: getErrorMessage(error) }, 'session');
516
+ logWarn('Session cleanup loop failed', { error: getErrorMessage(error) }, LOG_SESSION);
515
517
  }
516
518
  function logRejectedSettledResults(results, message) {
517
519
  for (const result of results) {
518
520
  if (result.status === 'rejected') {
519
- logWarn(message, { error: getErrorMessage(result.reason) }, 'session');
521
+ logWarn(message, { error: getErrorMessage(result.reason) }, LOG_SESSION);
520
522
  }
521
523
  }
522
524
  }
@@ -556,7 +558,7 @@ class SessionCleanupLoop {
556
558
  logInfo('Expired sessions evicted', {
557
559
  evicted: evicted.length,
558
560
  timestamp: new Date(now).toISOString(),
559
- }, 'session');
561
+ }, LOG_SESSION);
560
562
  }
561
563
  }
562
564
  async closeExpiredSession(sessionId, session) {
@@ -567,7 +569,7 @@ class SessionCleanupLoop {
567
569
  catch (error) {
568
570
  logWarn('Expired session pre-close hook failed', {
569
571
  error: getErrorMessage(error),
570
- }, 'session');
572
+ }, LOG_SESSION);
571
573
  }
572
574
  }
573
575
  const closePromise = Promise.allSettled([
@@ -596,7 +598,7 @@ class SessionCleanupLoop {
596
598
  catch (error) {
597
599
  logWarn('Session close operation failed or timed out', {
598
600
  error: getErrorMessage(error),
599
- }, 'session');
601
+ }, LOG_SESSION);
600
602
  }
601
603
  finally {
602
604
  if (timeoutId) {
@@ -609,7 +611,7 @@ class SessionCleanupLoop {
609
611
  catch (error) {
610
612
  logWarn('Failed to unregister session server', {
611
613
  error: getErrorMessage(error),
612
- }, 'session');
614
+ }, LOG_SESSION);
613
615
  }
614
616
  }
615
617
  logCloseFailure(target, error) {
@@ -617,9 +619,10 @@ class SessionCleanupLoop {
617
619
  return;
618
620
  logWarn(`Failed to close expired session ${target}`, {
619
621
  error: getErrorMessage(error),
620
- }, 'session');
622
+ }, LOG_SESSION);
621
623
  }
622
624
  }
623
625
  export function startSessionCleanupLoop(store, sessionTtlMs, options) {
624
- return new SessionCleanupLoop(store, sessionTtlMs, options?.onEvictSession, options?.cleanupIntervalMs).start();
626
+ const loop = new SessionCleanupLoop(store, sessionTtlMs, options?.onEvictSession, options?.cleanupIntervalMs);
627
+ return loop.start();
625
628
  }
@@ -0,0 +1,11 @@
1
+ export declare const EBLOCKED = "EBLOCKED";
2
+ export declare const ETIMEOUT = "ETIMEOUT";
3
+ export declare const EINVAL = "EINVAL";
4
+ export declare const ENODATA = "ENODATA";
5
+ export declare const EBADREDIRECT = "EBADREDIRECT";
6
+ export declare const EUNSUPPORTEDPROTOCOL = "EUNSUPPORTEDPROTOCOL";
7
+ export declare const FETCH_ERROR = "FETCH_ERROR";
8
+ export declare const ABORTED = "ABORTED";
9
+ export declare const QUEUE_FULL = "queue_full";
10
+ export declare const VALIDATION_ERROR = "VALIDATION_ERROR";
11
+ //# sourceMappingURL=error-codes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-codes.d.ts","sourceRoot":"","sources":["../../src/lib/error-codes.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,QAAQ,aAAa,CAAC;AACnC,eAAO,MAAM,QAAQ,aAAa,CAAC;AACnC,eAAO,MAAM,MAAM,WAAW,CAAC;AAC/B,eAAO,MAAM,OAAO,YAAY,CAAC;AAGjC,eAAO,MAAM,YAAY,iBAAiB,CAAC;AAC3C,eAAO,MAAM,oBAAoB,yBAAyB,CAAC;AAG3D,eAAO,MAAM,WAAW,gBAAgB,CAAC;AACzC,eAAO,MAAM,OAAO,YAAY,CAAC;AACjC,eAAO,MAAM,UAAU,eAAe,CAAC;AAGvC,eAAO,MAAM,gBAAgB,qBAAqB,CAAC"}
@@ -0,0 +1,15 @@
1
+ // ── Error codes ────────────────────────────────
2
+ // DNS / network resolution
3
+ export const EBLOCKED = 'EBLOCKED';
4
+ export const ETIMEOUT = 'ETIMEOUT';
5
+ export const EINVAL = 'EINVAL';
6
+ export const ENODATA = 'ENODATA';
7
+ // HTTP redirect
8
+ export const EBADREDIRECT = 'EBADREDIRECT';
9
+ export const EUNSUPPORTEDPROTOCOL = 'EUNSUPPORTEDPROTOCOL';
10
+ // Fetch pipeline
11
+ export const FETCH_ERROR = 'FETCH_ERROR';
12
+ export const ABORTED = 'ABORTED';
13
+ export const QUEUE_FULL = 'queue_full';
14
+ // Validation
15
+ export const VALIDATION_ERROR = 'VALIDATION_ERROR';
@@ -0,0 +1,13 @@
1
+ import { CodedError } from './utils.js';
2
+ export declare function blockedIpError(target: string, reason: 'cloud-metadata' | 'private'): CodedError;
3
+ export declare function blockedHostError(hostname: string): CodedError;
4
+ export declare function blockedCnameError(hostname: string, cname: string): CodedError;
5
+ export declare function dnsTimeoutError(hostname: string): CodedError;
6
+ export declare function dnsNoResultsError(hostname: string): CodedError;
7
+ export declare function invalidAddressFamilyError(hostname: string): CodedError;
8
+ export declare function invalidHostnameError(): CodedError;
9
+ export declare function invalidUrlError(): CodedError;
10
+ export declare function invalidRedirectError(): CodedError;
11
+ export declare function redirectCredentialsError(): CodedError;
12
+ export declare function unsupportedProtocolError(protocol: string): CodedError;
13
+ //# sourceMappingURL=error-messages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-messages.d.ts","sourceRoot":"","sources":["../../src/lib/error-messages.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAIxC,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,gBAAgB,GAAG,SAAS,GACnC,UAAU,CAUZ;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAM7D;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,UAAU,CAM7E;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAM5D;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAM9D;AAED,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAMtE;AAED,wBAAgB,oBAAoB,IAAI,UAAU,CAGjD;AAED,wBAAgB,eAAe,IAAI,UAAU,CAG5C;AAID,wBAAgB,oBAAoB,IAAI,UAAU,CAGjD;AAED,wBAAgB,wBAAwB,IAAI,UAAU,CAMrD;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAMrE"}
@@ -0,0 +1,51 @@
1
+ import { EBADREDIRECT, EBLOCKED, EINVAL, ENODATA, ETIMEOUT, EUNSUPPORTEDPROTOCOL, } from './error-codes.js';
2
+ import { CodedError } from './utils.js';
3
+ // ── DNS / Network ──────────────────────────────────────────────────
4
+ export function blockedIpError(target, reason) {
5
+ const detail = reason === 'cloud-metadata'
6
+ ? 'Cloud metadata endpoints are not allowed'
7
+ : 'Private IPs are not allowed';
8
+ const error = new CodedError(`Blocked IP range: ${target}. ${detail}`, EBLOCKED);
9
+ return error;
10
+ }
11
+ export function blockedHostError(hostname) {
12
+ const error = new CodedError(`Blocked host: ${hostname}. Internal hosts are not allowed`, EBLOCKED);
13
+ return error;
14
+ }
15
+ export function blockedCnameError(hostname, cname) {
16
+ const error = new CodedError(`Blocked DNS CNAME detected for ${hostname}: ${cname}`, EBLOCKED);
17
+ return error;
18
+ }
19
+ export function dnsTimeoutError(hostname) {
20
+ const error = new CodedError(`DNS lookup timed out for ${hostname}`, ETIMEOUT);
21
+ return error;
22
+ }
23
+ export function dnsNoResultsError(hostname) {
24
+ const error = new CodedError(`No DNS results returned for ${hostname}`, ENODATA);
25
+ return error;
26
+ }
27
+ export function invalidAddressFamilyError(hostname) {
28
+ const error = new CodedError(`Invalid address family returned for ${hostname}`, EINVAL);
29
+ return error;
30
+ }
31
+ export function invalidHostnameError() {
32
+ const error = new CodedError('Invalid hostname provided', EINVAL);
33
+ return error;
34
+ }
35
+ export function invalidUrlError() {
36
+ const error = new CodedError('Invalid URL', EINVAL);
37
+ return error;
38
+ }
39
+ // ── HTTP Redirect ──────────────────────────────────────────────────
40
+ export function invalidRedirectError() {
41
+ const error = new CodedError('Invalid redirect target', EBADREDIRECT);
42
+ return error;
43
+ }
44
+ export function redirectCredentialsError() {
45
+ const error = new CodedError('Redirect target includes credentials', EBADREDIRECT);
46
+ return error;
47
+ }
48
+ export function unsupportedProtocolError(protocol) {
49
+ const error = new CodedError(`Unsupported redirect protocol: ${protocol}`, EUNSUPPORTEDPROTOCOL);
50
+ return error;
51
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-pipeline.d.ts","sourceRoot":"","sources":["../../src/lib/fetch-pipeline.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAOrE,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,EAAE,UAAU,EAAE,CAAC;AAGtB,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AACD,UAAU,mBAAmB;IAC3B,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAmGD,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAClC,MAAM,GAAG,SAAS,CAQpB;AAyBD,UAAU,oBAAoB,CAAC,CAAC;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC5C,SAAS,EAAE,CAAC,KAAK,EAAE,mBAAmB,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACxE;AACD,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,IAAI,EAAE,CAAC,CAAC;IACR,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AACD,MAAM,MAAM,gBAAgB,GACxB,aAAa,GACb,cAAc,GACd,gBAAgB,GAChB,iBAAiB,GACjB,gBAAgB,GAChB,iBAAiB,CAAC;AAmBtB,wBAAsB,oBAAoB,CAAC,CAAC,EAC1C,OAAO,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAC/B,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAiD5B;AAED,MAAM,MAAM,sBAAsB,GAAG,uBAAuB,GAAG;IAC7D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;AAwBF,eAAO,MAAM,iBAAiB,GAC5B,OAAO,mBAAmB,EAC1B,KAAK,MAAM,EACX,SAAS,WAAW,KACnB,OAAO,CAAC,sBAAsB,CAchC,CAAC;AAEF,UAAU,oBAAoB;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACrD,QAAQ,CAAC,SAAS,EAAE,CAClB,KAAK,EAAE,mBAAmB,EAC1B,aAAa,EAAE,MAAM,KAClB,sBAAsB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;CAC/D;AACD,UAAU,eAAe;IACvB,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,oBAAoB,CAAC;CAC7D;AAMD,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,oBAAoB,EAC7B,IAAI,GAAE,eAAoB,GACzB,OAAO,CAAC;IACT,QAAQ,EAAE,cAAc,CAAC,sBAAsB,CAAC,CAAC;IACjD,YAAY,EAAE,mBAAmB,CAAC;CACnC,CAAC,CAyBD"}
1
+ {"version":3,"file":"fetch-pipeline.d.ts","sourceRoot":"","sources":["../../src/lib/fetch-pipeline.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAQrE,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,EAAE,UAAU,EAAE,CAAC;AAGtB,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AACD,UAAU,mBAAmB;IAC3B,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAmGD,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAClC,MAAM,GAAG,SAAS,CAQpB;AAyBD,UAAU,oBAAoB,CAAC,CAAC;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC5C,SAAS,EAAE,CAAC,KAAK,EAAE,mBAAmB,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACxE;AACD,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,IAAI,EAAE,CAAC,CAAC;IACR,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AACD,MAAM,MAAM,gBAAgB,GACxB,aAAa,GACb,cAAc,GACd,gBAAgB,GAChB,iBAAiB,GACjB,gBAAgB,GAChB,iBAAiB,CAAC;AAmBtB,wBAAsB,oBAAoB,CAAC,CAAC,EAC1C,OAAO,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAC/B,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAiD5B;AAED,MAAM,MAAM,sBAAsB,GAAG,uBAAuB,GAAG;IAC7D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;AAwBF,eAAO,MAAM,iBAAiB,GAC5B,OAAO,mBAAmB,EAC1B,KAAK,MAAM,EACX,SAAS,WAAW,KACnB,OAAO,CAAC,sBAAsB,CAchC,CAAC;AAEF,UAAU,oBAAoB;IAC5B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACrD,QAAQ,CAAC,SAAS,EAAE,CAClB,KAAK,EAAE,mBAAmB,EAC1B,aAAa,EAAE,MAAM,KAClB,sBAAsB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;CAC/D;AACD,UAAU,eAAe;IACvB,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,oBAAoB,CAAC;CAC7D;AAMD,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,oBAAoB,EAC7B,IAAI,GAAE,eAAoB,GACzB,OAAO,CAAC;IACT,QAAQ,EAAE,cAAc,CAAC,sBAAsB,CAAC,CAAC;IACjD,YAAY,EAAE,mBAAmB,CAAC;CACnC,CAAC,CAyBD"}
@@ -2,6 +2,7 @@ import { transformBufferToMarkdown } from '../transform/transform.js';
2
2
  import {} from '../transform/types.js';
3
3
  import { config, logDebug } from './core.js';
4
4
  import { fetchNormalizedUrlBuffer, normalizeUrl, transformToRawUrl, } from './http.js';
5
+ import { LOG_FETCH } from './logger-names.js';
5
6
  import { withSignal } from './utils.js';
6
7
  export { withSignal };
7
8
  const TRUNCATION_MARKER = '...[truncated]';
@@ -116,16 +117,16 @@ export async function executeFetchPipeline(options) {
116
117
  if (resolvedUrl.transformed) {
117
118
  logDebug('Using transformed raw content URL', {
118
119
  original: resolvedUrl.originalUrl,
119
- }, 'fetch');
120
+ }, LOG_FETCH);
120
121
  }
121
122
  options.onStage?.('fetch_remote');
122
- logDebug('Fetching URL', { url: resolvedUrl.normalizedUrl }, 'fetch');
123
+ logDebug('Fetching URL', { url: resolvedUrl.normalizedUrl }, LOG_FETCH);
123
124
  const { buffer, encoding, truncated, finalUrl } = await fetchNormalizedUrlBuffer(resolvedUrl.normalizedUrl, withSignal(options.signal));
124
125
  if (finalUrl && finalUrl !== resolvedUrl.normalizedUrl) {
125
126
  logDebug('Fetch redirected', {
126
127
  fromUrl: resolvedUrl.normalizedUrl,
127
128
  toUrl: finalUrl,
128
- }, 'fetch');
129
+ }, LOG_FETCH);
129
130
  }
130
131
  options.onStage?.('response_ready');
131
132
  options.onStage?.('transform_start');
@@ -177,7 +178,7 @@ export async function performSharedFetch(options, deps = {}) {
177
178
  url: pipeline.finalUrl ?? pipeline.url,
178
179
  contentSize: inlineResult.contentSize,
179
180
  maxInlineChars: config.constants.maxInlineContentChars,
180
- }, 'fetch');
181
+ }, LOG_FETCH);
181
182
  }
182
183
  return { pipeline, inlineResult };
183
184
  }
@@ -1 +1 @@
1
- {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/lib/http.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,KAAK,EAAmB,MAAM,QAAQ,CAAC;AAYhD,OAAO,EAOL,KAAK,eAAe,EAGrB,MAAM,UAAU,CAAC;AA+vClB,UAAU,qBAAqB;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAoKD,UAAU,YAAY;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AA6ND,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAE/C;AACD,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG;IAC/C,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAEA;AACD,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEjE;AACD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAE9D;AACD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAExD;AACD,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,GACb,qBAAqB,CAEvB;AACD,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,qBAAqB,EAC9B,QAAQ,EAAE,QAAQ,EAClB,WAAW,CAAC,EAAE,MAAM,GACnB,IAAI,CAEN;AACD,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,qBAAqB,EAC9B,KAAK,EAAE,OAAO,EACd,MAAM,CAAC,EAAE,MAAM,GACd,IAAI,CAEN;AACD,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,WAAW,EACjB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC,CAE7D;AACD,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CASzC;AACD,wBAAsB,kBAAkB,CACtC,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,MAAM,CAAC,CAEjB;AACD,wBAAsB,wBAAwB,CAC5C,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC;IACT,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,CAED"}
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/lib/http.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,KAAK,EAAmB,MAAM,QAAQ,CAAC;AAyBhD,OAAO,EAOL,KAAK,eAAe,EAErB,MAAM,UAAU,CAAC;AAkxClB,UAAU,qBAAqB;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAoKD,UAAU,YAAY;IACpB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AA6ND,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAE/C;AACD,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG;IAC/C,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAEA;AACD,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEjE;AACD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAE9D;AACD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAExD;AACD,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,GACb,qBAAqB,CAEvB;AACD,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,qBAAqB,EAC9B,QAAQ,EAAE,QAAQ,EAClB,WAAW,CAAC,EAAE,MAAM,GACnB,IAAI,CAEN;AACD,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,qBAAqB,EAC9B,KAAK,EAAE,OAAO,EACd,MAAM,CAAC,EAAE,MAAM,GACd,IAAI,CAEN;AACD,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,WAAW,EACjB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC,CAE7D;AACD,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CASzC;AACD,wBAAsB,kBAAkB,CACtC,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,MAAM,CAAC,CAEjB;AACD,wBAAsB,wBAAwB,CAC5C,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC;IACT,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,CAED"}
package/dist/lib/http.js CHANGED
@@ -8,9 +8,12 @@ import tls from 'node:tls';
8
8
  import { createBrotliDecompress, createGunzip, createInflate } from 'node:zlib';
9
9
  import { Agent } from 'undici';
10
10
  import { config, getOperationId, getRequestId, logDebug, logError, logWarn, redactUrl, } from './core.js';
11
+ import { EBADREDIRECT, EBLOCKED, EINVAL, ENODATA, VALIDATION_ERROR, } from './error-codes.js';
12
+ import { invalidRedirectError, redirectCredentialsError, unsupportedProtocolError, } from './error-messages.js';
13
+ import { LOG_FETCH } from './logger-names.js';
11
14
  import { isIP } from './url.js';
12
- import { BLOCKED_HOST_SUFFIXES, createDnsPreflight, IpBlocker, RawUrlTransformer, SafeDnsResolver, UrlNormalizer, VALIDATION_ERROR_CODE, } from './url.js';
13
- import { composeAbortSignal, createErrorWithCode, FetchError, isAbortError, isError, isObject, isSystemError, toError, } from './utils.js';
15
+ import { BLOCKED_HOST_SUFFIXES, createDnsPreflight, IpBlocker, RawUrlTransformer, SafeDnsResolver, UrlNormalizer, } from './url.js';
16
+ import { composeAbortSignal, FetchError, isAbortError, isError, isObject, isSystemError, toError, } from './utils.js';
14
17
  // ═══════════════════════════════════════════════════════════════════
15
18
  // ENCODING DETECTION
16
19
  // ═══════════════════════════════════════════════════════════════════
@@ -234,7 +237,10 @@ function isBinaryContent(buffer, encoding) {
234
237
  return hasNullByte(buffer, BINARY_SCAN_LIMIT);
235
238
  }
236
239
  function createBinaryContentError(url) {
237
- return new FetchError('Detailed content type check failed: binary content detected', url, 500, { reason: 'binary_content_detected' });
240
+ const error = new FetchError('Binary content detected', url, 500, {
241
+ reason: 'binary_content_detected',
242
+ });
243
+ return error;
238
244
  }
239
245
  // ═══════════════════════════════════════════════════════════════════
240
246
  // FETCH ERRORS
@@ -257,28 +263,50 @@ function parseRetryAfter(header) {
257
263
  }
258
264
  function createFetchError(input, url) {
259
265
  switch (input.kind) {
260
- case 'canceled':
261
- return new FetchError('Request was canceled', url, 499, {
266
+ case 'canceled': {
267
+ const error = new FetchError('Request canceled', url, 499, {
268
+ reason: 'aborted',
269
+ });
270
+ return error;
271
+ }
272
+ case 'aborted': {
273
+ const error = new FetchError('Request aborted during response read', url, 499, {
262
274
  reason: 'aborted',
263
275
  });
264
- case 'aborted':
265
- return new FetchError('Request was aborted during response read', url, 499, { reason: 'aborted' });
266
- case 'timeout':
267
- return new FetchError(`Request timeout after ${input.timeout}ms`, url, 504, { timeout: input.timeout });
268
- case 'rate-limited':
269
- return new FetchError('Too many requests', url, 429, {
276
+ return error;
277
+ }
278
+ case 'timeout': {
279
+ const error = new FetchError(`Request timed out after ${input.timeout}ms`, url, 504, { timeout: input.timeout });
280
+ return error;
281
+ }
282
+ case 'rate-limited': {
283
+ const error = new FetchError('Too many requests', url, 429, {
270
284
  retryAfter: parseRetryAfter(input.retryAfter),
271
285
  });
272
- case 'http':
273
- return new FetchError(`HTTP ${input.status}: ${input.statusText}`, url, input.status);
274
- case 'too-many-redirects':
275
- return new FetchError('Too many redirects', url);
276
- case 'missing-redirect-location':
277
- return new FetchError('Redirect response missing Location header', url);
278
- case 'network':
279
- return new FetchError(`Network error: Could not reach ${url}`, url, undefined, { message: input.message });
280
- case 'unknown':
281
- return new FetchError(input.message ?? 'Unexpected error', url);
286
+ return error;
287
+ }
288
+ case 'http': {
289
+ const error = new FetchError(`HTTP ${input.status}: ${input.statusText}`, url, input.status);
290
+ return error;
291
+ }
292
+ case 'too-many-redirects': {
293
+ const error = new FetchError('Too many redirects', url);
294
+ return error;
295
+ }
296
+ case 'missing-redirect-location': {
297
+ const error = new FetchError('Redirect missing Location header', url);
298
+ return error;
299
+ }
300
+ case 'network': {
301
+ const error = new FetchError('Network error', url, undefined, {
302
+ message: input.message,
303
+ });
304
+ return error;
305
+ }
306
+ case 'unknown': {
307
+ const error = new FetchError(input.message ?? 'Unexpected error', url);
308
+ return error;
309
+ }
282
310
  default: {
283
311
  const _exhaustive = input;
284
312
  return _exhaustive;
@@ -297,11 +325,11 @@ function resolveErrorUrl(error, fallback) {
297
325
  return typeof requestUrl === 'string' ? requestUrl : fallback;
298
326
  }
299
327
  const CLIENT_ERROR_CODES = new Set([
300
- VALIDATION_ERROR_CODE,
301
- 'EBADREDIRECT',
302
- 'EBLOCKED',
303
- 'ENODATA',
304
- 'EINVAL',
328
+ VALIDATION_ERROR,
329
+ EBADREDIRECT,
330
+ EBLOCKED,
331
+ ENODATA,
332
+ EINVAL,
305
333
  ]);
306
334
  function mapAbortError(error, timeoutMs, url) {
307
335
  return isTimeoutError(error)
@@ -311,10 +339,12 @@ function mapAbortError(error, timeoutMs, url) {
311
339
  function mapSystemError(error, url) {
312
340
  const { code, message } = error;
313
341
  if (code === 'ETIMEOUT') {
314
- return new FetchError(message, url, 504, { code });
342
+ const fetchError = new FetchError(message, url, 504, { code });
343
+ return fetchError;
315
344
  }
316
345
  if (code && CLIENT_ERROR_CODES.has(code)) {
317
- return new FetchError(message, url, 400, { code });
346
+ const fetchError = new FetchError(message, url, 400, { code });
347
+ return fetchError;
318
348
  }
319
349
  return createFetchError({ kind: 'network', message }, url);
320
350
  }
@@ -354,7 +384,7 @@ class MaxBytesError extends Error {
354
384
  }
355
385
  function createPinnedAgent(ipAddress) {
356
386
  const ca = tls.rootCertificates.length > 0 ? tls.rootCertificates : undefined;
357
- return new Agent({
387
+ const agent = new Agent({
358
388
  connect: {
359
389
  lookup: (hostname, options, callback) => {
360
390
  const family = isIP(ipAddress) === 6 ? 6 : 4;
@@ -373,6 +403,7 @@ function createPinnedAgent(ipAddress) {
373
403
  keepAliveTimeout: 1000,
374
404
  keepAliveMaxTimeout: 1000,
375
405
  });
406
+ return agent;
376
407
  }
377
408
  class RedirectFollower {
378
409
  fetchFn;
@@ -457,10 +488,10 @@ class RedirectFollower {
457
488
  resolveRedirectTarget(baseUrl, location) {
458
489
  const resolved = URL.parse(location, baseUrl);
459
490
  if (!resolved) {
460
- throw createErrorWithCode('Invalid redirect target', 'EBADREDIRECT');
491
+ throw invalidRedirectError();
461
492
  }
462
493
  if (resolved.username || resolved.password) {
463
- throw createErrorWithCode('Redirect target includes credentials', 'EBADREDIRECT');
494
+ throw redirectCredentialsError();
464
495
  }
465
496
  return this.normalizeUrl(resolved.href);
466
497
  }
@@ -472,7 +503,7 @@ class RedirectFollower {
472
503
  assertHttpProtocol(url) {
473
504
  const parsed = new URL(url);
474
505
  if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
475
- throw createErrorWithCode(`Unsupported redirect protocol: ${parsed.protocol}`, 'EUNSUPPORTEDPROTOCOL');
506
+ throw unsupportedProtocolError(parsed.protocol);
476
507
  }
477
508
  }
478
509
  async withRedirectErrorContext(url, fn) {
@@ -536,11 +567,12 @@ function assertSupportedContentType(contentType, url) {
536
567
  if (!mediaType) {
537
568
  logDebug('No Content-Type header; relying on binary-content detection', {
538
569
  url: redactUrl(url),
539
- }, 'fetch');
570
+ }, LOG_FETCH);
540
571
  return;
541
572
  }
542
573
  if (!isTextLikeMediaType(mediaType)) {
543
- throw new FetchError(`Unsupported content type: ${mediaType}`, url);
574
+ const error = new FetchError(`Unsupported content type: ${mediaType}`, url);
575
+ throw error;
544
576
  }
545
577
  }
546
578
  function extractEncodingTokens(value) {
@@ -561,10 +593,11 @@ function isSupportedContentEncoding(encoding) {
561
593
  return encoding === 'gzip' || encoding === 'deflate' || encoding === 'br';
562
594
  }
563
595
  function createUnsupportedContentEncodingError(url, encodingHeader) {
564
- return new FetchError(`Unsupported Content-Encoding: ${encodingHeader}`, url, 415, {
596
+ const error = new FetchError(`Unsupported Content-Encoding: ${encodingHeader}`, url, 415, {
565
597
  reason: 'unsupported_content_encoding',
566
598
  encoding: encodingHeader,
567
599
  });
600
+ return error;
568
601
  }
569
602
  function createDecompressor(encoding) {
570
603
  const options = { chunkSize: 64 * 1024 };
@@ -578,7 +611,7 @@ function createDecompressor(encoding) {
578
611
  }
579
612
  }
580
613
  function createPumpedStream(initialChunk, reader) {
581
- return new ReadableStream({
614
+ const stream = new ReadableStream({
582
615
  start(controller) {
583
616
  if (initialChunk && initialChunk.byteLength > 0) {
584
617
  controller.enqueue(initialChunk);
@@ -602,6 +635,7 @@ function createPumpedStream(initialChunk, reader) {
602
635
  void reader.cancel(reason).catch(() => undefined);
603
636
  },
604
637
  });
638
+ return stream;
605
639
  }
606
640
  function buildDecodePipeline(body, encodings, url, response, signal) {
607
641
  const decodeOrder = encodings.slice().reverse();
@@ -656,11 +690,12 @@ async function primeDecodedResponse(pipe, response, url, signal) {
656
690
  const first = await pipe.decodedReader.read();
657
691
  if (first.done) {
658
692
  clearAbortListener();
659
- return new Response(null, {
693
+ const result = new Response(null, {
660
694
  status: response.status,
661
695
  statusText: response.statusText,
662
696
  headers: pipe.headers,
663
697
  });
698
+ return result;
664
699
  }
665
700
  const body = createPumpedStream(first.value, pipe.decodedReader);
666
701
  if (signal) {
@@ -670,17 +705,19 @@ async function primeDecodedResponse(pipe, response, url, signal) {
670
705
  clearAbortListener();
671
706
  });
672
707
  }
673
- return new Response(body, {
708
+ const result = new Response(body, {
674
709
  status: response.status,
675
710
  statusText: response.statusText,
676
711
  headers: pipe.headers,
677
712
  });
713
+ return result;
678
714
  }
679
715
  catch (error) {
680
716
  clearAbortListener();
681
717
  pipe.cleanup();
682
718
  void pipe.decodedReader.cancel(error).catch(() => undefined);
683
- throw new FetchError(`Content-Encoding decode failed for ${redactUrl(url)}: ${isError(error) ? error.message : String(error)}`, url);
719
+ const fetchError = new FetchError(`Content-Encoding decode failed for ${redactUrl(url)}: ${isError(error) ? error.message : String(error)}`, url);
720
+ throw fetchError;
684
721
  }
685
722
  }
686
723
  async function decodeResponseIfNeeded(response, url, signal) {
@@ -780,7 +817,8 @@ class ResponseTextReader {
780
817
  total += remaining;
781
818
  yield slice;
782
819
  }
783
- throw new MaxBytesError();
820
+ const error = new MaxBytesError();
821
+ throw error;
784
822
  }
785
823
  total = newTotal;
786
824
  yield buf;
@@ -860,10 +898,11 @@ function isReadableStreamLike(value) {
860
898
  function assertReadableStreamLike(stream, url, stage) {
861
899
  if (isReadableStreamLike(stream))
862
900
  return;
863
- throw new FetchError('Invalid response stream', url, 500, {
901
+ const error = new FetchError('Invalid response stream', url, 500, {
864
902
  reason: 'invalid_stream',
865
903
  stage,
866
904
  });
905
+ throw error;
867
906
  }
868
907
  function toNodeReadableStream(stream, url, stage) {
869
908
  assertReadableStreamLike(stream, url, stage);
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Logger names for different components of the application.
3
+ */
4
+ export declare const LOG_AUTH = "auth";
5
+ export declare const LOG_HTTP = "http";
6
+ export declare const LOG_SESSION = "session";
7
+ export declare const LOG_SERVER = "server";
8
+ export declare const LOG_FETCH = "fetch";
9
+ export declare const LOG_TRANSFORM = "transform";
10
+ export declare const LOG_TASKS = "tasks";
11
+ export declare const LOG_RATE_LIMIT = "rate-limit";
12
+ export declare const LOG_MCP = "mcp";
13
+ export declare const LOG_FETCH_URL = "fetch-url";
14
+ //# sourceMappingURL=logger-names.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger-names.d.ts","sourceRoot":"","sources":["../../src/lib/logger-names.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,QAAQ,SAAS,CAAC;AAC/B,eAAO,MAAM,QAAQ,SAAS,CAAC;AAC/B,eAAO,MAAM,WAAW,YAAY,CAAC;AACrC,eAAO,MAAM,UAAU,WAAW,CAAC;AACnC,eAAO,MAAM,SAAS,UAAU,CAAC;AACjC,eAAO,MAAM,aAAa,cAAc,CAAC;AACzC,eAAO,MAAM,SAAS,UAAU,CAAC;AACjC,eAAO,MAAM,cAAc,eAAe,CAAC;AAC3C,eAAO,MAAM,OAAO,QAAQ,CAAC;AAC7B,eAAO,MAAM,aAAa,cAAc,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Logger names for different components of the application.
3
+ */
4
+ export const LOG_AUTH = 'auth';
5
+ export const LOG_HTTP = 'http';
6
+ export const LOG_SESSION = 'session';
7
+ export const LOG_SERVER = 'server';
8
+ export const LOG_FETCH = 'fetch';
9
+ export const LOG_TRANSFORM = 'transform';
10
+ export const LOG_TASKS = 'tasks';
11
+ export const LOG_RATE_LIMIT = 'rate-limit';
12
+ export const LOG_MCP = 'mcp';
13
+ export const LOG_FETCH_URL = 'fetch-url';
@@ -1,5 +1,5 @@
1
1
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
- import { type CallToolResult, McpError } from '@modelcontextprotocol/sdk/types.js';
2
+ import { McpError } from '@modelcontextprotocol/sdk/types.js';
3
3
  import { z } from 'zod';
4
4
  export declare function createMcpError(code: number, message: string, data?: unknown): McpError;
5
5
  export type JsonRpcId = string | number | null;
@@ -53,16 +53,6 @@ export declare function isJsonRpcResponseBody(body: unknown): body is JsonRpcRes
53
53
  export declare function isMcpMessageBody(body: unknown): body is JsonRpcMessageBody;
54
54
  export declare function acceptsEventStream(header: string | null | undefined): boolean;
55
55
  export declare function acceptsJsonAndEventStream(header: string | null | undefined): boolean;
56
- type ToolErrorResponse = CallToolResult & {
57
- isError: true;
58
- };
59
- export declare function createToolErrorResponse(message: string, url: string, extra?: {
60
- code?: string | number;
61
- statusCode?: number;
62
- details?: Record<string, unknown>;
63
- data?: unknown;
64
- }): ToolErrorResponse;
65
- export declare function handleToolError(error: unknown, url: string, fallbackMessage?: string): ToolErrorResponse;
66
56
  type CleanupCallback = () => void;
67
57
  type RequestHandlerFn = (request: unknown, extra?: unknown) => Promise<unknown>;
68
58
  interface ToolPresentation {