@fedify/vocab-runtime 2.5.0-dev.2339 → 2.5.0-dev.2358
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/deno.json +1 -1
- package/dist/{docloader-BMHljyYb.d.cts → docloader-BBnBpbsG.d.cts} +34 -1
- package/dist/{docloader-BMHljyYb.d.ts → docloader-BBnBpbsG.d.ts} +34 -1
- package/dist/internal/jsonld-cache.d.cts +1 -1
- package/dist/internal/jsonld-cache.d.ts +1 -1
- package/dist/internal/portable-dereference.d.cts +2 -2
- package/dist/internal/portable-dereference.d.ts +2 -2
- package/dist/mod.cjs +86 -1
- package/dist/mod.d.cts +3 -3
- package/dist/mod.d.ts +3 -3
- package/dist/mod.js +86 -2
- package/dist/{portable-nkTiqH0w.d.ts → portable-BDydjp5H.d.ts} +1 -1
- package/dist/{portable-6Aj-7dZJ.d.cts → portable-Dfvcg_Wy.d.cts} +1 -1
- package/dist/tests/{body-CljcAHhk.cjs → body-D-hRjA32.cjs} +1 -1
- package/dist/tests/{body-B3dGxaBV.mjs → body-KGbLDTQ8.mjs} +1 -1
- package/dist/tests/body.test.cjs +1 -1
- package/dist/tests/body.test.mjs +1 -1
- package/dist/tests/decimal.test.cjs +3 -2
- package/dist/tests/decimal.test.mjs +3 -2
- package/dist/tests/{docloader-iFFvNZ4G.mjs → docloader-C9mXSLig.mjs} +3 -3
- package/dist/tests/{docloader-CMUtR3iO.cjs → docloader-DOQw_Oeb.cjs} +3 -3
- package/dist/tests/docloader.test.cjs +4 -4
- package/dist/tests/docloader.test.mjs +4 -4
- package/dist/tests/internal/portable-dereference.test.cjs +1 -1
- package/dist/tests/internal/portable-dereference.test.mjs +1 -1
- package/dist/tests/{portable-media-D-jFwVq0.mjs → portable-media-CKahyX8x.mjs} +2 -2
- package/dist/tests/{portable-media-D4Ah_iys.cjs → portable-media-DUnPNsfj.cjs} +2 -2
- package/dist/tests/portable-media.test.cjs +1 -1
- package/dist/tests/portable-media.test.mjs +1 -1
- package/dist/tests/portable-workers.test.cjs +1 -1
- package/dist/tests/portable-workers.test.mjs +1 -1
- package/dist/tests/request-6JGmUBqf.cjs +210 -0
- package/dist/tests/request-D7wirQVZ.mjs +167 -0
- package/dist/tests/request.test.cjs +58 -1
- package/dist/tests/request.test.mjs +58 -1
- package/package.json +1 -1
- package/src/mod.ts +1 -0
- package/src/request.test.ts +143 -1
- package/src/request.ts +113 -0
- package/dist/tests/request-BM1AsOPj.mjs +0 -82
- package/dist/tests/request-lSaiCxqI.cjs +0 -119
- package/dist/tests/{portable-dereference-qTLMqe2_.cjs → portable-dereference-DaTBBvCj.cjs} +1 -1
- package/dist/tests/{portable-dereference-DmTYDy2p.mjs → portable-dereference-sGRs_qdT.mjs} +1 -1
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
const require_rolldown_runtime = require("./rolldown-runtime-emK7D4bc.cjs");
|
|
2
|
+
const require_url = require("./url-BNakuZ8k.cjs");
|
|
3
|
+
let node_process = require("node:process");
|
|
4
|
+
node_process = require_rolldown_runtime.__toESM(node_process, 1);
|
|
5
|
+
//#region deno.json
|
|
6
|
+
var name = "@fedify/vocab-runtime";
|
|
7
|
+
var version = "2.5.0-dev.2358+1d1813b7";
|
|
8
|
+
//#endregion
|
|
9
|
+
//#region src/request.ts
|
|
10
|
+
/**
|
|
11
|
+
* Error thrown when fetching a JSON-LD document failed.
|
|
12
|
+
*/
|
|
13
|
+
var FetchError = class extends Error {
|
|
14
|
+
/**
|
|
15
|
+
* The URL that failed to fetch.
|
|
16
|
+
*/
|
|
17
|
+
url;
|
|
18
|
+
/**
|
|
19
|
+
* The HTTP response that failed, if available.
|
|
20
|
+
*/
|
|
21
|
+
response;
|
|
22
|
+
/**
|
|
23
|
+
* Constructs a new `FetchError`.
|
|
24
|
+
*
|
|
25
|
+
* @param url The URL that failed to fetch.
|
|
26
|
+
* @param message Error message.
|
|
27
|
+
* @param response The failed HTTP response, if available.
|
|
28
|
+
*/
|
|
29
|
+
constructor(url, message, response) {
|
|
30
|
+
super(message == null ? url.toString() : `${url}: ${message}`);
|
|
31
|
+
this.name = "FetchError";
|
|
32
|
+
this.url = typeof url === "string" ? new URL(url) : url;
|
|
33
|
+
this.response = response;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
const MAX_CAUSE_DEPTH = 8;
|
|
37
|
+
/**
|
|
38
|
+
* Guesses whether an error thrown by a document loader is transient,
|
|
39
|
+
* i.e., whether fetching the same document again later could succeed.
|
|
40
|
+
*
|
|
41
|
+
* This is a heuristic classification, not a guarantee. Callers that retry
|
|
42
|
+
* on transient errors should still bound the number of retries. The rules
|
|
43
|
+
* are:
|
|
44
|
+
*
|
|
45
|
+
* - A {@link UrlError} is transient only if its
|
|
46
|
+
* {@link UrlError.reason | reason} is `"dns"`; URLs disallowed by SSRF
|
|
47
|
+
* protection are permanent.
|
|
48
|
+
* - A {@link FetchError} with a {@link FetchError.response | response} is
|
|
49
|
+
* transient if the status is 5xx, 408 (Request Timeout), or 429 (Too Many
|
|
50
|
+
* Requests); other statuses such as 404 are permanent.
|
|
51
|
+
* - A {@link FetchError} without a response is classified by its `cause`,
|
|
52
|
+
* which is how timeouts are reported. Without a cause, it is permanent
|
|
53
|
+
* (e.g., redirect loops, too many redirections, or bodies that exceed the
|
|
54
|
+
* size limit).
|
|
55
|
+
* - A `TimeoutError` or `AbortError` is transient.
|
|
56
|
+
* - A `TypeError` from parsing an invalid URL is permanent; any other
|
|
57
|
+
* `TypeError` is transient, since `fetch()` reports network failures
|
|
58
|
+
* that way.
|
|
59
|
+
* - A `SyntaxError` (a malformed JSON body) is permanent.
|
|
60
|
+
* - An `AggregateError`, e.g., from trying several gateways, is transient
|
|
61
|
+
* if any of its errors is.
|
|
62
|
+
* - Any other error is treated as transient.
|
|
63
|
+
*
|
|
64
|
+
* @param error The error thrown by a document loader.
|
|
65
|
+
* @returns `true` if the error is likely transient, `false` if retrying is
|
|
66
|
+
* unlikely to help.
|
|
67
|
+
* @since 2.5.0
|
|
68
|
+
*/
|
|
69
|
+
function isTransientFetchError(error) {
|
|
70
|
+
return classifyFetchError(error, /* @__PURE__ */ new Set(), 0);
|
|
71
|
+
}
|
|
72
|
+
function classifyFetchError(error, path, depth) {
|
|
73
|
+
if (depth > MAX_CAUSE_DEPTH || path.has(error)) return true;
|
|
74
|
+
path.add(error);
|
|
75
|
+
try {
|
|
76
|
+
return classifyErrorShape(error, path, depth);
|
|
77
|
+
} finally {
|
|
78
|
+
path.delete(error);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function classifyErrorShape(error, path, depth) {
|
|
82
|
+
if (!(error instanceof Error) && !isNamedError(error)) return true;
|
|
83
|
+
const name = error.name;
|
|
84
|
+
if (error instanceof require_url.UrlError || name === "UrlError") return error.reason === "dns";
|
|
85
|
+
if (name === "BodyTooLargeError") return false;
|
|
86
|
+
if (error instanceof FetchError || name === "FetchError") {
|
|
87
|
+
const response = error.response;
|
|
88
|
+
if (isResponseLike(response)) {
|
|
89
|
+
const status = response.status;
|
|
90
|
+
return status >= 500 || status === 408 || status === 429;
|
|
91
|
+
}
|
|
92
|
+
const cause = error.cause;
|
|
93
|
+
if (cause == null) return false;
|
|
94
|
+
return classifyFetchError(cause, path, depth + 1);
|
|
95
|
+
}
|
|
96
|
+
if (error instanceof AggregateError || name === "AggregateError") {
|
|
97
|
+
const errors = error.errors;
|
|
98
|
+
if (!Array.isArray(errors) || errors.length < 1) return true;
|
|
99
|
+
return errors.some((e) => classifyFetchError(e, path, depth + 1));
|
|
100
|
+
}
|
|
101
|
+
if (name === "TimeoutError" || name === "AbortError") return true;
|
|
102
|
+
if (error instanceof TypeError || name === "TypeError") {
|
|
103
|
+
const cause = error.cause;
|
|
104
|
+
return !isInvalidUrlError(error) && !isInvalidUrlError(cause);
|
|
105
|
+
}
|
|
106
|
+
if (error instanceof SyntaxError || name === "SyntaxError") return false;
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
function isNamedError(error) {
|
|
110
|
+
return typeof error === "object" && error != null && typeof error.name === "string";
|
|
111
|
+
}
|
|
112
|
+
function isResponseLike(value) {
|
|
113
|
+
return typeof value === "object" && value != null && typeof value.status === "number";
|
|
114
|
+
}
|
|
115
|
+
function isInvalidUrlError(error) {
|
|
116
|
+
if (typeof error !== "object" || error == null) return false;
|
|
117
|
+
const { code, message } = error;
|
|
118
|
+
return code === "ERR_INVALID_URL" || typeof message === "string" && message.startsWith("Invalid URL");
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* The `Accept` header value for fetching ActivityPub objects. ActivityPub
|
|
122
|
+
* and FEP-ef61 gateways require the ActivityStreams profile on the JSON-LD
|
|
123
|
+
* media type.
|
|
124
|
+
*/
|
|
125
|
+
const ACTIVITYPUB_ACCEPT = "application/activity+json, application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"";
|
|
126
|
+
/**
|
|
127
|
+
* Creates a request for the given URL.
|
|
128
|
+
* @param url The URL to create the request for.
|
|
129
|
+
* @param options The options for the request.
|
|
130
|
+
* @returns The created request.
|
|
131
|
+
* @internal
|
|
132
|
+
*/
|
|
133
|
+
function createActivityPubRequest(url, options = {}) {
|
|
134
|
+
return new Request(url, {
|
|
135
|
+
headers: {
|
|
136
|
+
Accept: ACTIVITYPUB_ACCEPT,
|
|
137
|
+
"User-Agent": typeof options.userAgent === "string" ? options.userAgent : getUserAgent(options.userAgent)
|
|
138
|
+
},
|
|
139
|
+
redirect: "manual"
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Gets the user agent string for the given application and URL.
|
|
144
|
+
* @param options The options for making the user agent string.
|
|
145
|
+
* @returns The user agent string.
|
|
146
|
+
* @since 1.3.0
|
|
147
|
+
*/
|
|
148
|
+
function getUserAgent({ software, url } = {}) {
|
|
149
|
+
const fedify = `Fedify/${version}`;
|
|
150
|
+
const runtime = globalThis.Deno?.version?.deno != null ? `Deno/${Deno.version.deno}` : globalThis.process?.versions?.bun != null ? `Bun/${node_process.default.versions.bun}` : "navigator" in globalThis && navigator.userAgent === "Cloudflare-Workers" ? navigator.userAgent : globalThis.process?.versions?.node != null ? `Node.js/${node_process.default.versions.node}` : null;
|
|
151
|
+
const userAgent = software == null ? [fedify] : [software, fedify];
|
|
152
|
+
if (runtime != null) userAgent.push(runtime);
|
|
153
|
+
if (url != null) userAgent.push(`+${url.toString()}`);
|
|
154
|
+
return `${userAgent.shift()} (${userAgent.join("; ")})`;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Logs the request.
|
|
158
|
+
* @param request The request to log.
|
|
159
|
+
* @internal
|
|
160
|
+
*/
|
|
161
|
+
function logRequest(logger, request) {
|
|
162
|
+
logger.debug("Fetching document: {method} {url} {headers}", {
|
|
163
|
+
method: request.method,
|
|
164
|
+
url: request.url,
|
|
165
|
+
headers: Object.fromEntries(request.headers.entries())
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
//#endregion
|
|
169
|
+
Object.defineProperty(exports, "FetchError", {
|
|
170
|
+
enumerable: true,
|
|
171
|
+
get: function() {
|
|
172
|
+
return FetchError;
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
Object.defineProperty(exports, "createActivityPubRequest", {
|
|
176
|
+
enumerable: true,
|
|
177
|
+
get: function() {
|
|
178
|
+
return createActivityPubRequest;
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
Object.defineProperty(exports, "getUserAgent", {
|
|
182
|
+
enumerable: true,
|
|
183
|
+
get: function() {
|
|
184
|
+
return getUserAgent;
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
Object.defineProperty(exports, "isTransientFetchError", {
|
|
188
|
+
enumerable: true,
|
|
189
|
+
get: function() {
|
|
190
|
+
return isTransientFetchError;
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
Object.defineProperty(exports, "logRequest", {
|
|
194
|
+
enumerable: true,
|
|
195
|
+
get: function() {
|
|
196
|
+
return logRequest;
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
Object.defineProperty(exports, "name", {
|
|
200
|
+
enumerable: true,
|
|
201
|
+
get: function() {
|
|
202
|
+
return name;
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
Object.defineProperty(exports, "version", {
|
|
206
|
+
enumerable: true,
|
|
207
|
+
get: function() {
|
|
208
|
+
return version;
|
|
209
|
+
}
|
|
210
|
+
});
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { n as UrlError } from "./url-DMxmp7ZG.mjs";
|
|
2
|
+
import process from "node:process";
|
|
3
|
+
//#region deno.json
|
|
4
|
+
var name = "@fedify/vocab-runtime";
|
|
5
|
+
var version = "2.5.0-dev.2358+1d1813b7";
|
|
6
|
+
//#endregion
|
|
7
|
+
//#region src/request.ts
|
|
8
|
+
/**
|
|
9
|
+
* Error thrown when fetching a JSON-LD document failed.
|
|
10
|
+
*/
|
|
11
|
+
var FetchError = class extends Error {
|
|
12
|
+
/**
|
|
13
|
+
* The URL that failed to fetch.
|
|
14
|
+
*/
|
|
15
|
+
url;
|
|
16
|
+
/**
|
|
17
|
+
* The HTTP response that failed, if available.
|
|
18
|
+
*/
|
|
19
|
+
response;
|
|
20
|
+
/**
|
|
21
|
+
* Constructs a new `FetchError`.
|
|
22
|
+
*
|
|
23
|
+
* @param url The URL that failed to fetch.
|
|
24
|
+
* @param message Error message.
|
|
25
|
+
* @param response The failed HTTP response, if available.
|
|
26
|
+
*/
|
|
27
|
+
constructor(url, message, response) {
|
|
28
|
+
super(message == null ? url.toString() : `${url}: ${message}`);
|
|
29
|
+
this.name = "FetchError";
|
|
30
|
+
this.url = typeof url === "string" ? new URL(url) : url;
|
|
31
|
+
this.response = response;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
const MAX_CAUSE_DEPTH = 8;
|
|
35
|
+
/**
|
|
36
|
+
* Guesses whether an error thrown by a document loader is transient,
|
|
37
|
+
* i.e., whether fetching the same document again later could succeed.
|
|
38
|
+
*
|
|
39
|
+
* This is a heuristic classification, not a guarantee. Callers that retry
|
|
40
|
+
* on transient errors should still bound the number of retries. The rules
|
|
41
|
+
* are:
|
|
42
|
+
*
|
|
43
|
+
* - A {@link UrlError} is transient only if its
|
|
44
|
+
* {@link UrlError.reason | reason} is `"dns"`; URLs disallowed by SSRF
|
|
45
|
+
* protection are permanent.
|
|
46
|
+
* - A {@link FetchError} with a {@link FetchError.response | response} is
|
|
47
|
+
* transient if the status is 5xx, 408 (Request Timeout), or 429 (Too Many
|
|
48
|
+
* Requests); other statuses such as 404 are permanent.
|
|
49
|
+
* - A {@link FetchError} without a response is classified by its `cause`,
|
|
50
|
+
* which is how timeouts are reported. Without a cause, it is permanent
|
|
51
|
+
* (e.g., redirect loops, too many redirections, or bodies that exceed the
|
|
52
|
+
* size limit).
|
|
53
|
+
* - A `TimeoutError` or `AbortError` is transient.
|
|
54
|
+
* - A `TypeError` from parsing an invalid URL is permanent; any other
|
|
55
|
+
* `TypeError` is transient, since `fetch()` reports network failures
|
|
56
|
+
* that way.
|
|
57
|
+
* - A `SyntaxError` (a malformed JSON body) is permanent.
|
|
58
|
+
* - An `AggregateError`, e.g., from trying several gateways, is transient
|
|
59
|
+
* if any of its errors is.
|
|
60
|
+
* - Any other error is treated as transient.
|
|
61
|
+
*
|
|
62
|
+
* @param error The error thrown by a document loader.
|
|
63
|
+
* @returns `true` if the error is likely transient, `false` if retrying is
|
|
64
|
+
* unlikely to help.
|
|
65
|
+
* @since 2.5.0
|
|
66
|
+
*/
|
|
67
|
+
function isTransientFetchError(error) {
|
|
68
|
+
return classifyFetchError(error, /* @__PURE__ */ new Set(), 0);
|
|
69
|
+
}
|
|
70
|
+
function classifyFetchError(error, path, depth) {
|
|
71
|
+
if (depth > MAX_CAUSE_DEPTH || path.has(error)) return true;
|
|
72
|
+
path.add(error);
|
|
73
|
+
try {
|
|
74
|
+
return classifyErrorShape(error, path, depth);
|
|
75
|
+
} finally {
|
|
76
|
+
path.delete(error);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function classifyErrorShape(error, path, depth) {
|
|
80
|
+
if (!(error instanceof Error) && !isNamedError(error)) return true;
|
|
81
|
+
const name = error.name;
|
|
82
|
+
if (error instanceof UrlError || name === "UrlError") return error.reason === "dns";
|
|
83
|
+
if (name === "BodyTooLargeError") return false;
|
|
84
|
+
if (error instanceof FetchError || name === "FetchError") {
|
|
85
|
+
const response = error.response;
|
|
86
|
+
if (isResponseLike(response)) {
|
|
87
|
+
const status = response.status;
|
|
88
|
+
return status >= 500 || status === 408 || status === 429;
|
|
89
|
+
}
|
|
90
|
+
const cause = error.cause;
|
|
91
|
+
if (cause == null) return false;
|
|
92
|
+
return classifyFetchError(cause, path, depth + 1);
|
|
93
|
+
}
|
|
94
|
+
if (error instanceof AggregateError || name === "AggregateError") {
|
|
95
|
+
const errors = error.errors;
|
|
96
|
+
if (!Array.isArray(errors) || errors.length < 1) return true;
|
|
97
|
+
return errors.some((e) => classifyFetchError(e, path, depth + 1));
|
|
98
|
+
}
|
|
99
|
+
if (name === "TimeoutError" || name === "AbortError") return true;
|
|
100
|
+
if (error instanceof TypeError || name === "TypeError") {
|
|
101
|
+
const cause = error.cause;
|
|
102
|
+
return !isInvalidUrlError(error) && !isInvalidUrlError(cause);
|
|
103
|
+
}
|
|
104
|
+
if (error instanceof SyntaxError || name === "SyntaxError") return false;
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
function isNamedError(error) {
|
|
108
|
+
return typeof error === "object" && error != null && typeof error.name === "string";
|
|
109
|
+
}
|
|
110
|
+
function isResponseLike(value) {
|
|
111
|
+
return typeof value === "object" && value != null && typeof value.status === "number";
|
|
112
|
+
}
|
|
113
|
+
function isInvalidUrlError(error) {
|
|
114
|
+
if (typeof error !== "object" || error == null) return false;
|
|
115
|
+
const { code, message } = error;
|
|
116
|
+
return code === "ERR_INVALID_URL" || typeof message === "string" && message.startsWith("Invalid URL");
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* The `Accept` header value for fetching ActivityPub objects. ActivityPub
|
|
120
|
+
* and FEP-ef61 gateways require the ActivityStreams profile on the JSON-LD
|
|
121
|
+
* media type.
|
|
122
|
+
*/
|
|
123
|
+
const ACTIVITYPUB_ACCEPT = "application/activity+json, application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"";
|
|
124
|
+
/**
|
|
125
|
+
* Creates a request for the given URL.
|
|
126
|
+
* @param url The URL to create the request for.
|
|
127
|
+
* @param options The options for the request.
|
|
128
|
+
* @returns The created request.
|
|
129
|
+
* @internal
|
|
130
|
+
*/
|
|
131
|
+
function createActivityPubRequest(url, options = {}) {
|
|
132
|
+
return new Request(url, {
|
|
133
|
+
headers: {
|
|
134
|
+
Accept: ACTIVITYPUB_ACCEPT,
|
|
135
|
+
"User-Agent": typeof options.userAgent === "string" ? options.userAgent : getUserAgent(options.userAgent)
|
|
136
|
+
},
|
|
137
|
+
redirect: "manual"
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Gets the user agent string for the given application and URL.
|
|
142
|
+
* @param options The options for making the user agent string.
|
|
143
|
+
* @returns The user agent string.
|
|
144
|
+
* @since 1.3.0
|
|
145
|
+
*/
|
|
146
|
+
function getUserAgent({ software, url } = {}) {
|
|
147
|
+
const fedify = `Fedify/${version}`;
|
|
148
|
+
const runtime = globalThis.Deno?.version?.deno != null ? `Deno/${Deno.version.deno}` : globalThis.process?.versions?.bun != null ? `Bun/${process.versions.bun}` : "navigator" in globalThis && navigator.userAgent === "Cloudflare-Workers" ? navigator.userAgent : globalThis.process?.versions?.node != null ? `Node.js/${process.versions.node}` : null;
|
|
149
|
+
const userAgent = software == null ? [fedify] : [software, fedify];
|
|
150
|
+
if (runtime != null) userAgent.push(runtime);
|
|
151
|
+
if (url != null) userAgent.push(`+${url.toString()}`);
|
|
152
|
+
return `${userAgent.shift()} (${userAgent.join("; ")})`;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Logs the request.
|
|
156
|
+
* @param request The request to log.
|
|
157
|
+
* @internal
|
|
158
|
+
*/
|
|
159
|
+
function logRequest(logger, request) {
|
|
160
|
+
logger.debug("Fetching document: {method} {url} {headers}", {
|
|
161
|
+
method: request.method,
|
|
162
|
+
url: request.url,
|
|
163
|
+
headers: Object.fromEntries(request.headers.entries())
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
//#endregion
|
|
167
|
+
export { logRequest as a, isTransientFetchError as i, createActivityPubRequest as n, name as o, getUserAgent as r, version as s, FetchError as t };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const require_rolldown_runtime = require("./rolldown-runtime-emK7D4bc.cjs");
|
|
2
|
-
const require_request = require("./request-
|
|
2
|
+
const require_request = require("./request-6JGmUBqf.cjs");
|
|
3
|
+
const require_url = require("./url-BNakuZ8k.cjs");
|
|
3
4
|
let node_test = require("node:test");
|
|
4
5
|
let node_process = require("node:process");
|
|
5
6
|
node_process = require_rolldown_runtime.__toESM(node_process, 1);
|
|
@@ -43,4 +44,60 @@ let node_assert = require("node:assert");
|
|
|
43
44
|
(0, node_test.test)("createActivityPubRequest() asks for the ActivityStreams profile", () => {
|
|
44
45
|
(0, node_assert.deepStrictEqual)(require_request.createActivityPubRequest("https://example.com/object").headers.get("Accept"), "application/activity+json, application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"");
|
|
45
46
|
});
|
|
47
|
+
(0, node_test.test)("isTransientFetchError() classifies document loader errors", () => {
|
|
48
|
+
const url = "https://example.com/object";
|
|
49
|
+
const response = (status) => new Response(null, { status });
|
|
50
|
+
(0, node_assert.deepStrictEqual)(require_request.isTransientFetchError(new require_request.FetchError(url, "HTTP 503", response(503))), true);
|
|
51
|
+
(0, node_assert.deepStrictEqual)(require_request.isTransientFetchError(new require_request.FetchError(url, "HTTP 408", response(408))), true);
|
|
52
|
+
(0, node_assert.deepStrictEqual)(require_request.isTransientFetchError(new require_request.FetchError(url, "HTTP 429", response(429))), true);
|
|
53
|
+
(0, node_assert.deepStrictEqual)(require_request.isTransientFetchError(new require_request.FetchError(url, "HTTP 404", response(404))), false);
|
|
54
|
+
(0, node_assert.deepStrictEqual)(require_request.isTransientFetchError(new require_request.FetchError(url, "HTTP 410", response(410))), false);
|
|
55
|
+
(0, node_assert.deepStrictEqual)(require_request.isTransientFetchError(new require_request.FetchError(url, "Redirect loop detected")), false);
|
|
56
|
+
const timeout = new require_request.FetchError(url, "Timed out after 1000 ms");
|
|
57
|
+
timeout.cause = new DOMException("Timed out", "TimeoutError");
|
|
58
|
+
(0, node_assert.deepStrictEqual)(require_request.isTransientFetchError(timeout), true);
|
|
59
|
+
const tooLarge = new require_request.FetchError(url, "Body exceeds the limit");
|
|
60
|
+
tooLarge.name = "BodyTooLargeError";
|
|
61
|
+
(0, node_assert.deepStrictEqual)(require_request.isTransientFetchError(tooLarge), false);
|
|
62
|
+
(0, node_assert.deepStrictEqual)(require_request.isTransientFetchError(new require_url.UrlError("DNS lookup failed", { reason: "dns" })), true);
|
|
63
|
+
(0, node_assert.deepStrictEqual)(require_request.isTransientFetchError(new require_url.UrlError("Disallowed private URL")), false);
|
|
64
|
+
(0, node_assert.deepStrictEqual)(require_request.isTransientFetchError(new TypeError("fetch failed", { cause: /* @__PURE__ */ new Error("ECONNRESET") })), true);
|
|
65
|
+
let invalidUrl;
|
|
66
|
+
try {
|
|
67
|
+
new URL("::");
|
|
68
|
+
} catch (error) {
|
|
69
|
+
invalidUrl = error;
|
|
70
|
+
}
|
|
71
|
+
(0, node_assert.deepStrictEqual)(require_request.isTransientFetchError(invalidUrl), false);
|
|
72
|
+
(0, node_assert.deepStrictEqual)(require_request.isTransientFetchError(new TypeError("Failed to parse URL from ::", { cause: Object.assign(/* @__PURE__ */ new TypeError("Invalid URL"), { code: "ERR_INVALID_URL" }) })), false);
|
|
73
|
+
(0, node_assert.deepStrictEqual)(require_request.isTransientFetchError(/* @__PURE__ */ new SyntaxError("Bad JSON")), false);
|
|
74
|
+
(0, node_assert.deepStrictEqual)(require_request.isTransientFetchError(new DOMException("Aborted", "AbortError")), true);
|
|
75
|
+
(0, node_assert.deepStrictEqual)(require_request.isTransientFetchError(/* @__PURE__ */ new Error("unknown")), true);
|
|
76
|
+
});
|
|
77
|
+
(0, node_test.test)("isTransientFetchError() recognizes errors from other package copies", () => {
|
|
78
|
+
(0, node_assert.deepStrictEqual)(require_request.isTransientFetchError(Object.assign(/* @__PURE__ */ new Error("DNS lookup failed"), {
|
|
79
|
+
name: "UrlError",
|
|
80
|
+
reason: "dns"
|
|
81
|
+
})), true);
|
|
82
|
+
(0, node_assert.deepStrictEqual)(require_request.isTransientFetchError(Object.assign(/* @__PURE__ */ new Error("HTTP 404"), {
|
|
83
|
+
name: "FetchError",
|
|
84
|
+
url: new URL("https://example.com/"),
|
|
85
|
+
response: new Response(null, { status: 404 })
|
|
86
|
+
})), false);
|
|
87
|
+
});
|
|
88
|
+
(0, node_test.test)("isTransientFetchError() classifies aggregate errors by their members", () => {
|
|
89
|
+
const notFound = (url) => new require_request.FetchError(url, "HTTP 404", new Response(null, { status: 404 }));
|
|
90
|
+
const unavailable = (url) => new require_request.FetchError(url, "HTTP 503", new Response(null, { status: 503 }));
|
|
91
|
+
(0, node_assert.deepStrictEqual)(require_request.isTransientFetchError(new AggregateError([notFound("https://a.example/"), notFound("https://b.example/")])), false);
|
|
92
|
+
(0, node_assert.deepStrictEqual)(require_request.isTransientFetchError(new AggregateError([notFound("https://a.example/"), unavailable("https://b.example/")])), true);
|
|
93
|
+
(0, node_assert.deepStrictEqual)(require_request.isTransientFetchError(/* @__PURE__ */ new AggregateError([])), true);
|
|
94
|
+
const gone = new require_request.FetchError("https://a.example/", "HTTP 410", new Response(null, { status: 410 }));
|
|
95
|
+
(0, node_assert.deepStrictEqual)(require_request.isTransientFetchError(new AggregateError([gone, gone])), false);
|
|
96
|
+
(0, node_assert.deepStrictEqual)(require_request.isTransientFetchError(new AggregateError([new require_request.FetchError("https://a.example/", "a", void 0), new require_request.FetchError("https://b.example/", "b", void 0)].map((e) => Object.assign(e, { cause: gone })))), false);
|
|
97
|
+
});
|
|
98
|
+
(0, node_test.test)("isTransientFetchError() tolerates cyclic causes", () => {
|
|
99
|
+
const error = new require_request.FetchError("https://example.com/", "cyclic");
|
|
100
|
+
error.cause = error;
|
|
101
|
+
(0, node_assert.deepStrictEqual)(require_request.isTransientFetchError(error), true);
|
|
102
|
+
});
|
|
46
103
|
//#endregion
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { n as createActivityPubRequest,
|
|
1
|
+
import { i as isTransientFetchError, n as createActivityPubRequest, r as getUserAgent, s as version, t as FetchError } from "./request-D7wirQVZ.mjs";
|
|
2
|
+
import { n as UrlError } from "./url-DMxmp7ZG.mjs";
|
|
2
3
|
import { test } from "node:test";
|
|
3
4
|
import process from "node:process";
|
|
4
5
|
import { deepStrictEqual } from "node:assert";
|
|
@@ -41,5 +42,61 @@ test("getUserAgent()", () => {
|
|
|
41
42
|
test("createActivityPubRequest() asks for the ActivityStreams profile", () => {
|
|
42
43
|
deepStrictEqual(createActivityPubRequest("https://example.com/object").headers.get("Accept"), "application/activity+json, application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"");
|
|
43
44
|
});
|
|
45
|
+
test("isTransientFetchError() classifies document loader errors", () => {
|
|
46
|
+
const url = "https://example.com/object";
|
|
47
|
+
const response = (status) => new Response(null, { status });
|
|
48
|
+
deepStrictEqual(isTransientFetchError(new FetchError(url, "HTTP 503", response(503))), true);
|
|
49
|
+
deepStrictEqual(isTransientFetchError(new FetchError(url, "HTTP 408", response(408))), true);
|
|
50
|
+
deepStrictEqual(isTransientFetchError(new FetchError(url, "HTTP 429", response(429))), true);
|
|
51
|
+
deepStrictEqual(isTransientFetchError(new FetchError(url, "HTTP 404", response(404))), false);
|
|
52
|
+
deepStrictEqual(isTransientFetchError(new FetchError(url, "HTTP 410", response(410))), false);
|
|
53
|
+
deepStrictEqual(isTransientFetchError(new FetchError(url, "Redirect loop detected")), false);
|
|
54
|
+
const timeout = new FetchError(url, "Timed out after 1000 ms");
|
|
55
|
+
timeout.cause = new DOMException("Timed out", "TimeoutError");
|
|
56
|
+
deepStrictEqual(isTransientFetchError(timeout), true);
|
|
57
|
+
const tooLarge = new FetchError(url, "Body exceeds the limit");
|
|
58
|
+
tooLarge.name = "BodyTooLargeError";
|
|
59
|
+
deepStrictEqual(isTransientFetchError(tooLarge), false);
|
|
60
|
+
deepStrictEqual(isTransientFetchError(new UrlError("DNS lookup failed", { reason: "dns" })), true);
|
|
61
|
+
deepStrictEqual(isTransientFetchError(new UrlError("Disallowed private URL")), false);
|
|
62
|
+
deepStrictEqual(isTransientFetchError(new TypeError("fetch failed", { cause: /* @__PURE__ */ new Error("ECONNRESET") })), true);
|
|
63
|
+
let invalidUrl;
|
|
64
|
+
try {
|
|
65
|
+
new URL("::");
|
|
66
|
+
} catch (error) {
|
|
67
|
+
invalidUrl = error;
|
|
68
|
+
}
|
|
69
|
+
deepStrictEqual(isTransientFetchError(invalidUrl), false);
|
|
70
|
+
deepStrictEqual(isTransientFetchError(new TypeError("Failed to parse URL from ::", { cause: Object.assign(/* @__PURE__ */ new TypeError("Invalid URL"), { code: "ERR_INVALID_URL" }) })), false);
|
|
71
|
+
deepStrictEqual(isTransientFetchError(/* @__PURE__ */ new SyntaxError("Bad JSON")), false);
|
|
72
|
+
deepStrictEqual(isTransientFetchError(new DOMException("Aborted", "AbortError")), true);
|
|
73
|
+
deepStrictEqual(isTransientFetchError(/* @__PURE__ */ new Error("unknown")), true);
|
|
74
|
+
});
|
|
75
|
+
test("isTransientFetchError() recognizes errors from other package copies", () => {
|
|
76
|
+
deepStrictEqual(isTransientFetchError(Object.assign(/* @__PURE__ */ new Error("DNS lookup failed"), {
|
|
77
|
+
name: "UrlError",
|
|
78
|
+
reason: "dns"
|
|
79
|
+
})), true);
|
|
80
|
+
deepStrictEqual(isTransientFetchError(Object.assign(/* @__PURE__ */ new Error("HTTP 404"), {
|
|
81
|
+
name: "FetchError",
|
|
82
|
+
url: new URL("https://example.com/"),
|
|
83
|
+
response: new Response(null, { status: 404 })
|
|
84
|
+
})), false);
|
|
85
|
+
});
|
|
86
|
+
test("isTransientFetchError() classifies aggregate errors by their members", () => {
|
|
87
|
+
const notFound = (url) => new FetchError(url, "HTTP 404", new Response(null, { status: 404 }));
|
|
88
|
+
const unavailable = (url) => new FetchError(url, "HTTP 503", new Response(null, { status: 503 }));
|
|
89
|
+
deepStrictEqual(isTransientFetchError(new AggregateError([notFound("https://a.example/"), notFound("https://b.example/")])), false);
|
|
90
|
+
deepStrictEqual(isTransientFetchError(new AggregateError([notFound("https://a.example/"), unavailable("https://b.example/")])), true);
|
|
91
|
+
deepStrictEqual(isTransientFetchError(/* @__PURE__ */ new AggregateError([])), true);
|
|
92
|
+
const gone = new FetchError("https://a.example/", "HTTP 410", new Response(null, { status: 410 }));
|
|
93
|
+
deepStrictEqual(isTransientFetchError(new AggregateError([gone, gone])), false);
|
|
94
|
+
deepStrictEqual(isTransientFetchError(new AggregateError([new FetchError("https://a.example/", "a", void 0), new FetchError("https://b.example/", "b", void 0)].map((e) => Object.assign(e, { cause: gone })))), false);
|
|
95
|
+
});
|
|
96
|
+
test("isTransientFetchError() tolerates cyclic causes", () => {
|
|
97
|
+
const error = new FetchError("https://example.com/", "cyclic");
|
|
98
|
+
error.cause = error;
|
|
99
|
+
deepStrictEqual(isTransientFetchError(error), true);
|
|
100
|
+
});
|
|
44
101
|
//#endregion
|
|
45
102
|
export {};
|
package/package.json
CHANGED