@atproto-labs/fetch 0.0.1 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,17 +1,32 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.fetchJsonZodProcessor = exports.fetchJsonProcessor = exports.jsonTranformer = exports.fetchTypeProcessor = exports.fetchResponseMaxSize = exports.fetchMaxSizeProcessor = exports.fetchOkProcessor = exports.FetchResponseError = void 0;
4
- const transformer_1 = require("@atproto-labs/transformer");
3
+ exports.fetchJsonZodProcessor = exports.fetchJsonProcessor = exports.fetchResponseJsonTranformer = exports.fetchResponseTypeChecker = exports.fetchTypeProcessor = exports.fetchResponseMaxSizeChecker = exports.fetchMaxSizeProcessor = exports.fetchOkTransformer = exports.fetchOkProcessor = exports.cancelBodyOnError = exports.extractMime = exports.extractLength = exports.checkLength = exports.peekJson = exports.FetchResponseError = void 0;
4
+ const pipe_1 = require("@atproto-labs/pipe");
5
5
  const fetch_error_js_1 = require("./fetch-error.js");
6
- const util_js_1 = require("./util.js");
7
6
  const transformed_response_js_1 = require("./transformed-response.js");
7
+ const util_js_1 = require("./util.js");
8
+ class FetchResponseError extends fetch_error_js_1.FetchError {
9
+ constructor(response, statusCode = response.status, message = response.statusText, options) {
10
+ super(statusCode, message, options);
11
+ Object.defineProperty(this, "response", {
12
+ enumerable: true,
13
+ configurable: true,
14
+ writable: true,
15
+ value: response
16
+ });
17
+ }
18
+ static async from(response, customMessage = extractResponseMessage, statusCode = response.status, options) {
19
+ const message = typeof customMessage === 'string'
20
+ ? customMessage
21
+ : typeof customMessage === 'function'
22
+ ? await customMessage(response)
23
+ : undefined;
24
+ return new FetchResponseError(response, statusCode, message, options);
25
+ }
26
+ }
27
+ exports.FetchResponseError = FetchResponseError;
8
28
  const extractResponseMessage = async (response) => {
9
- if (!response.body)
10
- return undefined;
11
- const contentType = response.headers.get('content-type');
12
- if (!contentType)
13
- return undefined;
14
- const mimeType = contentType.split(';')[0].trim();
29
+ const mimeType = extractMime(response);
15
30
  if (!mimeType)
16
31
  return undefined;
17
32
  try {
@@ -38,99 +53,137 @@ const extractResponseMessage = async (response) => {
38
53
  }
39
54
  return undefined;
40
55
  };
41
- class FetchResponseError extends fetch_error_js_1.FetchError {
42
- constructor(response, statusCode = response.status, message = response.statusText, options) {
43
- super(statusCode, message, { response, ...options });
56
+ async function peekJson(response, maxSize = Infinity) {
57
+ const type = extractMime(response);
58
+ if (type !== 'application/json')
59
+ return undefined;
60
+ checkLength(response, maxSize);
61
+ // 1) Clone the request so we can consume the body
62
+ const clonedResponse = response.clone();
63
+ // 2) Make sure the request's body is not too large
64
+ const limitedResponse = response.body && maxSize < Infinity
65
+ ? new transformed_response_js_1.TransformedResponse(clonedResponse, new util_js_1.MaxBytesTransformStream(maxSize))
66
+ : // Note: some runtimes (e.g. react-native) don't expose a body property
67
+ clonedResponse;
68
+ // 3) Parse the JSON
69
+ return limitedResponse.json();
70
+ }
71
+ exports.peekJson = peekJson;
72
+ function checkLength(response, maxBytes) {
73
+ // Note: negation accounts for invalid value types (NaN, non numbers)
74
+ if (!(maxBytes >= 0)) {
75
+ throw new TypeError('maxBytes must be a non-negative number');
44
76
  }
45
- static async from(response, statusCode = response.status, customMessage = extractResponseMessage, options) {
46
- const message = typeof customMessage === 'string'
47
- ? customMessage
48
- : typeof customMessage === 'function'
49
- ? await customMessage(response)
50
- : undefined;
51
- // Make sure the body gets consumed as, in some environments (Node 👀), the
52
- // response will not automatically be GC'd.
53
- if (!response.bodyUsed)
54
- await response.body?.cancel();
55
- return new FetchResponseError(response, statusCode, message, options);
77
+ const length = extractLength(response);
78
+ if (length != null && length > maxBytes) {
79
+ throw new FetchResponseError(response, 502, 'Response too large');
56
80
  }
81
+ return length;
57
82
  }
58
- exports.FetchResponseError = FetchResponseError;
59
- function fetchOkProcessor(customMessage) {
83
+ exports.checkLength = checkLength;
84
+ function extractLength(response) {
85
+ const contentLength = response.headers.get('Content-Length');
86
+ if (contentLength == null)
87
+ return undefined;
88
+ if (!/^\d+$/.test(contentLength)) {
89
+ throw new FetchResponseError(response, 502, 'Invalid Content-Length');
90
+ }
91
+ const length = Number(contentLength);
92
+ if (!Number.isSafeInteger(length)) {
93
+ throw new FetchResponseError(response, 502, 'Content-Length too large');
94
+ }
95
+ return length;
96
+ }
97
+ exports.extractLength = extractLength;
98
+ function extractMime(response) {
99
+ const contentType = response.headers.get('Content-Type');
100
+ if (contentType == null)
101
+ return undefined;
102
+ return contentType.split(';', 1)[0].trim();
103
+ }
104
+ exports.extractMime = extractMime;
105
+ /**
106
+ * If the transformer results in an error, ensure that the response body is
107
+ * consumed as, in some environments (Node 👀), the response will not
108
+ * automatically be GC'd.
109
+ *
110
+ * @see {@link https://undici.nodejs.org/#/?id=garbage-collection}
111
+ * @param [onCancellationError] - Callback to handle any async body cancelling
112
+ * error. Defaults to logging the error. Do not use `null` if the request is
113
+ * cloned.
114
+ */
115
+ function cancelBodyOnError(transformer, onCancellationError = util_js_1.logCancellationError) {
60
116
  return async (response) => {
61
- if (response.ok)
62
- return response;
63
- throw await FetchResponseError.from(response, undefined, customMessage);
117
+ try {
118
+ return await transformer(response);
119
+ }
120
+ catch (err) {
121
+ await (0, util_js_1.cancelBody)(response, onCancellationError ?? undefined);
122
+ throw err;
123
+ }
64
124
  };
65
125
  }
126
+ exports.cancelBodyOnError = cancelBodyOnError;
127
+ function fetchOkProcessor(customMessage) {
128
+ return cancelBodyOnError((response) => {
129
+ return fetchOkTransformer(response, customMessage);
130
+ });
131
+ }
66
132
  exports.fetchOkProcessor = fetchOkProcessor;
133
+ async function fetchOkTransformer(response, customMessage) {
134
+ if (response.ok)
135
+ return response;
136
+ throw await FetchResponseError.from(response, customMessage);
137
+ }
138
+ exports.fetchOkTransformer = fetchOkTransformer;
67
139
  function fetchMaxSizeProcessor(maxBytes) {
68
140
  if (maxBytes === Infinity)
69
141
  return (response) => response;
70
142
  if (!Number.isFinite(maxBytes) || maxBytes < 0) {
71
- throw new TypeError('maxBytes must be a non-negative number');
143
+ throw new TypeError('maxBytes must be a 0, Infinity or a positive number');
72
144
  }
73
- return async (response) => fetchResponseMaxSize(response, maxBytes);
145
+ return cancelBodyOnError((response) => {
146
+ return fetchResponseMaxSizeChecker(response, maxBytes);
147
+ });
74
148
  }
75
149
  exports.fetchMaxSizeProcessor = fetchMaxSizeProcessor;
76
- async function fetchResponseMaxSize(response, maxBytes) {
150
+ function fetchResponseMaxSizeChecker(response, maxBytes) {
77
151
  if (maxBytes === Infinity)
78
152
  return response;
153
+ checkLength(response, maxBytes);
154
+ // Some engines (react-native 👀) don't expose a body property. In that case,
155
+ // we will only rely on the Content-Length header.
79
156
  if (!response.body)
80
157
  return response;
81
- const contentLength = response.headers.get('content-length');
82
- if (contentLength) {
83
- const length = Number(contentLength);
84
- if (!(length < maxBytes)) {
85
- const err = new FetchResponseError(response, 502, 'Response too large');
86
- await response.body.cancel(err);
87
- throw err;
88
- }
89
- }
90
- let bytesRead = 0;
91
- const transform = new TransformStream({
92
- transform: (chunk, ctrl) => {
93
- if ((bytesRead += chunk.length) <= maxBytes) {
94
- ctrl.enqueue(chunk);
95
- }
96
- else {
97
- ctrl.error(new FetchResponseError(response, 502, 'Response too large'));
98
- }
99
- },
100
- });
158
+ const transform = new util_js_1.MaxBytesTransformStream(maxBytes);
101
159
  return new transformed_response_js_1.TransformedResponse(response, transform);
102
160
  }
103
- exports.fetchResponseMaxSize = fetchResponseMaxSize;
104
- function fetchTypeProcessor(expectedType, contentTypeRequired = true) {
105
- const isExpected = typeof expectedType === 'string'
106
- ? (ct) => ct === expectedType
107
- : expectedType instanceof RegExp
108
- ? (ct) => expectedType.test(ct)
109
- : expectedType;
110
- return async (response) => {
111
- const contentType = response.headers
112
- .get('content-type')
113
- ?.split(';')[0]
114
- .trim();
115
- if (contentType) {
116
- if (!isExpected(contentType)) {
117
- throw await FetchResponseError.from(response, 502, `Unexpected response Content-Type (${contentType})`);
118
- }
119
- }
120
- else if (contentTypeRequired) {
121
- throw await FetchResponseError.from(response, 502, 'Missing response Content-Type header');
122
- }
123
- return response;
124
- };
161
+ exports.fetchResponseMaxSizeChecker = fetchResponseMaxSizeChecker;
162
+ function fetchTypeProcessor(expectedMime, contentTypeRequired = true) {
163
+ const isExpected = typeof expectedMime === 'string'
164
+ ? (mimeType) => mimeType === expectedMime
165
+ : expectedMime instanceof RegExp
166
+ ? (mimeType) => expectedMime.test(mimeType)
167
+ : expectedMime;
168
+ return cancelBodyOnError((response) => {
169
+ return fetchResponseTypeChecker(response, isExpected, contentTypeRequired);
170
+ });
125
171
  }
126
172
  exports.fetchTypeProcessor = fetchTypeProcessor;
127
- async function jsonTranformer(response) {
128
- if (response.body === null) {
129
- throw new FetchResponseError(response, 502, 'No response body');
173
+ async function fetchResponseTypeChecker(response, isExpectedMime, contentTypeRequired = true) {
174
+ const mimeType = extractMime(response);
175
+ if (mimeType) {
176
+ if (!isExpectedMime(mimeType)) {
177
+ throw await FetchResponseError.from(response, `Unexpected response Content-Type (${mimeType})`, 502);
178
+ }
130
179
  }
131
- if (response.bodyUsed) {
132
- throw new FetchResponseError(response, 500, 'Response body already used');
180
+ else if (contentTypeRequired) {
181
+ throw await FetchResponseError.from(response, 'Missing response Content-Type header', 502);
133
182
  }
183
+ return response;
184
+ }
185
+ exports.fetchResponseTypeChecker = fetchResponseTypeChecker;
186
+ async function fetchResponseJsonTranformer(response) {
134
187
  try {
135
188
  const json = (await response.json());
136
189
  return { response, json };
@@ -139,9 +192,9 @@ async function jsonTranformer(response) {
139
192
  throw new FetchResponseError(response, 502, 'Unable to parse response as JSON', { cause });
140
193
  }
141
194
  }
142
- exports.jsonTranformer = jsonTranformer;
143
- function fetchJsonProcessor(contentType = /^application\/(?:[^+]+\+)?json$/, contentTypeRequired = true) {
144
- return (0, transformer_1.compose)(fetchTypeProcessor(contentType, contentTypeRequired), (jsonTranformer));
195
+ exports.fetchResponseJsonTranformer = fetchResponseJsonTranformer;
196
+ function fetchJsonProcessor(expectedMime = /^application\/(?:[^+]+\+)?json$/, contentTypeRequired = true) {
197
+ return (0, pipe_1.pipe)(fetchTypeProcessor(expectedMime, contentTypeRequired), cancelBodyOnError((fetchResponseJsonTranformer)));
145
198
  }
146
199
  exports.fetchJsonProcessor = fetchJsonProcessor;
147
200
  function fetchJsonZodProcessor(schema, params) {
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-response.js","sourceRoot":"","sources":["../src/fetch-response.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fetch-response.js","sourceRoot":"","sources":["../src/fetch-response.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,48 @@
1
- import { Fetch } from './fetch.js';
2
- export declare const loggedFetchWrap: ({ fetch, }?: {
3
- fetch?: Fetch | undefined;
4
- }) => Fetch;
5
- export declare const timeoutFetchWrap: ({ fetch, timeout, }?: {
6
- fetch?: Fetch | undefined;
7
- timeout?: number | undefined;
8
- }) => Fetch;
9
- export declare function fetchTimeout(this: ThisParameterType<Fetch>, request: Request, timeout?: number, fetch?: Fetch): Promise<Response>;
1
+ import { Fetch, FetchContext } from './fetch.js';
2
+ type LogFn<Args extends unknown[]> = (...args: Args) => void | PromiseLike<void>;
3
+ export declare function loggedFetch<C = FetchContext>({ fetch, logRequest, logResponse, logError, }: {
4
+ fetch?: Fetch<C> | undefined;
5
+ logRequest?: boolean | LogFn<[request: Request]> | undefined;
6
+ logResponse?: boolean | LogFn<[response: Response, request: Request]> | undefined;
7
+ logError?: boolean | LogFn<[error: unknown, request: Request]> | undefined;
8
+ }): Fetch<C>;
9
+ export declare const timedFetch: <C = FetchContext>(timeout?: number, fetch?: Fetch<C>) => Fetch<C>;
10
+ /**
11
+ * Wraps a fetch function to bind it to a specific context, and wrap any thrown
12
+ * errors into a FetchRequestError.
13
+ *
14
+ * @example
15
+ *
16
+ * ```ts
17
+ * class MyClient {
18
+ * constructor(private fetch = globalThis.fetch) {}
19
+ *
20
+ * async get(url: string) {
21
+ * // This will generate an error, because the context used is not a
22
+ * // FetchContext (it's a MyClient instance).
23
+ * return this.fetch(url)
24
+ * }
25
+ * }
26
+ * ```
27
+ *
28
+ * @example
29
+ *
30
+ * ```ts
31
+ * class MyClient {
32
+ * private fetch: Fetch<unknown>
33
+ *
34
+ * constructor(fetch = globalThis.fetch) {
35
+ * this.fetch = bindFetch(fetch)
36
+ * }
37
+ *
38
+ * async get(url: string) {
39
+ * return this.fetch(url) // no more error
40
+ * }
41
+ * }
42
+ * ```
43
+ */
44
+ export declare function bindFetch<C = FetchContext>(fetch?: Fetch<C>, context?: C): ((this: unknown, input: string | Request | URL, init?: RequestInit | undefined) => Promise<Response>) & {
45
+ bind(context: unknown): (input: string | Request | URL, init?: RequestInit | undefined) => Promise<Response>;
46
+ };
47
+ export {};
10
48
  //# sourceMappingURL=fetch-wrap.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-wrap.d.ts","sourceRoot":"","sources":["../src/fetch-wrap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAGlC,eAAO,MAAM,eAAe;;MAEnB,KAIR,CAAA;AAyCD,eAAO,MAAM,gBAAgB;;;MAGpB,KAQR,CAAA;AAED,wBAAsB,YAAY,CAChC,IAAI,EAAE,iBAAiB,CAAC,KAAK,CAAC,EAC9B,OAAO,EAAE,OAAO,EAChB,OAAO,SAAO,EACd,KAAK,GAAE,KAAwB,GAC9B,OAAO,CAAC,QAAQ,CAAC,CAgCnB"}
1
+ {"version":3,"file":"fetch-wrap.d.ts","sourceRoot":"","sources":["../src/fetch-wrap.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,YAAY,EAAwB,MAAM,YAAY,CAAA;AAItE,KAAK,KAAK,CAAC,IAAI,SAAS,OAAO,EAAE,IAAI,CAAC,GAAG,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,CAAA;AAEhF,wBAAgB,WAAW,CAAC,CAAC,GAAG,YAAY,EAAE,EAC5C,KAAoC,EACpC,UAAwD,EACxD,WAA6E,EAC7E,QAAsE,GACvE;;;;;CAAA,YAgDA;AAED,eAAO,MAAM,UAAU,+CAEd,MAAM,CAAC,CAAC,KACd,MAAM,CAAC,CAqCT,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,SAAS,CAAC,CAAC,GAAG,YAAY,EACxC,KAAK,GAAE,KAAK,CAAC,CAAC,CAAoB,EAClC,OAAO,GAAE,CAAmB;;EAS7B"}
@@ -1,73 +1,124 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.fetchTimeout = exports.timeoutFetchWrap = exports.loggedFetchWrap = void 0;
3
+ exports.bindFetch = exports.timedFetch = exports.loggedFetch = void 0;
4
+ const fetch_request_js_1 = require("./fetch-request.js");
5
+ const fetch_js_1 = require("./fetch.js");
4
6
  const transformed_response_js_1 = require("./transformed-response.js");
5
- const loggedFetchWrap = ({ fetch = globalThis.fetch, } = {}) => {
6
- return async function (request) {
7
- return fetchLog.call(this, request, fetch);
8
- };
9
- };
10
- exports.loggedFetchWrap = loggedFetchWrap;
11
- async function fetchLog(request, fetch = globalThis.fetch) {
12
- console.info(`> ${request.method} ${request.url}\n` +
13
- stringifyPayload(request.headers, await request.clone().text()));
14
- try {
15
- const response = await fetch(request);
16
- console.info(`< HTTP/1.1 ${response.status} ${response.statusText}\n` +
17
- stringifyPayload(response.headers, await response.clone().text()));
18
- return response;
19
- }
20
- catch (error) {
21
- console.error(`< Error:`, error);
22
- throw error;
23
- }
7
+ const util_js_1 = require("./util.js");
8
+ function loggedFetch({ fetch = globalThis.fetch, logRequest = true, logResponse = true, logError = true, }) {
9
+ const onRequest = logRequest === true
10
+ ? async (request) => {
11
+ const requestMessage = await (0, util_js_1.stringifyMessage)(request);
12
+ console.info(`> ${request.method} ${request.url}\n${(0, util_js_1.padLines)(requestMessage, ' ')}`);
13
+ }
14
+ : logRequest || undefined;
15
+ const onResponse = logResponse === true
16
+ ? async (response) => {
17
+ const responseMessage = await (0, util_js_1.stringifyMessage)(response.clone());
18
+ console.info(`< HTTP/1.1 ${response.status} ${response.statusText}\n${(0, util_js_1.padLines)(responseMessage, ' ')}`);
19
+ }
20
+ : logResponse || undefined;
21
+ const onError = logError === true
22
+ ? async (error) => {
23
+ console.error(`< Error:`, error);
24
+ }
25
+ : logError || undefined;
26
+ if (!onRequest && !onResponse && !onError)
27
+ return fetch;
28
+ return (0, fetch_js_1.toRequestTransformer)(async function (request) {
29
+ if (onRequest)
30
+ await onRequest(request);
31
+ try {
32
+ const response = await fetch.call(this, request);
33
+ if (onResponse)
34
+ await onResponse(response, request);
35
+ return response;
36
+ }
37
+ catch (error) {
38
+ if (onError)
39
+ await onError(error, request);
40
+ throw error;
41
+ }
42
+ });
24
43
  }
25
- const stringifyPayload = (headers, body) => [stringifyHeaders(headers), stringifyBody(body)]
26
- .filter(Boolean)
27
- .join('\n ') + '\n ';
28
- const stringifyHeaders = (headers) => Array.from(headers)
29
- .map(([name, value]) => ` ${name}: ${value}\n`)
30
- .join('');
31
- const stringifyBody = (body) => body ? `\n ${body.replace(/\r?\n/g, '\\n')}` : '';
32
- const timeoutFetchWrap = ({ fetch = globalThis.fetch, timeout = 60e3, } = {}) => {
44
+ exports.loggedFetch = loggedFetch;
45
+ const timedFetch = (timeout = 60e3, fetch = globalThis.fetch) => {
33
46
  if (timeout === Infinity)
34
47
  return fetch;
35
48
  if (!Number.isFinite(timeout) || timeout <= 0) {
36
49
  throw new TypeError('Timeout must be positive');
37
50
  }
38
- return async function (request) {
39
- return fetchTimeout.call(this, request, timeout, fetch);
40
- };
51
+ return (0, fetch_js_1.toRequestTransformer)(async function (request) {
52
+ const controller = new AbortController();
53
+ const signal = controller.signal;
54
+ const abort = () => {
55
+ controller.abort();
56
+ };
57
+ const cleanup = () => {
58
+ clearTimeout(timer);
59
+ request.signal?.removeEventListener('abort', abort);
60
+ };
61
+ const timer = setTimeout(abort, timeout);
62
+ if (typeof timer === 'object')
63
+ timer.unref?.(); // only on node
64
+ request.signal?.addEventListener('abort', abort);
65
+ signal.addEventListener('abort', cleanup);
66
+ const response = await fetch.call(this, request, { signal });
67
+ if (!response.body) {
68
+ cleanup();
69
+ return response;
70
+ }
71
+ else {
72
+ // Cleanup the timer & event listeners when the body stream is closed
73
+ const transform = new TransformStream({ flush: cleanup });
74
+ return new transformed_response_js_1.TransformedResponse(response, transform);
75
+ }
76
+ });
41
77
  };
42
- exports.timeoutFetchWrap = timeoutFetchWrap;
43
- async function fetchTimeout(request, timeout = 30e3, fetch = globalThis.fetch) {
44
- if (timeout === Infinity)
45
- return fetch(request);
46
- if (!Number.isFinite(timeout) || timeout <= 0) {
47
- throw new TypeError('Timeout must be positive');
48
- }
49
- const controller = new AbortController();
50
- const signal = controller.signal;
51
- const abort = () => {
52
- controller.abort();
53
- };
54
- const cleanup = () => {
55
- clearTimeout(timeoutId);
56
- request.signal?.removeEventListener('abort', abort);
57
- };
58
- const timeoutId = setTimeout(abort, timeout).unref();
59
- request.signal?.addEventListener('abort', abort);
60
- signal.addEventListener('abort', cleanup);
61
- const response = await fetch(new Request(request, { signal }));
62
- if (!response.body) {
63
- cleanup();
64
- return response;
65
- }
66
- else {
67
- // Cleanup the timer & event listeners when the body stream is closed
68
- const transform = new TransformStream({ flush: cleanup });
69
- return new transformed_response_js_1.TransformedResponse(response, transform);
70
- }
78
+ exports.timedFetch = timedFetch;
79
+ /**
80
+ * Wraps a fetch function to bind it to a specific context, and wrap any thrown
81
+ * errors into a FetchRequestError.
82
+ *
83
+ * @example
84
+ *
85
+ * ```ts
86
+ * class MyClient {
87
+ * constructor(private fetch = globalThis.fetch) {}
88
+ *
89
+ * async get(url: string) {
90
+ * // This will generate an error, because the context used is not a
91
+ * // FetchContext (it's a MyClient instance).
92
+ * return this.fetch(url)
93
+ * }
94
+ * }
95
+ * ```
96
+ *
97
+ * @example
98
+ *
99
+ * ```ts
100
+ * class MyClient {
101
+ * private fetch: Fetch<unknown>
102
+ *
103
+ * constructor(fetch = globalThis.fetch) {
104
+ * this.fetch = bindFetch(fetch)
105
+ * }
106
+ *
107
+ * async get(url: string) {
108
+ * return this.fetch(url) // no more error
109
+ * }
110
+ * }
111
+ * ```
112
+ */
113
+ function bindFetch(fetch = globalThis.fetch, context = globalThis) {
114
+ return (0, fetch_js_1.toRequestTransformer)(async (request) => {
115
+ try {
116
+ return await fetch.call(context, request);
117
+ }
118
+ catch (err) {
119
+ throw fetch_request_js_1.FetchRequestError.from(request, err);
120
+ }
121
+ });
71
122
  }
72
- exports.fetchTimeout = fetchTimeout;
123
+ exports.bindFetch = bindFetch;
73
124
  //# sourceMappingURL=fetch-wrap.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-wrap.js","sourceRoot":"","sources":["../src/fetch-wrap.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fetch-wrap.js","sourceRoot":"","sources":["../src/fetch-wrap.ts"],"names":[],"mappings":"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"}
package/dist/fetch.d.ts CHANGED
@@ -1,2 +1,9 @@
1
- export type Fetch = (this: void | null | typeof globalThis, input: Request) => Promise<Response>;
1
+ import { ThisParameterOverride } from './util.js';
2
+ export type FetchContext = void | null | typeof globalThis;
3
+ export type FetchBound = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
4
+ export type Fetch<C = FetchContext> = ThisParameterOverride<C, FetchBound>;
5
+ export type SimpleFetchBound = (input: Request) => Promise<Response>;
6
+ export type SimpleFetch<C = FetchContext> = ThisParameterOverride<C, SimpleFetchBound>;
7
+ export declare function toRequestTransformer<C, O>(requestTransformer: (this: C, input: Request) => O): ThisParameterOverride<C, (input: string | URL | Request, init?: RequestInit) => O>;
8
+ export declare function asRequest(input: string | URL | Request, init?: RequestInit): Request;
2
9
  //# sourceMappingURL=fetch.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../src/fetch.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,KAAK,GAAG,CAClB,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,UAAU,EACrC,KAAK,EAAE,OAAO,KACX,OAAO,CAAC,QAAQ,CAAC,CAAA"}
1
+ {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../src/fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAA;AAEjD,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,GAAG,OAAO,UAAU,CAAA;AAE1D,MAAM,MAAM,UAAU,GAAG,CACvB,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,OAAO,EAC7B,IAAI,CAAC,EAAE,WAAW,KACf,OAAO,CAAC,QAAQ,CAAC,CAAA;AAMtB,MAAM,MAAM,KAAK,CAAC,CAAC,GAAG,YAAY,IAAI,qBAAqB,CAAC,CAAC,EAAE,UAAU,CAAC,CAAA;AAE1E,MAAM,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AACpE,MAAM,MAAM,WAAW,CAAC,CAAC,GAAG,YAAY,IAAI,qBAAqB,CAC/D,CAAC,EACD,gBAAgB,CACjB,CAAA;AAED,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,CAAC,EACvC,kBAAkB,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,KAAK,CAAC,GACjD,qBAAqB,CACtB,CAAC,EACD,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,OAAO,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,CAAC,CACzD,CAIA;AAED,wBAAgB,SAAS,CACvB,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,OAAO,EAC7B,IAAI,CAAC,EAAE,WAAW,GACjB,OAAO,CAGT"}
package/dist/fetch.js CHANGED
@@ -1,3 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.asRequest = exports.toRequestTransformer = void 0;
4
+ function toRequestTransformer(requestTransformer) {
5
+ return function (input, init) {
6
+ return requestTransformer.call(this, asRequest(input, init));
7
+ };
8
+ }
9
+ exports.toRequestTransformer = toRequestTransformer;
10
+ function asRequest(input, init) {
11
+ if (!init && input instanceof Request)
12
+ return input;
13
+ return new Request(input, init);
14
+ }
15
+ exports.asRequest = asRequest;
3
16
  //# sourceMappingURL=fetch.js.map
package/dist/fetch.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.js","sourceRoot":"","sources":["../src/fetch.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"fetch.js","sourceRoot":"","sources":["../src/fetch.ts"],"names":[],"mappings":";;;AAqBA,SAAgB,oBAAoB,CAClC,kBAAkD;IAKlD,OAAO,UAAmB,KAAK,EAAE,IAAI;QACnC,OAAO,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAA;IAC9D,CAAC,CAAA;AACH,CAAC;AATD,oDASC;AAED,SAAgB,SAAS,CACvB,KAA6B,EAC7B,IAAkB;IAElB,IAAI,CAAC,IAAI,IAAI,KAAK,YAAY,OAAO;QAAE,OAAO,KAAK,CAAA;IACnD,OAAO,IAAI,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;AACjC,CAAC;AAND,8BAMC"}
@@ -1 +1 @@
1
- {"version":3,"file":"transformed-response.d.ts","sourceRoot":"","sources":["../src/transformed-response.ts"],"names":[],"mappings":"AAAA,qBAAa,mBAAoB,SAAQ,QAAQ;;gBAGnC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe;IAc1D;;OAEG;IACH,IAAI,GAAG,WAEN;IACD,IAAI,UAAU,YAEb;IACD,IAAI,IAAI,iBAEP;IACD,IAAI,UAAU,WAEb;CACF"}
1
+ {"version":3,"file":"transformed-response.d.ts","sourceRoot":"","sources":["../src/transformed-response.ts"],"names":[],"mappings":"AAAA,qBAAa,mBAAoB,SAAQ,QAAQ;;gBAGnC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe;IAiB1D;;OAEG;IACH,IAAI,GAAG,WAEN;IACD,IAAI,UAAU,YAEb;IACD,IAAI,IAAI,iBAEP;IACD,IAAI,UAAU,WAEb;CACF"}