@fedify/fedify 2.4.0-dev.2054 → 2.4.0-dev.2063
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/dist/{builder-C86Z3BKs.mjs → builder-BzS4brdy.mjs} +8 -2
- package/dist/compat/mod.d.cts +1 -1
- package/dist/compat/mod.d.ts +1 -1
- package/dist/compat/transformers.test.mjs +1 -1
- package/dist/{compound-proof-BcZqTCwy.mjs → compound-proof-BrSXP5so.mjs} +1 -1
- package/dist/{context-BJPHhBmD.d.ts → context-D_gg4M0n.d.ts} +102 -1
- package/dist/{context-Bh_mJfbD.d.cts → context-b36TpPoG.d.cts} +102 -1
- package/dist/{deno-Bz6KTcon.mjs → deno-CVZgG4sc.mjs} +1 -1
- package/dist/{docloader-DS54zLD1.mjs → docloader-DBb8z7_l.mjs} +2 -2
- package/dist/federation/builder.test.mjs +1 -1
- package/dist/federation/compound-fanout.test.mjs +3 -3
- package/dist/federation/handler-compound-proof.test.mjs +3 -3
- package/dist/federation/handler.test.mjs +5 -5
- package/dist/federation/hashlink-media.test.d.mts +2 -0
- package/dist/federation/hashlink-media.test.mjs +422 -0
- package/dist/federation/idempotency.test.mjs +2 -2
- package/dist/federation/metrics.test.mjs +1 -1
- package/dist/federation/middleware.test.mjs +7 -7
- package/dist/federation/mod.cjs +1 -1
- package/dist/federation/mod.d.cts +3 -3
- package/dist/federation/mod.d.ts +3 -3
- package/dist/federation/mod.js +1 -1
- package/dist/federation/outgoing-proof.test.mjs +5 -5
- package/dist/federation/portable.test.mjs +3 -3
- package/dist/federation/router.test.mjs +2 -152
- package/dist/federation/send.test.mjs +3 -3
- package/dist/federation/tasks/enqueue.test.mjs +1 -1
- package/dist/federation/tasks/tasks.test.mjs +2 -2
- package/dist/federation/temporal.test.mjs +1 -1
- package/dist/federation/webfinger.test.mjs +1 -1
- package/dist/{federation-su1OEWsM.cjs → federation-BrsIzNK5.cjs} +139 -21
- package/dist/{http-C3WGK1dL.js → http-99KVDtMr.js} +1 -1
- package/dist/{http-LmUsMjK_.cjs → http-CVjwUCCu.cjs} +1 -1
- package/dist/{http-Ty805y3A.mjs → http-znjq5j6a.mjs} +3 -3
- package/dist/{key-BMc-2eW0.mjs → key-BnMA6vpl.mjs} +2 -2
- package/dist/{kv-cache-BhPPtHg7.mjs → kv-cache--REpvHgG.mjs} +1 -1
- package/dist/{kv-cache-CuaZnk6r.cjs → kv-cache-D2O0JspA.cjs} +1 -1
- package/dist/{kv-cache-BcHCmrC8.js → kv-cache-aijDx_jN.js} +1 -1
- package/dist/{ld-OpXWt-80.mjs → ld-BBVP8ock.mjs} +3 -3
- package/dist/{metrics-CTAe8lYz.mjs → metrics-B5spFq82.mjs} +1 -1
- package/dist/{middleware-C-JLcqy7.mjs → middleware-ClrGS1xy.mjs} +1 -1
- package/dist/{middleware-BtwW3G41.mjs → middleware-Cw8EWwAT.mjs} +145 -33
- package/dist/{middleware-_CMav1o7.js → middleware-CzYM4cJI.js} +140 -22
- package/dist/{mod-DU8aVzQJ.d.cts → mod-Bfenkg_c.d.cts} +1 -1
- package/dist/{mod-BofpDIcU.d.ts → mod-BhMvsgdF.d.ts} +1 -1
- package/dist/{mod-CNRAxXEb.d.ts → mod-Dhm7SqyE.d.ts} +150 -2
- package/dist/{mod-CVQFWefn.d.cts → mod-pLbeNwcC.d.cts} +150 -2
- package/dist/mod.cjs +6 -5
- package/dist/mod.d.cts +5 -5
- package/dist/mod.d.ts +5 -5
- package/dist/mod.js +6 -6
- package/dist/nodeinfo/handler.test.mjs +1 -1
- package/dist/{owner-Bcm4pLXw.cjs → owner-CHBQ0sSj.cjs} +34 -2
- package/dist/{owner-B-TLr-1I.js → owner-Cu_KMvQN.js} +29 -3
- package/dist/{owner-RxB_eQpU.mjs → owner-Hc0hvbbX.mjs} +2 -2
- package/dist/{proof-CVf2XbEa.mjs → proof-B69bJaSn.mjs} +32 -6
- package/dist/router-u5O5KCQr.mjs +156 -0
- package/dist/{send-DF9KzhJH.mjs → send-BB5rBhvN.mjs} +3 -3
- package/dist/sig/compound-proof-discovery.test.mjs +1 -1
- package/dist/sig/compound-proof-producer.test.mjs +1 -1
- package/dist/sig/compound-proof-verification.test.mjs +2 -2
- package/dist/sig/compound-proof.test.mjs +2 -2
- package/dist/sig/http.test.mjs +2 -2
- package/dist/sig/key.test.mjs +1 -1
- package/dist/sig/ld.test.mjs +2 -2
- package/dist/sig/mod.cjs +4 -2
- package/dist/sig/mod.d.cts +2 -2
- package/dist/sig/mod.d.ts +2 -2
- package/dist/sig/mod.js +4 -3
- package/dist/sig/owner.test.mjs +1 -1
- package/dist/sig/portable-collection.test.d.mts +2 -0
- package/dist/sig/portable-collection.test.mjs +971 -0
- package/dist/sig/proof.test.mjs +3 -3
- package/dist/sig-B8WDBV-h.js +401 -0
- package/dist/sig-dut4BzEW.cjs +405 -0
- package/dist/{temporal-B6U3fEUW.mjs → temporal-CcRkOx3C.mjs} +1 -1
- package/dist/testing/kv.test.mjs +1 -1
- package/dist/testing/mod.d.mts +101 -0
- package/dist/utils/docloader.test.mjs +2 -2
- package/dist/utils/kv-cache.test.mjs +1 -1
- package/dist/utils/mod.cjs +1 -1
- package/dist/utils/mod.js +1 -1
- package/package.json +7 -7
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
import "temporal-polyfill";
|
|
2
|
+
import "urlpattern-polyfill";
|
|
3
|
+
globalThis.addEventListener = () => {};
|
|
4
|
+
import { t as MemoryKvStore } from "../kv-DCHkaJ9-.mjs";
|
|
5
|
+
import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
|
|
6
|
+
import { t as assertFalse } from "../assert_false-CPdRnc3E.mjs";
|
|
7
|
+
import { t as assertInstanceOf } from "../assert_instance_of-mrXWWNY-.mjs";
|
|
8
|
+
import { t as assertThrows } from "../assert_throws-BYITOvPO.mjs";
|
|
9
|
+
import "../std__assert-DvMDRPes.mjs";
|
|
10
|
+
import { t as assertStrictEquals } from "../assert_strict_equals-CYvBmkpC.mjs";
|
|
11
|
+
import { t as assert } from "../assert-D1Eafmd_.mjs";
|
|
12
|
+
import { r as ed25519PublicKey } from "../keys-DIJNHW-Y.mjs";
|
|
13
|
+
import { _ as parseHashlinkGatewayRequest, o as createFederation } from "../middleware-Cw8EWwAT.mjs";
|
|
14
|
+
import { r as createFederationBuilder } from "../builder-BzS4brdy.mjs";
|
|
15
|
+
import { n as RouterError } from "../router-u5O5KCQr.mjs";
|
|
16
|
+
import { Note } from "@fedify/vocab";
|
|
17
|
+
import { createTestMeterProvider, mockDocumentLoader, test } from "@fedify/fixture";
|
|
18
|
+
import { computeDigestMultibase, encodeMultibase, exportDidKey } from "@fedify/vocab-runtime";
|
|
19
|
+
//#region src/federation/hashlink-media.test.ts
|
|
20
|
+
const textDecoder = new TextDecoder();
|
|
21
|
+
const FEP_DIGEST = "zQmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n";
|
|
22
|
+
const mediaBytes = new TextEncoder().encode("Hello, portable world!");
|
|
23
|
+
const mediaDigest = await computeDigestMultibase(mediaBytes);
|
|
24
|
+
const mediaSha256 = new Uint8Array(await crypto.subtle.digest("SHA-256", mediaBytes));
|
|
25
|
+
const ffDigest = (/* @__PURE__ */ new Uint8Array(32)).fill(255);
|
|
26
|
+
const ffMultihash = new Uint8Array([
|
|
27
|
+
18,
|
|
28
|
+
32,
|
|
29
|
+
...ffDigest
|
|
30
|
+
]);
|
|
31
|
+
const ffBase64 = textDecoder.decode(encodeMultibase("base64", ffMultihash));
|
|
32
|
+
const ffBase58 = textDecoder.decode(encodeMultibase("base58btc", ffMultihash));
|
|
33
|
+
function mediaUrl(hashlink) {
|
|
34
|
+
return `https://example.com/.well-known/apgateway/${hashlink}`;
|
|
35
|
+
}
|
|
36
|
+
function parse(url) {
|
|
37
|
+
return parseHashlinkGatewayRequest(new URL(url));
|
|
38
|
+
}
|
|
39
|
+
function assertMedia(url) {
|
|
40
|
+
const result = parse(url);
|
|
41
|
+
assert(result != null, `${url} should be a hashlink media request`);
|
|
42
|
+
if (result.type !== "media") throw new Error(`${url} should not be malformed: ${result.error}`);
|
|
43
|
+
return result.media;
|
|
44
|
+
}
|
|
45
|
+
function assertMalformed(url) {
|
|
46
|
+
const result = parse(url);
|
|
47
|
+
assert(result != null, `${url} should be a hashlink media request`);
|
|
48
|
+
assertEquals(result.type, "malformed", url);
|
|
49
|
+
if (result.type === "malformed") assertInstanceOf(result.error, TypeError);
|
|
50
|
+
}
|
|
51
|
+
function createTestFederation() {
|
|
52
|
+
return createFederation({
|
|
53
|
+
kv: new MemoryKvStore(),
|
|
54
|
+
documentLoaderFactory: () => mockDocumentLoader,
|
|
55
|
+
contextLoaderFactory: () => mockDocumentLoader
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
test("parseHashlinkGatewayRequest()", async (t) => {
|
|
59
|
+
await t.step("parses a hashlink", () => {
|
|
60
|
+
const media = assertMedia(mediaUrl(`hl:${mediaDigest}`));
|
|
61
|
+
assertEquals(media.hashlink, `hl:${mediaDigest}`);
|
|
62
|
+
assertEquals(media.digestMultibase, mediaDigest);
|
|
63
|
+
assertEquals(media.algorithm, "sha2-256");
|
|
64
|
+
assertEquals(media.digest, mediaSha256);
|
|
65
|
+
assertEquals(media.multihash, new Uint8Array([
|
|
66
|
+
18,
|
|
67
|
+
32,
|
|
68
|
+
...mediaSha256
|
|
69
|
+
]));
|
|
70
|
+
assert(Object.isFrozen(media));
|
|
71
|
+
});
|
|
72
|
+
await t.step("parses the example of FEP-ef61", () => {
|
|
73
|
+
const media = assertMedia(mediaUrl(`hl:${FEP_DIGEST}`));
|
|
74
|
+
assertEquals(media.digestMultibase, FEP_DIGEST);
|
|
75
|
+
assertEquals(media.digest.length, 32);
|
|
76
|
+
});
|
|
77
|
+
await t.step("normalizes the scheme and percent-encoding", () => {
|
|
78
|
+
for (const hashlink of [`HL:${mediaDigest}`, `hl%3a${mediaDigest}`]) {
|
|
79
|
+
const media = assertMedia(mediaUrl(hashlink));
|
|
80
|
+
assertEquals(media.hashlink, `hl:${mediaDigest}`);
|
|
81
|
+
assertEquals(media.digestMultibase, mediaDigest);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
await t.step("accepts slashes in a base64 digest", () => {
|
|
85
|
+
assert(ffBase64.includes("/"));
|
|
86
|
+
for (const hashlink of [`hl:${ffBase64}`, `hl:${ffBase64.replaceAll("/", "%2F")}`]) {
|
|
87
|
+
const media = assertMedia(mediaUrl(hashlink));
|
|
88
|
+
assertEquals(media.digestMultibase, ffBase64);
|
|
89
|
+
assertEquals(media.digest, ffDigest);
|
|
90
|
+
assertEquals(media.multihash, ffMultihash);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
await t.step("keeps the requested multibase encoding", () => {
|
|
94
|
+
const base58 = assertMedia(mediaUrl(`hl:${ffBase58}`));
|
|
95
|
+
const base64 = assertMedia(mediaUrl(`hl:${ffBase64}`));
|
|
96
|
+
assertEquals(base58.digestMultibase, ffBase58);
|
|
97
|
+
assertEquals(base64.digestMultibase, ffBase64);
|
|
98
|
+
assertEquals(base58.digest, base64.digest);
|
|
99
|
+
assertEquals(base58.multihash, base64.multihash);
|
|
100
|
+
});
|
|
101
|
+
await t.step("ignores the query", () => {
|
|
102
|
+
assertEquals(assertMedia(mediaUrl(`hl:${mediaDigest}?v=1`)).digestMultibase, mediaDigest);
|
|
103
|
+
});
|
|
104
|
+
await t.step("returns fresh digest bytes", () => {
|
|
105
|
+
const a = assertMedia(mediaUrl(`hl:${mediaDigest}`));
|
|
106
|
+
const b = assertMedia(mediaUrl(`hl:${mediaDigest}`));
|
|
107
|
+
a.digest.fill(0);
|
|
108
|
+
a.multihash.fill(0);
|
|
109
|
+
assertEquals(b.digest, mediaSha256);
|
|
110
|
+
});
|
|
111
|
+
await t.step("ignores other URLs", async () => {
|
|
112
|
+
const did = await exportDidKey(ed25519PublicKey.publicKey);
|
|
113
|
+
for (const url of [
|
|
114
|
+
"https://example.com/.well-known/apgateway",
|
|
115
|
+
"https://example.com/.well-known/apgateway/",
|
|
116
|
+
`https://example.com/.well-known/apgateway/${did}/notes/1`,
|
|
117
|
+
`https://example.com/.WELL-KNOWN/apgateway/hl:${mediaDigest}`,
|
|
118
|
+
`https://example.com/.well-known/apgateway-media/hl:${mediaDigest}`,
|
|
119
|
+
`https://example.com/hl:${mediaDigest}`,
|
|
120
|
+
`https://example.com/.well-known/apgateway/x/hl:${mediaDigest}`,
|
|
121
|
+
`https://example.com/.well-known/apgateway/hlx${mediaDigest}`
|
|
122
|
+
]) assertStrictEquals(parse(url), null, url);
|
|
123
|
+
});
|
|
124
|
+
await t.step("recognizes malformed hashlinks", () => {
|
|
125
|
+
const sha512 = textDecoder.decode(encodeMultibase("base58btc", new Uint8Array([
|
|
126
|
+
19,
|
|
127
|
+
64,
|
|
128
|
+
.../* @__PURE__ */ new Uint8Array(64)
|
|
129
|
+
])));
|
|
130
|
+
const short = textDecoder.decode(encodeMultibase("base58btc", new Uint8Array([
|
|
131
|
+
18,
|
|
132
|
+
16,
|
|
133
|
+
.../* @__PURE__ */ new Uint8Array(16)
|
|
134
|
+
])));
|
|
135
|
+
for (const hashlink of [
|
|
136
|
+
"hl:",
|
|
137
|
+
"hl:z",
|
|
138
|
+
"hl:zInvalid0OIl",
|
|
139
|
+
`hl:${sha512}`,
|
|
140
|
+
`hl:${short}`,
|
|
141
|
+
`hl:${mediaDigest}:zCwPSdabLuj3jue1qYujzunnKwpL4myKdyeqySyFhnzZ8qdfW3bb6W8dVdRu`,
|
|
142
|
+
`hl:${mediaDigest}/`,
|
|
143
|
+
`hl:${mediaDigest}/extra`,
|
|
144
|
+
`hl:${mediaDigest}%E0%A4%A`,
|
|
145
|
+
`hl:${mediaDigest}%0A`
|
|
146
|
+
]) assertMalformed(mediaUrl(hashlink));
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
test("Federation.fetch() serves hashlink media", async (t) => {
|
|
150
|
+
await t.step("passes the parsed hashlink to the dispatcher", async () => {
|
|
151
|
+
const federation = createTestFederation();
|
|
152
|
+
const calls = [];
|
|
153
|
+
federation.setHashlinkMediaDispatcher((ctx, media) => {
|
|
154
|
+
calls.push([ctx, media]);
|
|
155
|
+
return new Response(mediaBytes, { headers: { "Content-Type": "text/plain" } });
|
|
156
|
+
});
|
|
157
|
+
const response = await federation.fetch(new Request(mediaUrl(`hl:${mediaDigest}?download=1`)), { contextData: void 0 });
|
|
158
|
+
assertEquals(response.status, 200);
|
|
159
|
+
assertEquals(response.headers.get("Content-Type"), "text/plain");
|
|
160
|
+
assertEquals(new Uint8Array(await response.arrayBuffer()), mediaBytes);
|
|
161
|
+
assertEquals(calls.length, 1);
|
|
162
|
+
const [ctx, media] = calls[0];
|
|
163
|
+
assertEquals(ctx.request.url, mediaUrl(`hl:${mediaDigest}?download=1`));
|
|
164
|
+
assertEquals(ctx.url.href, mediaUrl(`hl:${mediaDigest}?download=1`));
|
|
165
|
+
assertEquals(media.hashlink, `hl:${mediaDigest}`);
|
|
166
|
+
assertEquals(media.digestMultibase, mediaDigest);
|
|
167
|
+
assertEquals(media.algorithm, "sha2-256");
|
|
168
|
+
assertEquals(media.digest, mediaSha256);
|
|
169
|
+
});
|
|
170
|
+
await t.step("sends the response of the dispatcher as is", async () => {
|
|
171
|
+
const federation = createTestFederation();
|
|
172
|
+
let pulled = 0;
|
|
173
|
+
let dispatched;
|
|
174
|
+
federation.setHashlinkMediaDispatcher(() => {
|
|
175
|
+
const body = new ReadableStream({ pull(controller) {
|
|
176
|
+
pulled++;
|
|
177
|
+
controller.enqueue(mediaBytes.subarray(0, 4));
|
|
178
|
+
} }, { highWaterMark: 0 });
|
|
179
|
+
dispatched = new Response(body, {
|
|
180
|
+
status: 206,
|
|
181
|
+
statusText: "Partial Content",
|
|
182
|
+
headers: {
|
|
183
|
+
"Content-Type": "image/png",
|
|
184
|
+
"Content-Range": "bytes 0-3/22",
|
|
185
|
+
"Cache-Control": "public, max-age=31536000, immutable",
|
|
186
|
+
"Content-Disposition": "attachment",
|
|
187
|
+
ETag: `"${mediaDigest}"`,
|
|
188
|
+
"Accept-Ranges": "bytes"
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
return dispatched;
|
|
192
|
+
});
|
|
193
|
+
const response = await federation.fetch(new Request(mediaUrl(`hl:${mediaDigest}`), { headers: { Range: "bytes=0-3" } }), { contextData: void 0 });
|
|
194
|
+
assertStrictEquals(response, dispatched);
|
|
195
|
+
assertEquals(pulled, 0);
|
|
196
|
+
assertEquals(response.status, 206);
|
|
197
|
+
assertEquals(response.statusText, "Partial Content");
|
|
198
|
+
assertEquals(response.headers.get("Content-Range"), "bytes 0-3/22");
|
|
199
|
+
assertEquals(response.headers.get("Cache-Control"), "public, max-age=31536000, immutable");
|
|
200
|
+
assertEquals(response.headers.get("Content-Disposition"), "attachment");
|
|
201
|
+
assertEquals(response.headers.get("ETag"), `"${mediaDigest}"`);
|
|
202
|
+
const reader = response.body.getReader();
|
|
203
|
+
assertEquals((await reader.read()).value, mediaBytes.subarray(0, 4));
|
|
204
|
+
await reader.cancel();
|
|
205
|
+
});
|
|
206
|
+
await t.step("does not touch the Vary header", async () => {
|
|
207
|
+
const federation = createTestFederation();
|
|
208
|
+
federation.setHashlinkMediaDispatcher(() => new Response(mediaBytes, { headers: { Vary: "Accept-Encoding" } }));
|
|
209
|
+
assertEquals((await federation.fetch(new Request(mediaUrl(`hl:${mediaDigest}`), { headers: { Accept: "application/activity+json" } }), { contextData: void 0 })).headers.get("Vary"), "Accept-Encoding");
|
|
210
|
+
});
|
|
211
|
+
await t.step("sends responses with immutable headers", async () => {
|
|
212
|
+
const federation = createTestFederation();
|
|
213
|
+
federation.setHashlinkMediaDispatcher(() => Response.redirect("https://cdn.example/media.png", 302));
|
|
214
|
+
const response = await federation.fetch(new Request(mediaUrl(`hl:${mediaDigest}`), { headers: { Accept: "application/activity+json" } }), { contextData: void 0 });
|
|
215
|
+
assertEquals(response.status, 302);
|
|
216
|
+
assertEquals(response.headers.get("Location"), "https://cdn.example/media.png");
|
|
217
|
+
});
|
|
218
|
+
await t.step("responds with 404 if the dispatcher returns null", async () => {
|
|
219
|
+
const federation = createTestFederation();
|
|
220
|
+
federation.setHashlinkMediaDispatcher(() => null);
|
|
221
|
+
assertEquals((await federation.fetch(new Request(mediaUrl(`hl:${mediaDigest}`)), { contextData: void 0 })).status, 404);
|
|
222
|
+
const custom = await federation.fetch(new Request(mediaUrl(`hl:${mediaDigest}`)), {
|
|
223
|
+
contextData: void 0,
|
|
224
|
+
onNotFound: () => new Response("Nope.", { status: 404 })
|
|
225
|
+
});
|
|
226
|
+
assertEquals(custom.status, 404);
|
|
227
|
+
assertEquals(await custom.text(), "Nope.");
|
|
228
|
+
});
|
|
229
|
+
await t.step("responds with 400 to malformed hashlinks", async () => {
|
|
230
|
+
const federation = createTestFederation();
|
|
231
|
+
let called = false;
|
|
232
|
+
federation.setHashlinkMediaDispatcher(() => {
|
|
233
|
+
called = true;
|
|
234
|
+
return new Response(mediaBytes);
|
|
235
|
+
});
|
|
236
|
+
for (const hashlink of [
|
|
237
|
+
"hl:zInvalid",
|
|
238
|
+
`hl:${mediaDigest}/`,
|
|
239
|
+
`hl:${mediaDigest}:z123`
|
|
240
|
+
]) {
|
|
241
|
+
const response = await federation.fetch(new Request(mediaUrl(hashlink)), { contextData: void 0 });
|
|
242
|
+
assertEquals(response.status, 400, hashlink);
|
|
243
|
+
assertEquals(response.headers.get("Content-Type"), "text/plain; charset=utf-8");
|
|
244
|
+
}
|
|
245
|
+
assertFalse(called);
|
|
246
|
+
});
|
|
247
|
+
await t.step("responds with 405 to other methods", async () => {
|
|
248
|
+
const federation = createTestFederation();
|
|
249
|
+
let called = false;
|
|
250
|
+
federation.setHashlinkMediaDispatcher(() => {
|
|
251
|
+
called = true;
|
|
252
|
+
return new Response(mediaBytes);
|
|
253
|
+
});
|
|
254
|
+
for (const hashlink of [`hl:${mediaDigest}`, "hl:zInvalid"]) {
|
|
255
|
+
const response = await federation.fetch(new Request(mediaUrl(hashlink), {
|
|
256
|
+
method: "POST",
|
|
257
|
+
body: mediaBytes
|
|
258
|
+
}), { contextData: void 0 });
|
|
259
|
+
assertEquals(response.status, 405);
|
|
260
|
+
assertEquals(response.headers.get("Allow"), "GET, HEAD");
|
|
261
|
+
}
|
|
262
|
+
assertFalse(called);
|
|
263
|
+
});
|
|
264
|
+
await t.step("responds to HEAD requests without bodies", async () => {
|
|
265
|
+
const federation = createTestFederation();
|
|
266
|
+
let cancelled = false;
|
|
267
|
+
let method;
|
|
268
|
+
federation.setHashlinkMediaDispatcher((ctx) => {
|
|
269
|
+
method = ctx.request.method;
|
|
270
|
+
const body = new ReadableStream({
|
|
271
|
+
start(controller) {
|
|
272
|
+
controller.enqueue(mediaBytes);
|
|
273
|
+
},
|
|
274
|
+
cancel() {
|
|
275
|
+
cancelled = true;
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
return new Response(body, { headers: {
|
|
279
|
+
"Content-Type": "image/png",
|
|
280
|
+
"Content-Length": mediaBytes.length.toString()
|
|
281
|
+
} });
|
|
282
|
+
});
|
|
283
|
+
const response = await federation.fetch(new Request(mediaUrl(`hl:${mediaDigest}`), { method: "HEAD" }), { contextData: void 0 });
|
|
284
|
+
assertEquals(method, "HEAD");
|
|
285
|
+
assertEquals(response.status, 200);
|
|
286
|
+
assertStrictEquals(response.body, null);
|
|
287
|
+
assert(cancelled);
|
|
288
|
+
assertEquals(response.headers.get("Content-Type"), "image/png");
|
|
289
|
+
assertEquals(response.headers.get("Content-Length"), mediaBytes.length.toString());
|
|
290
|
+
const malformed = await federation.fetch(new Request(mediaUrl("hl:zInvalid"), { method: "HEAD" }), { contextData: void 0 });
|
|
291
|
+
assertEquals(malformed.status, 400);
|
|
292
|
+
assertStrictEquals(malformed.body, null);
|
|
293
|
+
});
|
|
294
|
+
await t.step("does not wait for cancelling a cloned body", async () => {
|
|
295
|
+
const federation = createTestFederation();
|
|
296
|
+
const cached = new Response(mediaBytes, { headers: { "Content-Type": "image/png" } });
|
|
297
|
+
federation.setHashlinkMediaDispatcher(() => cached.clone());
|
|
298
|
+
let timer;
|
|
299
|
+
const response = await Promise.race([federation.fetch(new Request(mediaUrl(`hl:${mediaDigest}`), { method: "HEAD" }), { contextData: void 0 }), new Promise((resolve) => {
|
|
300
|
+
timer = setTimeout(() => resolve(null), 1e3);
|
|
301
|
+
})]);
|
|
302
|
+
clearTimeout(timer);
|
|
303
|
+
assert(response != null, "the HEAD response should not hang");
|
|
304
|
+
assertEquals(response.status, 200);
|
|
305
|
+
assertStrictEquals(response.body, null);
|
|
306
|
+
assertEquals(response.headers.get("Content-Type"), "image/png");
|
|
307
|
+
await cached.body.cancel();
|
|
308
|
+
});
|
|
309
|
+
await t.step("returns onNotFound responses as is", async () => {
|
|
310
|
+
const federation = createTestFederation();
|
|
311
|
+
federation.setHashlinkMediaDispatcher(() => null);
|
|
312
|
+
const notFound = new Response("", { status: 404 });
|
|
313
|
+
for (const method of ["GET", "HEAD"]) assertStrictEquals(await federation.fetch(new Request(mediaUrl(`hl:${mediaDigest}`), { method }), {
|
|
314
|
+
contextData: void 0,
|
|
315
|
+
onNotFound: () => notFound
|
|
316
|
+
}), notFound, method);
|
|
317
|
+
});
|
|
318
|
+
await t.step("propagates errors thrown by the dispatcher", async () => {
|
|
319
|
+
const federation = createTestFederation();
|
|
320
|
+
const error = /* @__PURE__ */ new Error("Storage is down.");
|
|
321
|
+
federation.setHashlinkMediaDispatcher(() => {
|
|
322
|
+
throw error;
|
|
323
|
+
});
|
|
324
|
+
let thrown;
|
|
325
|
+
try {
|
|
326
|
+
await federation.fetch(new Request(mediaUrl(`hl:${mediaDigest}`)), { contextData: void 0 });
|
|
327
|
+
} catch (e) {
|
|
328
|
+
thrown = e;
|
|
329
|
+
}
|
|
330
|
+
assertStrictEquals(thrown, error);
|
|
331
|
+
});
|
|
332
|
+
await t.step("records metrics", async () => {
|
|
333
|
+
const [meterProvider, recorder] = createTestMeterProvider();
|
|
334
|
+
const federation = createFederation({
|
|
335
|
+
kv: new MemoryKvStore(),
|
|
336
|
+
documentLoaderFactory: () => mockDocumentLoader,
|
|
337
|
+
contextLoaderFactory: () => mockDocumentLoader,
|
|
338
|
+
meterProvider
|
|
339
|
+
});
|
|
340
|
+
federation.setHashlinkMediaDispatcher(() => new Response(mediaBytes));
|
|
341
|
+
await federation.fetch(new Request(mediaUrl(`hl:${mediaDigest}`)), { contextData: void 0 });
|
|
342
|
+
await federation.fetch(new Request(mediaUrl("hl:zInvalid")), { contextData: void 0 });
|
|
343
|
+
const counts = recorder.getMeasurements("fedify.http.server.request.count");
|
|
344
|
+
assertEquals(counts.length, 2);
|
|
345
|
+
for (const [count, status] of [[counts[0], 200], [counts[1], 400]]) {
|
|
346
|
+
assertEquals(count.attributes["fedify.endpoint"], "hashlink_media");
|
|
347
|
+
assertEquals(count.attributes["http.response.status_code"], status);
|
|
348
|
+
assertEquals(count.attributes["fedify.route.template"], "/.well-known/apgateway/hl:{digestMultibase}");
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
});
|
|
352
|
+
test("Federation.fetch() routes hashlink media apart from other routes", async (t) => {
|
|
353
|
+
const did = await exportDidKey(ed25519PublicKey.publicKey);
|
|
354
|
+
await t.step("responds with 404 without a dispatcher", async () => {
|
|
355
|
+
const federation = createTestFederation();
|
|
356
|
+
for (const method of ["GET", "POST"]) assertEquals((await federation.fetch(new Request(mediaUrl(`hl:${mediaDigest}`), { method }), { contextData: void 0 })).status, 404, method);
|
|
357
|
+
assertEquals((await federation.fetch(new Request(mediaUrl("hl:zInvalid")), { contextData: void 0 })).status, 404);
|
|
358
|
+
});
|
|
359
|
+
await t.step("keeps portable objects apart from media", async () => {
|
|
360
|
+
const federation = createTestFederation();
|
|
361
|
+
const objectCalls = [];
|
|
362
|
+
let mediaCalled = false;
|
|
363
|
+
federation.setObjectDispatcher(Note, "/notes/{id}", (_ctx, values) => {
|
|
364
|
+
objectCalls.push(values);
|
|
365
|
+
return null;
|
|
366
|
+
});
|
|
367
|
+
federation.setHashlinkMediaDispatcher(() => {
|
|
368
|
+
mediaCalled = true;
|
|
369
|
+
return null;
|
|
370
|
+
});
|
|
371
|
+
assertEquals((await federation.fetch(new Request(`https://example.com/.well-known/apgateway/${did}/notes/1`, { headers: { Accept: "application/activity+json" } }), { contextData: void 0 })).status, 404);
|
|
372
|
+
assertEquals(objectCalls, [{ id: "1" }]);
|
|
373
|
+
assertFalse(mediaCalled);
|
|
374
|
+
await federation.fetch(new Request(mediaUrl(`hl:${mediaDigest}`), { headers: { Accept: "application/activity+json" } }), { contextData: void 0 });
|
|
375
|
+
assert(mediaCalled);
|
|
376
|
+
assertEquals(objectCalls.length, 1);
|
|
377
|
+
});
|
|
378
|
+
await t.step("lets application routes shadow the gateway", async () => {
|
|
379
|
+
const federation = createTestFederation();
|
|
380
|
+
const objectCalls = [];
|
|
381
|
+
let mediaCalled = false;
|
|
382
|
+
federation.setObjectDispatcher(Note, "/.well-known/apgateway/{+id}", (_ctx, values) => {
|
|
383
|
+
objectCalls.push(values);
|
|
384
|
+
return null;
|
|
385
|
+
});
|
|
386
|
+
federation.setHashlinkMediaDispatcher(() => {
|
|
387
|
+
mediaCalled = true;
|
|
388
|
+
return new Response(mediaBytes);
|
|
389
|
+
});
|
|
390
|
+
assertEquals((await federation.fetch(new Request(mediaUrl(`hl:${mediaDigest}`), { headers: { Accept: "application/activity+json" } }), { contextData: void 0 })).status, 404);
|
|
391
|
+
assertEquals(objectCalls, [{ id: `hl:${mediaDigest}` }]);
|
|
392
|
+
assertFalse(mediaCalled);
|
|
393
|
+
});
|
|
394
|
+
await t.step("keeps unrelated paths not found", async () => {
|
|
395
|
+
const federation = createTestFederation();
|
|
396
|
+
let mediaCalled = false;
|
|
397
|
+
federation.setHashlinkMediaDispatcher(() => {
|
|
398
|
+
mediaCalled = true;
|
|
399
|
+
return new Response(mediaBytes);
|
|
400
|
+
});
|
|
401
|
+
for (const url of [
|
|
402
|
+
`https://example.com/hl:${mediaDigest}`,
|
|
403
|
+
"https://example.com/.well-known/apgateway",
|
|
404
|
+
`https://example.com/.well-known/apgateway-media/hl:${mediaDigest}`
|
|
405
|
+
]) assertEquals((await federation.fetch(new Request(url), { contextData: void 0 })).status, 404, url);
|
|
406
|
+
assertFalse(mediaCalled);
|
|
407
|
+
});
|
|
408
|
+
});
|
|
409
|
+
test("FederationBuilder.setHashlinkMediaDispatcher()", async () => {
|
|
410
|
+
const builder = createFederationBuilder();
|
|
411
|
+
builder.setHashlinkMediaDispatcher(() => new Response(mediaBytes));
|
|
412
|
+
assertThrows(() => builder.setHashlinkMediaDispatcher(() => null), RouterError, "Hashlink media dispatcher already set.");
|
|
413
|
+
const response = await (await builder.build({
|
|
414
|
+
kv: new MemoryKvStore(),
|
|
415
|
+
documentLoaderFactory: () => mockDocumentLoader,
|
|
416
|
+
contextLoaderFactory: () => mockDocumentLoader
|
|
417
|
+
})).fetch(new Request(mediaUrl(`hl:${mediaDigest}`)), { contextData: void 0 });
|
|
418
|
+
assertEquals(response.status, 200);
|
|
419
|
+
assertEquals(new Uint8Array(await response.arrayBuffer()), mediaBytes);
|
|
420
|
+
});
|
|
421
|
+
//#endregion
|
|
422
|
+
export {};
|
|
@@ -5,8 +5,8 @@ import { t as MemoryKvStore } from "../kv-DCHkaJ9-.mjs";
|
|
|
5
5
|
import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
|
|
6
6
|
import "../std__assert-DvMDRPes.mjs";
|
|
7
7
|
import { n as ed25519PrivateKey, r as ed25519PublicKey, t as ed25519Multikey } from "../keys-DIJNHW-Y.mjs";
|
|
8
|
-
import { o as createFederation } from "../middleware-
|
|
9
|
-
import { r as signObject } from "../proof-
|
|
8
|
+
import { o as createFederation } from "../middleware-Cw8EWwAT.mjs";
|
|
9
|
+
import { r as signObject } from "../proof-B69bJaSn.mjs";
|
|
10
10
|
import { Create, Follow, Person } from "@fedify/vocab";
|
|
11
11
|
import { mockDocumentLoader, test } from "@fedify/fixture";
|
|
12
12
|
//#region src/federation/idempotency.test.ts
|
|
@@ -4,7 +4,7 @@ globalThis.addEventListener = () => {};
|
|
|
4
4
|
import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
|
|
5
5
|
import "../std__assert-DvMDRPes.mjs";
|
|
6
6
|
import { t as assertRejects } from "../assert_rejects-CTptdYck.mjs";
|
|
7
|
-
import { _ as recordKeyLookup, a as instrumentDocumentLoader, b as recordWebFingerHandle, c as recordCircuitBreakerStateChange, d as recordCollectionRequest, f as recordCollectionTotalItems, g as recordInboxActivity, h as recordFanoutRecipients, i as getRemoteHost, l as recordCollectionDispatchDuration, m as recordDocumentFetch, p as recordDocumentCache, r as getFederationMetrics, t as classifyFetchError, u as recordCollectionPageItems, v as recordOutboxActivity, x as registerQueueDepthGauge, y as recordOutboxEnqueue } from "../metrics-
|
|
7
|
+
import { _ as recordKeyLookup, a as instrumentDocumentLoader, b as recordWebFingerHandle, c as recordCircuitBreakerStateChange, d as recordCollectionRequest, f as recordCollectionTotalItems, g as recordInboxActivity, h as recordFanoutRecipients, i as getRemoteHost, l as recordCollectionDispatchDuration, m as recordDocumentFetch, p as recordDocumentCache, r as getFederationMetrics, t as classifyFetchError, u as recordCollectionPageItems, v as recordOutboxActivity, x as registerQueueDepthGauge, y as recordOutboxEnqueue } from "../metrics-B5spFq82.mjs";
|
|
8
8
|
import { createTestMeterProvider, test } from "@fedify/fixture";
|
|
9
9
|
import { FetchError } from "@fedify/vocab-runtime";
|
|
10
10
|
import { DataPointType, MeterProvider, MetricReader } from "@opentelemetry/sdk-metrics";
|
|
@@ -16,14 +16,14 @@ import "../std__assert-DvMDRPes.mjs";
|
|
|
16
16
|
import { t as assertRejects } from "../assert_rejects-CTptdYck.mjs";
|
|
17
17
|
import { t as assertStrictEquals } from "../assert_strict_equals-CYvBmkpC.mjs";
|
|
18
18
|
import { t as assert } from "../assert-D1Eafmd_.mjs";
|
|
19
|
-
import { g as recordInboxActivity } from "../metrics-
|
|
20
|
-
import { l as verifyRequest, s as signRequest } from "../http-
|
|
19
|
+
import { g as recordInboxActivity } from "../metrics-B5spFq82.mjs";
|
|
20
|
+
import { l as verifyRequest, s as signRequest } from "../http-znjq5j6a.mjs";
|
|
21
21
|
import { a as rsaPrivateKey3, c as rsaPublicKey3, i as rsaPrivateKey2, n as ed25519PrivateKey, r as ed25519PublicKey, s as rsaPublicKey2, t as ed25519Multikey } from "../keys-DIJNHW-Y.mjs";
|
|
22
|
-
import { t as getAuthenticatedDocumentLoader } from "../docloader-
|
|
23
|
-
import {
|
|
24
|
-
import { a as compactJsonLd, h as verifyJsonLd, p as signJsonLd, s as detachSignature } from "../ld-
|
|
25
|
-
import { t as doesActorOwnKey } from "../owner-
|
|
26
|
-
import { a as verifyObject, r as signObject } from "../proof-
|
|
22
|
+
import { t as getAuthenticatedDocumentLoader } from "../docloader-DBb8z7_l.mjs";
|
|
23
|
+
import { i as KvSpecDeterminer, n as FederationImpl, o as createFederation, r as InboxContextImpl, t as ContextImpl, v as handleBenchmarkTrigger } from "../middleware-Cw8EWwAT.mjs";
|
|
24
|
+
import { a as compactJsonLd, h as verifyJsonLd, p as signJsonLd, s as detachSignature } from "../ld-BBVP8ock.mjs";
|
|
25
|
+
import { t as doesActorOwnKey } from "../owner-Hc0hvbbX.mjs";
|
|
26
|
+
import { a as verifyObject, r as signObject } from "../proof-B69bJaSn.mjs";
|
|
27
27
|
import { t as CircuitBreaker } from "../circuit-breaker-C5NqoLBJ.mjs";
|
|
28
28
|
import { t as TaskCodec } from "../codec-C6rTrpIp.mjs";
|
|
29
29
|
import { t as markCircuitBreakerLegacySweepDone } from "../circuit-breaker-test-utils-DW6YC_Pe.mjs";
|
package/dist/federation/mod.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const require_federation = require("../federation-
|
|
3
|
+
const require_federation = require("../federation-BrsIzNK5.cjs");
|
|
4
4
|
exports.CircuitBreaker = require_federation.CircuitBreaker;
|
|
5
5
|
exports.InProcessMessageQueue = require_federation.InProcessMessageQueue;
|
|
6
6
|
exports.MemoryKvStore = require_federation.MemoryKvStore;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import { $ as MessageQueue, A as ObjectCallbackSetters, At as
|
|
2
|
+
import { $ as MessageQueue, A as ObjectCallbackSetters, At as InboxListener, B as TaskDefinitionOptions, Bt as UnverifiedActivityHandler, C as FederationOptions, Ct as CollectionDispatcher, D as InboxChallengePolicy, Dt as HashlinkMediaDispatcher, E as IdempotencyStrategy, Et as CustomCollectionDispatcher, F as FederationQueueOptions, Ft as OutboxErrorHandler, G as RetryContext, Gt as PageItems, H as TaskHandler, Ht as WebFingerLinksDispatcher, I as createFederation, It as OutboxListener, J as RespondWithObjectOptions, K as RetryPolicy, Kt as buildCollectionSynchronizationHeader, L as Message, Lt as OutboxListenerErrorHandler, M as Rfc6570Expression, Mt as NodeInfoDispatcher, N as FederationKvPrefixes, Nt as ObjectAuthorizePredicate, O as InboxListenerSetters, Ot as HashlinkMediaRequest, P as FederationOrigin, Pt as ObjectDispatcher, Q as InProcessMessageQueueOptions, R as createFederationBuilder, Rt as OutboxPermanentFailureHandler, S as FederationFetchOptions, St as CollectionCursor, T as IdempotencyKeyCallback, Tt as CustomCollectionCursor, U as TaskRegistry, Ut as SendActivityError, V as TaskEnqueueOptions, Vt as UnverifiedActivityReason, W as CreateExponentialBackoffPolicyOptions, Wt as SenderKeyPair, X as respondWithObjectIfAcceptable, Y as respondWithObject, Z as InProcessMessageQueue, _ as CustomCollectionCallbackSetters, _t as ActorDispatcher, a as GetSignedKeyOptions, at as CircuitBreakerActivityDrop, b as FederationBenchmarkOptions, bt as AuthorizePredicate, c as ParseUriResult, ct as CircuitBreakerFailurePolicy, d as RouteActivityOptions, dt as CircuitBreakerState, et as MessageQueueDepth, f as SendActivityOptions, ft as CircuitBreakerStateChange, g as ConstructorWithTypeId, gt as ActorAliasMapper, h as CollectionCallbackSetters, ht as parseCircuitBreakerKvState, i as GetActorOptions, it as CircuitBreaker, j as OutboxListenerSetters, jt as MediaUploaderCallback, k as MediaUploaderSetters, kt as InboxErrorHandler, l as PortableRequest, lt as CircuitBreakerKvState, m as ActorCallbackSetters, mt as normalizeCircuitBreakerOptions, n as Context, nt as MessageQueueListenOptions, o as InboxContext, ot as CircuitBreakerBeforeSendDecision, p as SendActivityOptionsForCollection, pt as NormalizedCircuitBreakerOptions, q as createExponentialBackoffPolicy, qt as digest, r as ForwardActivityOptions, rt as ParallelMessageQueue, s as OutboxContext, st as CircuitBreakerCreateOptions, t as ActorKeyPair, tt as MessageQueueEnqueueOptions, u as RequestContext, ut as CircuitBreakerOptions, v as Federatable, vt as ActorHandleMapper, w as FederationStartQueueOptions, wt as CustomCollectionCounter, x as FederationBuilder, xt as CollectionCounter, y as Federation, yt as ActorKeyPairsDispatcher, z as TaskDefinition, zt as SharedInboxKeyDispatcher } from "../context-b36TpPoG.cjs";
|
|
3
3
|
import { a as MemoryKvStore, i as KvStoreSetOptions, n as KvStore, r as KvStoreListEntry, t as KvKey } from "../kv-BhNbN8Ed.cjs";
|
|
4
|
-
import { a as RouterOptions, i as RouterError, n as handleWebFinger, o as RouterRouteResult, r as Router, t as WebFingerHandlerParameters } from "../mod-
|
|
5
|
-
export { ActorAliasMapper, ActorCallbackSetters, ActorDispatcher, ActorHandleMapper, ActorKeyPair, ActorKeyPairsDispatcher, AuthorizePredicate, CircuitBreaker, CircuitBreakerActivityDrop, CircuitBreakerBeforeSendDecision, CircuitBreakerCreateOptions, CircuitBreakerFailurePolicy, CircuitBreakerKvState, CircuitBreakerOptions, CircuitBreakerState, CircuitBreakerStateChange, CollectionCallbackSetters, CollectionCounter, CollectionCursor, CollectionDispatcher, ConstructorWithTypeId, Context, CreateExponentialBackoffPolicyOptions, CustomCollectionCallbackSetters, CustomCollectionCounter, CustomCollectionCursor, CustomCollectionDispatcher, Federatable, Federation, FederationBenchmarkOptions, FederationBuilder, FederationFetchOptions, FederationKvPrefixes, FederationOptions, FederationOrigin, FederationQueueOptions, FederationStartQueueOptions, ForwardActivityOptions, GetActorOptions, GetSignedKeyOptions, IdempotencyKeyCallback, IdempotencyStrategy, InProcessMessageQueue, InProcessMessageQueueOptions, InboxChallengePolicy, InboxContext, InboxErrorHandler, InboxListener, InboxListenerSetters, KvKey, KvStore, KvStoreListEntry, KvStoreSetOptions, MediaUploaderCallback, MediaUploaderSetters, MemoryKvStore, Message, MessageQueue, MessageQueueDepth, MessageQueueEnqueueOptions, MessageQueueListenOptions, NodeInfoDispatcher, NormalizedCircuitBreakerOptions, ObjectAuthorizePredicate, ObjectCallbackSetters, ObjectDispatcher, OutboxContext, OutboxErrorHandler, OutboxListener, OutboxListenerErrorHandler, OutboxListenerSetters, OutboxPermanentFailureHandler, PageItems, ParallelMessageQueue, ParseUriResult, PortableRequest, RequestContext, RespondWithObjectOptions, RetryContext, RetryPolicy, Rfc6570Expression, RouteActivityOptions, Router, RouterError, RouterOptions, RouterRouteResult, SendActivityError, SendActivityOptions, SendActivityOptionsForCollection, SenderKeyPair, SharedInboxKeyDispatcher, TaskDefinition, TaskDefinitionOptions, TaskEnqueueOptions, TaskHandler, TaskRegistry, UnverifiedActivityHandler, UnverifiedActivityReason, WebFingerHandlerParameters, WebFingerLinksDispatcher, buildCollectionSynchronizationHeader, createExponentialBackoffPolicy, createFederation, createFederationBuilder, digest, handleWebFinger, normalizeCircuitBreakerOptions, parseCircuitBreakerKvState, respondWithObject, respondWithObjectIfAcceptable };
|
|
4
|
+
import { a as RouterOptions, i as RouterError, n as handleWebFinger, o as RouterRouteResult, r as Router, t as WebFingerHandlerParameters } from "../mod-Bfenkg_c.cjs";
|
|
5
|
+
export { ActorAliasMapper, ActorCallbackSetters, ActorDispatcher, ActorHandleMapper, ActorKeyPair, ActorKeyPairsDispatcher, AuthorizePredicate, CircuitBreaker, CircuitBreakerActivityDrop, CircuitBreakerBeforeSendDecision, CircuitBreakerCreateOptions, CircuitBreakerFailurePolicy, CircuitBreakerKvState, CircuitBreakerOptions, CircuitBreakerState, CircuitBreakerStateChange, CollectionCallbackSetters, CollectionCounter, CollectionCursor, CollectionDispatcher, ConstructorWithTypeId, Context, CreateExponentialBackoffPolicyOptions, CustomCollectionCallbackSetters, CustomCollectionCounter, CustomCollectionCursor, CustomCollectionDispatcher, Federatable, Federation, FederationBenchmarkOptions, FederationBuilder, FederationFetchOptions, FederationKvPrefixes, FederationOptions, FederationOrigin, FederationQueueOptions, FederationStartQueueOptions, ForwardActivityOptions, GetActorOptions, GetSignedKeyOptions, HashlinkMediaDispatcher, HashlinkMediaRequest, IdempotencyKeyCallback, IdempotencyStrategy, InProcessMessageQueue, InProcessMessageQueueOptions, InboxChallengePolicy, InboxContext, InboxErrorHandler, InboxListener, InboxListenerSetters, KvKey, KvStore, KvStoreListEntry, KvStoreSetOptions, MediaUploaderCallback, MediaUploaderSetters, MemoryKvStore, Message, MessageQueue, MessageQueueDepth, MessageQueueEnqueueOptions, MessageQueueListenOptions, NodeInfoDispatcher, NormalizedCircuitBreakerOptions, ObjectAuthorizePredicate, ObjectCallbackSetters, ObjectDispatcher, OutboxContext, OutboxErrorHandler, OutboxListener, OutboxListenerErrorHandler, OutboxListenerSetters, OutboxPermanentFailureHandler, PageItems, ParallelMessageQueue, ParseUriResult, PortableRequest, RequestContext, RespondWithObjectOptions, RetryContext, RetryPolicy, Rfc6570Expression, RouteActivityOptions, Router, RouterError, RouterOptions, RouterRouteResult, SendActivityError, SendActivityOptions, SendActivityOptionsForCollection, SenderKeyPair, SharedInboxKeyDispatcher, TaskDefinition, TaskDefinitionOptions, TaskEnqueueOptions, TaskHandler, TaskRegistry, UnverifiedActivityHandler, UnverifiedActivityReason, WebFingerHandlerParameters, WebFingerLinksDispatcher, buildCollectionSynchronizationHeader, createExponentialBackoffPolicy, createFederation, createFederationBuilder, digest, handleWebFinger, normalizeCircuitBreakerOptions, parseCircuitBreakerKvState, respondWithObject, respondWithObjectIfAcceptable };
|
package/dist/federation/mod.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
|
-
import { $ as MessageQueue, A as ObjectCallbackSetters, At as
|
|
2
|
+
import { $ as MessageQueue, A as ObjectCallbackSetters, At as InboxListener, B as TaskDefinitionOptions, Bt as UnverifiedActivityHandler, C as FederationOptions, Ct as CollectionDispatcher, D as InboxChallengePolicy, Dt as HashlinkMediaDispatcher, E as IdempotencyStrategy, Et as CustomCollectionDispatcher, F as FederationQueueOptions, Ft as OutboxErrorHandler, G as RetryContext, Gt as PageItems, H as TaskHandler, Ht as WebFingerLinksDispatcher, I as createFederation, It as OutboxListener, J as RespondWithObjectOptions, K as RetryPolicy, Kt as buildCollectionSynchronizationHeader, L as Message, Lt as OutboxListenerErrorHandler, M as Rfc6570Expression, Mt as NodeInfoDispatcher, N as FederationKvPrefixes, Nt as ObjectAuthorizePredicate, O as InboxListenerSetters, Ot as HashlinkMediaRequest, P as FederationOrigin, Pt as ObjectDispatcher, Q as InProcessMessageQueueOptions, R as createFederationBuilder, Rt as OutboxPermanentFailureHandler, S as FederationFetchOptions, St as CollectionCursor, T as IdempotencyKeyCallback, Tt as CustomCollectionCursor, U as TaskRegistry, Ut as SendActivityError, V as TaskEnqueueOptions, Vt as UnverifiedActivityReason, W as CreateExponentialBackoffPolicyOptions, Wt as SenderKeyPair, X as respondWithObjectIfAcceptable, Y as respondWithObject, Z as InProcessMessageQueue, _ as CustomCollectionCallbackSetters, _t as ActorDispatcher, a as GetSignedKeyOptions, at as CircuitBreakerActivityDrop, b as FederationBenchmarkOptions, bt as AuthorizePredicate, c as ParseUriResult, ct as CircuitBreakerFailurePolicy, d as RouteActivityOptions, dt as CircuitBreakerState, et as MessageQueueDepth, f as SendActivityOptions, ft as CircuitBreakerStateChange, g as ConstructorWithTypeId, gt as ActorAliasMapper, h as CollectionCallbackSetters, ht as parseCircuitBreakerKvState, i as GetActorOptions, it as CircuitBreaker, j as OutboxListenerSetters, jt as MediaUploaderCallback, k as MediaUploaderSetters, kt as InboxErrorHandler, l as PortableRequest, lt as CircuitBreakerKvState, m as ActorCallbackSetters, mt as normalizeCircuitBreakerOptions, n as Context, nt as MessageQueueListenOptions, o as InboxContext, ot as CircuitBreakerBeforeSendDecision, p as SendActivityOptionsForCollection, pt as NormalizedCircuitBreakerOptions, q as createExponentialBackoffPolicy, qt as digest, r as ForwardActivityOptions, rt as ParallelMessageQueue, s as OutboxContext, st as CircuitBreakerCreateOptions, t as ActorKeyPair, tt as MessageQueueEnqueueOptions, u as RequestContext, ut as CircuitBreakerOptions, v as Federatable, vt as ActorHandleMapper, w as FederationStartQueueOptions, wt as CustomCollectionCounter, x as FederationBuilder, xt as CollectionCounter, y as Federation, yt as ActorKeyPairsDispatcher, z as TaskDefinition, zt as SharedInboxKeyDispatcher } from "../context-D_gg4M0n.js";
|
|
3
3
|
import { a as MemoryKvStore, i as KvStoreSetOptions, n as KvStore, r as KvStoreListEntry, t as KvKey } from "../kv-BhNbN8Ed.js";
|
|
4
|
-
import { a as RouterOptions, i as RouterError, n as handleWebFinger, o as RouterRouteResult, r as Router, t as WebFingerHandlerParameters } from "../mod-
|
|
5
|
-
export { ActorAliasMapper, ActorCallbackSetters, ActorDispatcher, ActorHandleMapper, ActorKeyPair, ActorKeyPairsDispatcher, AuthorizePredicate, CircuitBreaker, CircuitBreakerActivityDrop, CircuitBreakerBeforeSendDecision, CircuitBreakerCreateOptions, CircuitBreakerFailurePolicy, CircuitBreakerKvState, CircuitBreakerOptions, CircuitBreakerState, CircuitBreakerStateChange, CollectionCallbackSetters, CollectionCounter, CollectionCursor, CollectionDispatcher, ConstructorWithTypeId, Context, CreateExponentialBackoffPolicyOptions, CustomCollectionCallbackSetters, CustomCollectionCounter, CustomCollectionCursor, CustomCollectionDispatcher, Federatable, Federation, FederationBenchmarkOptions, FederationBuilder, FederationFetchOptions, FederationKvPrefixes, FederationOptions, FederationOrigin, FederationQueueOptions, FederationStartQueueOptions, ForwardActivityOptions, GetActorOptions, GetSignedKeyOptions, IdempotencyKeyCallback, IdempotencyStrategy, InProcessMessageQueue, InProcessMessageQueueOptions, InboxChallengePolicy, InboxContext, InboxErrorHandler, InboxListener, InboxListenerSetters, KvKey, KvStore, KvStoreListEntry, KvStoreSetOptions, MediaUploaderCallback, MediaUploaderSetters, MemoryKvStore, Message, MessageQueue, MessageQueueDepth, MessageQueueEnqueueOptions, MessageQueueListenOptions, NodeInfoDispatcher, NormalizedCircuitBreakerOptions, ObjectAuthorizePredicate, ObjectCallbackSetters, ObjectDispatcher, OutboxContext, OutboxErrorHandler, OutboxListener, OutboxListenerErrorHandler, OutboxListenerSetters, OutboxPermanentFailureHandler, PageItems, ParallelMessageQueue, ParseUriResult, PortableRequest, RequestContext, RespondWithObjectOptions, RetryContext, RetryPolicy, Rfc6570Expression, RouteActivityOptions, Router, RouterError, RouterOptions, RouterRouteResult, SendActivityError, SendActivityOptions, SendActivityOptionsForCollection, SenderKeyPair, SharedInboxKeyDispatcher, TaskDefinition, TaskDefinitionOptions, TaskEnqueueOptions, TaskHandler, TaskRegistry, UnverifiedActivityHandler, UnverifiedActivityReason, WebFingerHandlerParameters, WebFingerLinksDispatcher, buildCollectionSynchronizationHeader, createExponentialBackoffPolicy, createFederation, createFederationBuilder, digest, handleWebFinger, normalizeCircuitBreakerOptions, parseCircuitBreakerKvState, respondWithObject, respondWithObjectIfAcceptable };
|
|
4
|
+
import { a as RouterOptions, i as RouterError, n as handleWebFinger, o as RouterRouteResult, r as Router, t as WebFingerHandlerParameters } from "../mod-BhMvsgdF.js";
|
|
5
|
+
export { ActorAliasMapper, ActorCallbackSetters, ActorDispatcher, ActorHandleMapper, ActorKeyPair, ActorKeyPairsDispatcher, AuthorizePredicate, CircuitBreaker, CircuitBreakerActivityDrop, CircuitBreakerBeforeSendDecision, CircuitBreakerCreateOptions, CircuitBreakerFailurePolicy, CircuitBreakerKvState, CircuitBreakerOptions, CircuitBreakerState, CircuitBreakerStateChange, CollectionCallbackSetters, CollectionCounter, CollectionCursor, CollectionDispatcher, ConstructorWithTypeId, Context, CreateExponentialBackoffPolicyOptions, CustomCollectionCallbackSetters, CustomCollectionCounter, CustomCollectionCursor, CustomCollectionDispatcher, Federatable, Federation, FederationBenchmarkOptions, FederationBuilder, FederationFetchOptions, FederationKvPrefixes, FederationOptions, FederationOrigin, FederationQueueOptions, FederationStartQueueOptions, ForwardActivityOptions, GetActorOptions, GetSignedKeyOptions, HashlinkMediaDispatcher, HashlinkMediaRequest, IdempotencyKeyCallback, IdempotencyStrategy, InProcessMessageQueue, InProcessMessageQueueOptions, InboxChallengePolicy, InboxContext, InboxErrorHandler, InboxListener, InboxListenerSetters, KvKey, KvStore, KvStoreListEntry, KvStoreSetOptions, MediaUploaderCallback, MediaUploaderSetters, MemoryKvStore, Message, MessageQueue, MessageQueueDepth, MessageQueueEnqueueOptions, MessageQueueListenOptions, NodeInfoDispatcher, NormalizedCircuitBreakerOptions, ObjectAuthorizePredicate, ObjectCallbackSetters, ObjectDispatcher, OutboxContext, OutboxErrorHandler, OutboxListener, OutboxListenerErrorHandler, OutboxListenerSetters, OutboxPermanentFailureHandler, PageItems, ParallelMessageQueue, ParseUriResult, PortableRequest, RequestContext, RespondWithObjectOptions, RetryContext, RetryPolicy, Rfc6570Expression, RouteActivityOptions, Router, RouterError, RouterOptions, RouterRouteResult, SendActivityError, SendActivityOptions, SendActivityOptionsForCollection, SenderKeyPair, SharedInboxKeyDispatcher, TaskDefinition, TaskDefinitionOptions, TaskEnqueueOptions, TaskHandler, TaskRegistry, UnverifiedActivityHandler, UnverifiedActivityReason, WebFingerHandlerParameters, WebFingerLinksDispatcher, buildCollectionSynchronizationHeader, createExponentialBackoffPolicy, createFederation, createFederationBuilder, digest, handleWebFinger, normalizeCircuitBreakerOptions, parseCircuitBreakerKvState, respondWithObject, respondWithObjectIfAcceptable };
|
package/dist/federation/mod.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Temporal } from "temporal-polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
|
-
import { a as respondWithObject, c as digest, d as parseCircuitBreakerKvState, f as createFederationBuilder, i as SendActivityError, l as CircuitBreaker, n as handleWebFinger, o as respondWithObjectIfAcceptable, r as createExponentialBackoffPolicy, s as buildCollectionSynchronizationHeader, t as createFederation, u as normalizeCircuitBreakerOptions } from "../middleware-
|
|
3
|
+
import { a as respondWithObject, c as digest, d as parseCircuitBreakerKvState, f as createFederationBuilder, i as SendActivityError, l as CircuitBreaker, n as handleWebFinger, o as respondWithObjectIfAcceptable, r as createExponentialBackoffPolicy, s as buildCollectionSynchronizationHeader, t as createFederation, u as normalizeCircuitBreakerOptions } from "../middleware-CzYM4cJI.js";
|
|
4
4
|
import { getLogger } from "@logtape/logtape";
|
|
5
5
|
import { Router as Router$1, RouterError as RouterError$1, assertPath, isPath } from "@fedify/uri-template";
|
|
6
6
|
import { isEqual } from "es-toolkit";
|
|
@@ -7,12 +7,12 @@ import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
|
|
|
7
7
|
import "../std__assert-DvMDRPes.mjs";
|
|
8
8
|
import { t as assertRejects } from "../assert_rejects-CTptdYck.mjs";
|
|
9
9
|
import { t as assert } from "../assert-D1Eafmd_.mjs";
|
|
10
|
-
import { t as exportJwk } from "../key-
|
|
10
|
+
import { t as exportJwk } from "../key-BnMA6vpl.mjs";
|
|
11
11
|
import { i as rsaPrivateKey2, n as ed25519PrivateKey, r as ed25519PublicKey, s as rsaPublicKey2 } from "../keys-DIJNHW-Y.mjs";
|
|
12
|
-
import { n as FederationImpl, o as createFederation } from "../middleware-
|
|
13
|
-
import { s as detachSignature } from "../ld-
|
|
14
|
-
import { r as signObject } from "../proof-
|
|
15
|
-
import { a as verifyCompoundPortableObjectProofs } from "../compound-proof-
|
|
12
|
+
import { n as FederationImpl, o as createFederation } from "../middleware-Cw8EWwAT.mjs";
|
|
13
|
+
import { s as detachSignature } from "../ld-BBVP8ock.mjs";
|
|
14
|
+
import { r as signObject } from "../proof-B69bJaSn.mjs";
|
|
15
|
+
import { a as verifyCompoundPortableObjectProofs } from "../compound-proof-BrSXP5so.mjs";
|
|
16
16
|
import { Create, Note, Person } from "@fedify/vocab";
|
|
17
17
|
import { mockDocumentLoader, test } from "@fedify/fixture";
|
|
18
18
|
import { exportDidKey, parseIri } from "@fedify/vocab-runtime";
|
|
@@ -7,10 +7,10 @@ import { t as assertInstanceOf } from "../assert_instance_of-mrXWWNY-.mjs";
|
|
|
7
7
|
import { t as assertThrows } from "../assert_throws-BYITOvPO.mjs";
|
|
8
8
|
import "../std__assert-DvMDRPes.mjs";
|
|
9
9
|
import { t as assertStrictEquals } from "../assert_strict_equals-CYvBmkpC.mjs";
|
|
10
|
-
import { s as signRequest } from "../http-
|
|
10
|
+
import { s as signRequest } from "../http-znjq5j6a.mjs";
|
|
11
11
|
import { a as rsaPrivateKey3, c as rsaPublicKey3, i as rsaPrivateKey2, n as ed25519PrivateKey, r as ed25519PublicKey, s as rsaPublicKey2 } from "../keys-DIJNHW-Y.mjs";
|
|
12
|
-
import { g as PORTABLE_OBJECT_CONTENT_TYPE, o as createFederation } from "../middleware-
|
|
13
|
-
import { o as verifyPortableObjectProof, r as signObject } from "../proof-
|
|
12
|
+
import { g as PORTABLE_OBJECT_CONTENT_TYPE, o as createFederation } from "../middleware-Cw8EWwAT.mjs";
|
|
13
|
+
import { o as verifyPortableObjectProof, r as signObject } from "../proof-B69bJaSn.mjs";
|
|
14
14
|
import { Collection, Create, Note, Object as Object$1, Person, Tombstone, lookupObject } from "@fedify/vocab";
|
|
15
15
|
import { mockDocumentLoader, test } from "@fedify/fixture";
|
|
16
16
|
import { exportDidKey, formatIri, parseIri } from "@fedify/vocab-runtime";
|