@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
package/src/request.test.ts
CHANGED
|
@@ -2,7 +2,13 @@ import { deepStrictEqual } from "node:assert";
|
|
|
2
2
|
import process from "node:process";
|
|
3
3
|
import { test } from "node:test";
|
|
4
4
|
import metadata from "../deno.json" with { type: "json" };
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
createActivityPubRequest,
|
|
7
|
+
FetchError,
|
|
8
|
+
getUserAgent,
|
|
9
|
+
isTransientFetchError,
|
|
10
|
+
} from "./request.ts";
|
|
11
|
+
import { UrlError } from "./url.ts";
|
|
6
12
|
|
|
7
13
|
test("getUserAgent()", () => {
|
|
8
14
|
if ("Deno" in globalThis) {
|
|
@@ -100,3 +106,139 @@ test("createActivityPubRequest() asks for the ActivityStreams profile", () => {
|
|
|
100
106
|
'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
|
|
101
107
|
);
|
|
102
108
|
});
|
|
109
|
+
|
|
110
|
+
test("isTransientFetchError() classifies document loader errors", () => {
|
|
111
|
+
const url = "https://example.com/object";
|
|
112
|
+
const response = (status: number) => new Response(null, { status });
|
|
113
|
+
deepStrictEqual(
|
|
114
|
+
isTransientFetchError(new FetchError(url, "HTTP 503", response(503))),
|
|
115
|
+
true,
|
|
116
|
+
);
|
|
117
|
+
deepStrictEqual(
|
|
118
|
+
isTransientFetchError(new FetchError(url, "HTTP 408", response(408))),
|
|
119
|
+
true,
|
|
120
|
+
);
|
|
121
|
+
deepStrictEqual(
|
|
122
|
+
isTransientFetchError(new FetchError(url, "HTTP 429", response(429))),
|
|
123
|
+
true,
|
|
124
|
+
);
|
|
125
|
+
deepStrictEqual(
|
|
126
|
+
isTransientFetchError(new FetchError(url, "HTTP 404", response(404))),
|
|
127
|
+
false,
|
|
128
|
+
);
|
|
129
|
+
deepStrictEqual(
|
|
130
|
+
isTransientFetchError(new FetchError(url, "HTTP 410", response(410))),
|
|
131
|
+
false,
|
|
132
|
+
);
|
|
133
|
+
deepStrictEqual(
|
|
134
|
+
isTransientFetchError(new FetchError(url, "Redirect loop detected")),
|
|
135
|
+
false,
|
|
136
|
+
);
|
|
137
|
+
const timeout = new FetchError(url, "Timed out after 1000 ms");
|
|
138
|
+
timeout.cause = new DOMException("Timed out", "TimeoutError");
|
|
139
|
+
deepStrictEqual(isTransientFetchError(timeout), true);
|
|
140
|
+
const tooLarge = new FetchError(url, "Body exceeds the limit");
|
|
141
|
+
tooLarge.name = "BodyTooLargeError";
|
|
142
|
+
deepStrictEqual(isTransientFetchError(tooLarge), false);
|
|
143
|
+
deepStrictEqual(
|
|
144
|
+
isTransientFetchError(new UrlError("DNS lookup failed", { reason: "dns" })),
|
|
145
|
+
true,
|
|
146
|
+
);
|
|
147
|
+
deepStrictEqual(
|
|
148
|
+
isTransientFetchError(new UrlError("Disallowed private URL")),
|
|
149
|
+
false,
|
|
150
|
+
);
|
|
151
|
+
deepStrictEqual(
|
|
152
|
+
isTransientFetchError(
|
|
153
|
+
new TypeError("fetch failed", { cause: new Error("ECONNRESET") }),
|
|
154
|
+
),
|
|
155
|
+
true,
|
|
156
|
+
);
|
|
157
|
+
let invalidUrl: unknown;
|
|
158
|
+
try {
|
|
159
|
+
new URL("::");
|
|
160
|
+
} catch (error) {
|
|
161
|
+
invalidUrl = error;
|
|
162
|
+
}
|
|
163
|
+
deepStrictEqual(isTransientFetchError(invalidUrl), false);
|
|
164
|
+
deepStrictEqual(
|
|
165
|
+
isTransientFetchError(
|
|
166
|
+
new TypeError("Failed to parse URL from ::", {
|
|
167
|
+
cause: Object.assign(new TypeError("Invalid URL"), {
|
|
168
|
+
code: "ERR_INVALID_URL",
|
|
169
|
+
}),
|
|
170
|
+
}),
|
|
171
|
+
),
|
|
172
|
+
false,
|
|
173
|
+
);
|
|
174
|
+
deepStrictEqual(isTransientFetchError(new SyntaxError("Bad JSON")), false);
|
|
175
|
+
deepStrictEqual(
|
|
176
|
+
isTransientFetchError(new DOMException("Aborted", "AbortError")),
|
|
177
|
+
true,
|
|
178
|
+
);
|
|
179
|
+
deepStrictEqual(isTransientFetchError(new Error("unknown")), true);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
test("isTransientFetchError() recognizes errors from other package copies", () => {
|
|
183
|
+
const dns = Object.assign(new Error("DNS lookup failed"), {
|
|
184
|
+
name: "UrlError",
|
|
185
|
+
reason: "dns",
|
|
186
|
+
});
|
|
187
|
+
deepStrictEqual(isTransientFetchError(dns), true);
|
|
188
|
+
const notFound = Object.assign(new Error("HTTP 404"), {
|
|
189
|
+
name: "FetchError",
|
|
190
|
+
url: new URL("https://example.com/"),
|
|
191
|
+
response: new Response(null, { status: 404 }),
|
|
192
|
+
});
|
|
193
|
+
deepStrictEqual(isTransientFetchError(notFound), false);
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
test("isTransientFetchError() classifies aggregate errors by their members", () => {
|
|
197
|
+
const notFound = (url: string) =>
|
|
198
|
+
new FetchError(url, "HTTP 404", new Response(null, { status: 404 }));
|
|
199
|
+
const unavailable = (url: string) =>
|
|
200
|
+
new FetchError(url, "HTTP 503", new Response(null, { status: 503 }));
|
|
201
|
+
deepStrictEqual(
|
|
202
|
+
isTransientFetchError(
|
|
203
|
+
new AggregateError([
|
|
204
|
+
notFound("https://a.example/"),
|
|
205
|
+
notFound("https://b.example/"),
|
|
206
|
+
]),
|
|
207
|
+
),
|
|
208
|
+
false,
|
|
209
|
+
);
|
|
210
|
+
deepStrictEqual(
|
|
211
|
+
isTransientFetchError(
|
|
212
|
+
new AggregateError([
|
|
213
|
+
notFound("https://a.example/"),
|
|
214
|
+
unavailable("https://b.example/"),
|
|
215
|
+
]),
|
|
216
|
+
),
|
|
217
|
+
true,
|
|
218
|
+
);
|
|
219
|
+
deepStrictEqual(isTransientFetchError(new AggregateError([])), true);
|
|
220
|
+
const gone = new FetchError(
|
|
221
|
+
"https://a.example/",
|
|
222
|
+
"HTTP 410",
|
|
223
|
+
new Response(null, { status: 410 }),
|
|
224
|
+
);
|
|
225
|
+
deepStrictEqual(
|
|
226
|
+
isTransientFetchError(new AggregateError([gone, gone])),
|
|
227
|
+
false,
|
|
228
|
+
);
|
|
229
|
+
deepStrictEqual(
|
|
230
|
+
isTransientFetchError(
|
|
231
|
+
new AggregateError([
|
|
232
|
+
new FetchError("https://a.example/", "a", undefined),
|
|
233
|
+
new FetchError("https://b.example/", "b", undefined),
|
|
234
|
+
].map((e) => Object.assign(e, { cause: gone }))),
|
|
235
|
+
),
|
|
236
|
+
false,
|
|
237
|
+
);
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
test("isTransientFetchError() tolerates cyclic causes", () => {
|
|
241
|
+
const error = new FetchError("https://example.com/", "cyclic");
|
|
242
|
+
error.cause = error;
|
|
243
|
+
deepStrictEqual(isTransientFetchError(error), true);
|
|
244
|
+
});
|
package/src/request.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Logger } from "@logtape/logtape";
|
|
2
2
|
import process from "node:process";
|
|
3
3
|
import metadata from "../deno.json" with { type: "json" };
|
|
4
|
+
import { UrlError } from "./url.ts";
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Error thrown when fetching a JSON-LD document failed.
|
|
@@ -31,6 +32,118 @@ export class FetchError extends Error {
|
|
|
31
32
|
}
|
|
32
33
|
}
|
|
33
34
|
|
|
35
|
+
const MAX_CAUSE_DEPTH = 8;
|
|
36
|
+
|
|
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
|
+
export function isTransientFetchError(error: unknown): boolean {
|
|
70
|
+
return classifyFetchError(error, new Set(), 0);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function classifyFetchError(
|
|
74
|
+
error: unknown,
|
|
75
|
+
path: Set<unknown>,
|
|
76
|
+
depth: number,
|
|
77
|
+
): boolean {
|
|
78
|
+
// Only an error on the current path is a cycle; the same error can appear
|
|
79
|
+
// in several branches, e.g., twice in an AggregateError:
|
|
80
|
+
if (depth > MAX_CAUSE_DEPTH || path.has(error)) return true;
|
|
81
|
+
path.add(error);
|
|
82
|
+
try {
|
|
83
|
+
return classifyErrorShape(error, path, depth);
|
|
84
|
+
} finally {
|
|
85
|
+
path.delete(error);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function classifyErrorShape(
|
|
90
|
+
error: unknown,
|
|
91
|
+
path: Set<unknown>,
|
|
92
|
+
depth: number,
|
|
93
|
+
): boolean {
|
|
94
|
+
if (!(error instanceof Error) && !isNamedError(error)) return true;
|
|
95
|
+
const name = (error as { readonly name: string }).name;
|
|
96
|
+
if (error instanceof UrlError || name === "UrlError") {
|
|
97
|
+
return (error as { readonly reason?: unknown }).reason === "dns";
|
|
98
|
+
}
|
|
99
|
+
if (name === "BodyTooLargeError") return false;
|
|
100
|
+
if (error instanceof FetchError || name === "FetchError") {
|
|
101
|
+
const response = (error as { readonly response?: unknown }).response;
|
|
102
|
+
if (isResponseLike(response)) {
|
|
103
|
+
const status = response.status;
|
|
104
|
+
return status >= 500 || status === 408 || status === 429;
|
|
105
|
+
}
|
|
106
|
+
const cause = (error as { readonly cause?: unknown }).cause;
|
|
107
|
+
if (cause == null) return false;
|
|
108
|
+
return classifyFetchError(cause, path, depth + 1);
|
|
109
|
+
}
|
|
110
|
+
if (error instanceof AggregateError || name === "AggregateError") {
|
|
111
|
+
const errors = (error as { readonly errors?: unknown }).errors;
|
|
112
|
+
if (!Array.isArray(errors) || errors.length < 1) return true;
|
|
113
|
+
return errors.some((e) => classifyFetchError(e, path, depth + 1));
|
|
114
|
+
}
|
|
115
|
+
if (name === "TimeoutError" || name === "AbortError") return true;
|
|
116
|
+
if (error instanceof TypeError || name === "TypeError") {
|
|
117
|
+
// Node.js's fetch() wraps the URL parsing error as its cause:
|
|
118
|
+
const cause = (error as { readonly cause?: unknown }).cause;
|
|
119
|
+
return !isInvalidUrlError(error) && !isInvalidUrlError(cause);
|
|
120
|
+
}
|
|
121
|
+
if (error instanceof SyntaxError || name === "SyntaxError") return false;
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function isNamedError(error: unknown): boolean {
|
|
126
|
+
return typeof error === "object" && error != null &&
|
|
127
|
+
typeof (error as { readonly name?: unknown }).name === "string";
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function isResponseLike(
|
|
131
|
+
value: unknown,
|
|
132
|
+
): value is { readonly status: number } {
|
|
133
|
+
return typeof value === "object" && value != null &&
|
|
134
|
+
typeof (value as { readonly status?: unknown }).status === "number";
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function isInvalidUrlError(error: unknown): boolean {
|
|
138
|
+
if (typeof error !== "object" || error == null) return false;
|
|
139
|
+
const { code, message } = error as {
|
|
140
|
+
readonly code?: unknown;
|
|
141
|
+
readonly message?: unknown;
|
|
142
|
+
};
|
|
143
|
+
return code === "ERR_INVALID_URL" ||
|
|
144
|
+
typeof message === "string" && message.startsWith("Invalid URL");
|
|
145
|
+
}
|
|
146
|
+
|
|
34
147
|
/**
|
|
35
148
|
* The `Accept` header value for fetching ActivityPub objects. ActivityPub
|
|
36
149
|
* and FEP-ef61 gateways require the ActivityStreams profile on the JSON-LD
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import process from "node:process";
|
|
2
|
-
//#region deno.json
|
|
3
|
-
var name = "@fedify/vocab-runtime";
|
|
4
|
-
var version = "2.5.0-dev.2339+5e786861";
|
|
5
|
-
//#endregion
|
|
6
|
-
//#region src/request.ts
|
|
7
|
-
/**
|
|
8
|
-
* Error thrown when fetching a JSON-LD document failed.
|
|
9
|
-
*/
|
|
10
|
-
var FetchError = class extends Error {
|
|
11
|
-
/**
|
|
12
|
-
* The URL that failed to fetch.
|
|
13
|
-
*/
|
|
14
|
-
url;
|
|
15
|
-
/**
|
|
16
|
-
* The HTTP response that failed, if available.
|
|
17
|
-
*/
|
|
18
|
-
response;
|
|
19
|
-
/**
|
|
20
|
-
* Constructs a new `FetchError`.
|
|
21
|
-
*
|
|
22
|
-
* @param url The URL that failed to fetch.
|
|
23
|
-
* @param message Error message.
|
|
24
|
-
* @param response The failed HTTP response, if available.
|
|
25
|
-
*/
|
|
26
|
-
constructor(url, message, response) {
|
|
27
|
-
super(message == null ? url.toString() : `${url}: ${message}`);
|
|
28
|
-
this.name = "FetchError";
|
|
29
|
-
this.url = typeof url === "string" ? new URL(url) : url;
|
|
30
|
-
this.response = response;
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
/**
|
|
34
|
-
* The `Accept` header value for fetching ActivityPub objects. ActivityPub
|
|
35
|
-
* and FEP-ef61 gateways require the ActivityStreams profile on the JSON-LD
|
|
36
|
-
* media type.
|
|
37
|
-
*/
|
|
38
|
-
const ACTIVITYPUB_ACCEPT = "application/activity+json, application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"";
|
|
39
|
-
/**
|
|
40
|
-
* Creates a request for the given URL.
|
|
41
|
-
* @param url The URL to create the request for.
|
|
42
|
-
* @param options The options for the request.
|
|
43
|
-
* @returns The created request.
|
|
44
|
-
* @internal
|
|
45
|
-
*/
|
|
46
|
-
function createActivityPubRequest(url, options = {}) {
|
|
47
|
-
return new Request(url, {
|
|
48
|
-
headers: {
|
|
49
|
-
Accept: ACTIVITYPUB_ACCEPT,
|
|
50
|
-
"User-Agent": typeof options.userAgent === "string" ? options.userAgent : getUserAgent(options.userAgent)
|
|
51
|
-
},
|
|
52
|
-
redirect: "manual"
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Gets the user agent string for the given application and URL.
|
|
57
|
-
* @param options The options for making the user agent string.
|
|
58
|
-
* @returns The user agent string.
|
|
59
|
-
* @since 1.3.0
|
|
60
|
-
*/
|
|
61
|
-
function getUserAgent({ software, url } = {}) {
|
|
62
|
-
const fedify = `Fedify/${version}`;
|
|
63
|
-
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;
|
|
64
|
-
const userAgent = software == null ? [fedify] : [software, fedify];
|
|
65
|
-
if (runtime != null) userAgent.push(runtime);
|
|
66
|
-
if (url != null) userAgent.push(`+${url.toString()}`);
|
|
67
|
-
return `${userAgent.shift()} (${userAgent.join("; ")})`;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Logs the request.
|
|
71
|
-
* @param request The request to log.
|
|
72
|
-
* @internal
|
|
73
|
-
*/
|
|
74
|
-
function logRequest(logger, request) {
|
|
75
|
-
logger.debug("Fetching document: {method} {url} {headers}", {
|
|
76
|
-
method: request.method,
|
|
77
|
-
url: request.url,
|
|
78
|
-
headers: Object.fromEntries(request.headers.entries())
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
//#endregion
|
|
82
|
-
export { name as a, logRequest as i, createActivityPubRequest as n, version as o, getUserAgent as r, FetchError as t };
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
const require_rolldown_runtime = require("./rolldown-runtime-emK7D4bc.cjs");
|
|
2
|
-
let node_process = require("node:process");
|
|
3
|
-
node_process = require_rolldown_runtime.__toESM(node_process, 1);
|
|
4
|
-
//#region deno.json
|
|
5
|
-
var name = "@fedify/vocab-runtime";
|
|
6
|
-
var version = "2.5.0-dev.2339+5e786861";
|
|
7
|
-
//#endregion
|
|
8
|
-
//#region src/request.ts
|
|
9
|
-
/**
|
|
10
|
-
* Error thrown when fetching a JSON-LD document failed.
|
|
11
|
-
*/
|
|
12
|
-
var FetchError = class extends Error {
|
|
13
|
-
/**
|
|
14
|
-
* The URL that failed to fetch.
|
|
15
|
-
*/
|
|
16
|
-
url;
|
|
17
|
-
/**
|
|
18
|
-
* The HTTP response that failed, if available.
|
|
19
|
-
*/
|
|
20
|
-
response;
|
|
21
|
-
/**
|
|
22
|
-
* Constructs a new `FetchError`.
|
|
23
|
-
*
|
|
24
|
-
* @param url The URL that failed to fetch.
|
|
25
|
-
* @param message Error message.
|
|
26
|
-
* @param response The failed HTTP response, if available.
|
|
27
|
-
*/
|
|
28
|
-
constructor(url, message, response) {
|
|
29
|
-
super(message == null ? url.toString() : `${url}: ${message}`);
|
|
30
|
-
this.name = "FetchError";
|
|
31
|
-
this.url = typeof url === "string" ? new URL(url) : url;
|
|
32
|
-
this.response = response;
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
/**
|
|
36
|
-
* The `Accept` header value for fetching ActivityPub objects. ActivityPub
|
|
37
|
-
* and FEP-ef61 gateways require the ActivityStreams profile on the JSON-LD
|
|
38
|
-
* media type.
|
|
39
|
-
*/
|
|
40
|
-
const ACTIVITYPUB_ACCEPT = "application/activity+json, application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"";
|
|
41
|
-
/**
|
|
42
|
-
* Creates a request for the given URL.
|
|
43
|
-
* @param url The URL to create the request for.
|
|
44
|
-
* @param options The options for the request.
|
|
45
|
-
* @returns The created request.
|
|
46
|
-
* @internal
|
|
47
|
-
*/
|
|
48
|
-
function createActivityPubRequest(url, options = {}) {
|
|
49
|
-
return new Request(url, {
|
|
50
|
-
headers: {
|
|
51
|
-
Accept: ACTIVITYPUB_ACCEPT,
|
|
52
|
-
"User-Agent": typeof options.userAgent === "string" ? options.userAgent : getUserAgent(options.userAgent)
|
|
53
|
-
},
|
|
54
|
-
redirect: "manual"
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Gets the user agent string for the given application and URL.
|
|
59
|
-
* @param options The options for making the user agent string.
|
|
60
|
-
* @returns The user agent string.
|
|
61
|
-
* @since 1.3.0
|
|
62
|
-
*/
|
|
63
|
-
function getUserAgent({ software, url } = {}) {
|
|
64
|
-
const fedify = `Fedify/${version}`;
|
|
65
|
-
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;
|
|
66
|
-
const userAgent = software == null ? [fedify] : [software, fedify];
|
|
67
|
-
if (runtime != null) userAgent.push(runtime);
|
|
68
|
-
if (url != null) userAgent.push(`+${url.toString()}`);
|
|
69
|
-
return `${userAgent.shift()} (${userAgent.join("; ")})`;
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Logs the request.
|
|
73
|
-
* @param request The request to log.
|
|
74
|
-
* @internal
|
|
75
|
-
*/
|
|
76
|
-
function logRequest(logger, request) {
|
|
77
|
-
logger.debug("Fetching document: {method} {url} {headers}", {
|
|
78
|
-
method: request.method,
|
|
79
|
-
url: request.url,
|
|
80
|
-
headers: Object.fromEntries(request.headers.entries())
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
//#endregion
|
|
84
|
-
Object.defineProperty(exports, "FetchError", {
|
|
85
|
-
enumerable: true,
|
|
86
|
-
get: function() {
|
|
87
|
-
return FetchError;
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
Object.defineProperty(exports, "createActivityPubRequest", {
|
|
91
|
-
enumerable: true,
|
|
92
|
-
get: function() {
|
|
93
|
-
return createActivityPubRequest;
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
|
-
Object.defineProperty(exports, "getUserAgent", {
|
|
97
|
-
enumerable: true,
|
|
98
|
-
get: function() {
|
|
99
|
-
return getUserAgent;
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
Object.defineProperty(exports, "logRequest", {
|
|
103
|
-
enumerable: true,
|
|
104
|
-
get: function() {
|
|
105
|
-
return logRequest;
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
Object.defineProperty(exports, "name", {
|
|
109
|
-
enumerable: true,
|
|
110
|
-
get: function() {
|
|
111
|
-
return name;
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
Object.defineProperty(exports, "version", {
|
|
115
|
-
enumerable: true,
|
|
116
|
-
get: function() {
|
|
117
|
-
return version;
|
|
118
|
-
}
|
|
119
|
-
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const require_contexts = require("./contexts-C9Lj11SC.cjs");
|
|
2
1
|
const require_url = require("./url-BNakuZ8k.cjs");
|
|
2
|
+
const require_contexts = require("./contexts-C9Lj11SC.cjs");
|
|
3
3
|
require("./jsonld-CmDhHNTx.cjs");
|
|
4
4
|
const require_jsonld_cache = require("./jsonld-cache-BEXiiM-V.cjs");
|
|
5
5
|
let _logtape_logtape = require("@logtape/logtape");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as preloadedContexts } from "./contexts-duRA_dDC.mjs";
|
|
2
1
|
import { h as parseGatewayOrigin, o as formatIri, s as fromCompatibleEf61Id, t as GATEWAY_HINT_PARAMETER, u as haveSameFe34Origin } from "./url-DMxmp7ZG.mjs";
|
|
2
|
+
import { t as preloadedContexts } from "./contexts-duRA_dDC.mjs";
|
|
3
3
|
import "./jsonld-DweIJ07b.mjs";
|
|
4
4
|
import { c as unwrapReleasedDocumentLoader, s as registerDocumentLoaderWrapper } from "./jsonld-cache-DFnWsLuZ.mjs";
|
|
5
5
|
import { getLogger } from "@logtape/logtape";
|