@atproto-labs/fetch 0.1.0 → 0.1.2
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-error.d.ts +3 -2
- package/dist/fetch-error.d.ts.map +1 -1
- package/dist/fetch-error.js +4 -43
- package/dist/fetch-error.js.map +1 -1
- package/dist/fetch-request.d.ts +17 -3
- package/dist/fetch-request.d.ts.map +1 -1
- package/dist/fetch-request.js +89 -17
- package/dist/fetch-request.js.map +1 -1
- package/dist/fetch-response.js +15 -15
- package/dist/fetch-response.js.map +1 -1
- package/dist/fetch-wrap.d.ts +10 -5
- package/dist/fetch-wrap.d.ts.map +1 -1
- package/dist/fetch-wrap.js +29 -9
- package/dist/fetch-wrap.js.map +1 -1
- package/dist/fetch.js +2 -3
- package/dist/fetch.js.map +1 -1
- package/dist/util.d.ts +1 -0
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +12 -6
- package/dist/util.js.map +1 -1
- package/package.json +2 -2
- package/src/fetch-error.ts +8 -54
- package/src/fetch-request.ts +111 -14
- package/src/fetch-wrap.ts +40 -12
- package/src/util.ts +7 -0
- package/tsconfig.build.tsbuildinfo +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @atproto-labs/fetch
|
|
2
2
|
|
|
3
|
+
## 0.1.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#3135](https://github.com/bluesky-social/atproto/pull/3135) [`622654672`](https://github.com/bluesky-social/atproto/commit/6226546725d1bb0375e3c9e0d71af173e8253c4f) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Support parsing of more fetch() errors
|
|
8
|
+
|
|
9
|
+
## 0.1.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [#2770](https://github.com/bluesky-social/atproto/pull/2770) [`a07b21151`](https://github.com/bluesky-social/atproto/commit/a07b21151f1850340c4b7797ebb11521b1a6cdf3) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Expose extractUrl utility
|
|
14
|
+
|
|
15
|
+
- [#2770](https://github.com/bluesky-social/atproto/pull/2770) [`a07b21151`](https://github.com/bluesky-social/atproto/commit/a07b21151f1850340c4b7797ebb11521b1a6cdf3) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Add redirectCheckRequestTransform utility to prevent request redirects
|
|
16
|
+
|
|
17
|
+
- [#2770](https://github.com/bluesky-social/atproto/pull/2770) [`a07b21151`](https://github.com/bluesky-social/atproto/commit/a07b21151f1850340c4b7797ebb11521b1a6cdf3) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Allow customizing fetch logging function
|
|
18
|
+
|
|
3
19
|
## 0.1.0
|
|
4
20
|
|
|
5
21
|
### Minor Changes
|
package/dist/fetch-error.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
export declare class FetchError extends Error {
|
|
1
|
+
export declare abstract class FetchError extends Error {
|
|
2
2
|
readonly statusCode: number;
|
|
3
|
-
constructor(statusCode
|
|
3
|
+
constructor(statusCode: number, message?: string, options?: ErrorOptions);
|
|
4
|
+
get expose(): boolean;
|
|
4
5
|
}
|
|
5
6
|
//# sourceMappingURL=fetch-error.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-error.d.ts","sourceRoot":"","sources":["../src/fetch-error.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"fetch-error.d.ts","sourceRoot":"","sources":["../src/fetch-error.ts"],"names":[],"mappings":"AAAA,8BAAsB,UAAW,SAAQ,KAAK;aAE1B,UAAU,EAAE,MAAM;gBAAlB,UAAU,EAAE,MAAM,EAClC,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,YAAY;IAKxB,IAAI,MAAM,YAET;CACF"}
|
package/dist/fetch-error.js
CHANGED
|
@@ -3,56 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.FetchError = void 0;
|
|
4
4
|
class FetchError extends Error {
|
|
5
5
|
constructor(statusCode, message, options) {
|
|
6
|
-
if (statusCode == null || !message) {
|
|
7
|
-
const info = extractInfo(extractRootCause(options?.cause));
|
|
8
|
-
statusCode = statusCode ?? info[0];
|
|
9
|
-
message = message || info[1];
|
|
10
|
-
}
|
|
11
6
|
super(message, options);
|
|
12
7
|
Object.defineProperty(this, "statusCode", {
|
|
13
8
|
enumerable: true,
|
|
14
9
|
configurable: true,
|
|
15
10
|
writable: true,
|
|
16
|
-
value:
|
|
11
|
+
value: statusCode
|
|
17
12
|
});
|
|
18
|
-
this.statusCode = statusCode;
|
|
19
13
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
function extractRootCause(err) {
|
|
23
|
-
// Unwrap the Network error from undici (i.e. Node's internal fetch() implementation)
|
|
24
|
-
// https://github.com/nodejs/undici/blob/3274c975947ce11a08508743df026f73598bfead/lib/web/fetch/index.js#L223-L228
|
|
25
|
-
if (err instanceof TypeError &&
|
|
26
|
-
err.message === 'fetch failed' &&
|
|
27
|
-
err.cause !== undefined) {
|
|
28
|
-
return err.cause;
|
|
14
|
+
get expose() {
|
|
15
|
+
return true;
|
|
29
16
|
}
|
|
30
|
-
return err;
|
|
31
|
-
}
|
|
32
|
-
function extractInfo(err) {
|
|
33
|
-
if (typeof err === 'string' && err.length > 0) {
|
|
34
|
-
return [500, err];
|
|
35
|
-
}
|
|
36
|
-
if (!(err instanceof Error)) {
|
|
37
|
-
return [500, 'Failed to fetch'];
|
|
38
|
-
}
|
|
39
|
-
const code = err['code'];
|
|
40
|
-
if (typeof code === 'string') {
|
|
41
|
-
switch (true) {
|
|
42
|
-
case code === 'ENOTFOUND':
|
|
43
|
-
return [400, 'Invalid hostname'];
|
|
44
|
-
case code === 'ECONNREFUSED':
|
|
45
|
-
return [502, 'Connection refused'];
|
|
46
|
-
case code === 'DEPTH_ZERO_SELF_SIGNED_CERT':
|
|
47
|
-
return [502, 'Self-signed certificate'];
|
|
48
|
-
case code.startsWith('ERR_TLS'):
|
|
49
|
-
return [502, 'TLS error'];
|
|
50
|
-
case code.startsWith('ECONN'):
|
|
51
|
-
return [502, 'Connection error'];
|
|
52
|
-
default:
|
|
53
|
-
return [500, `${code} error`];
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
return [500, err.message];
|
|
57
17
|
}
|
|
18
|
+
exports.FetchError = FetchError;
|
|
58
19
|
//# sourceMappingURL=fetch-error.js.map
|
package/dist/fetch-error.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-error.js","sourceRoot":"","sources":["../src/fetch-error.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"fetch-error.js","sourceRoot":"","sources":["../src/fetch-error.ts"],"names":[],"mappings":";;;AAAA,MAAsB,UAAW,SAAQ,KAAK;IAC5C,YACkB,UAAkB,EAClC,OAAgB,EAChB,OAAsB;QAEtB,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QAJvB;;;;mBAAgB,UAAU;WAAQ;IAKpC,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAA;IACb,CAAC;CACF;AAZD,gCAYC"}
|
package/dist/fetch-request.d.ts
CHANGED
|
@@ -1,11 +1,25 @@
|
|
|
1
1
|
import { FetchError } from './fetch-error.js';
|
|
2
|
+
import { asRequest } from './fetch.js';
|
|
2
3
|
export declare class FetchRequestError extends FetchError {
|
|
3
4
|
readonly request: Request;
|
|
4
5
|
constructor(request: Request, statusCode?: number, message?: string, options?: ErrorOptions);
|
|
6
|
+
get expose(): boolean;
|
|
5
7
|
static from(request: Request, cause: unknown): FetchRequestError;
|
|
6
8
|
}
|
|
7
|
-
export declare function protocolCheckRequestTransform(protocols:
|
|
8
|
-
|
|
9
|
+
export declare function protocolCheckRequestTransform(protocols: {
|
|
10
|
+
'about:'?: boolean;
|
|
11
|
+
'blob:'?: boolean;
|
|
12
|
+
'data:'?: boolean;
|
|
13
|
+
'file:'?: boolean;
|
|
14
|
+
'http:'?: boolean | {
|
|
15
|
+
allowCustomPort: boolean;
|
|
16
|
+
};
|
|
17
|
+
'https:'?: boolean | {
|
|
18
|
+
allowCustomPort: boolean;
|
|
19
|
+
};
|
|
20
|
+
}): (input: Request | string | URL, init?: RequestInit) => Request;
|
|
21
|
+
export declare function redirectCheckRequestTransform(): (input: Request | string | URL, init?: RequestInit) => Request;
|
|
22
|
+
export declare function requireHostHeaderTransform(): (input: Request | string | URL, init?: RequestInit) => Request;
|
|
9
23
|
export declare const DEFAULT_FORBIDDEN_DOMAIN_NAMES: string[];
|
|
10
|
-
export declare function forbiddenDomainNameRequestTransform(denyList?: Iterable<string>):
|
|
24
|
+
export declare function forbiddenDomainNameRequestTransform(denyList?: Iterable<string>): typeof asRequest | ((input: Request | string | URL, init?: RequestInit) => Promise<Request>);
|
|
11
25
|
//# sourceMappingURL=fetch-request.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-request.d.ts","sourceRoot":"","sources":["../src/fetch-request.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"fetch-request.d.ts","sourceRoot":"","sources":["../src/fetch-request.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAGtC,qBAAa,iBAAkB,SAAQ,UAAU;aAE7B,OAAO,EAAE,OAAO;gBAAhB,OAAO,EAAE,OAAO,EAChC,UAAU,CAAC,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,YAAY;IAWxB,IAAI,MAAM,YAKT;IAED,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,iBAAiB;CAIjE;AA6DD,wBAAgB,6BAA6B,CAAC,SAAS,EAAE;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,GAAG;QAAE,eAAe,EAAE,OAAO,CAAA;KAAE,CAAA;IAChD,QAAQ,CAAC,EAAE,OAAO,GAAG;QAAE,eAAe,EAAE,OAAO,CAAA;KAAE,CAAA;CAClD,WACgB,OAAO,GAAG,MAAM,GAAG,GAAG,SAAS,WAAW,aA0B1D;AAED,wBAAgB,6BAA6B,YAC5B,OAAO,GAAG,MAAM,GAAG,GAAG,SAAS,WAAW,aAa1D;AAED,wBAAgB,0BAA0B,YACzB,OAAO,GAAG,MAAM,GAAG,GAAG,SAAS,WAAW,aAuB1D;AAED,eAAO,MAAM,8BAA8B,UAS1C,CAAA;AAED,wBAAgB,mCAAmC,CACjD,QAAQ,GAAE,QAAQ,CAAC,MAAM,CAAkC,+BAUtC,OAAO,GAAG,MAAM,GAAG,GAAG,SAAS,WAAW,uBAsBhE"}
|
package/dist/fetch-request.js
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.DEFAULT_FORBIDDEN_DOMAIN_NAMES = exports.FetchRequestError = void 0;
|
|
4
|
+
exports.protocolCheckRequestTransform = protocolCheckRequestTransform;
|
|
5
|
+
exports.redirectCheckRequestTransform = redirectCheckRequestTransform;
|
|
6
|
+
exports.requireHostHeaderTransform = requireHostHeaderTransform;
|
|
7
|
+
exports.forbiddenDomainNameRequestTransform = forbiddenDomainNameRequestTransform;
|
|
4
8
|
const fetch_error_js_1 = require("./fetch-error.js");
|
|
5
9
|
const fetch_js_1 = require("./fetch.js");
|
|
6
10
|
const util_js_1 = require("./util.js");
|
|
7
11
|
class FetchRequestError extends fetch_error_js_1.FetchError {
|
|
8
12
|
constructor(request, statusCode, message, options) {
|
|
13
|
+
if (statusCode == null || !message) {
|
|
14
|
+
const info = extractInfo(extractRootCause(options?.cause));
|
|
15
|
+
statusCode ?? (statusCode = info[0]);
|
|
16
|
+
message || (message = info[1]);
|
|
17
|
+
}
|
|
9
18
|
super(statusCode, message, options);
|
|
10
19
|
Object.defineProperty(this, "request", {
|
|
11
20
|
enumerable: true,
|
|
@@ -14,6 +23,12 @@ class FetchRequestError extends fetch_error_js_1.FetchError {
|
|
|
14
23
|
value: request
|
|
15
24
|
});
|
|
16
25
|
}
|
|
26
|
+
get expose() {
|
|
27
|
+
// A 500 request error means that the request was not made due to an infra,
|
|
28
|
+
// programming or server side issue. The message should no be exposed to
|
|
29
|
+
// downstream clients.
|
|
30
|
+
return this.statusCode !== 500;
|
|
31
|
+
}
|
|
17
32
|
static from(request, cause) {
|
|
18
33
|
if (cause instanceof FetchRequestError)
|
|
19
34
|
return cause;
|
|
@@ -21,28 +36,87 @@ class FetchRequestError extends fetch_error_js_1.FetchError {
|
|
|
21
36
|
}
|
|
22
37
|
}
|
|
23
38
|
exports.FetchRequestError = FetchRequestError;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
39
|
+
function extractRootCause(err) {
|
|
40
|
+
// Unwrap the Network error from undici (i.e. Node's internal fetch() implementation)
|
|
41
|
+
// https://github.com/nodejs/undici/blob/3274c975947ce11a08508743df026f73598bfead/lib/web/fetch/index.js#L223-L228
|
|
42
|
+
if (err instanceof TypeError &&
|
|
43
|
+
err.message === 'fetch failed' &&
|
|
44
|
+
err.cause !== undefined) {
|
|
45
|
+
return err.cause;
|
|
46
|
+
}
|
|
47
|
+
return err;
|
|
48
|
+
}
|
|
49
|
+
function extractInfo(err) {
|
|
50
|
+
if (typeof err === 'string' && err.length > 0) {
|
|
51
|
+
return [500, err];
|
|
52
|
+
}
|
|
53
|
+
if (!(err instanceof Error)) {
|
|
54
|
+
return [500, 'Failed to fetch'];
|
|
55
|
+
}
|
|
56
|
+
// Undici fetch() "network" errors
|
|
57
|
+
switch (err.message) {
|
|
58
|
+
case 'failed to fetch the data URL':
|
|
59
|
+
return [400, err.message];
|
|
60
|
+
case 'unexpected redirect':
|
|
61
|
+
case 'cors failure':
|
|
62
|
+
case 'blocked':
|
|
63
|
+
case 'proxy authentication required':
|
|
64
|
+
// These cases could be represented either as a 4xx user error (invalid
|
|
65
|
+
// URL provided), or as a 5xx server error (server didn't behave as
|
|
66
|
+
// expected).
|
|
67
|
+
return [502, err.message];
|
|
68
|
+
}
|
|
69
|
+
// NodeJS errors
|
|
70
|
+
const code = err['code'];
|
|
71
|
+
if (typeof code === 'string') {
|
|
72
|
+
switch (true) {
|
|
73
|
+
case code === 'ENOTFOUND':
|
|
74
|
+
return [400, 'Invalid hostname'];
|
|
75
|
+
case code === 'ECONNREFUSED':
|
|
76
|
+
return [502, 'Connection refused'];
|
|
77
|
+
case code === 'DEPTH_ZERO_SELF_SIGNED_CERT':
|
|
78
|
+
return [502, 'Self-signed certificate'];
|
|
79
|
+
case code.startsWith('ERR_TLS'):
|
|
80
|
+
return [502, 'TLS error'];
|
|
81
|
+
case code.startsWith('ECONN'):
|
|
82
|
+
return [502, 'Connection error'];
|
|
83
|
+
default:
|
|
84
|
+
return [500, `${code} error`];
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return [500, err.message];
|
|
88
|
+
}
|
|
29
89
|
function protocolCheckRequestTransform(protocols) {
|
|
30
|
-
const allowedProtocols = new Set(protocols);
|
|
31
90
|
return (input, init) => {
|
|
32
|
-
const { protocol } = extractUrl(input);
|
|
91
|
+
const { protocol, port } = (0, util_js_1.extractUrl)(input);
|
|
33
92
|
const request = (0, fetch_js_1.asRequest)(input, init);
|
|
34
|
-
|
|
35
|
-
|
|
93
|
+
const config = Object.hasOwn(protocols, protocol) ? protocols[protocol] : undefined;
|
|
94
|
+
if (!config) {
|
|
95
|
+
throw new FetchRequestError(request, 400, `Forbidden protocol "${protocol}"`);
|
|
96
|
+
}
|
|
97
|
+
else if (config === true) {
|
|
98
|
+
// Safe to proceed
|
|
99
|
+
}
|
|
100
|
+
else if (!config['allowCustomPort'] && port !== '') {
|
|
101
|
+
throw new FetchRequestError(request, 400, `Custom ${protocol} ports not allowed`);
|
|
36
102
|
}
|
|
37
103
|
return request;
|
|
38
104
|
};
|
|
39
105
|
}
|
|
40
|
-
|
|
41
|
-
|
|
106
|
+
function redirectCheckRequestTransform() {
|
|
107
|
+
return (input, init) => {
|
|
108
|
+
const request = (0, fetch_js_1.asRequest)(input, init);
|
|
109
|
+
if (request.redirect === 'follow') {
|
|
110
|
+
throw new FetchRequestError(request, 500, 'Request redirect must be "error" or "manual"');
|
|
111
|
+
}
|
|
112
|
+
return request;
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function requireHostHeaderTransform() {
|
|
42
116
|
return (input, init) => {
|
|
43
117
|
// Note that fetch() will automatically add the Host header from the URL and
|
|
44
118
|
// discard any Host header manually set in the request.
|
|
45
|
-
const { protocol, hostname } = extractUrl(input);
|
|
119
|
+
const { protocol, hostname } = (0, util_js_1.extractUrl)(input);
|
|
46
120
|
const request = (0, fetch_js_1.asRequest)(input, init);
|
|
47
121
|
// "Host" header only makes sense in the context of an HTTP request
|
|
48
122
|
if (protocol !== 'http:' && protocol !== 'https:') {
|
|
@@ -54,7 +128,6 @@ function requireHostHeaderTranform() {
|
|
|
54
128
|
return request;
|
|
55
129
|
};
|
|
56
130
|
}
|
|
57
|
-
exports.requireHostHeaderTranform = requireHostHeaderTranform;
|
|
58
131
|
exports.DEFAULT_FORBIDDEN_DOMAIN_NAMES = [
|
|
59
132
|
'example.com',
|
|
60
133
|
'*.example.com',
|
|
@@ -70,10 +143,10 @@ function forbiddenDomainNameRequestTransform(denyList = exports.DEFAULT_FORBIDDE
|
|
|
70
143
|
// Optimization: if no forbidden domain names are provided, we can skip the
|
|
71
144
|
// check entirely.
|
|
72
145
|
if (denySet.size === 0) {
|
|
73
|
-
return
|
|
146
|
+
return fetch_js_1.asRequest;
|
|
74
147
|
}
|
|
75
148
|
return async (input, init) => {
|
|
76
|
-
const { hostname } = extractUrl(input);
|
|
149
|
+
const { hostname } = (0, util_js_1.extractUrl)(input);
|
|
77
150
|
const request = (0, fetch_js_1.asRequest)(input, init);
|
|
78
151
|
// Full domain name check
|
|
79
152
|
if (denySet.has(hostname)) {
|
|
@@ -91,5 +164,4 @@ function forbiddenDomainNameRequestTransform(denyList = exports.DEFAULT_FORBIDDE
|
|
|
91
164
|
return request;
|
|
92
165
|
};
|
|
93
166
|
}
|
|
94
|
-
exports.forbiddenDomainNameRequestTransform = forbiddenDomainNameRequestTransform;
|
|
95
167
|
//# sourceMappingURL=fetch-request.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-request.js","sourceRoot":"","sources":["../src/fetch-request.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"fetch-request.js","sourceRoot":"","sources":["../src/fetch-request.ts"],"names":[],"mappings":";;;AA4FA,sEAkCC;AAED,sEAcC;AAED,gEAwBC;AAaD,kFAiCC;AAtND,qDAA6C;AAC7C,yCAAsC;AACtC,uCAA4C;AAE5C,MAAa,iBAAkB,SAAQ,2BAAU;IAC/C,YACkB,OAAgB,EAChC,UAAmB,EACnB,OAAgB,EAChB,OAAsB;QAEtB,IAAI,UAAU,IAAI,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACnC,MAAM,IAAI,GAAG,WAAW,CAAC,gBAAgB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAA;YAC1D,UAAU,KAAV,UAAU,GAAK,IAAI,CAAC,CAAC,CAAC,EAAA;YACtB,OAAO,KAAP,OAAO,GAAK,IAAI,CAAC,CAAC,CAAC,EAAA;QACrB,CAAC;QAED,KAAK,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;QAXnC;;;;mBAAgB,OAAO;WAAS;IAYlC,CAAC;IAED,IAAI,MAAM;QACR,2EAA2E;QAC3E,wEAAwE;QACxE,sBAAsB;QACtB,OAAO,IAAI,CAAC,UAAU,KAAK,GAAG,CAAA;IAChC,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,OAAgB,EAAE,KAAc;QAC1C,IAAI,KAAK,YAAY,iBAAiB;YAAE,OAAO,KAAK,CAAA;QACpD,OAAO,IAAI,iBAAiB,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;IACxE,CAAC;CACF;AA3BD,8CA2BC;AAED,SAAS,gBAAgB,CAAC,GAAY;IACpC,qFAAqF;IACrF,kHAAkH;IAClH,IACE,GAAG,YAAY,SAAS;QACxB,GAAG,CAAC,OAAO,KAAK,cAAc;QAC9B,GAAG,CAAC,KAAK,KAAK,SAAS,EACvB,CAAC;QACD,OAAO,GAAG,CAAC,KAAK,CAAA;IAClB,CAAC;IAED,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,SAAS,WAAW,CAAC,GAAY;IAC/B,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9C,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;IACnB,CAAC;IAED,IAAI,CAAC,CAAC,GAAG,YAAY,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAA;IACjC,CAAC;IAED,kCAAkC;IAClC,QAAQ,GAAG,CAAC,OAAO,EAAE,CAAC;QACpB,KAAK,8BAA8B;YACjC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;QAC3B,KAAK,qBAAqB,CAAC;QAC3B,KAAK,cAAc,CAAC;QACpB,KAAK,SAAS,CAAC;QACf,KAAK,+BAA+B;YAClC,uEAAuE;YACvE,mEAAmE;YACnE,aAAa;YACb,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IAC7B,CAAC;IAED,gBAAgB;IAChB,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,CAAA;IACxB,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,IAAI,KAAK,WAAW;gBACvB,OAAO,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAA;YAClC,KAAK,IAAI,KAAK,cAAc;gBAC1B,OAAO,CAAC,GAAG,EAAE,oBAAoB,CAAC,CAAA;YACpC,KAAK,IAAI,KAAK,6BAA6B;gBACzC,OAAO,CAAC,GAAG,EAAE,yBAAyB,CAAC,CAAA;YACzC,KAAK,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;gBAC7B,OAAO,CAAC,GAAG,EAAE,WAAW,CAAC,CAAA;YAC3B,KAAK,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;gBAC3B,OAAO,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAA;YAClC;gBACE,OAAO,CAAC,GAAG,EAAE,GAAG,IAAI,QAAQ,CAAC,CAAA;QACjC,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;AAC3B,CAAC;AAED,SAAgB,6BAA6B,CAAC,SAO7C;IACC,OAAO,CAAC,KAA6B,EAAE,IAAkB,EAAE,EAAE;QAC3D,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,IAAA,oBAAU,EAAC,KAAK,CAAC,CAAA;QAE5C,MAAM,OAAO,GAAG,IAAA,oBAAS,EAAC,KAAK,EAAE,IAAI,CAAC,CAAA;QAEtC,MAAM,MAAM,GACV,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;QAEtE,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,iBAAiB,CACzB,OAAO,EACP,GAAG,EACH,uBAAuB,QAAQ,GAAG,CACnC,CAAA;QACH,CAAC;aAAM,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YAC3B,kBAAkB;QACpB,CAAC;aAAM,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,IAAI,IAAI,KAAK,EAAE,EAAE,CAAC;YACrD,MAAM,IAAI,iBAAiB,CACzB,OAAO,EACP,GAAG,EACH,UAAU,QAAQ,oBAAoB,CACvC,CAAA;QACH,CAAC;QAED,OAAO,OAAO,CAAA;IAChB,CAAC,CAAA;AACH,CAAC;AAED,SAAgB,6BAA6B;IAC3C,OAAO,CAAC,KAA6B,EAAE,IAAkB,EAAE,EAAE;QAC3D,MAAM,OAAO,GAAG,IAAA,oBAAS,EAAC,KAAK,EAAE,IAAI,CAAC,CAAA;QAEtC,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAClC,MAAM,IAAI,iBAAiB,CACzB,OAAO,EACP,GAAG,EACH,8CAA8C,CAC/C,CAAA;QACH,CAAC;QAED,OAAO,OAAO,CAAA;IAChB,CAAC,CAAA;AACH,CAAC;AAED,SAAgB,0BAA0B;IACxC,OAAO,CAAC,KAA6B,EAAE,IAAkB,EAAE,EAAE;QAC3D,4EAA4E;QAC5E,uDAAuD;QAEvD,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,IAAA,oBAAU,EAAC,KAAK,CAAC,CAAA;QAEhD,MAAM,OAAO,GAAG,IAAA,oBAAS,EAAC,KAAK,EAAE,IAAI,CAAC,CAAA;QAEtC,mEAAmE;QACnE,IAAI,QAAQ,KAAK,OAAO,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAClD,MAAM,IAAI,iBAAiB,CACzB,OAAO,EACP,GAAG,EACH,IAAI,QAAQ,4BAA4B,CACzC,CAAA;QACH,CAAC;QAED,IAAI,CAAC,QAAQ,IAAI,IAAA,cAAI,EAAC,QAAQ,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,iBAAiB,CAAC,OAAO,EAAE,GAAG,EAAE,kBAAkB,CAAC,CAAA;QAC/D,CAAC;QAED,OAAO,OAAO,CAAA;IAChB,CAAC,CAAA;AACH,CAAC;AAEY,QAAA,8BAA8B,GAAG;IAC5C,aAAa;IACb,eAAe;IACf,aAAa;IACb,eAAe;IACf,aAAa;IACb,eAAe;IACf,uBAAuB;IACvB,yBAAyB;CAC1B,CAAA;AAED,SAAgB,mCAAmC,CACjD,WAA6B,sCAA8B;IAE3D,MAAM,OAAO,GAAG,IAAI,GAAG,CAAS,QAAQ,CAAC,CAAA;IAEzC,2EAA2E;IAC3E,kBAAkB;IAClB,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,oBAAS,CAAA;IAClB,CAAC;IAED,OAAO,KAAK,EAAE,KAA6B,EAAE,IAAkB,EAAE,EAAE;QACjE,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAA,oBAAU,EAAC,KAAK,CAAC,CAAA;QAEtC,MAAM,OAAO,GAAG,IAAA,oBAAS,EAAC,KAAK,EAAE,IAAI,CAAC,CAAA;QAEtC,yBAAyB;QACzB,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,iBAAiB,CAAC,OAAO,EAAE,GAAG,EAAE,oBAAoB,CAAC,CAAA;QACjE,CAAC;QAED,wBAAwB;QACxB,IAAI,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QAClC,OAAO,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC;YACrB,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;YAC5C,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC,EAAE,CAAC;gBAClC,MAAM,IAAI,iBAAiB,CAAC,OAAO,EAAE,GAAG,EAAE,oBAAoB,CAAC,CAAA;YACjE,CAAC;YACD,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,CAAC,CAAA;QAC5C,CAAC;QAED,OAAO,OAAO,CAAA;IAChB,CAAC,CAAA;AACH,CAAC"}
|
package/dist/fetch-response.js
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.FetchResponseError = void 0;
|
|
4
|
+
exports.peekJson = peekJson;
|
|
5
|
+
exports.checkLength = checkLength;
|
|
6
|
+
exports.extractLength = extractLength;
|
|
7
|
+
exports.extractMime = extractMime;
|
|
8
|
+
exports.cancelBodyOnError = cancelBodyOnError;
|
|
9
|
+
exports.fetchOkProcessor = fetchOkProcessor;
|
|
10
|
+
exports.fetchOkTransformer = fetchOkTransformer;
|
|
11
|
+
exports.fetchMaxSizeProcessor = fetchMaxSizeProcessor;
|
|
12
|
+
exports.fetchResponseMaxSizeChecker = fetchResponseMaxSizeChecker;
|
|
13
|
+
exports.fetchTypeProcessor = fetchTypeProcessor;
|
|
14
|
+
exports.fetchResponseTypeChecker = fetchResponseTypeChecker;
|
|
15
|
+
exports.fetchResponseJsonTranformer = fetchResponseJsonTranformer;
|
|
16
|
+
exports.fetchJsonProcessor = fetchJsonProcessor;
|
|
17
|
+
exports.fetchJsonZodProcessor = fetchJsonZodProcessor;
|
|
4
18
|
const pipe_1 = require("@atproto-labs/pipe");
|
|
5
19
|
const fetch_error_js_1 = require("./fetch-error.js");
|
|
6
20
|
const transformed_response_js_1 = require("./transformed-response.js");
|
|
@@ -68,7 +82,6 @@ async function peekJson(response, maxSize = Infinity) {
|
|
|
68
82
|
// 3) Parse the JSON
|
|
69
83
|
return limitedResponse.json();
|
|
70
84
|
}
|
|
71
|
-
exports.peekJson = peekJson;
|
|
72
85
|
function checkLength(response, maxBytes) {
|
|
73
86
|
// Note: negation accounts for invalid value types (NaN, non numbers)
|
|
74
87
|
if (!(maxBytes >= 0)) {
|
|
@@ -80,7 +93,6 @@ function checkLength(response, maxBytes) {
|
|
|
80
93
|
}
|
|
81
94
|
return length;
|
|
82
95
|
}
|
|
83
|
-
exports.checkLength = checkLength;
|
|
84
96
|
function extractLength(response) {
|
|
85
97
|
const contentLength = response.headers.get('Content-Length');
|
|
86
98
|
if (contentLength == null)
|
|
@@ -94,14 +106,12 @@ function extractLength(response) {
|
|
|
94
106
|
}
|
|
95
107
|
return length;
|
|
96
108
|
}
|
|
97
|
-
exports.extractLength = extractLength;
|
|
98
109
|
function extractMime(response) {
|
|
99
110
|
const contentType = response.headers.get('Content-Type');
|
|
100
111
|
if (contentType == null)
|
|
101
112
|
return undefined;
|
|
102
113
|
return contentType.split(';', 1)[0].trim();
|
|
103
114
|
}
|
|
104
|
-
exports.extractMime = extractMime;
|
|
105
115
|
/**
|
|
106
116
|
* If the transformer results in an error, ensure that the response body is
|
|
107
117
|
* consumed as, in some environments (Node 👀), the response will not
|
|
@@ -123,19 +133,16 @@ function cancelBodyOnError(transformer, onCancellationError = util_js_1.logCance
|
|
|
123
133
|
}
|
|
124
134
|
};
|
|
125
135
|
}
|
|
126
|
-
exports.cancelBodyOnError = cancelBodyOnError;
|
|
127
136
|
function fetchOkProcessor(customMessage) {
|
|
128
137
|
return cancelBodyOnError((response) => {
|
|
129
138
|
return fetchOkTransformer(response, customMessage);
|
|
130
139
|
});
|
|
131
140
|
}
|
|
132
|
-
exports.fetchOkProcessor = fetchOkProcessor;
|
|
133
141
|
async function fetchOkTransformer(response, customMessage) {
|
|
134
142
|
if (response.ok)
|
|
135
143
|
return response;
|
|
136
144
|
throw await FetchResponseError.from(response, customMessage);
|
|
137
145
|
}
|
|
138
|
-
exports.fetchOkTransformer = fetchOkTransformer;
|
|
139
146
|
function fetchMaxSizeProcessor(maxBytes) {
|
|
140
147
|
if (maxBytes === Infinity)
|
|
141
148
|
return (response) => response;
|
|
@@ -146,7 +153,6 @@ function fetchMaxSizeProcessor(maxBytes) {
|
|
|
146
153
|
return fetchResponseMaxSizeChecker(response, maxBytes);
|
|
147
154
|
});
|
|
148
155
|
}
|
|
149
|
-
exports.fetchMaxSizeProcessor = fetchMaxSizeProcessor;
|
|
150
156
|
function fetchResponseMaxSizeChecker(response, maxBytes) {
|
|
151
157
|
if (maxBytes === Infinity)
|
|
152
158
|
return response;
|
|
@@ -158,7 +164,6 @@ function fetchResponseMaxSizeChecker(response, maxBytes) {
|
|
|
158
164
|
const transform = new util_js_1.MaxBytesTransformStream(maxBytes);
|
|
159
165
|
return new transformed_response_js_1.TransformedResponse(response, transform);
|
|
160
166
|
}
|
|
161
|
-
exports.fetchResponseMaxSizeChecker = fetchResponseMaxSizeChecker;
|
|
162
167
|
function fetchTypeProcessor(expectedMime, contentTypeRequired = true) {
|
|
163
168
|
const isExpected = typeof expectedMime === 'string'
|
|
164
169
|
? (mimeType) => mimeType === expectedMime
|
|
@@ -169,7 +174,6 @@ function fetchTypeProcessor(expectedMime, contentTypeRequired = true) {
|
|
|
169
174
|
return fetchResponseTypeChecker(response, isExpected, contentTypeRequired);
|
|
170
175
|
});
|
|
171
176
|
}
|
|
172
|
-
exports.fetchTypeProcessor = fetchTypeProcessor;
|
|
173
177
|
async function fetchResponseTypeChecker(response, isExpectedMime, contentTypeRequired = true) {
|
|
174
178
|
const mimeType = extractMime(response);
|
|
175
179
|
if (mimeType) {
|
|
@@ -182,7 +186,6 @@ async function fetchResponseTypeChecker(response, isExpectedMime, contentTypeReq
|
|
|
182
186
|
}
|
|
183
187
|
return response;
|
|
184
188
|
}
|
|
185
|
-
exports.fetchResponseTypeChecker = fetchResponseTypeChecker;
|
|
186
189
|
async function fetchResponseJsonTranformer(response) {
|
|
187
190
|
try {
|
|
188
191
|
const json = (await response.json());
|
|
@@ -192,13 +195,10 @@ async function fetchResponseJsonTranformer(response) {
|
|
|
192
195
|
throw new FetchResponseError(response, 502, 'Unable to parse response as JSON', { cause });
|
|
193
196
|
}
|
|
194
197
|
}
|
|
195
|
-
exports.fetchResponseJsonTranformer = fetchResponseJsonTranformer;
|
|
196
198
|
function fetchJsonProcessor(expectedMime = /^application\/(?:[^+]+\+)?json$/, contentTypeRequired = true) {
|
|
197
199
|
return (0, pipe_1.pipe)(fetchTypeProcessor(expectedMime, contentTypeRequired), cancelBodyOnError((fetchResponseJsonTranformer)));
|
|
198
200
|
}
|
|
199
|
-
exports.fetchJsonProcessor = fetchJsonProcessor;
|
|
200
201
|
function fetchJsonZodProcessor(schema, params) {
|
|
201
202
|
return async (jsonResponse) => schema.parseAsync(jsonResponse.json, params);
|
|
202
203
|
}
|
|
203
|
-
exports.fetchJsonZodProcessor = fetchJsonZodProcessor;
|
|
204
204
|
//# sourceMappingURL=fetch-response.js.map
|
|
@@ -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/dist/fetch-wrap.d.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { Fetch, FetchContext } from './fetch.js';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
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>;
|
|
5
9
|
export declare const timedFetch: <C = FetchContext>(timeout?: number, fetch?: Fetch<C>) => Fetch<C>;
|
|
6
10
|
/**
|
|
7
11
|
* Wraps a fetch function to bind it to a specific context, and wrap any thrown
|
|
@@ -37,7 +41,8 @@ export declare const timedFetch: <C = FetchContext>(timeout?: number, fetch?: Fe
|
|
|
37
41
|
* }
|
|
38
42
|
* ```
|
|
39
43
|
*/
|
|
40
|
-
export declare function bindFetch<C = FetchContext>(fetch?: Fetch<C>, context?: C): ((this: unknown, input: string |
|
|
41
|
-
bind(context: unknown): (input: string |
|
|
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>;
|
|
42
46
|
};
|
|
47
|
+
export {};
|
|
43
48
|
//# sourceMappingURL=fetch-wrap.d.ts.map
|
package/dist/fetch-wrap.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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,
|
|
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,GAAI,CAAC,2CAEnB,KAAK,CAAC,CAAC,CAAC,KACd,KAAK,CAAC,CAAC,CAqCT,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,SAAS,CAAC,CAAC,GAAG,YAAY,EACxC,KAAK,GAAE,KAAK,CAAC,CAAC,CAAoB,EAClC,OAAO,GAAE,CAAmB;;EAS7B"}
|
package/dist/fetch-wrap.js
CHANGED
|
@@ -1,27 +1,48 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.timedFetch = void 0;
|
|
4
|
+
exports.loggedFetch = loggedFetch;
|
|
5
|
+
exports.bindFetch = bindFetch;
|
|
4
6
|
const fetch_request_js_1 = require("./fetch-request.js");
|
|
5
7
|
const fetch_js_1 = require("./fetch.js");
|
|
6
8
|
const transformed_response_js_1 = require("./transformed-response.js");
|
|
7
9
|
const util_js_1 = require("./util.js");
|
|
8
|
-
function loggedFetch(fetch = globalThis.fetch) {
|
|
10
|
+
function loggedFetch({ fetch = globalThis.fetch, logRequest = true, logResponse = true, logError = true, }) {
|
|
11
|
+
const onRequest = logRequest === true
|
|
12
|
+
? async (request) => {
|
|
13
|
+
const requestMessage = await (0, util_js_1.stringifyMessage)(request);
|
|
14
|
+
console.info(`> ${request.method} ${request.url}\n${(0, util_js_1.padLines)(requestMessage, ' ')}`);
|
|
15
|
+
}
|
|
16
|
+
: logRequest || undefined;
|
|
17
|
+
const onResponse = logResponse === true
|
|
18
|
+
? async (response) => {
|
|
19
|
+
const responseMessage = await (0, util_js_1.stringifyMessage)(response.clone());
|
|
20
|
+
console.info(`< HTTP/1.1 ${response.status} ${response.statusText}\n${(0, util_js_1.padLines)(responseMessage, ' ')}`);
|
|
21
|
+
}
|
|
22
|
+
: logResponse || undefined;
|
|
23
|
+
const onError = logError === true
|
|
24
|
+
? async (error) => {
|
|
25
|
+
console.error(`< Error:`, error);
|
|
26
|
+
}
|
|
27
|
+
: logError || undefined;
|
|
28
|
+
if (!onRequest && !onResponse && !onError)
|
|
29
|
+
return fetch;
|
|
9
30
|
return (0, fetch_js_1.toRequestTransformer)(async function (request) {
|
|
10
|
-
|
|
11
|
-
|
|
31
|
+
if (onRequest)
|
|
32
|
+
await onRequest(request);
|
|
12
33
|
try {
|
|
13
34
|
const response = await fetch.call(this, request);
|
|
14
|
-
|
|
15
|
-
|
|
35
|
+
if (onResponse)
|
|
36
|
+
await onResponse(response, request);
|
|
16
37
|
return response;
|
|
17
38
|
}
|
|
18
39
|
catch (error) {
|
|
19
|
-
|
|
40
|
+
if (onError)
|
|
41
|
+
await onError(error, request);
|
|
20
42
|
throw error;
|
|
21
43
|
}
|
|
22
44
|
});
|
|
23
45
|
}
|
|
24
|
-
exports.loggedFetch = loggedFetch;
|
|
25
46
|
const timedFetch = (timeout = 60e3, fetch = globalThis.fetch) => {
|
|
26
47
|
if (timeout === Infinity)
|
|
27
48
|
return fetch;
|
|
@@ -100,5 +121,4 @@ function bindFetch(fetch = globalThis.fetch, context = globalThis) {
|
|
|
100
121
|
}
|
|
101
122
|
});
|
|
102
123
|
}
|
|
103
|
-
exports.bindFetch = bindFetch;
|
|
104
124
|
//# sourceMappingURL=fetch-wrap.js.map
|
package/dist/fetch-wrap.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-wrap.js","sourceRoot":"","sources":["../src/fetch-wrap.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"fetch-wrap.js","sourceRoot":"","sources":["../src/fetch-wrap.ts"],"names":[],"mappings":"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"}
|
package/dist/fetch.js
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.toRequestTransformer = toRequestTransformer;
|
|
4
|
+
exports.asRequest = asRequest;
|
|
4
5
|
function toRequestTransformer(requestTransformer) {
|
|
5
6
|
return function (input, init) {
|
|
6
7
|
return requestTransformer.call(this, asRequest(input, init));
|
|
7
8
|
};
|
|
8
9
|
}
|
|
9
|
-
exports.toRequestTransformer = toRequestTransformer;
|
|
10
10
|
function asRequest(input, init) {
|
|
11
11
|
if (!init && input instanceof Request)
|
|
12
12
|
return input;
|
|
13
13
|
return new Request(input, init);
|
|
14
14
|
}
|
|
15
|
-
exports.asRequest = asRequest;
|
|
16
15
|
//# 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,oDASC;AAED,8BAMC;AAjBD,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;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"}
|
package/dist/util.d.ts
CHANGED
|
@@ -52,4 +52,5 @@ export declare function logCancellationError(err: unknown): void;
|
|
|
52
52
|
export declare function stringifyMessage(input: Body & {
|
|
53
53
|
headers: Headers;
|
|
54
54
|
}): Promise<string>;
|
|
55
|
+
export declare const extractUrl: (input: Request | string | URL) => URL;
|
|
55
56
|
//# sourceMappingURL=util.d.ts.map
|
package/dist/util.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAA;AACzD,MAAM,MAAM,IAAI,GAAG,UAAU,GAAG,IAAI,EAAE,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAA;CAAE,CAAA;AAC5E,MAAM,MAAM,UAAU,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAA;AAChD,MAAM,MAAM,SAAS,GAAG,IAAI,EAAE,CAAA;AAE9B,MAAM,MAAM,qBAAqB,CAC/B,CAAC,EACD,EAAE,SAAS,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,GAAG,IAC3B,EAAE,SAAS,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,KAAK,MAAM,CAAC,GACxC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG;IAC7B,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,CAAA;CACpC,GACD,KAAK,CAAA;AAET,wBAAgB,IAAI,CAAC,QAAQ,EAAE,MAAM,WAQpC;AAGD,eAAO,MAAM,QAAQ,
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAA;AACzD,MAAM,MAAM,IAAI,GAAG,UAAU,GAAG,IAAI,EAAE,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAA;CAAE,CAAA;AAC5E,MAAM,MAAM,UAAU,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAA;AAChD,MAAM,MAAM,SAAS,GAAG,IAAI,EAAE,CAAA;AAE9B,MAAM,MAAM,qBAAqB,CAC/B,CAAC,EACD,EAAE,SAAS,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,GAAG,IAC3B,EAAE,SAAS,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,KAAK,MAAM,CAAC,GACxC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG;IAC7B,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,CAAA;CACpC,GACD,KAAK,CAAA;AAET,wBAAgB,IAAI,CAAC,QAAQ,EAAE,MAAM,WAQpC;AAGD,eAAO,MAAM,QAAQ,GAAI,CAAC,KAAK,CAAC,8HAe/B,CAAA;AAED,eAAO,MAAM,QAAQ,GAAI,CAAC,KAAK,CAAC,6BAA4C,CAAA;AAE5E,qBAAa,uBAAwB,SAAQ,eAAe,CAC1D,UAAU,EACV,UAAU,CACX;gBACa,QAAQ,EAAE,MAAM;CAqB7B;AAGD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,UAGlD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAsB,UAAU,CAC9B,IAAI,EAAE,IAAI,EACV,mBAAmB,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC,GACrD,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAEvD;AAED,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,IAAI,GAAG;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,mBAQxE;AA2BD,eAAO,MAAM,UAAU,UAAW,OAAO,GAAG,MAAM,GAAG,GAAG,QAK9B,CAAA"}
|
package/dist/util.js
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// @TODO: Move some of these to a shared package ?
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.
|
|
4
|
+
exports.extractUrl = exports.MaxBytesTransformStream = exports.ifString = exports.ifObject = void 0;
|
|
5
|
+
exports.isIp = isIp;
|
|
6
|
+
exports.padLines = padLines;
|
|
7
|
+
exports.cancelBody = cancelBody;
|
|
8
|
+
exports.logCancellationError = logCancellationError;
|
|
9
|
+
exports.stringifyMessage = stringifyMessage;
|
|
5
10
|
function isIp(hostname) {
|
|
6
11
|
// IPv4
|
|
7
12
|
if (hostname.match(/^\d+\.\d+\.\d+\.\d+$/))
|
|
@@ -11,7 +16,6 @@ function isIp(hostname) {
|
|
|
11
16
|
return true;
|
|
12
17
|
return false;
|
|
13
18
|
}
|
|
14
|
-
exports.isIp = isIp;
|
|
15
19
|
const plainObjectProto = Object.prototype;
|
|
16
20
|
const ifObject = (v) => {
|
|
17
21
|
if (typeof v === 'object' && v != null && !Array.isArray(v)) {
|
|
@@ -52,7 +56,6 @@ function padLines(input, pad) {
|
|
|
52
56
|
return input;
|
|
53
57
|
return pad + input.replace(LINE_BREAK, `$&${pad}`);
|
|
54
58
|
}
|
|
55
|
-
exports.padLines = padLines;
|
|
56
59
|
/**
|
|
57
60
|
* @param [onCancellationError] - Callback that will trigger to asynchronously
|
|
58
61
|
* handle any error that occurs while cancelling the response body. Providing
|
|
@@ -101,11 +104,9 @@ async function cancelBody(body, onCancellationError) {
|
|
|
101
104
|
}
|
|
102
105
|
}
|
|
103
106
|
}
|
|
104
|
-
exports.cancelBody = cancelBody;
|
|
105
107
|
function logCancellationError(err) {
|
|
106
108
|
console.warn('Failed to cancel response body', err);
|
|
107
109
|
}
|
|
108
|
-
exports.logCancellationError = logCancellationError;
|
|
109
110
|
async function stringifyMessage(input) {
|
|
110
111
|
try {
|
|
111
112
|
const headers = stringifyHeaders(input.headers);
|
|
@@ -116,7 +117,6 @@ async function stringifyMessage(input) {
|
|
|
116
117
|
void cancelBody(input, 'log');
|
|
117
118
|
}
|
|
118
119
|
}
|
|
119
|
-
exports.stringifyMessage = stringifyMessage;
|
|
120
120
|
function stringifyHeaders(headers) {
|
|
121
121
|
return Array.from(headers)
|
|
122
122
|
.map(([name, value]) => `${name}: ${value}`)
|
|
@@ -139,4 +139,10 @@ async function stringifyBody(body) {
|
|
|
139
139
|
return '[Body could not be read]';
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
|
+
const extractUrl = (input) => typeof input === 'string'
|
|
143
|
+
? new URL(input)
|
|
144
|
+
: input instanceof URL
|
|
145
|
+
? input
|
|
146
|
+
: new URL(input.url);
|
|
147
|
+
exports.extractUrl = extractUrl;
|
|
142
148
|
//# sourceMappingURL=util.js.map
|
package/dist/util.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":";AAAA,kDAAkD;;;AAgBlD,SAAgB,IAAI,CAAC,QAAgB;IACnC,OAAO;IACP,IAAI,QAAQ,CAAC,KAAK,CAAC,sBAAsB,CAAC;QAAE,OAAO,IAAI,CAAA;IAEvD,OAAO;IACP,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAA;IAEnE,OAAO,KAAK,CAAA;AACd,CAAC;
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atproto-labs/fetch",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Isomorphic wrapper utilities for fetch API",
|
|
6
6
|
"keywords": [
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"@atproto-labs/pipe": "0.1.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"typescript": "^5.
|
|
29
|
+
"typescript": "^5.6.3"
|
|
30
30
|
},
|
|
31
31
|
"optionalDependencies": {
|
|
32
32
|
"zod": "^3.23.8"
|
package/src/fetch-error.ts
CHANGED
|
@@ -1,59 +1,13 @@
|
|
|
1
|
-
export class FetchError extends Error {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const info = extractInfo(extractRootCause(options?.cause))
|
|
7
|
-
statusCode = statusCode ?? info[0]
|
|
8
|
-
message = message || info[1]
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
super(message, options)
|
|
12
|
-
|
|
13
|
-
this.statusCode = statusCode
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function extractRootCause(err: unknown): unknown {
|
|
18
|
-
// Unwrap the Network error from undici (i.e. Node's internal fetch() implementation)
|
|
19
|
-
// https://github.com/nodejs/undici/blob/3274c975947ce11a08508743df026f73598bfead/lib/web/fetch/index.js#L223-L228
|
|
20
|
-
if (
|
|
21
|
-
err instanceof TypeError &&
|
|
22
|
-
err.message === 'fetch failed' &&
|
|
23
|
-
err.cause !== undefined
|
|
1
|
+
export abstract class FetchError extends Error {
|
|
2
|
+
constructor(
|
|
3
|
+
public readonly statusCode: number,
|
|
4
|
+
message?: string,
|
|
5
|
+
options?: ErrorOptions,
|
|
24
6
|
) {
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
return err
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function extractInfo(err: unknown): [statusCode: number, message: string] {
|
|
32
|
-
if (typeof err === 'string' && err.length > 0) {
|
|
33
|
-
return [500, err]
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
if (!(err instanceof Error)) {
|
|
37
|
-
return [500, 'Failed to fetch']
|
|
7
|
+
super(message, options)
|
|
38
8
|
}
|
|
39
9
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
switch (true) {
|
|
43
|
-
case code === 'ENOTFOUND':
|
|
44
|
-
return [400, 'Invalid hostname']
|
|
45
|
-
case code === 'ECONNREFUSED':
|
|
46
|
-
return [502, 'Connection refused']
|
|
47
|
-
case code === 'DEPTH_ZERO_SELF_SIGNED_CERT':
|
|
48
|
-
return [502, 'Self-signed certificate']
|
|
49
|
-
case code.startsWith('ERR_TLS'):
|
|
50
|
-
return [502, 'TLS error']
|
|
51
|
-
case code.startsWith('ECONN'):
|
|
52
|
-
return [502, 'Connection error']
|
|
53
|
-
default:
|
|
54
|
-
return [500, `${code} error`]
|
|
55
|
-
}
|
|
10
|
+
get expose() {
|
|
11
|
+
return true
|
|
56
12
|
}
|
|
57
|
-
|
|
58
|
-
return [500, err.message]
|
|
59
13
|
}
|
package/src/fetch-request.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FetchError } from './fetch-error.js'
|
|
2
2
|
import { asRequest } from './fetch.js'
|
|
3
|
-
import { isIp } from './util.js'
|
|
3
|
+
import { extractUrl, isIp } from './util.js'
|
|
4
4
|
|
|
5
5
|
export class FetchRequestError extends FetchError {
|
|
6
6
|
constructor(
|
|
@@ -9,35 +9,132 @@ export class FetchRequestError extends FetchError {
|
|
|
9
9
|
message?: string,
|
|
10
10
|
options?: ErrorOptions,
|
|
11
11
|
) {
|
|
12
|
+
if (statusCode == null || !message) {
|
|
13
|
+
const info = extractInfo(extractRootCause(options?.cause))
|
|
14
|
+
statusCode ??= info[0]
|
|
15
|
+
message ||= info[1]
|
|
16
|
+
}
|
|
17
|
+
|
|
12
18
|
super(statusCode, message, options)
|
|
13
19
|
}
|
|
14
20
|
|
|
21
|
+
get expose() {
|
|
22
|
+
// A 500 request error means that the request was not made due to an infra,
|
|
23
|
+
// programming or server side issue. The message should no be exposed to
|
|
24
|
+
// downstream clients.
|
|
25
|
+
return this.statusCode !== 500
|
|
26
|
+
}
|
|
27
|
+
|
|
15
28
|
static from(request: Request, cause: unknown): FetchRequestError {
|
|
16
29
|
if (cause instanceof FetchRequestError) return cause
|
|
17
30
|
return new FetchRequestError(request, undefined, undefined, { cause })
|
|
18
31
|
}
|
|
19
32
|
}
|
|
20
33
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
34
|
+
function extractRootCause(err: unknown): unknown {
|
|
35
|
+
// Unwrap the Network error from undici (i.e. Node's internal fetch() implementation)
|
|
36
|
+
// https://github.com/nodejs/undici/blob/3274c975947ce11a08508743df026f73598bfead/lib/web/fetch/index.js#L223-L228
|
|
37
|
+
if (
|
|
38
|
+
err instanceof TypeError &&
|
|
39
|
+
err.message === 'fetch failed' &&
|
|
40
|
+
err.cause !== undefined
|
|
41
|
+
) {
|
|
42
|
+
return err.cause
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return err
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function extractInfo(err: unknown): [statusCode: number, message: string] {
|
|
49
|
+
if (typeof err === 'string' && err.length > 0) {
|
|
50
|
+
return [500, err]
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (!(err instanceof Error)) {
|
|
54
|
+
return [500, 'Failed to fetch']
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Undici fetch() "network" errors
|
|
58
|
+
switch (err.message) {
|
|
59
|
+
case 'failed to fetch the data URL':
|
|
60
|
+
return [400, err.message]
|
|
61
|
+
case 'unexpected redirect':
|
|
62
|
+
case 'cors failure':
|
|
63
|
+
case 'blocked':
|
|
64
|
+
case 'proxy authentication required':
|
|
65
|
+
// These cases could be represented either as a 4xx user error (invalid
|
|
66
|
+
// URL provided), or as a 5xx server error (server didn't behave as
|
|
67
|
+
// expected).
|
|
68
|
+
return [502, err.message]
|
|
69
|
+
}
|
|
27
70
|
|
|
28
|
-
|
|
29
|
-
const
|
|
71
|
+
// NodeJS errors
|
|
72
|
+
const code = err['code']
|
|
73
|
+
if (typeof code === 'string') {
|
|
74
|
+
switch (true) {
|
|
75
|
+
case code === 'ENOTFOUND':
|
|
76
|
+
return [400, 'Invalid hostname']
|
|
77
|
+
case code === 'ECONNREFUSED':
|
|
78
|
+
return [502, 'Connection refused']
|
|
79
|
+
case code === 'DEPTH_ZERO_SELF_SIGNED_CERT':
|
|
80
|
+
return [502, 'Self-signed certificate']
|
|
81
|
+
case code.startsWith('ERR_TLS'):
|
|
82
|
+
return [502, 'TLS error']
|
|
83
|
+
case code.startsWith('ECONN'):
|
|
84
|
+
return [502, 'Connection error']
|
|
85
|
+
default:
|
|
86
|
+
return [500, `${code} error`]
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return [500, err.message]
|
|
91
|
+
}
|
|
30
92
|
|
|
93
|
+
export function protocolCheckRequestTransform(protocols: {
|
|
94
|
+
'about:'?: boolean
|
|
95
|
+
'blob:'?: boolean
|
|
96
|
+
'data:'?: boolean
|
|
97
|
+
'file:'?: boolean
|
|
98
|
+
'http:'?: boolean | { allowCustomPort: boolean }
|
|
99
|
+
'https:'?: boolean | { allowCustomPort: boolean }
|
|
100
|
+
}) {
|
|
31
101
|
return (input: Request | string | URL, init?: RequestInit) => {
|
|
32
|
-
const { protocol } = extractUrl(input)
|
|
102
|
+
const { protocol, port } = extractUrl(input)
|
|
33
103
|
|
|
34
104
|
const request = asRequest(input, init)
|
|
35
105
|
|
|
36
|
-
|
|
106
|
+
const config: undefined | boolean | { allowCustomPort?: boolean } =
|
|
107
|
+
Object.hasOwn(protocols, protocol) ? protocols[protocol] : undefined
|
|
108
|
+
|
|
109
|
+
if (!config) {
|
|
110
|
+
throw new FetchRequestError(
|
|
111
|
+
request,
|
|
112
|
+
400,
|
|
113
|
+
`Forbidden protocol "${protocol}"`,
|
|
114
|
+
)
|
|
115
|
+
} else if (config === true) {
|
|
116
|
+
// Safe to proceed
|
|
117
|
+
} else if (!config['allowCustomPort'] && port !== '') {
|
|
37
118
|
throw new FetchRequestError(
|
|
38
119
|
request,
|
|
39
120
|
400,
|
|
40
|
-
`
|
|
121
|
+
`Custom ${protocol} ports not allowed`,
|
|
122
|
+
)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return request
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export function redirectCheckRequestTransform() {
|
|
130
|
+
return (input: Request | string | URL, init?: RequestInit) => {
|
|
131
|
+
const request = asRequest(input, init)
|
|
132
|
+
|
|
133
|
+
if (request.redirect === 'follow') {
|
|
134
|
+
throw new FetchRequestError(
|
|
135
|
+
request,
|
|
136
|
+
500,
|
|
137
|
+
'Request redirect must be "error" or "manual"',
|
|
41
138
|
)
|
|
42
139
|
}
|
|
43
140
|
|
|
@@ -45,7 +142,7 @@ export function protocolCheckRequestTransform(protocols: Iterable<string>) {
|
|
|
45
142
|
}
|
|
46
143
|
}
|
|
47
144
|
|
|
48
|
-
export function
|
|
145
|
+
export function requireHostHeaderTransform() {
|
|
49
146
|
return (input: Request | string | URL, init?: RequestInit) => {
|
|
50
147
|
// Note that fetch() will automatically add the Host header from the URL and
|
|
51
148
|
// discard any Host header manually set in the request.
|
|
@@ -90,7 +187,7 @@ export function forbiddenDomainNameRequestTransform(
|
|
|
90
187
|
// Optimization: if no forbidden domain names are provided, we can skip the
|
|
91
188
|
// check entirely.
|
|
92
189
|
if (denySet.size === 0) {
|
|
93
|
-
return
|
|
190
|
+
return asRequest
|
|
94
191
|
}
|
|
95
192
|
|
|
96
193
|
return async (input: Request | string | URL, init?: RequestInit) => {
|
package/src/fetch-wrap.ts
CHANGED
|
@@ -3,29 +3,57 @@ import { Fetch, FetchContext, toRequestTransformer } from './fetch.js'
|
|
|
3
3
|
import { TransformedResponse } from './transformed-response.js'
|
|
4
4
|
import { padLines, stringifyMessage } from './util.js'
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
type LogFn<Args extends unknown[]> = (...args: Args) => void | PromiseLike<void>
|
|
7
|
+
|
|
8
|
+
export function loggedFetch<C = FetchContext>({
|
|
9
|
+
fetch = globalThis.fetch as Fetch<C>,
|
|
10
|
+
logRequest = true as boolean | LogFn<[request: Request]>,
|
|
11
|
+
logResponse = true as boolean | LogFn<[response: Response, request: Request]>,
|
|
12
|
+
logError = true as boolean | LogFn<[error: unknown, request: Request]>,
|
|
13
|
+
}) {
|
|
14
|
+
const onRequest =
|
|
15
|
+
logRequest === true
|
|
16
|
+
? async (request) => {
|
|
17
|
+
const requestMessage = await stringifyMessage(request)
|
|
18
|
+
console.info(
|
|
19
|
+
`> ${request.method} ${request.url}\n${padLines(requestMessage, ' ')}`,
|
|
20
|
+
)
|
|
21
|
+
}
|
|
22
|
+
: logRequest || undefined
|
|
23
|
+
|
|
24
|
+
const onResponse =
|
|
25
|
+
logResponse === true
|
|
26
|
+
? async (response) => {
|
|
27
|
+
const responseMessage = await stringifyMessage(response.clone())
|
|
28
|
+
console.info(
|
|
29
|
+
`< HTTP/1.1 ${response.status} ${response.statusText}\n${padLines(responseMessage, ' ')}`,
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
: logResponse || undefined
|
|
33
|
+
|
|
34
|
+
const onError =
|
|
35
|
+
logError === true
|
|
36
|
+
? async (error) => {
|
|
37
|
+
console.error(`< Error:`, error)
|
|
38
|
+
}
|
|
39
|
+
: logError || undefined
|
|
40
|
+
|
|
41
|
+
if (!onRequest && !onResponse && !onError) return fetch
|
|
42
|
+
|
|
9
43
|
return toRequestTransformer(async function (
|
|
10
44
|
this: C,
|
|
11
45
|
request,
|
|
12
46
|
): Promise<Response> {
|
|
13
|
-
|
|
14
|
-
console.info(
|
|
15
|
-
`> ${request.method} ${request.url}\n${padLines(requestMessage, ' ')}`,
|
|
16
|
-
)
|
|
47
|
+
if (onRequest) await onRequest(request)
|
|
17
48
|
|
|
18
49
|
try {
|
|
19
50
|
const response = await fetch.call(this, request)
|
|
20
51
|
|
|
21
|
-
|
|
22
|
-
console.info(
|
|
23
|
-
`< HTTP/1.1 ${response.status} ${response.statusText}\n${padLines(responseMessage, ' ')}`,
|
|
24
|
-
)
|
|
52
|
+
if (onResponse) await onResponse(response, request)
|
|
25
53
|
|
|
26
54
|
return response
|
|
27
55
|
} catch (error) {
|
|
28
|
-
|
|
56
|
+
if (onError) await onError(error, request)
|
|
29
57
|
|
|
30
58
|
throw error
|
|
31
59
|
}
|
package/src/util.ts
CHANGED
|
@@ -167,3 +167,10 @@ async function stringifyBody(body: Body) {
|
|
|
167
167
|
return '[Body could not be read]'
|
|
168
168
|
}
|
|
169
169
|
}
|
|
170
|
+
|
|
171
|
+
export const extractUrl = (input: Request | string | URL) =>
|
|
172
|
+
typeof input === 'string'
|
|
173
|
+
? new URL(input)
|
|
174
|
+
: input instanceof URL
|
|
175
|
+
? input
|
|
176
|
+
: new URL(input.url)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"root":["./src/fetch-error.ts","./src/fetch-request.ts","./src/fetch-response.ts","./src/fetch-wrap.ts","./src/fetch.ts","./src/index.ts","./src/transformed-response.ts","./src/util.ts"],"version":"5.6.3"}
|