@atproto-labs/fetch 0.1.2 → 0.2.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.
- package/CHANGELOG.md +16 -0
- package/dist/fetch-response.d.ts +6 -6
- package/dist/fetch-response.d.ts.map +1 -1
- package/dist/fetch-response.js +22 -6
- package/dist/fetch-response.js.map +1 -1
- package/package.json +1 -1
- package/src/fetch-response.ts +27 -13
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @atproto-labs/fetch
|
|
2
2
|
|
|
3
|
+
## 0.2.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#3220](https://github.com/bluesky-social/atproto/pull/3220) [`61dc0d60e`](https://github.com/bluesky-social/atproto/commit/61dc0d60e19b88c6427a54c6d95a391b5f4da7bd) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Apply new linting rules regarding import order
|
|
8
|
+
|
|
9
|
+
## 0.2.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- [#3343](https://github.com/bluesky-social/atproto/pull/3343) [`5ece8c6ae`](https://github.com/bluesky-social/atproto/commit/5ece8c6aeab9c5c3f51295d93ed6e27c3c6095c2) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Fix typo in `ResponseTranformer` and `fetchResponseJsonTranformer`
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- [#3343](https://github.com/bluesky-social/atproto/pull/3343) [`5ece8c6ae`](https://github.com/bluesky-social/atproto/commit/5ece8c6aeab9c5c3f51295d93ed6e27c3c6095c2) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Response mime type check is now case-insensitive (as per rfc2616)
|
|
18
|
+
|
|
3
19
|
## 0.1.2
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/dist/fetch-response.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import type { ParseParams, TypeOf, ZodTypeAny } from 'zod';
|
|
1
2
|
import { Transformer } from '@atproto-labs/pipe';
|
|
2
|
-
import type { ZodTypeAny, ParseParams, TypeOf } from 'zod';
|
|
3
3
|
import { FetchError } from './fetch-error.js';
|
|
4
4
|
import { Json } from './util.js';
|
|
5
|
-
export type
|
|
5
|
+
export type ResponseTransformer = Transformer<Response>;
|
|
6
6
|
export type ResponseMessageGetter = Transformer<Response, string | undefined>;
|
|
7
7
|
export declare class FetchResponseError extends FetchError {
|
|
8
8
|
readonly response: Response;
|
|
@@ -24,19 +24,19 @@ export declare function extractMime(response: Response): string | undefined;
|
|
|
24
24
|
* cloned.
|
|
25
25
|
*/
|
|
26
26
|
export declare function cancelBodyOnError<T>(transformer: Transformer<Response, T>, onCancellationError?: null | ((err: unknown) => void)): (response: Response) => Promise<T>;
|
|
27
|
-
export declare function fetchOkProcessor(customMessage?: string | ResponseMessageGetter):
|
|
27
|
+
export declare function fetchOkProcessor(customMessage?: string | ResponseMessageGetter): ResponseTransformer;
|
|
28
28
|
export declare function fetchOkTransformer(response: Response, customMessage?: string | ResponseMessageGetter): Promise<Response>;
|
|
29
|
-
export declare function fetchMaxSizeProcessor(maxBytes: number):
|
|
29
|
+
export declare function fetchMaxSizeProcessor(maxBytes: number): ResponseTransformer;
|
|
30
30
|
export declare function fetchResponseMaxSizeChecker(response: Response, maxBytes: number): Response;
|
|
31
31
|
export type MimeTypeCheckFn = (mimeType: string) => boolean;
|
|
32
32
|
export type MimeTypeCheck = string | RegExp | MimeTypeCheckFn;
|
|
33
|
-
export declare function fetchTypeProcessor(expectedMime: MimeTypeCheck, contentTypeRequired?: boolean):
|
|
33
|
+
export declare function fetchTypeProcessor(expectedMime: MimeTypeCheck, contentTypeRequired?: boolean): ResponseTransformer;
|
|
34
34
|
export declare function fetchResponseTypeChecker(response: Response, isExpectedMime: MimeTypeCheckFn, contentTypeRequired?: boolean): Promise<Response>;
|
|
35
35
|
export type ParsedJsonResponse<T = Json> = {
|
|
36
36
|
response: Response;
|
|
37
37
|
json: T;
|
|
38
38
|
};
|
|
39
|
-
export declare function
|
|
39
|
+
export declare function fetchResponseJsonTransformer<T = Json>(response: Response): Promise<ParsedJsonResponse<T>>;
|
|
40
40
|
export declare function fetchJsonProcessor<T = Json>(expectedMime?: MimeTypeCheck, contentTypeRequired?: boolean): Transformer<Response, ParsedJsonResponse<T>>;
|
|
41
41
|
export declare function fetchJsonZodProcessor<S extends ZodTypeAny>(schema: S, params?: Partial<ParseParams>): Transformer<ParsedJsonResponse, TypeOf<S>>;
|
|
42
42
|
//# sourceMappingURL=fetch-response.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-response.d.ts","sourceRoot":"","sources":["../src/fetch-response.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"fetch-response.d.ts","sourceRoot":"","sources":["../src/fetch-response.ts"],"names":[],"mappings":"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"}
|
package/dist/fetch-response.js
CHANGED
|
@@ -12,13 +12,29 @@ exports.fetchMaxSizeProcessor = fetchMaxSizeProcessor;
|
|
|
12
12
|
exports.fetchResponseMaxSizeChecker = fetchResponseMaxSizeChecker;
|
|
13
13
|
exports.fetchTypeProcessor = fetchTypeProcessor;
|
|
14
14
|
exports.fetchResponseTypeChecker = fetchResponseTypeChecker;
|
|
15
|
-
exports.
|
|
15
|
+
exports.fetchResponseJsonTransformer = fetchResponseJsonTransformer;
|
|
16
16
|
exports.fetchJsonProcessor = fetchJsonProcessor;
|
|
17
17
|
exports.fetchJsonZodProcessor = fetchJsonZodProcessor;
|
|
18
18
|
const pipe_1 = require("@atproto-labs/pipe");
|
|
19
19
|
const fetch_error_js_1 = require("./fetch-error.js");
|
|
20
20
|
const transformed_response_js_1 = require("./transformed-response.js");
|
|
21
21
|
const util_js_1 = require("./util.js");
|
|
22
|
+
/**
|
|
23
|
+
* media-type = type "/" subtype *( ";" parameter )
|
|
24
|
+
* type = token
|
|
25
|
+
* subtype = token
|
|
26
|
+
* token = 1*<any CHAR except CTLs or separators>
|
|
27
|
+
* separators = "(" | ")" | "<" | ">" | "@"
|
|
28
|
+
* | "," | ";" | ":" | "\" | <">
|
|
29
|
+
* | "/" | "[" | "]" | "?" | "="
|
|
30
|
+
* | "{" | "}" | SP | HT
|
|
31
|
+
* CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
|
|
32
|
+
* SP = <US-ASCII SP, space (32)>
|
|
33
|
+
* HT = <US-ASCII HT, horizontal-tab (9)>
|
|
34
|
+
* @note The type, subtype, and parameter attribute names are case-insensitive.
|
|
35
|
+
* @see {@link https://datatracker.ietf.org/doc/html/rfc2616#autoid-23}
|
|
36
|
+
*/
|
|
37
|
+
const JSON_MIME = /^application\/(?:[^()<>@,;:/[\]\\?={} \t]+\+)?json$/i;
|
|
22
38
|
class FetchResponseError extends fetch_error_js_1.FetchError {
|
|
23
39
|
constructor(response, statusCode = response.status, message = response.statusText, options) {
|
|
24
40
|
super(statusCode, message, options);
|
|
@@ -47,7 +63,7 @@ const extractResponseMessage = async (response) => {
|
|
|
47
63
|
if (mimeType === 'text/plain') {
|
|
48
64
|
return await response.text();
|
|
49
65
|
}
|
|
50
|
-
else if (
|
|
66
|
+
else if (JSON_MIME.test(mimeType)) {
|
|
51
67
|
const json = await response.json();
|
|
52
68
|
if (typeof json === 'string')
|
|
53
69
|
return json;
|
|
@@ -177,7 +193,7 @@ function fetchTypeProcessor(expectedMime, contentTypeRequired = true) {
|
|
|
177
193
|
async function fetchResponseTypeChecker(response, isExpectedMime, contentTypeRequired = true) {
|
|
178
194
|
const mimeType = extractMime(response);
|
|
179
195
|
if (mimeType) {
|
|
180
|
-
if (!isExpectedMime(mimeType)) {
|
|
196
|
+
if (!isExpectedMime(mimeType.toLowerCase())) {
|
|
181
197
|
throw await FetchResponseError.from(response, `Unexpected response Content-Type (${mimeType})`, 502);
|
|
182
198
|
}
|
|
183
199
|
}
|
|
@@ -186,7 +202,7 @@ async function fetchResponseTypeChecker(response, isExpectedMime, contentTypeReq
|
|
|
186
202
|
}
|
|
187
203
|
return response;
|
|
188
204
|
}
|
|
189
|
-
async function
|
|
205
|
+
async function fetchResponseJsonTransformer(response) {
|
|
190
206
|
try {
|
|
191
207
|
const json = (await response.json());
|
|
192
208
|
return { response, json };
|
|
@@ -195,8 +211,8 @@ async function fetchResponseJsonTranformer(response) {
|
|
|
195
211
|
throw new FetchResponseError(response, 502, 'Unable to parse response as JSON', { cause });
|
|
196
212
|
}
|
|
197
213
|
}
|
|
198
|
-
function fetchJsonProcessor(expectedMime =
|
|
199
|
-
return (0, pipe_1.pipe)(fetchTypeProcessor(expectedMime, contentTypeRequired), cancelBodyOnError((
|
|
214
|
+
function fetchJsonProcessor(expectedMime = JSON_MIME, contentTypeRequired = true) {
|
|
215
|
+
return (0, pipe_1.pipe)(fetchTypeProcessor(expectedMime, contentTypeRequired), cancelBodyOnError((fetchResponseJsonTransformer)));
|
|
200
216
|
}
|
|
201
217
|
function fetchJsonZodProcessor(schema, params) {
|
|
202
218
|
return async (jsonResponse) => schema.parseAsync(jsonResponse.json, params);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-response.js","sourceRoot":"","sources":["../src/fetch-response.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"fetch-response.js","sourceRoot":"","sources":["../src/fetch-response.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/fetch-response.ts
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
|
+
import type { ParseParams, TypeOf, ZodTypeAny } from 'zod'
|
|
1
2
|
import { Transformer, pipe } from '@atproto-labs/pipe'
|
|
2
|
-
|
|
3
|
-
// optional dependency for typing purposes
|
|
4
|
-
import type { ZodTypeAny, ParseParams, TypeOf } from 'zod'
|
|
5
|
-
|
|
6
3
|
import { FetchError } from './fetch-error.js'
|
|
7
4
|
import { TransformedResponse } from './transformed-response.js'
|
|
8
5
|
import {
|
|
@@ -14,7 +11,24 @@ import {
|
|
|
14
11
|
logCancellationError,
|
|
15
12
|
} from './util.js'
|
|
16
13
|
|
|
17
|
-
|
|
14
|
+
/**
|
|
15
|
+
* media-type = type "/" subtype *( ";" parameter )
|
|
16
|
+
* type = token
|
|
17
|
+
* subtype = token
|
|
18
|
+
* token = 1*<any CHAR except CTLs or separators>
|
|
19
|
+
* separators = "(" | ")" | "<" | ">" | "@"
|
|
20
|
+
* | "," | ";" | ":" | "\" | <">
|
|
21
|
+
* | "/" | "[" | "]" | "?" | "="
|
|
22
|
+
* | "{" | "}" | SP | HT
|
|
23
|
+
* CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
|
|
24
|
+
* SP = <US-ASCII SP, space (32)>
|
|
25
|
+
* HT = <US-ASCII HT, horizontal-tab (9)>
|
|
26
|
+
* @note The type, subtype, and parameter attribute names are case-insensitive.
|
|
27
|
+
* @see {@link https://datatracker.ietf.org/doc/html/rfc2616#autoid-23}
|
|
28
|
+
*/
|
|
29
|
+
const JSON_MIME = /^application\/(?:[^()<>@,;:/[\]\\?={} \t]+\+)?json$/i
|
|
30
|
+
|
|
31
|
+
export type ResponseTransformer = Transformer<Response>
|
|
18
32
|
export type ResponseMessageGetter = Transformer<Response, string | undefined>
|
|
19
33
|
|
|
20
34
|
export class FetchResponseError extends FetchError {
|
|
@@ -51,7 +65,7 @@ const extractResponseMessage: ResponseMessageGetter = async (response) => {
|
|
|
51
65
|
try {
|
|
52
66
|
if (mimeType === 'text/plain') {
|
|
53
67
|
return await response.text()
|
|
54
|
-
} else if (
|
|
68
|
+
} else if (JSON_MIME.test(mimeType)) {
|
|
55
69
|
const json: unknown = await response.json()
|
|
56
70
|
|
|
57
71
|
if (typeof json === 'string') return json
|
|
@@ -155,7 +169,7 @@ export function cancelBodyOnError<T>(
|
|
|
155
169
|
|
|
156
170
|
export function fetchOkProcessor(
|
|
157
171
|
customMessage?: string | ResponseMessageGetter,
|
|
158
|
-
):
|
|
172
|
+
): ResponseTransformer {
|
|
159
173
|
return cancelBodyOnError((response) => {
|
|
160
174
|
return fetchOkTransformer(response, customMessage)
|
|
161
175
|
})
|
|
@@ -169,7 +183,7 @@ export async function fetchOkTransformer(
|
|
|
169
183
|
throw await FetchResponseError.from(response, customMessage)
|
|
170
184
|
}
|
|
171
185
|
|
|
172
|
-
export function fetchMaxSizeProcessor(maxBytes: number):
|
|
186
|
+
export function fetchMaxSizeProcessor(maxBytes: number): ResponseTransformer {
|
|
173
187
|
if (maxBytes === Infinity) return (response) => response
|
|
174
188
|
if (!Number.isFinite(maxBytes) || maxBytes < 0) {
|
|
175
189
|
throw new TypeError('maxBytes must be a 0, Infinity or a positive number')
|
|
@@ -200,7 +214,7 @@ export type MimeTypeCheck = string | RegExp | MimeTypeCheckFn
|
|
|
200
214
|
export function fetchTypeProcessor(
|
|
201
215
|
expectedMime: MimeTypeCheck,
|
|
202
216
|
contentTypeRequired = true,
|
|
203
|
-
):
|
|
217
|
+
): ResponseTransformer {
|
|
204
218
|
const isExpected: MimeTypeCheckFn =
|
|
205
219
|
typeof expectedMime === 'string'
|
|
206
220
|
? (mimeType) => mimeType === expectedMime
|
|
@@ -220,7 +234,7 @@ export async function fetchResponseTypeChecker(
|
|
|
220
234
|
): Promise<Response> {
|
|
221
235
|
const mimeType = extractMime(response)
|
|
222
236
|
if (mimeType) {
|
|
223
|
-
if (!isExpectedMime(mimeType)) {
|
|
237
|
+
if (!isExpectedMime(mimeType.toLowerCase())) {
|
|
224
238
|
throw await FetchResponseError.from(
|
|
225
239
|
response,
|
|
226
240
|
`Unexpected response Content-Type (${mimeType})`,
|
|
@@ -243,7 +257,7 @@ export type ParsedJsonResponse<T = Json> = {
|
|
|
243
257
|
json: T
|
|
244
258
|
}
|
|
245
259
|
|
|
246
|
-
export async function
|
|
260
|
+
export async function fetchResponseJsonTransformer<T = Json>(
|
|
247
261
|
response: Response,
|
|
248
262
|
): Promise<ParsedJsonResponse<T>> {
|
|
249
263
|
try {
|
|
@@ -260,12 +274,12 @@ export async function fetchResponseJsonTranformer<T = Json>(
|
|
|
260
274
|
}
|
|
261
275
|
|
|
262
276
|
export function fetchJsonProcessor<T = Json>(
|
|
263
|
-
expectedMime: MimeTypeCheck =
|
|
277
|
+
expectedMime: MimeTypeCheck = JSON_MIME,
|
|
264
278
|
contentTypeRequired = true,
|
|
265
279
|
): Transformer<Response, ParsedJsonResponse<T>> {
|
|
266
280
|
return pipe(
|
|
267
281
|
fetchTypeProcessor(expectedMime, contentTypeRequired),
|
|
268
|
-
cancelBodyOnError(
|
|
282
|
+
cancelBodyOnError(fetchResponseJsonTransformer<T>),
|
|
269
283
|
)
|
|
270
284
|
}
|
|
271
285
|
|