@fedify/fedify 2.3.0-dev.1048 → 2.3.0-dev.1050
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-BhiIuyGK.mjs → builder-5M0ZV0s3.mjs} +2 -2
- package/dist/compat/transformers.test.mjs +1 -1
- package/dist/{deno-D9LpbVQR.mjs → deno-BvRV20GH.mjs} +1 -1
- package/dist/{docloader-y2viZ2Tx.mjs → docloader-YOsFpxMZ.mjs} +2 -2
- package/dist/federation/builder.test.mjs +1 -1
- package/dist/federation/handler.test.mjs +2 -2
- package/dist/federation/idempotency.test.mjs +2 -2
- package/dist/federation/middleware.test.mjs +199 -6
- package/dist/federation/mod.cjs +1 -1
- package/dist/federation/mod.js +1 -1
- package/dist/federation/send.test.mjs +3 -3
- package/dist/federation/webfinger.test.mjs +1 -1
- package/dist/{http-D6yvDhyL.mjs → http-BETUCsB0.mjs} +2 -2
- package/dist/{http-CA4xKsSY.js → http-Cj-JmUpS.js} +1 -1
- package/dist/{http-Bj0uN6d-.cjs → http-DT4PVP4u.cjs} +1 -1
- package/dist/{key-BPjHWwyv.mjs → key-CjtOXvjb.mjs} +1 -1
- package/dist/{kv-cache-DarvCOHt.js → kv-cache-BOU_yvQi.js} +1 -1
- package/dist/{kv-cache-BdSTsjLb.cjs → kv-cache-DqiCNMDz.cjs} +1 -1
- package/dist/{ld-D9yQwfkO.mjs → ld-WRlX-hAe.mjs} +2 -2
- package/dist/{middleware-0n0ctSu_.js → middleware-B0YQlYeu.js} +96 -7
- package/dist/{middleware-THfK90u_.mjs → middleware-BD-WrN2n.mjs} +50 -13
- package/dist/{middleware-Ccpokmfe.cjs → middleware-C-fzauLy.cjs} +97 -8
- package/dist/{middleware-C5ao_lvm.mjs → middleware-CAUZmBAN.mjs} +1 -1
- package/dist/{middleware-DTxZNOqy.cjs → middleware-D3TvoZdj.cjs} +1 -1
- package/dist/mod.cjs +4 -4
- package/dist/mod.js +4 -4
- package/dist/nodeinfo/handler.test.mjs +1 -1
- package/dist/{owner-CebIXUof.mjs → owner-B6F-ovsj.mjs} +2 -2
- package/dist/{proof-UXZOysVc.mjs → proof-CN82dCfF.mjs} +2 -2
- package/dist/{proof-C2QsttUL.cjs → proof-CP3pE1Ok.cjs} +1 -1
- package/dist/{proof-Cdxbeq4n.js → proof-DCfIkmPR.js} +1 -1
- package/dist/{send-_8qtDYZA.mjs → send-DNs8Rwv0.mjs} +54 -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 +2 -2
- package/dist/sig/mod.js +2 -2
- package/dist/sig/owner.test.mjs +1 -1
- package/dist/sig/proof.test.mjs +1 -1
- package/dist/utils/docloader.test.mjs +2 -2
- package/dist/utils/mod.cjs +1 -1
- package/dist/utils/mod.js +1 -1
- package/package.json +6 -6
|
@@ -2,7 +2,7 @@ import "@js-temporal/polyfill";
|
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
4
|
import { n as RouterError, t as Router } from "./router-CrMLXoOr.mjs";
|
|
5
|
-
import { n as version, t as name } from "./deno-
|
|
5
|
+
import { n as version, t as name } from "./deno-BvRV20GH.mjs";
|
|
6
6
|
import { t as ActivityListenerSet } from "./activity-listener-tztVvlNb.mjs";
|
|
7
7
|
import { Tombstone, getTypeId } from "@fedify/vocab";
|
|
8
8
|
import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
|
|
@@ -59,7 +59,7 @@ var FederationBuilderImpl = class {
|
|
|
59
59
|
this.collectionTypeIds = {};
|
|
60
60
|
}
|
|
61
61
|
async build(options) {
|
|
62
|
-
const { FederationImpl } = await import("./middleware-
|
|
62
|
+
const { FederationImpl } = await import("./middleware-CAUZmBAN.mjs");
|
|
63
63
|
const f = new FederationImpl(options);
|
|
64
64
|
const trailingSlashInsensitiveValue = f.router.trailingSlashInsensitive;
|
|
65
65
|
f.router = this.router.clone();
|
|
@@ -5,7 +5,7 @@ import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
|
|
|
5
5
|
import { t as assertInstanceOf } from "../assert_instance_of-C4Ri6VuN.mjs";
|
|
6
6
|
import { t as assert } from "../assert-DikXweDx.mjs";
|
|
7
7
|
import { t as MemoryKvStore } from "../kv-x2IvBUyq.mjs";
|
|
8
|
-
import { n as FederationImpl, v as actorDehydrator, y as autoIdAssigner } from "../middleware-
|
|
8
|
+
import { n as FederationImpl, v as actorDehydrator, y as autoIdAssigner } from "../middleware-BD-WrN2n.mjs";
|
|
9
9
|
import { test } from "@fedify/fixture";
|
|
10
10
|
import { Follow, Person } from "@fedify/vocab";
|
|
11
11
|
//#region src/compat/transformers.test.ts
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import "@js-temporal/polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { o as validateCryptoKey } from "./key-
|
|
5
|
-
import { n as doubleKnock } from "./http-
|
|
4
|
+
import { o as validateCryptoKey } from "./key-CjtOXvjb.mjs";
|
|
5
|
+
import { n as doubleKnock } from "./http-BETUCsB0.mjs";
|
|
6
6
|
import { curry } from "es-toolkit";
|
|
7
7
|
import { UrlError, createActivityPubRequest, getRemoteDocument, logRequest, validatePublicUrl } from "@fedify/vocab-runtime";
|
|
8
8
|
import { getLogger } from "@logtape/logtape";
|
|
@@ -6,7 +6,7 @@ import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
|
|
|
6
6
|
import { i as assertExists } from "../std__assert-CRDpx_HF.mjs";
|
|
7
7
|
import { t as assertThrows } from "../assert_throws-4NwKEy2q.mjs";
|
|
8
8
|
import { t as MemoryKvStore } from "../kv-x2IvBUyq.mjs";
|
|
9
|
-
import { r as createFederationBuilder } from "../builder-
|
|
9
|
+
import { r as createFederationBuilder } from "../builder-5M0ZV0s3.mjs";
|
|
10
10
|
import { test } from "@fedify/fixture";
|
|
11
11
|
import { Activity, Note, Person } from "@fedify/vocab";
|
|
12
12
|
//#region src/federation/builder.test.ts
|
|
@@ -7,10 +7,10 @@ import { r as assertGreaterOrEqual } from "../std__assert-CRDpx_HF.mjs";
|
|
|
7
7
|
import { t as assertInstanceOf } from "../assert_instance_of-C4Ri6VuN.mjs";
|
|
8
8
|
import { t as assert } from "../assert-DikXweDx.mjs";
|
|
9
9
|
import { r as parseAcceptSignature } from "../accept-CceiKpCy.mjs";
|
|
10
|
-
import { s as signRequest } from "../http-
|
|
10
|
+
import { s as signRequest } from "../http-BETUCsB0.mjs";
|
|
11
11
|
import { a as rsaPrivateKey3, c as rsaPublicKey3, s as rsaPublicKey2 } from "../keys-C3kae-6B.mjs";
|
|
12
12
|
import { t as MemoryKvStore } from "../kv-x2IvBUyq.mjs";
|
|
13
|
-
import { c as handleActor, d as handleInbox, f as handleObject, h as respondWithObjectIfAcceptable, l as handleCollection, m as respondWithObject, o as createFederation, p as handleOutbox, u as handleCustomCollection } from "../middleware-
|
|
13
|
+
import { c as handleActor, d as handleInbox, f as handleObject, h as respondWithObjectIfAcceptable, l as handleCollection, m as respondWithObject, o as createFederation, p as handleOutbox, u as handleCustomCollection } from "../middleware-BD-WrN2n.mjs";
|
|
14
14
|
import { t as ActivityListenerSet } from "../activity-listener-tztVvlNb.mjs";
|
|
15
15
|
import { createTestMeterProvider, createTestTracerProvider, mockDocumentLoader, test } from "@fedify/fixture";
|
|
16
16
|
import { Activity, Create, Note, Person, Tombstone } from "@fedify/vocab";
|
|
@@ -4,9 +4,9 @@ globalThis.addEventListener = () => {};
|
|
|
4
4
|
import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
|
|
5
5
|
import "../std__assert-CRDpx_HF.mjs";
|
|
6
6
|
import { n as ed25519PrivateKey, r as ed25519PublicKey, t as ed25519Multikey } from "../keys-C3kae-6B.mjs";
|
|
7
|
-
import { r as signObject } from "../proof-
|
|
7
|
+
import { r as signObject } from "../proof-CN82dCfF.mjs";
|
|
8
8
|
import { t as MemoryKvStore } from "../kv-x2IvBUyq.mjs";
|
|
9
|
-
import { o as createFederation } from "../middleware-
|
|
9
|
+
import { o as createFederation } from "../middleware-BD-WrN2n.mjs";
|
|
10
10
|
import { mockDocumentLoader, test } from "@fedify/fixture";
|
|
11
11
|
import { Create, Follow, Person } from "@fedify/vocab";
|
|
12
12
|
//#region src/federation/idempotency.test.ts
|
|
@@ -11,14 +11,14 @@ import { t as assertNotEquals } from "../assert_not_equals--wG9hV7u.mjs";
|
|
|
11
11
|
import { t as assertStrictEquals } from "../assert_strict_equals-Dmjbg-bA.mjs";
|
|
12
12
|
import { t as assert } from "../assert-DikXweDx.mjs";
|
|
13
13
|
import { t as esm_default } from "../esm-DhnRLoG9.mjs";
|
|
14
|
-
import { l as verifyRequest, s as signRequest } from "../http-
|
|
14
|
+
import { l as verifyRequest, s as signRequest } from "../http-BETUCsB0.mjs";
|
|
15
15
|
import { a as rsaPrivateKey3, c as rsaPublicKey3, i as rsaPrivateKey2, n as ed25519PrivateKey, r as ed25519PublicKey, s as rsaPublicKey2, t as ed25519Multikey } from "../keys-C3kae-6B.mjs";
|
|
16
|
-
import { t as getAuthenticatedDocumentLoader } from "../docloader-
|
|
17
|
-
import { a as signJsonLd, o as verifyJsonLd, r as detachSignature } from "../ld-
|
|
18
|
-
import { t as doesActorOwnKey } from "../owner-
|
|
19
|
-
import { i as verifyObject, r as signObject } from "../proof-
|
|
16
|
+
import { t as getAuthenticatedDocumentLoader } from "../docloader-YOsFpxMZ.mjs";
|
|
17
|
+
import { a as signJsonLd, o as verifyJsonLd, r as detachSignature } from "../ld-WRlX-hAe.mjs";
|
|
18
|
+
import { t as doesActorOwnKey } from "../owner-B6F-ovsj.mjs";
|
|
19
|
+
import { i as verifyObject, r as signObject } from "../proof-CN82dCfF.mjs";
|
|
20
20
|
import { t as MemoryKvStore } from "../kv-x2IvBUyq.mjs";
|
|
21
|
-
import { i as KvSpecDeterminer, n as FederationImpl, o as createFederation, r as InboxContextImpl, t as ContextImpl } from "../middleware-
|
|
21
|
+
import { i as KvSpecDeterminer, n as FederationImpl, o as createFederation, r as InboxContextImpl, t as ContextImpl } from "../middleware-BD-WrN2n.mjs";
|
|
22
22
|
import { createTestMeterProvider, createTestTracerProvider, mockDocumentLoader, test } from "@fedify/fixture";
|
|
23
23
|
import * as vocab from "@fedify/vocab";
|
|
24
24
|
import { getTypeId, lookupObject } from "@fedify/vocab";
|
|
@@ -956,6 +956,199 @@ test("Federation.fetch()", async (t) => {
|
|
|
956
956
|
});
|
|
957
957
|
esm_default.hardReset();
|
|
958
958
|
});
|
|
959
|
+
test("Federation.fetch() records HTTP server request metrics", async (t) => {
|
|
960
|
+
const createTestContext = () => {
|
|
961
|
+
const kv = new MemoryKvStore();
|
|
962
|
+
const [meterProvider, recorder] = createTestMeterProvider();
|
|
963
|
+
const federation = createFederation({
|
|
964
|
+
kv,
|
|
965
|
+
meterProvider,
|
|
966
|
+
documentLoaderFactory: () => mockDocumentLoader
|
|
967
|
+
});
|
|
968
|
+
federation.setActorDispatcher("/users/{identifier}", (ctx, identifier) => {
|
|
969
|
+
if (identifier === "boom") throw new Error("explosion in actor dispatcher");
|
|
970
|
+
return new vocab.Person({
|
|
971
|
+
id: ctx.getActorUri(identifier),
|
|
972
|
+
inbox: ctx.getInboxUri(identifier),
|
|
973
|
+
preferredUsername: identifier
|
|
974
|
+
});
|
|
975
|
+
});
|
|
976
|
+
federation.setNodeInfoDispatcher("/nodeinfo/2.1", () => ({
|
|
977
|
+
software: {
|
|
978
|
+
name: "example",
|
|
979
|
+
version: "1.0.0"
|
|
980
|
+
},
|
|
981
|
+
protocols: ["activitypub"],
|
|
982
|
+
usage: {
|
|
983
|
+
users: {},
|
|
984
|
+
localPosts: 0,
|
|
985
|
+
localComments: 0
|
|
986
|
+
}
|
|
987
|
+
}));
|
|
988
|
+
federation.setFollowersDispatcher("/users/{identifier}/followers", () => ({ items: [] }));
|
|
989
|
+
federation.setCollectionDispatcher("custom-collection", vocab.Object, "/users/{identifier}/custom/{id}", () => ({ items: [] }));
|
|
990
|
+
federation.setInboxListeners("/users/{identifier}/inbox", "/inbox");
|
|
991
|
+
return {
|
|
992
|
+
federation,
|
|
993
|
+
recorder
|
|
994
|
+
};
|
|
995
|
+
};
|
|
996
|
+
await t.step("records a successful actor request", async () => {
|
|
997
|
+
const { federation, recorder } = createTestContext();
|
|
998
|
+
assertEquals((await federation.fetch(new Request("https://example.com/users/alice", {
|
|
999
|
+
method: "GET",
|
|
1000
|
+
headers: { "Accept": "application/activity+json" }
|
|
1001
|
+
}), { contextData: void 0 })).status, 200);
|
|
1002
|
+
const counts = recorder.getMeasurements("fedify.http.server.request.count");
|
|
1003
|
+
assertEquals(counts.length, 1);
|
|
1004
|
+
assertEquals(counts[0].type, "counter");
|
|
1005
|
+
assertEquals(counts[0].value, 1);
|
|
1006
|
+
assertEquals(counts[0].attributes["http.request.method"], "GET");
|
|
1007
|
+
assertEquals(counts[0].attributes["fedify.endpoint"], "actor");
|
|
1008
|
+
assertEquals(counts[0].attributes["http.response.status_code"], 200);
|
|
1009
|
+
assertEquals(counts[0].attributes["fedify.route.template"], "/users/{identifier}");
|
|
1010
|
+
const durations = recorder.getMeasurements("fedify.http.server.request.duration");
|
|
1011
|
+
assertEquals(durations.length, 1);
|
|
1012
|
+
assertEquals(durations[0].type, "histogram");
|
|
1013
|
+
assert(durations[0].value >= 0);
|
|
1014
|
+
assertEquals(durations[0].attributes["fedify.endpoint"], "actor");
|
|
1015
|
+
assertEquals(durations[0].attributes["http.response.status_code"], 200);
|
|
1016
|
+
assertEquals(durations[0].attributes["fedify.route.template"], "/users/{identifier}");
|
|
1017
|
+
});
|
|
1018
|
+
await t.step("records WebFinger requests", async () => {
|
|
1019
|
+
const { federation, recorder } = createTestContext();
|
|
1020
|
+
assertEquals((await federation.fetch(new Request("https://example.com/.well-known/webfinger?resource=acct:alice@example.com"), { contextData: void 0 })).status, 200);
|
|
1021
|
+
const counts = recorder.getMeasurements("fedify.http.server.request.count");
|
|
1022
|
+
assertEquals(counts.length, 1);
|
|
1023
|
+
assertEquals(counts[0].attributes["fedify.endpoint"], "webfinger");
|
|
1024
|
+
assertEquals(counts[0].attributes["fedify.route.template"], "/.well-known/webfinger");
|
|
1025
|
+
assertEquals(counts[0].attributes["http.response.status_code"], 200);
|
|
1026
|
+
});
|
|
1027
|
+
await t.step("records NodeInfo JRD requests", async () => {
|
|
1028
|
+
const { federation, recorder } = createTestContext();
|
|
1029
|
+
assertEquals((await federation.fetch(new Request("https://example.com/.well-known/nodeinfo"), { contextData: void 0 })).status, 200);
|
|
1030
|
+
const counts = recorder.getMeasurements("fedify.http.server.request.count");
|
|
1031
|
+
assertEquals(counts.length, 1);
|
|
1032
|
+
assertEquals(counts[0].attributes["fedify.endpoint"], "nodeinfo");
|
|
1033
|
+
assertEquals(counts[0].attributes["fedify.route.template"], "/.well-known/nodeinfo");
|
|
1034
|
+
});
|
|
1035
|
+
await t.step("records NodeInfo dispatcher requests", async () => {
|
|
1036
|
+
const { federation, recorder } = createTestContext();
|
|
1037
|
+
assertEquals((await federation.fetch(new Request("https://example.com/nodeinfo/2.1"), { contextData: void 0 })).status, 200);
|
|
1038
|
+
const counts = recorder.getMeasurements("fedify.http.server.request.count");
|
|
1039
|
+
assertEquals(counts.length, 1);
|
|
1040
|
+
assertEquals(counts[0].attributes["fedify.endpoint"], "nodeinfo");
|
|
1041
|
+
assertEquals(counts[0].attributes["fedify.route.template"], "/nodeinfo/2.1");
|
|
1042
|
+
});
|
|
1043
|
+
await t.step("records 404 not_found for unmatched paths", async () => {
|
|
1044
|
+
const { federation, recorder } = createTestContext();
|
|
1045
|
+
assertEquals((await federation.fetch(new Request("https://example.com/no/such/path"), { contextData: void 0 })).status, 404);
|
|
1046
|
+
const counts = recorder.getMeasurements("fedify.http.server.request.count");
|
|
1047
|
+
assertEquals(counts.length, 1);
|
|
1048
|
+
assertEquals(counts[0].attributes["fedify.endpoint"], "not_found");
|
|
1049
|
+
assertEquals(counts[0].attributes["http.response.status_code"], 404);
|
|
1050
|
+
assertEquals(counts[0].attributes["fedify.route.template"], void 0);
|
|
1051
|
+
});
|
|
1052
|
+
await t.step("records 406 not_acceptable when JSON-LD Accept missing", async () => {
|
|
1053
|
+
const { federation, recorder } = createTestContext();
|
|
1054
|
+
assertEquals((await federation.fetch(new Request("https://example.com/users/alice", {
|
|
1055
|
+
method: "GET",
|
|
1056
|
+
headers: { "Accept": "text/html" }
|
|
1057
|
+
}), { contextData: void 0 })).status, 406);
|
|
1058
|
+
const counts = recorder.getMeasurements("fedify.http.server.request.count");
|
|
1059
|
+
assertEquals(counts.length, 1);
|
|
1060
|
+
assertEquals(counts[0].attributes["fedify.endpoint"], "not_acceptable");
|
|
1061
|
+
assertEquals(counts[0].attributes["http.response.status_code"], 406);
|
|
1062
|
+
assertEquals(counts[0].attributes["fedify.route.template"], "/users/{identifier}");
|
|
1063
|
+
});
|
|
1064
|
+
await t.step("records thrown errors after classification with the matched endpoint", async () => {
|
|
1065
|
+
const { federation, recorder } = createTestContext();
|
|
1066
|
+
await assertRejects(() => federation.fetch(new Request("https://example.com/users/boom", {
|
|
1067
|
+
method: "GET",
|
|
1068
|
+
headers: { "Accept": "application/activity+json" }
|
|
1069
|
+
}), { contextData: void 0 }), Error, "explosion");
|
|
1070
|
+
const counts = recorder.getMeasurements("fedify.http.server.request.count");
|
|
1071
|
+
assertEquals(counts.length, 1);
|
|
1072
|
+
assertEquals(counts[0].attributes["fedify.endpoint"], "actor");
|
|
1073
|
+
assertEquals(counts[0].attributes["http.response.status_code"], void 0);
|
|
1074
|
+
assertEquals(counts[0].attributes["fedify.route.template"], "/users/{identifier}");
|
|
1075
|
+
const durations = recorder.getMeasurements("fedify.http.server.request.duration");
|
|
1076
|
+
assertEquals(durations.length, 1);
|
|
1077
|
+
assertEquals(durations[0].attributes["fedify.endpoint"], "actor");
|
|
1078
|
+
});
|
|
1079
|
+
await t.step("collapses user-defined collection dispatchers to endpoint=collection", async () => {
|
|
1080
|
+
const { federation, recorder } = createTestContext();
|
|
1081
|
+
assertEquals((await federation.fetch(new Request("https://example.com/users/alice/custom/1", {
|
|
1082
|
+
method: "GET",
|
|
1083
|
+
headers: { "Accept": "application/activity+json" }
|
|
1084
|
+
}), { contextData: void 0 })).status, 200);
|
|
1085
|
+
const counts = recorder.getMeasurements("fedify.http.server.request.count");
|
|
1086
|
+
assertEquals(counts.length, 1);
|
|
1087
|
+
assertEquals(counts[0].attributes["fedify.endpoint"], "collection");
|
|
1088
|
+
assertEquals(counts[0].attributes["fedify.route.template"], "/users/{identifier}/custom/{id}");
|
|
1089
|
+
});
|
|
1090
|
+
await t.step("records followers as endpoint=followers", async () => {
|
|
1091
|
+
const { federation, recorder } = createTestContext();
|
|
1092
|
+
assertEquals((await federation.fetch(new Request("https://example.com/users/alice/followers", {
|
|
1093
|
+
method: "GET",
|
|
1094
|
+
headers: { "Accept": "application/activity+json" }
|
|
1095
|
+
}), { contextData: void 0 })).status, 200);
|
|
1096
|
+
const counts = recorder.getMeasurements("fedify.http.server.request.count");
|
|
1097
|
+
assertEquals(counts.length, 1);
|
|
1098
|
+
assertEquals(counts[0].attributes["fedify.endpoint"], "followers");
|
|
1099
|
+
assertEquals(counts[0].attributes["fedify.route.template"], "/users/{identifier}/followers");
|
|
1100
|
+
});
|
|
1101
|
+
await t.step("records sharedInbox as endpoint=shared_inbox", async () => {
|
|
1102
|
+
const kv = new MemoryKvStore();
|
|
1103
|
+
const [meterProvider, recorder] = createTestMeterProvider();
|
|
1104
|
+
const federation = createFederation({
|
|
1105
|
+
kv,
|
|
1106
|
+
meterProvider,
|
|
1107
|
+
documentLoaderFactory: () => mockDocumentLoader
|
|
1108
|
+
});
|
|
1109
|
+
federation.setInboxListeners("/users/{identifier}/inbox", "/inbox");
|
|
1110
|
+
assert((await federation.fetch(new Request("https://example.com/inbox", {
|
|
1111
|
+
method: "POST",
|
|
1112
|
+
headers: { "accept": "application/ld+json" }
|
|
1113
|
+
}), { contextData: void 0 })).status >= 400);
|
|
1114
|
+
const counts = recorder.getMeasurements("fedify.http.server.request.count");
|
|
1115
|
+
assertEquals(counts.length, 1);
|
|
1116
|
+
assertEquals(counts[0].attributes["fedify.endpoint"], "shared_inbox");
|
|
1117
|
+
assertEquals(counts[0].attributes["fedify.route.template"], "/inbox");
|
|
1118
|
+
assertEquals(counts[0].attributes["http.request.method"], "POST");
|
|
1119
|
+
});
|
|
1120
|
+
await t.step("normalizes unknown HTTP methods to _OTHER for cardinality control", async () => {
|
|
1121
|
+
const { federation, recorder } = createTestContext();
|
|
1122
|
+
assert((await federation.fetch(new Request("https://example.com/users/alice", {
|
|
1123
|
+
method: "PROPFIND",
|
|
1124
|
+
headers: { "Accept": "application/activity+json" }
|
|
1125
|
+
}), { contextData: void 0 })).status >= 100);
|
|
1126
|
+
const counts = recorder.getMeasurements("fedify.http.server.request.count");
|
|
1127
|
+
assertEquals(counts.length, 1);
|
|
1128
|
+
assertEquals(counts[0].attributes["http.request.method"], "_OTHER");
|
|
1129
|
+
});
|
|
1130
|
+
await t.step("preserves QUERY as a known HTTP method", async () => {
|
|
1131
|
+
const { federation, recorder } = createTestContext();
|
|
1132
|
+
assert((await federation.fetch(new Request("https://example.com/users/alice", {
|
|
1133
|
+
method: "QUERY",
|
|
1134
|
+
headers: { "Accept": "application/activity+json" }
|
|
1135
|
+
}), { contextData: void 0 })).status >= 100);
|
|
1136
|
+
const counts = recorder.getMeasurements("fedify.http.server.request.count");
|
|
1137
|
+
assertEquals(counts.length, 1);
|
|
1138
|
+
assertEquals(counts[0].attributes["http.request.method"], "QUERY");
|
|
1139
|
+
});
|
|
1140
|
+
await t.step("uses the global meter provider when none is configured", async () => {
|
|
1141
|
+
const federation = createFederation({
|
|
1142
|
+
kv: new MemoryKvStore(),
|
|
1143
|
+
documentLoaderFactory: () => mockDocumentLoader
|
|
1144
|
+
});
|
|
1145
|
+
federation.setActorDispatcher("/users/{identifier}", (ctx, identifier) => new vocab.Person({ id: ctx.getActorUri(identifier) }));
|
|
1146
|
+
assertEquals((await federation.fetch(new Request("https://example.com/users/alice", {
|
|
1147
|
+
method: "GET",
|
|
1148
|
+
headers: { "Accept": "application/activity+json" }
|
|
1149
|
+
}), { contextData: void 0 })).status, 200);
|
|
1150
|
+
});
|
|
1151
|
+
});
|
|
959
1152
|
test("Federation.setInboxListeners()", async (t) => {
|
|
960
1153
|
const kv = new MemoryKvStore();
|
|
961
1154
|
esm_default.spyGlobal();
|
package/dist/federation/mod.cjs
CHANGED
|
@@ -2,7 +2,7 @@ const { Temporal } = require("@js-temporal/polyfill");
|
|
|
2
2
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
3
3
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
4
4
|
require("../chunk-DDcVe30Y.cjs");
|
|
5
|
-
const require_middleware = require("../middleware-
|
|
5
|
+
const require_middleware = require("../middleware-C-fzauLy.cjs");
|
|
6
6
|
let es_toolkit = require("es-toolkit");
|
|
7
7
|
//#region src/federation/kv.ts
|
|
8
8
|
/**
|
package/dist/federation/mod.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Temporal } from "@js-temporal/polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
|
-
import { a as createExponentialBackoffPolicy, c as buildCollectionSynchronizationHeader, d as Router, f as RouterError, i as SendActivityError, l as digest, o as respondWithObject, r as handleWebFinger, s as respondWithObjectIfAcceptable, t as createFederation, u as createFederationBuilder } from "../middleware-
|
|
3
|
+
import { a as createExponentialBackoffPolicy, c as buildCollectionSynchronizationHeader, d as Router, f as RouterError, i as SendActivityError, l as digest, o as respondWithObject, r as handleWebFinger, s as respondWithObjectIfAcceptable, t as createFederation, u as createFederationBuilder } from "../middleware-B0YQlYeu.js";
|
|
4
4
|
import { isEqual } from "es-toolkit";
|
|
5
5
|
//#region src/federation/kv.ts
|
|
6
6
|
/**
|
|
@@ -9,10 +9,10 @@ import { t as assertInstanceOf } from "../assert_instance_of-C4Ri6VuN.mjs";
|
|
|
9
9
|
import { t as assertNotEquals } from "../assert_not_equals--wG9hV7u.mjs";
|
|
10
10
|
import { t as assert } from "../assert-DikXweDx.mjs";
|
|
11
11
|
import { t as esm_default } from "../esm-DhnRLoG9.mjs";
|
|
12
|
-
import { l as verifyRequest } from "../http-
|
|
12
|
+
import { l as verifyRequest } from "../http-BETUCsB0.mjs";
|
|
13
13
|
import { i as rsaPrivateKey2, n as ed25519PrivateKey, s as rsaPublicKey2, t as ed25519Multikey } from "../keys-C3kae-6B.mjs";
|
|
14
|
-
import { t as doesActorOwnKey } from "../owner-
|
|
15
|
-
import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "../send-
|
|
14
|
+
import { t as doesActorOwnKey } from "../owner-B6F-ovsj.mjs";
|
|
15
|
+
import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "../send-DNs8Rwv0.mjs";
|
|
16
16
|
import { createTestMeterProvider, createTestTracerProvider, mockDocumentLoader, test } from "@fedify/fixture";
|
|
17
17
|
import { Activity, Application, Endpoints, Group, Person, Service } from "@fedify/vocab";
|
|
18
18
|
//#region ../../node_modules/.pnpm/@opentelemetry+sdk-metrics@2.5.0_@opentelemetry+api@1.9.0/node_modules/@opentelemetry/sdk-metrics/build/src/export/AggregationTemporality.js
|
|
@@ -5,7 +5,7 @@ import { r as createRequestContext } from "../context-7Azky82W.mjs";
|
|
|
5
5
|
import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
|
|
6
6
|
import "../std__assert-CRDpx_HF.mjs";
|
|
7
7
|
import { t as MemoryKvStore } from "../kv-x2IvBUyq.mjs";
|
|
8
|
-
import { o as createFederation, s as handleWebFinger } from "../middleware-
|
|
8
|
+
import { o as createFederation, s as handleWebFinger } from "../middleware-BD-WrN2n.mjs";
|
|
9
9
|
import { test } from "@fedify/fixture";
|
|
10
10
|
import { Image, Link, Person, Tombstone } from "@fedify/vocab";
|
|
11
11
|
//#region src/federation/webfinger.test.ts
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Temporal } from "@js-temporal/polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { n as version, t as name } from "./deno-
|
|
4
|
+
import { n as version, t as name } from "./deno-BvRV20GH.mjs";
|
|
5
5
|
import { i as validateAcceptSignature, n as fulfillAcceptSignature, r as parseAcceptSignature } from "./accept-CceiKpCy.mjs";
|
|
6
|
-
import { o as validateCryptoKey, r as fetchKeyDetailed } from "./key-
|
|
6
|
+
import { o as validateCryptoKey, r as fetchKeyDetailed } from "./key-CjtOXvjb.mjs";
|
|
7
7
|
import { CryptographicKey } from "@fedify/vocab";
|
|
8
8
|
import { SpanStatusCode, trace } from "@opentelemetry/api";
|
|
9
9
|
import { FetchError } from "@fedify/vocab-runtime";
|
|
@@ -10,7 +10,7 @@ import { ATTR_HTTP_REQUEST_HEADER, ATTR_HTTP_REQUEST_METHOD, ATTR_URL_FULL } fro
|
|
|
10
10
|
import { decodeBase64, encodeBase64 } from "byte-encodings/base64";
|
|
11
11
|
//#region deno.json
|
|
12
12
|
var name = "@fedify/fedify";
|
|
13
|
-
var version = "2.3.0-dev.
|
|
13
|
+
var version = "2.3.0-dev.1050+74157106";
|
|
14
14
|
//#endregion
|
|
15
15
|
//#region src/sig/accept.ts
|
|
16
16
|
/**
|
|
@@ -11,7 +11,7 @@ let _opentelemetry_semantic_conventions = require("@opentelemetry/semantic-conve
|
|
|
11
11
|
let byte_encodings_base64 = require("byte-encodings/base64");
|
|
12
12
|
//#region deno.json
|
|
13
13
|
var name = "@fedify/fedify";
|
|
14
|
-
var version = "2.3.0-dev.
|
|
14
|
+
var version = "2.3.0-dev.1050+74157106";
|
|
15
15
|
//#endregion
|
|
16
16
|
//#region src/sig/accept.ts
|
|
17
17
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "@js-temporal/polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { n as version, t as name } from "./deno-
|
|
4
|
+
import { n as version, t as name } from "./deno-BvRV20GH.mjs";
|
|
5
5
|
import { CryptographicKey, Object as Object$1, isActor } from "@fedify/vocab";
|
|
6
6
|
import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
|
|
7
7
|
import { FetchError, getDocumentLoader } from "@fedify/vocab-runtime";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Temporal } from "@js-temporal/polyfill";
|
|
2
2
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3
|
-
import { d as validateCryptoKey, t as doubleKnock } from "./http-
|
|
3
|
+
import { d as validateCryptoKey, t as doubleKnock } from "./http-Cj-JmUpS.js";
|
|
4
4
|
import { getLogger } from "@logtape/logtape";
|
|
5
5
|
import { curry } from "es-toolkit";
|
|
6
6
|
import { UrlError, createActivityPubRequest, getRemoteDocument, logRequest, preloadedContexts, validatePublicUrl } from "@fedify/vocab-runtime";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const { Temporal } = require("@js-temporal/polyfill");
|
|
2
2
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
3
3
|
require("./chunk-DDcVe30Y.cjs");
|
|
4
|
-
const require_http = require("./http-
|
|
4
|
+
const require_http = require("./http-DT4PVP4u.cjs");
|
|
5
5
|
let _logtape_logtape = require("@logtape/logtape");
|
|
6
6
|
let es_toolkit = require("es-toolkit");
|
|
7
7
|
let _fedify_vocab_runtime = require("@fedify/vocab-runtime");
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import "@js-temporal/polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { n as version, t as name } from "./deno-
|
|
5
|
-
import { n as fetchKey, o as validateCryptoKey } from "./key-
|
|
4
|
+
import { n as version, t as name } from "./deno-BvRV20GH.mjs";
|
|
5
|
+
import { n as fetchKey, o as validateCryptoKey } from "./key-CjtOXvjb.mjs";
|
|
6
6
|
import { Activity, CryptographicKey, Object as Object$1, getTypeId } from "@fedify/vocab";
|
|
7
7
|
import { SpanStatusCode, trace } from "@opentelemetry/api";
|
|
8
8
|
import { getDocumentLoader } from "@fedify/vocab-runtime";
|
|
@@ -2,10 +2,10 @@ import { Temporal } from "@js-temporal/polyfill";
|
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
import { t as __exportAll } from "./chunk-nlSIicah.js";
|
|
4
4
|
import { r as getDefaultActivityTransformers } from "./transformers-ve6e2xcg.js";
|
|
5
|
-
import { _ as version, a as verifyRequestDetailed, d as validateCryptoKey, f as formatAcceptSignature, g as name, i as verifyRequest, n as parseRfc9421SignatureInput, o as exportJwk, t as doubleKnock, u as importJwk } from "./http-
|
|
6
|
-
import { c as getKeyOwner, d as detachSignature, f as hasSignatureLike, i as verifyObject, m as verifyJsonLd, n as hasProofLike, o as normalizeOutgoingActivityJsonLd, p as signJsonLd, r as signObject, s as doesActorOwnKey } from "./proof-
|
|
5
|
+
import { _ as version, a as verifyRequestDetailed, d as validateCryptoKey, f as formatAcceptSignature, g as name, i as verifyRequest, n as parseRfc9421SignatureInput, o as exportJwk, t as doubleKnock, u as importJwk } from "./http-Cj-JmUpS.js";
|
|
6
|
+
import { c as getKeyOwner, d as detachSignature, f as hasSignatureLike, i as verifyObject, m as verifyJsonLd, n as hasProofLike, o as normalizeOutgoingActivityJsonLd, p as signJsonLd, r as signObject, s as doesActorOwnKey } from "./proof-DCfIkmPR.js";
|
|
7
7
|
import { n as getNodeInfo, t as nodeInfoToJson } from "./types-hvL8ElAs.js";
|
|
8
|
-
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-
|
|
8
|
+
import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-BOU_yvQi.js";
|
|
9
9
|
import { getLogger, withContext } from "@logtape/logtape";
|
|
10
10
|
import { Activity, Collection, CollectionPage, CryptographicKey, Link, Multikey, Object as Object$1, OrderedCollection, OrderedCollectionPage, Tombstone, getTypeId, lookupObject, traverseCollection } from "@fedify/vocab";
|
|
11
11
|
import { SpanKind, SpanStatusCode, context, metrics, propagation, trace } from "@opentelemetry/api";
|
|
@@ -786,6 +786,8 @@ var FederationMetrics = class {
|
|
|
786
786
|
signatureVerificationFailure;
|
|
787
787
|
deliveryDuration;
|
|
788
788
|
inboxProcessingDuration;
|
|
789
|
+
httpServerRequestCount;
|
|
790
|
+
httpServerRequestDuration;
|
|
789
791
|
constructor(meterProvider) {
|
|
790
792
|
const meter = meterProvider.getMeter(name, version);
|
|
791
793
|
this.deliverySent = meter.createCounter("activitypub.delivery.sent", {
|
|
@@ -808,6 +810,30 @@ var FederationMetrics = class {
|
|
|
808
810
|
description: "Duration of ActivityPub inbox listener processing.",
|
|
809
811
|
unit: "ms"
|
|
810
812
|
});
|
|
813
|
+
this.httpServerRequestCount = meter.createCounter("fedify.http.server.request.count", {
|
|
814
|
+
description: "HTTP requests handled by Federation.fetch().",
|
|
815
|
+
unit: "{request}"
|
|
816
|
+
});
|
|
817
|
+
this.httpServerRequestDuration = meter.createHistogram("fedify.http.server.request.duration", {
|
|
818
|
+
description: "Duration of HTTP requests handled by Federation.fetch().",
|
|
819
|
+
unit: "ms",
|
|
820
|
+
advice: { explicitBucketBoundaries: [
|
|
821
|
+
5,
|
|
822
|
+
10,
|
|
823
|
+
25,
|
|
824
|
+
50,
|
|
825
|
+
75,
|
|
826
|
+
100,
|
|
827
|
+
250,
|
|
828
|
+
500,
|
|
829
|
+
750,
|
|
830
|
+
1e3,
|
|
831
|
+
2500,
|
|
832
|
+
5e3,
|
|
833
|
+
7500,
|
|
834
|
+
1e4
|
|
835
|
+
] }
|
|
836
|
+
});
|
|
811
837
|
}
|
|
812
838
|
recordDelivery(inbox, durationMs, success, activityType) {
|
|
813
839
|
const deliveryAttributes = {
|
|
@@ -832,7 +858,33 @@ var FederationMetrics = class {
|
|
|
832
858
|
recordInboxProcessingDuration(activityType, durationMs) {
|
|
833
859
|
this.inboxProcessingDuration.record(durationMs, { "activitypub.activity.type": activityType });
|
|
834
860
|
}
|
|
861
|
+
recordHttpServerRequest(method, endpoint, durationMs, options = {}) {
|
|
862
|
+
const attributes = {
|
|
863
|
+
"http.request.method": normalizeHttpMethod(method),
|
|
864
|
+
"fedify.endpoint": endpoint
|
|
865
|
+
};
|
|
866
|
+
if (options.statusCode != null) attributes["http.response.status_code"] = options.statusCode;
|
|
867
|
+
if (options.routeTemplate != null) attributes["fedify.route.template"] = options.routeTemplate;
|
|
868
|
+
this.httpServerRequestCount.add(1, attributes);
|
|
869
|
+
this.httpServerRequestDuration.record(durationMs, attributes);
|
|
870
|
+
}
|
|
835
871
|
};
|
|
872
|
+
const KNOWN_HTTP_METHODS = new Set([
|
|
873
|
+
"CONNECT",
|
|
874
|
+
"DELETE",
|
|
875
|
+
"GET",
|
|
876
|
+
"HEAD",
|
|
877
|
+
"OPTIONS",
|
|
878
|
+
"PATCH",
|
|
879
|
+
"POST",
|
|
880
|
+
"PUT",
|
|
881
|
+
"QUERY",
|
|
882
|
+
"TRACE"
|
|
883
|
+
]);
|
|
884
|
+
function normalizeHttpMethod(method) {
|
|
885
|
+
const upper = method.toUpperCase();
|
|
886
|
+
return KNOWN_HTTP_METHODS.has(upper) ? upper : "_OTHER";
|
|
887
|
+
}
|
|
836
888
|
const federationMetrics = /* @__PURE__ */ new WeakMap();
|
|
837
889
|
/**
|
|
838
890
|
* Gets the cached Fedify metric instruments for a meter provider.
|
|
@@ -3577,6 +3629,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3577
3629
|
fetch(request, options) {
|
|
3578
3630
|
return withContext({ requestId: getRequestId(request) }, async () => {
|
|
3579
3631
|
const tracer = this._getTracer();
|
|
3632
|
+
const metricState = {};
|
|
3633
|
+
const metricStart = performance.now();
|
|
3580
3634
|
return await tracer.startActiveSpan(request.method, {
|
|
3581
3635
|
kind: SpanKind.SERVER,
|
|
3582
3636
|
attributes: {
|
|
@@ -3600,10 +3654,12 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3600
3654
|
response = await this.#fetch(request, {
|
|
3601
3655
|
...options,
|
|
3602
3656
|
span,
|
|
3603
|
-
tracer
|
|
3657
|
+
tracer,
|
|
3658
|
+
metricState
|
|
3604
3659
|
});
|
|
3605
3660
|
if (acceptsJsonLd(request)) response.headers.set("Vary", "Accept");
|
|
3606
3661
|
} catch (error) {
|
|
3662
|
+
getFederationMetrics(this.meterProvider).recordHttpServerRequest(request.method, metricState.endpoint ?? "error", getDurationMs(metricStart), { routeTemplate: metricState.routeTemplate });
|
|
3607
3663
|
span.setStatus({
|
|
3608
3664
|
code: SpanStatusCode.ERROR,
|
|
3609
3665
|
message: `${error}`
|
|
@@ -3616,6 +3672,10 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3616
3672
|
});
|
|
3617
3673
|
throw error;
|
|
3618
3674
|
}
|
|
3675
|
+
getFederationMetrics(this.meterProvider).recordHttpServerRequest(request.method, metricState.endpoint ?? "error", getDurationMs(metricStart), {
|
|
3676
|
+
statusCode: response.status,
|
|
3677
|
+
routeTemplate: metricState.routeTemplate
|
|
3678
|
+
});
|
|
3619
3679
|
if (span.isRecording()) {
|
|
3620
3680
|
span.setAttribute(ATTR_HTTP_RESPONSE_STATUS_CODE, response.status);
|
|
3621
3681
|
for (const [k, v] of response.headers) span.setAttribute(ATTR_HTTP_RESPONSE_HEADER(k), [v]);
|
|
@@ -3641,13 +3701,18 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3641
3701
|
});
|
|
3642
3702
|
});
|
|
3643
3703
|
}
|
|
3644
|
-
async #fetch(request, { onNotFound, onNotAcceptable, onUnauthorized, contextData, span, tracer }) {
|
|
3704
|
+
async #fetch(request, { onNotFound, onNotAcceptable, onUnauthorized, contextData, span, tracer, metricState }) {
|
|
3645
3705
|
onNotFound ??= notFound;
|
|
3646
3706
|
onNotAcceptable ??= notAcceptable;
|
|
3647
3707
|
onUnauthorized ??= unauthorized;
|
|
3648
3708
|
const url = new URL(request.url);
|
|
3649
3709
|
const route = this.router.route(url.pathname);
|
|
3650
|
-
if (route == null)
|
|
3710
|
+
if (route == null) {
|
|
3711
|
+
metricState.endpoint = "not_found";
|
|
3712
|
+
return await onNotFound(request);
|
|
3713
|
+
}
|
|
3714
|
+
metricState.routeTemplate = route.template;
|
|
3715
|
+
metricState.endpoint = getEndpointCategory(route.name);
|
|
3651
3716
|
span.updateName(`${request.method} ${route.template}`);
|
|
3652
3717
|
let context = this.#createContext(request, contextData);
|
|
3653
3718
|
const routeName = route.name.replace(/:.*$/, "");
|
|
@@ -3668,7 +3733,10 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3668
3733
|
nodeInfoDispatcher: this.nodeInfoDispatcher
|
|
3669
3734
|
});
|
|
3670
3735
|
}
|
|
3671
|
-
if (request.method !== "POST" && !acceptsJsonLd(request))
|
|
3736
|
+
if (request.method !== "POST" && !acceptsJsonLd(request)) {
|
|
3737
|
+
metricState.endpoint = "not_acceptable";
|
|
3738
|
+
return await onNotAcceptable(request);
|
|
3739
|
+
}
|
|
3672
3740
|
switch (routeName) {
|
|
3673
3741
|
case "actor":
|
|
3674
3742
|
case "actorAlias": {
|
|
@@ -3859,12 +3927,33 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3859
3927
|
});
|
|
3860
3928
|
}
|
|
3861
3929
|
default: {
|
|
3930
|
+
metricState.endpoint = "not_found";
|
|
3862
3931
|
const response = onNotFound(request);
|
|
3863
3932
|
return response instanceof Promise ? await response : response;
|
|
3864
3933
|
}
|
|
3865
3934
|
}
|
|
3866
3935
|
}
|
|
3867
3936
|
};
|
|
3937
|
+
function getEndpointCategory(routeName) {
|
|
3938
|
+
if (routeName.startsWith("object:")) return "object";
|
|
3939
|
+
if (routeName.startsWith("collection:") || routeName.startsWith("orderedCollection:")) return "collection";
|
|
3940
|
+
if (routeName.startsWith("actorAlias:")) return "actor";
|
|
3941
|
+
switch (routeName) {
|
|
3942
|
+
case "webfinger": return "webfinger";
|
|
3943
|
+
case "nodeInfoJrd":
|
|
3944
|
+
case "nodeInfo": return "nodeinfo";
|
|
3945
|
+
case "actor": return "actor";
|
|
3946
|
+
case "inbox": return "inbox";
|
|
3947
|
+
case "sharedInbox": return "shared_inbox";
|
|
3948
|
+
case "outbox": return "outbox";
|
|
3949
|
+
case "following": return "following";
|
|
3950
|
+
case "followers": return "followers";
|
|
3951
|
+
case "liked": return "liked";
|
|
3952
|
+
case "featured": return "featured";
|
|
3953
|
+
case "featuredTags": return "featured_tags";
|
|
3954
|
+
default: return "not_found";
|
|
3955
|
+
}
|
|
3956
|
+
}
|
|
3868
3957
|
const FANOUT_THRESHOLD = 5;
|
|
3869
3958
|
var ContextImpl = class ContextImpl {
|
|
3870
3959
|
url;
|