@fedify/fedify 2.3.0-dev.1048 → 2.3.0-dev.1069
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-DQ2zYTeA.mjs} +2 -2
- package/dist/compat/transformers.test.mjs +1 -1
- package/dist/{deno-D9LpbVQR.mjs → deno-CFXqOz6w.mjs} +1 -1
- package/dist/{docloader-y2viZ2Tx.mjs → docloader-QNtAtTZF.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-CA4xKsSY.js → http-D2EDlTr2.js} +1 -1
- package/dist/{http-D6yvDhyL.mjs → http-QHJGzUe8.mjs} +2 -2
- package/dist/{http-Bj0uN6d-.cjs → http-e1wtIlFo.cjs} +1 -1
- package/dist/{key-BPjHWwyv.mjs → key-CpAxygvh.mjs} +1 -1
- package/dist/{kv-cache-BdSTsjLb.cjs → kv-cache-B3GfB70S.cjs} +1 -1
- package/dist/{kv-cache-DarvCOHt.js → kv-cache-KLjvIlKt.js} +1 -1
- package/dist/{ld-D9yQwfkO.mjs → ld-Ce_vkKjG.mjs} +2 -2
- package/dist/{middleware-C5ao_lvm.mjs → middleware-BJMPv7_l.mjs} +1 -1
- package/dist/{middleware-DTxZNOqy.cjs → middleware-CibncbiT.cjs} +1 -1
- package/dist/{middleware-Ccpokmfe.cjs → middleware-DOLrvK_b.cjs} +97 -8
- package/dist/{middleware-0n0ctSu_.js → middleware-De241etq.js} +96 -7
- package/dist/{middleware-THfK90u_.mjs → middleware-DsGmXfXz.mjs} +50 -13
- 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-DmgzyItA.mjs} +2 -2
- package/dist/{proof-C2QsttUL.cjs → proof-BU1TpFYI.cjs} +1 -1
- package/dist/{proof-UXZOysVc.mjs → proof-C3q2IhUr.mjs} +2 -2
- package/dist/{proof-Cdxbeq4n.js → proof-DLDsFYfD.js} +1 -1
- package/dist/{send-_8qtDYZA.mjs → send-CTi2iPXp.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 +5 -5
|
@@ -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-CFXqOz6w.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-BJMPv7_l.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-DsGmXfXz.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-CpAxygvh.mjs";
|
|
5
|
+
import { n as doubleKnock } from "./http-QHJGzUe8.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-DQ2zYTeA.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-QHJGzUe8.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-DsGmXfXz.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-C3q2IhUr.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-DsGmXfXz.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-QHJGzUe8.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-QNtAtTZF.mjs";
|
|
17
|
+
import { a as signJsonLd, o as verifyJsonLd, r as detachSignature } from "../ld-Ce_vkKjG.mjs";
|
|
18
|
+
import { t as doesActorOwnKey } from "../owner-DmgzyItA.mjs";
|
|
19
|
+
import { i as verifyObject, r as signObject } from "../proof-C3q2IhUr.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-DsGmXfXz.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-DOLrvK_b.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-De241etq.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-QHJGzUe8.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-DmgzyItA.mjs";
|
|
15
|
+
import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "../send-CTi2iPXp.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-DsGmXfXz.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
|
|
@@ -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.1069+81e910ce";
|
|
14
14
|
//#endregion
|
|
15
15
|
//#region src/sig/accept.ts
|
|
16
16
|
/**
|
|
@@ -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-CFXqOz6w.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-CpAxygvh.mjs";
|
|
7
7
|
import { CryptographicKey } from "@fedify/vocab";
|
|
8
8
|
import { SpanStatusCode, trace } from "@opentelemetry/api";
|
|
9
9
|
import { FetchError } from "@fedify/vocab-runtime";
|
|
@@ -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.1069+81e910ce";
|
|
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-CFXqOz6w.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,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-e1wtIlFo.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,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-D2EDlTr2.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,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-CFXqOz6w.mjs";
|
|
5
|
+
import { n as fetchKey, o as validateCryptoKey } from "./key-CpAxygvh.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";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
const { Temporal } = require("@js-temporal/polyfill");
|
|
2
2
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
3
|
-
const require_middleware = require("./middleware-
|
|
3
|
+
const require_middleware = require("./middleware-DOLrvK_b.cjs");
|
|
4
4
|
exports.FederationImpl = require_middleware.FederationImpl;
|
|
@@ -2,10 +2,10 @@ const { Temporal } = require("@js-temporal/polyfill");
|
|
|
2
2
|
const { URLPattern } = require("urlpattern-polyfill");
|
|
3
3
|
require("./chunk-DDcVe30Y.cjs");
|
|
4
4
|
const require_transformers = require("./transformers-NeAONrAq.cjs");
|
|
5
|
-
const require_http = require("./http-
|
|
6
|
-
const require_proof = require("./proof-
|
|
5
|
+
const require_http = require("./http-e1wtIlFo.cjs");
|
|
6
|
+
const require_proof = require("./proof-BU1TpFYI.cjs");
|
|
7
7
|
const require_types = require("./types-KC4QAoxe.cjs");
|
|
8
|
-
const require_kv_cache = require("./kv-cache-
|
|
8
|
+
const require_kv_cache = require("./kv-cache-B3GfB70S.cjs");
|
|
9
9
|
let _logtape_logtape = require("@logtape/logtape");
|
|
10
10
|
let _fedify_vocab = require("@fedify/vocab");
|
|
11
11
|
let _opentelemetry_api = require("@opentelemetry/api");
|
|
@@ -211,7 +211,7 @@ var FederationBuilderImpl = class {
|
|
|
211
211
|
this.collectionTypeIds = {};
|
|
212
212
|
}
|
|
213
213
|
async build(options) {
|
|
214
|
-
const { FederationImpl } = await Promise.resolve().then(() => require("./middleware-
|
|
214
|
+
const { FederationImpl } = await Promise.resolve().then(() => require("./middleware-CibncbiT.cjs"));
|
|
215
215
|
const f = new FederationImpl(options);
|
|
216
216
|
const trailingSlashInsensitiveValue = f.router.trailingSlashInsensitive;
|
|
217
217
|
f.router = this.router.clone();
|
|
@@ -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(require_http.name, require_http.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.
|
|
@@ -3569,6 +3621,8 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3569
3621
|
fetch(request, options) {
|
|
3570
3622
|
return (0, _logtape_logtape.withContext)({ requestId: getRequestId(request) }, async () => {
|
|
3571
3623
|
const tracer = this._getTracer();
|
|
3624
|
+
const metricState = {};
|
|
3625
|
+
const metricStart = performance.now();
|
|
3572
3626
|
return await tracer.startActiveSpan(request.method, {
|
|
3573
3627
|
kind: _opentelemetry_api.SpanKind.SERVER,
|
|
3574
3628
|
attributes: {
|
|
@@ -3592,10 +3646,12 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3592
3646
|
response = await this.#fetch(request, {
|
|
3593
3647
|
...options,
|
|
3594
3648
|
span,
|
|
3595
|
-
tracer
|
|
3649
|
+
tracer,
|
|
3650
|
+
metricState
|
|
3596
3651
|
});
|
|
3597
3652
|
if (acceptsJsonLd(request)) response.headers.set("Vary", "Accept");
|
|
3598
3653
|
} catch (error) {
|
|
3654
|
+
getFederationMetrics(this.meterProvider).recordHttpServerRequest(request.method, metricState.endpoint ?? "error", getDurationMs(metricStart), { routeTemplate: metricState.routeTemplate });
|
|
3599
3655
|
span.setStatus({
|
|
3600
3656
|
code: _opentelemetry_api.SpanStatusCode.ERROR,
|
|
3601
3657
|
message: `${error}`
|
|
@@ -3608,6 +3664,10 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3608
3664
|
});
|
|
3609
3665
|
throw error;
|
|
3610
3666
|
}
|
|
3667
|
+
getFederationMetrics(this.meterProvider).recordHttpServerRequest(request.method, metricState.endpoint ?? "error", getDurationMs(metricStart), {
|
|
3668
|
+
statusCode: response.status,
|
|
3669
|
+
routeTemplate: metricState.routeTemplate
|
|
3670
|
+
});
|
|
3611
3671
|
if (span.isRecording()) {
|
|
3612
3672
|
span.setAttribute(_opentelemetry_semantic_conventions.ATTR_HTTP_RESPONSE_STATUS_CODE, response.status);
|
|
3613
3673
|
for (const [k, v] of response.headers) span.setAttribute((0, _opentelemetry_semantic_conventions.ATTR_HTTP_RESPONSE_HEADER)(k), [v]);
|
|
@@ -3633,13 +3693,18 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3633
3693
|
});
|
|
3634
3694
|
});
|
|
3635
3695
|
}
|
|
3636
|
-
async #fetch(request, { onNotFound, onNotAcceptable, onUnauthorized, contextData, span, tracer }) {
|
|
3696
|
+
async #fetch(request, { onNotFound, onNotAcceptable, onUnauthorized, contextData, span, tracer, metricState }) {
|
|
3637
3697
|
onNotFound ??= notFound;
|
|
3638
3698
|
onNotAcceptable ??= notAcceptable;
|
|
3639
3699
|
onUnauthorized ??= unauthorized;
|
|
3640
3700
|
const url = new URL(request.url);
|
|
3641
3701
|
const route = this.router.route(url.pathname);
|
|
3642
|
-
if (route == null)
|
|
3702
|
+
if (route == null) {
|
|
3703
|
+
metricState.endpoint = "not_found";
|
|
3704
|
+
return await onNotFound(request);
|
|
3705
|
+
}
|
|
3706
|
+
metricState.routeTemplate = route.template;
|
|
3707
|
+
metricState.endpoint = getEndpointCategory(route.name);
|
|
3643
3708
|
span.updateName(`${request.method} ${route.template}`);
|
|
3644
3709
|
let context = this.#createContext(request, contextData);
|
|
3645
3710
|
const routeName = route.name.replace(/:.*$/, "");
|
|
@@ -3660,7 +3725,10 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3660
3725
|
nodeInfoDispatcher: this.nodeInfoDispatcher
|
|
3661
3726
|
});
|
|
3662
3727
|
}
|
|
3663
|
-
if (request.method !== "POST" && !acceptsJsonLd(request))
|
|
3728
|
+
if (request.method !== "POST" && !acceptsJsonLd(request)) {
|
|
3729
|
+
metricState.endpoint = "not_acceptable";
|
|
3730
|
+
return await onNotAcceptable(request);
|
|
3731
|
+
}
|
|
3664
3732
|
switch (routeName) {
|
|
3665
3733
|
case "actor":
|
|
3666
3734
|
case "actorAlias": {
|
|
@@ -3851,12 +3919,33 @@ var FederationImpl = class extends FederationBuilderImpl {
|
|
|
3851
3919
|
});
|
|
3852
3920
|
}
|
|
3853
3921
|
default: {
|
|
3922
|
+
metricState.endpoint = "not_found";
|
|
3854
3923
|
const response = onNotFound(request);
|
|
3855
3924
|
return response instanceof Promise ? await response : response;
|
|
3856
3925
|
}
|
|
3857
3926
|
}
|
|
3858
3927
|
}
|
|
3859
3928
|
};
|
|
3929
|
+
function getEndpointCategory(routeName) {
|
|
3930
|
+
if (routeName.startsWith("object:")) return "object";
|
|
3931
|
+
if (routeName.startsWith("collection:") || routeName.startsWith("orderedCollection:")) return "collection";
|
|
3932
|
+
if (routeName.startsWith("actorAlias:")) return "actor";
|
|
3933
|
+
switch (routeName) {
|
|
3934
|
+
case "webfinger": return "webfinger";
|
|
3935
|
+
case "nodeInfoJrd":
|
|
3936
|
+
case "nodeInfo": return "nodeinfo";
|
|
3937
|
+
case "actor": return "actor";
|
|
3938
|
+
case "inbox": return "inbox";
|
|
3939
|
+
case "sharedInbox": return "shared_inbox";
|
|
3940
|
+
case "outbox": return "outbox";
|
|
3941
|
+
case "following": return "following";
|
|
3942
|
+
case "followers": return "followers";
|
|
3943
|
+
case "liked": return "liked";
|
|
3944
|
+
case "featured": return "featured";
|
|
3945
|
+
case "featuredTags": return "featured_tags";
|
|
3946
|
+
default: return "not_found";
|
|
3947
|
+
}
|
|
3948
|
+
}
|
|
3860
3949
|
const FANOUT_THRESHOLD = 5;
|
|
3861
3950
|
var ContextImpl = class ContextImpl {
|
|
3862
3951
|
url;
|