@fedify/fedify 2.3.0-dev.1013 → 2.3.0-dev.1034

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.
Files changed (95) hide show
  1. package/dist/{builder-CROLcFVM.mjs → builder-y06Dq5bp.mjs} +14 -4
  2. package/dist/chunk-QSgtlS85.mjs +29 -0
  3. package/dist/compat/mod.d.cts +1 -1
  4. package/dist/compat/mod.d.ts +1 -1
  5. package/dist/compat/outgoing-jsonld.test.mjs +1 -1
  6. package/dist/compat/public-audience.test.mjs +1 -1
  7. package/dist/compat/transformers.test.mjs +2 -2
  8. package/dist/{context-Dk_tacqz.mjs → context-7Azky82W.mjs} +3 -2
  9. package/dist/{context-BDl7Y6f-.d.cts → context-BKLGj9QO.d.cts} +24 -1
  10. package/dist/{context-zTZAI3KP.d.ts → context-DrNqYkPw.d.ts} +24 -1
  11. package/dist/{deno-Ctd-K-t6.mjs → deno-DB1H1VHx.mjs} +1 -1
  12. package/dist/{docloader-q9QT51g3.mjs → docloader-3HwiWeYL.mjs} +2 -2
  13. package/dist/{esm-DVILvP5e.mjs → esm-DhnRLoG9.mjs} +1 -24
  14. package/dist/execAsync-eck5rbtb.mjs +13 -0
  15. package/dist/federation/builder.test.mjs +8 -3
  16. package/dist/federation/collection.test.mjs +1 -1
  17. package/dist/federation/handler.test.mjs +48 -11
  18. package/dist/federation/idempotency.test.mjs +4 -4
  19. package/dist/federation/inbox.test.mjs +1 -1
  20. package/dist/federation/keycache.test.mjs +2 -2
  21. package/dist/federation/kv.test.mjs +1 -1
  22. package/dist/federation/middleware.test.mjs +138 -15
  23. package/dist/federation/mod.cjs +1 -1
  24. package/dist/federation/mod.d.cts +2 -2
  25. package/dist/federation/mod.d.ts +2 -2
  26. package/dist/federation/mod.js +1 -1
  27. package/dist/federation/negotiation.test.mjs +1 -1
  28. package/dist/federation/retry.test.mjs +1 -1
  29. package/dist/federation/send.test.mjs +4540 -11
  30. package/dist/federation/webfinger.test.mjs +3 -3
  31. package/dist/getMachineId-bsd-DqZ4QRFp.mjs +29 -0
  32. package/dist/getMachineId-darwin-DMbbW3m7.mjs +26 -0
  33. package/dist/getMachineId-linux-lyeD2ug3.mjs +22 -0
  34. package/dist/getMachineId-unsupported-JuKr57jY.mjs +17 -0
  35. package/dist/getMachineId-win-Dxyf5pJq.mjs +28 -0
  36. package/dist/{http-1NL30qCe.js → http-BUr93aO6.js} +1 -1
  37. package/dist/{http-CX_zHeOD.mjs → http-D9zG-L9N.mjs} +3 -3
  38. package/dist/{http-Du1Jgf2P.cjs → http-FnUTcdMf.cjs} +1 -1
  39. package/dist/{key-C1Oto4it.mjs → key-CV57mOYH.mjs} +1 -1
  40. package/dist/{kv-cache-aGOwL6Vj.cjs → kv-cache-BG9O8wVV.cjs} +1 -1
  41. package/dist/{kv-cache-CsC3P4uu.js → kv-cache-C3esyJFP.js} +1 -1
  42. package/dist/{ld-Dl1HIB1a.mjs → ld-sUf94RJ8.mjs} +2 -2
  43. package/dist/{middleware-BiFLcrEX.cjs → middleware-CKkBrsOD.cjs} +203 -32
  44. package/dist/{middleware-C1cf3_6V.mjs → middleware-cMxbPxDe.mjs} +1 -1
  45. package/dist/{middleware-CKJC8DRf.js → middleware-fAuUxD9-.js} +203 -32
  46. package/dist/{middleware-BwC5U8zJ.cjs → middleware-ohzkLsW4.cjs} +1 -1
  47. package/dist/{middleware-CEWDB8EB.mjs → middleware-pb2EqN_r.mjs} +75 -27
  48. package/dist/{mod-ckCOmoCz.d.ts → mod-B8Z8mBLk.d.ts} +1 -1
  49. package/dist/{mod-BghZgD_U.d.cts → mod-DClCOv0M.d.cts} +1 -1
  50. package/dist/mod.cjs +4 -4
  51. package/dist/mod.d.cts +2 -2
  52. package/dist/mod.d.ts +2 -2
  53. package/dist/mod.js +4 -4
  54. package/dist/nodeinfo/client.test.mjs +2 -2
  55. package/dist/nodeinfo/handler.test.mjs +3 -3
  56. package/dist/nodeinfo/types.test.mjs +1 -1
  57. package/dist/otel/exporter.test.mjs +25 -22
  58. package/dist/otel/mod.cjs +6 -5
  59. package/dist/otel/mod.d.cts +3 -2
  60. package/dist/otel/mod.d.ts +3 -2
  61. package/dist/otel/mod.js +6 -5
  62. package/dist/{outgoing-jsonld-CNmZLixq.mjs → outgoing-jsonld-Bi7n-dEy.mjs} +1 -1
  63. package/dist/{owner-CEWFJlqo.mjs → owner-DsPgl527.mjs} +2 -2
  64. package/dist/{proof-CDA3f-i5.cjs → proof-BhJpq_J9.cjs} +1 -1
  65. package/dist/{proof-BFyPVl1r.mjs → proof-iVfYyJpY.mjs} +4 -4
  66. package/dist/{proof-Dedf8md5.js → proof-k4mEvvdS.js} +1 -1
  67. package/dist/send-D-vYdfC6.mjs +306 -0
  68. package/dist/sig/accept.test.mjs +1 -1
  69. package/dist/sig/http.test.mjs +4 -4
  70. package/dist/sig/key.test.mjs +2 -2
  71. package/dist/sig/ld.test.mjs +3 -3
  72. package/dist/sig/mod.cjs +2 -2
  73. package/dist/sig/mod.js +2 -2
  74. package/dist/sig/owner.test.mjs +2 -2
  75. package/dist/sig/proof.test.mjs +3 -3
  76. package/dist/testing/mod.d.mts +18 -1
  77. package/dist/testing/mod.mjs +1 -1
  78. package/dist/utils/docloader.test.mjs +4 -4
  79. package/dist/utils/kv-cache.test.mjs +1 -1
  80. package/dist/utils/mod.cjs +1 -1
  81. package/dist/utils/mod.js +1 -1
  82. package/package.json +7 -6
  83. package/dist/send-BJickEP4.mjs +0 -193
  84. /package/dist/{accept-CPkZzmGN.mjs → accept-CceiKpCy.mjs} +0 -0
  85. /package/dist/{activity-listener-ell7W1s9.mjs → activity-listener-tztVvlNb.mjs} +0 -0
  86. /package/dist/{client-D_1QpnWt.mjs → client-CIiz1WX7.mjs} +0 -0
  87. /package/dist/{collection-D-HqUuA2.mjs → collection-CA3V5zyK.mjs} +0 -0
  88. /package/dist/{keycache-EGATflN-.mjs → keycache-BeU0LCII.mjs} +0 -0
  89. /package/dist/{keys-DGu1NFwu.mjs → keys-C3kae-6B.mjs} +0 -0
  90. /package/dist/{kv-cache-U__xU4qR.mjs → kv-cache-Bmv7tUzz.mjs} +0 -0
  91. /package/dist/{kv-rV3vodCc.mjs → kv-x2IvBUyq.mjs} +0 -0
  92. /package/dist/{negotiation-SQvQgUqe.mjs → negotiation-VnHNB0Q5.mjs} +0 -0
  93. /package/dist/{public-audience-DYFHzm_c.mjs → public-audience-PVTwU_Ex.mjs} +0 -0
  94. /package/dist/{retry-bMXBL97A.mjs → retry-_VvV0h9f.mjs} +0 -0
  95. /package/dist/{types-J53Kw7so.mjs → types-BFowWFTT.mjs} +0 -0
@@ -1,11 +1,11 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { r as createRequestContext } from "../context-Dk_tacqz.mjs";
4
+ 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
- import { t as MemoryKvStore } from "../kv-rV3vodCc.mjs";
8
- import { o as createFederation, s as handleWebFinger } from "../middleware-CEWDB8EB.mjs";
7
+ import { t as MemoryKvStore } from "../kv-x2IvBUyq.mjs";
8
+ import { o as createFederation, s as handleWebFinger } from "../middleware-pb2EqN_r.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
@@ -0,0 +1,29 @@
1
+ import "@js-temporal/polyfill";
2
+ import "urlpattern-polyfill";
3
+ globalThis.addEventListener = () => {};
4
+ import { n as __require, t as __commonJSMin } from "./chunk-QSgtlS85.mjs";
5
+ import { t as require_execAsync } from "./execAsync-eck5rbtb.mjs";
6
+ //#region ../../node_modules/.pnpm/@opentelemetry+resources@2.5.0_@opentelemetry+api@1.9.0/node_modules/@opentelemetry/resources/build/src/detectors/platform/node/machine-id/getMachineId-bsd.js
7
+ var require_getMachineId_bsd = /* @__PURE__ */ __commonJSMin(((exports) => {
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.getMachineId = void 0;
10
+ const fs_1 = __require("fs");
11
+ const execAsync_1 = require_execAsync();
12
+ const api_1 = __require("@opentelemetry/api");
13
+ async function getMachineId() {
14
+ try {
15
+ return (await fs_1.promises.readFile("/etc/hostid", { encoding: "utf8" })).trim();
16
+ } catch (e) {
17
+ api_1.diag.debug(`error reading machine id: ${e}`);
18
+ }
19
+ try {
20
+ return (await (0, execAsync_1.execAsync)("kenv -q smbios.system.uuid")).stdout.trim();
21
+ } catch (e) {
22
+ api_1.diag.debug(`error reading machine id: ${e}`);
23
+ }
24
+ }
25
+ exports.getMachineId = getMachineId;
26
+ }));
27
+ //#endregion
28
+ export default require_getMachineId_bsd();
29
+ export {};
@@ -0,0 +1,26 @@
1
+ import "@js-temporal/polyfill";
2
+ import "urlpattern-polyfill";
3
+ globalThis.addEventListener = () => {};
4
+ import { n as __require, t as __commonJSMin } from "./chunk-QSgtlS85.mjs";
5
+ import { t as require_execAsync } from "./execAsync-eck5rbtb.mjs";
6
+ //#region ../../node_modules/.pnpm/@opentelemetry+resources@2.5.0_@opentelemetry+api@1.9.0/node_modules/@opentelemetry/resources/build/src/detectors/platform/node/machine-id/getMachineId-darwin.js
7
+ var require_getMachineId_darwin = /* @__PURE__ */ __commonJSMin(((exports) => {
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.getMachineId = void 0;
10
+ const execAsync_1 = require_execAsync();
11
+ const api_1 = __require("@opentelemetry/api");
12
+ async function getMachineId() {
13
+ try {
14
+ const idLine = (await (0, execAsync_1.execAsync)("ioreg -rd1 -c \"IOPlatformExpertDevice\"")).stdout.split("\n").find((line) => line.includes("IOPlatformUUID"));
15
+ if (!idLine) return;
16
+ const parts = idLine.split("\" = \"");
17
+ if (parts.length === 2) return parts[1].slice(0, -1);
18
+ } catch (e) {
19
+ api_1.diag.debug(`error reading machine id: ${e}`);
20
+ }
21
+ }
22
+ exports.getMachineId = getMachineId;
23
+ }));
24
+ //#endregion
25
+ export default require_getMachineId_darwin();
26
+ export {};
@@ -0,0 +1,22 @@
1
+ import "@js-temporal/polyfill";
2
+ import "urlpattern-polyfill";
3
+ globalThis.addEventListener = () => {};
4
+ import { n as __require, t as __commonJSMin } from "./chunk-QSgtlS85.mjs";
5
+ //#region ../../node_modules/.pnpm/@opentelemetry+resources@2.5.0_@opentelemetry+api@1.9.0/node_modules/@opentelemetry/resources/build/src/detectors/platform/node/machine-id/getMachineId-linux.js
6
+ var require_getMachineId_linux = /* @__PURE__ */ __commonJSMin(((exports) => {
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.getMachineId = void 0;
9
+ const fs_1 = __require("fs");
10
+ const api_1 = __require("@opentelemetry/api");
11
+ async function getMachineId() {
12
+ for (const path of ["/etc/machine-id", "/var/lib/dbus/machine-id"]) try {
13
+ return (await fs_1.promises.readFile(path, { encoding: "utf8" })).trim();
14
+ } catch (e) {
15
+ api_1.diag.debug(`error reading machine id: ${e}`);
16
+ }
17
+ }
18
+ exports.getMachineId = getMachineId;
19
+ }));
20
+ //#endregion
21
+ export default require_getMachineId_linux();
22
+ export {};
@@ -0,0 +1,17 @@
1
+ import "@js-temporal/polyfill";
2
+ import "urlpattern-polyfill";
3
+ globalThis.addEventListener = () => {};
4
+ import { n as __require, t as __commonJSMin } from "./chunk-QSgtlS85.mjs";
5
+ //#region ../../node_modules/.pnpm/@opentelemetry+resources@2.5.0_@opentelemetry+api@1.9.0/node_modules/@opentelemetry/resources/build/src/detectors/platform/node/machine-id/getMachineId-unsupported.js
6
+ var require_getMachineId_unsupported = /* @__PURE__ */ __commonJSMin(((exports) => {
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.getMachineId = void 0;
9
+ const api_1 = __require("@opentelemetry/api");
10
+ async function getMachineId() {
11
+ api_1.diag.debug("could not read machine-id: unsupported platform");
12
+ }
13
+ exports.getMachineId = getMachineId;
14
+ }));
15
+ //#endregion
16
+ export default require_getMachineId_unsupported();
17
+ export {};
@@ -0,0 +1,28 @@
1
+ import "@js-temporal/polyfill";
2
+ import "urlpattern-polyfill";
3
+ globalThis.addEventListener = () => {};
4
+ import { n as __require, t as __commonJSMin } from "./chunk-QSgtlS85.mjs";
5
+ import { t as require_execAsync } from "./execAsync-eck5rbtb.mjs";
6
+ //#region ../../node_modules/.pnpm/@opentelemetry+resources@2.5.0_@opentelemetry+api@1.9.0/node_modules/@opentelemetry/resources/build/src/detectors/platform/node/machine-id/getMachineId-win.js
7
+ var require_getMachineId_win = /* @__PURE__ */ __commonJSMin(((exports) => {
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.getMachineId = void 0;
10
+ const process = __require("process");
11
+ const execAsync_1 = require_execAsync();
12
+ const api_1 = __require("@opentelemetry/api");
13
+ async function getMachineId() {
14
+ const args = "QUERY HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography /v MachineGuid";
15
+ let command = "%windir%\\System32\\REG.exe";
16
+ if (process.arch === "ia32" && "PROCESSOR_ARCHITEW6432" in process.env) command = "%windir%\\sysnative\\cmd.exe /c " + command;
17
+ try {
18
+ const parts = (await (0, execAsync_1.execAsync)(`${command} ${args}`)).stdout.split("REG_SZ");
19
+ if (parts.length === 2) return parts[1].trim();
20
+ } catch (e) {
21
+ api_1.diag.debug(`error reading machine id: ${e}`);
22
+ }
23
+ }
24
+ exports.getMachineId = getMachineId;
25
+ }));
26
+ //#endregion
27
+ export default require_getMachineId_win();
28
+ export {};
@@ -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.1013+4aa6a88c";
13
+ var version = "2.3.0-dev.1034+b85b5daa";
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-Ctd-K-t6.mjs";
5
- import { i as validateAcceptSignature, n as fulfillAcceptSignature, r as parseAcceptSignature } from "./accept-CPkZzmGN.mjs";
6
- import { o as validateCryptoKey, r as fetchKeyDetailed } from "./key-C1Oto4it.mjs";
4
+ import { n as version, t as name } from "./deno-DB1H1VHx.mjs";
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-CV57mOYH.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.1013+4aa6a88c";
14
+ var version = "2.3.0-dev.1034+b85b5daa";
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-Ctd-K-t6.mjs";
4
+ import { n as version, t as name } from "./deno-DB1H1VHx.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-Du1Jgf2P.cjs");
4
+ const require_http = require("./http-FnUTcdMf.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-1NL30qCe.js";
3
+ import { d as validateCryptoKey, t as doubleKnock } from "./http-BUr93aO6.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-Ctd-K-t6.mjs";
5
- import { n as fetchKey, o as validateCryptoKey } from "./key-C1Oto4it.mjs";
4
+ import { n as version, t as name } from "./deno-DB1H1VHx.mjs";
5
+ import { n as fetchKey, o as validateCryptoKey } from "./key-CV57mOYH.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 @@ 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-Du1Jgf2P.cjs");
6
- const require_proof = require("./proof-CDA3f-i5.cjs");
5
+ const require_http = require("./http-FnUTcdMf.cjs");
6
+ const require_proof = require("./proof-BhJpq_J9.cjs");
7
7
  const require_types = require("./types-KC4QAoxe.cjs");
8
- const require_kv_cache = require("./kv-cache-aGOwL6Vj.cjs");
8
+ const require_kv_cache = require("./kv-cache-BG9O8wVV.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");
@@ -160,6 +160,7 @@ var RouterError = class extends Error {
160
160
  };
161
161
  //#endregion
162
162
  //#region src/federation/builder.ts
163
+ const ACTOR_ALIAS_PREFIX = "actorAlias:";
163
164
  function validateSingleIdentifierVariablePath(path, errorMessage) {
164
165
  const operatorMatches = globalThis.Array.from(path.matchAll(/{([+#./;?&]?)([A-Za-z_][A-Za-z0-9_]*)}/g));
165
166
  if (operatorMatches.length !== 1 || operatorMatches[0]?.[2] !== "identifier") throw new RouterError(errorMessage);
@@ -210,7 +211,7 @@ var FederationBuilderImpl = class {
210
211
  this.collectionTypeIds = {};
211
212
  }
212
213
  async build(options) {
213
- const { FederationImpl } = await Promise.resolve().then(() => require("./middleware-BwC5U8zJ.cjs"));
214
+ const { FederationImpl } = await Promise.resolve().then(() => require("./middleware-ohzkLsW4.cjs"));
214
215
  const f = new FederationImpl(options);
215
216
  const trailingSlashInsensitiveValue = f.router.trailingSlashInsensitive;
216
217
  f.router = this.router.clone();
@@ -346,6 +347,15 @@ var FederationBuilderImpl = class {
346
347
  callbacks.aliasMapper = mapper;
347
348
  return setters;
348
349
  },
350
+ mapActorAlias: (path, identifier) => {
351
+ if (identifier === "") throw new RouterError("Identifier cannot be empty.");
352
+ if (this.router.has(`actorAlias:${identifier}`)) throw new RouterError(`Actor alias for "${identifier}" already set.`);
353
+ if (new Router().add(path, "temp").size > 0) throw new RouterError("Path for actor alias must have no variables.");
354
+ const existingRoute = this.router.route(path);
355
+ if (existingRoute != null) throw new RouterError(`Actor alias path "${path}" conflicts with existing route "${existingRoute.name}".`);
356
+ this.router.add(path, `${ACTOR_ALIAS_PREFIX}${identifier}`);
357
+ return setters;
358
+ },
349
359
  authorize(predicate) {
350
360
  callbacks.authorizePredicate = predicate;
351
361
  return setters;
@@ -769,8 +779,90 @@ async function buildCollectionSynchronizationHeader(collectionId, actorIds) {
769
779
  return `collectionId="${collectionId}", url="${url}", digest="${(0, byte_encodings_hex.encodeHex)(await digest(actorIds))}"`;
770
780
  }
771
781
  //#endregion
782
+ //#region src/federation/metrics.ts
783
+ var FederationMetrics = class {
784
+ deliverySent;
785
+ deliveryPermanentFailure;
786
+ signatureVerificationFailure;
787
+ deliveryDuration;
788
+ inboxProcessingDuration;
789
+ constructor(meterProvider) {
790
+ const meter = meterProvider.getMeter(require_http.name, require_http.version);
791
+ this.deliverySent = meter.createCounter("activitypub.delivery.sent", {
792
+ description: "ActivityPub delivery attempts.",
793
+ unit: "{attempt}"
794
+ });
795
+ this.deliveryPermanentFailure = meter.createCounter("activitypub.delivery.permanent_failure", {
796
+ description: "ActivityPub deliveries abandoned as permanent failures.",
797
+ unit: "{failure}"
798
+ });
799
+ this.signatureVerificationFailure = meter.createCounter("activitypub.signature.verification_failure", {
800
+ description: "ActivityPub signature verification failures.",
801
+ unit: "{failure}"
802
+ });
803
+ this.deliveryDuration = meter.createHistogram("activitypub.delivery.duration", {
804
+ description: "Duration of ActivityPub delivery attempts.",
805
+ unit: "ms"
806
+ });
807
+ this.inboxProcessingDuration = meter.createHistogram("activitypub.inbox.processing_duration", {
808
+ description: "Duration of ActivityPub inbox listener processing.",
809
+ unit: "ms"
810
+ });
811
+ }
812
+ recordDelivery(inbox, durationMs, success, activityType) {
813
+ const deliveryAttributes = {
814
+ "activitypub.remote.host": getRemoteHost(inbox),
815
+ "activitypub.delivery.success": success
816
+ };
817
+ if (activityType != null) deliveryAttributes["activitypub.activity.type"] = activityType;
818
+ this.deliverySent.add(1, deliveryAttributes);
819
+ this.deliveryDuration.record(durationMs, deliveryAttributes);
820
+ }
821
+ recordPermanentFailure(inbox, statusCode) {
822
+ this.deliveryPermanentFailure.add(1, {
823
+ "activitypub.remote.host": getRemoteHost(inbox),
824
+ "http.response.status_code": statusCode
825
+ });
826
+ }
827
+ recordSignatureVerificationFailure(reason, remoteHost) {
828
+ const attributes = { "activitypub.verification.failure_reason": reason };
829
+ if (remoteHost != null) attributes["activitypub.remote.host"] = remoteHost;
830
+ this.signatureVerificationFailure.add(1, attributes);
831
+ }
832
+ recordInboxProcessingDuration(activityType, durationMs) {
833
+ this.inboxProcessingDuration.record(durationMs, { "activitypub.activity.type": activityType });
834
+ }
835
+ };
836
+ const federationMetrics = /* @__PURE__ */ new WeakMap();
837
+ /**
838
+ * Gets the cached Fedify metric instruments for a meter provider.
839
+ * @since 2.3.0
840
+ */
841
+ function getFederationMetrics(meterProvider = _opentelemetry_api.metrics.getMeterProvider()) {
842
+ let instruments = federationMetrics.get(meterProvider);
843
+ if (instruments == null) {
844
+ instruments = new FederationMetrics(meterProvider);
845
+ federationMetrics.set(meterProvider, instruments);
846
+ }
847
+ return instruments;
848
+ }
849
+ /**
850
+ * Gets the bounded remote host attribute value for a URL.
851
+ * @since 2.3.0
852
+ */
853
+ function getRemoteHost(url) {
854
+ return url.hostname;
855
+ }
856
+ /**
857
+ * Gets an elapsed duration in milliseconds from a `performance.now()` value.
858
+ * @since 2.3.0
859
+ */
860
+ function getDurationMs(start) {
861
+ return Math.max(0, performance.now() - start);
862
+ }
863
+ //#endregion
772
864
  //#region src/federation/inbox.ts
773
- async function routeActivity({ context: ctx, json, activity, recipient, inboxListeners, inboxContextFactory, inboxErrorHandler, kv, kvPrefixes, queue, span, tracerProvider, idempotencyStrategy }) {
865
+ async function routeActivity({ context: ctx, json, activity, recipient, inboxListeners, inboxContextFactory, inboxErrorHandler, kv, kvPrefixes, queue, span, meterProvider, tracerProvider, idempotencyStrategy }) {
774
866
  const logger = (0, _logtape_logtape.getLogger)([
775
867
  "fedify",
776
868
  "federation",
@@ -871,7 +963,13 @@ async function routeActivity({ context: ctx, json, activity, recipient, inboxLis
871
963
  const { class: cls, listener } = dispatched;
872
964
  span.updateName(`activitypub.dispatch_inbox_listener ${cls.name}`);
873
965
  try {
874
- await listener(inboxContextFactory(recipient, json, activity?.id?.href, (0, _fedify_vocab.getTypeId)(activity).href), activity);
966
+ const activityType = (0, _fedify_vocab.getTypeId)(activity).href;
967
+ const started = performance.now();
968
+ try {
969
+ await listener(inboxContextFactory(recipient, json, activity?.id?.href, activityType), activity);
970
+ } finally {
971
+ getFederationMetrics(meterProvider).recordInboxProcessingDuration(activityType, getDurationMs(started));
972
+ }
875
973
  } catch (error) {
876
974
  try {
877
975
  await inboxErrorHandler?.(ctx, error);
@@ -1681,6 +1779,8 @@ async function handleInboxInternal(request, parameters, span) {
1681
1779
  });
1682
1780
  if (verification.verified === false) {
1683
1781
  const reason = verification.reason;
1782
+ const remoteHost = "keyId" in reason && reason.keyId != null ? getRemoteHost(reason.keyId) : void 0;
1783
+ getFederationMetrics(parameters.meterProvider).recordSignatureVerificationFailure(reason.type, remoteHost);
1684
1784
  logger.error("Failed to verify the request's HTTP Signatures.", {
1685
1785
  recipient,
1686
1786
  reason: reason.type,
@@ -1767,6 +1867,7 @@ async function handleInboxInternal(request, parameters, span) {
1767
1867
  "http_signatures.key_id": httpSigKey?.id?.href ?? ""
1768
1868
  });
1769
1869
  if (httpSigKey != null && !await require_proof.doesActorOwnKey(activity, httpSigKey, ctx)) {
1870
+ getFederationMetrics(parameters.meterProvider).recordSignatureVerificationFailure("actorKeyMismatch", httpSigKey.id == null ? void 0 : getRemoteHost(httpSigKey.id));
1770
1871
  logger.error("The signer ({keyId}) and the actor ({actorId}) do not match.", {
1771
1872
  activity: json,
1772
1873
  recipient,
@@ -1784,6 +1885,7 @@ async function handleInboxInternal(request, parameters, span) {
1784
1885
  }
1785
1886
  if (pendingNonceLabel != null) {
1786
1887
  if (!await verifySignatureNonce(request, kv, kvPrefixes.acceptSignatureNonce, pendingNonceLabel)) {
1888
+ getFederationMetrics(parameters.meterProvider).recordSignatureVerificationFailure("invalidNonce", httpSigKey?.id == null ? void 0 : getRemoteHost(httpSigKey.id));
1787
1889
  logger.error("Signature nonce verification failed (missing, expired, or replayed).", { recipient });
1788
1890
  return await getFailedSignatureResponse(inboxChallengePolicy, kv, kvPrefixes);
1789
1891
  }
@@ -1800,6 +1902,7 @@ async function handleInboxInternal(request, parameters, span) {
1800
1902
  kvPrefixes,
1801
1903
  queue,
1802
1904
  span,
1905
+ meterProvider: parameters.meterProvider,
1803
1906
  tracerProvider,
1804
1907
  idempotencyStrategy: parameters.idempotencyStrategy
1805
1908
  });
@@ -2447,6 +2550,25 @@ function sendActivity(options) {
2447
2550
  });
2448
2551
  }
2449
2552
  const MAX_ERROR_RESPONSE_BODY_BYTES = 1024;
2553
+ function getActivityActorId(activity) {
2554
+ if (!isRecord(activity)) return void 0;
2555
+ return getIdValue(activity.actor);
2556
+ }
2557
+ function getIdValue(value) {
2558
+ if (typeof value === "string" && value !== "") return value;
2559
+ if (value instanceof URL) return value.href;
2560
+ if (Array.isArray(value)) {
2561
+ for (const item of value) {
2562
+ const id = getIdValue(item);
2563
+ if (id != null) return id;
2564
+ }
2565
+ return;
2566
+ }
2567
+ if (isRecord(value)) return getIdValue(value.id);
2568
+ }
2569
+ function isRecord(value) {
2570
+ return typeof value === "object" && value != null;
2571
+ }
2450
2572
  async function readLimitedResponseBody(response, maxBytes) {
2451
2573
  if (response.body == null) return "";
2452
2574
  const reader = response.body.getReader();
@@ -2474,12 +2596,15 @@ async function readLimitedResponseBody(response, maxBytes) {
2474
2596
  if (truncated) result += "… (truncated)";
2475
2597
  return result;
2476
2598
  }
2477
- async function sendActivityInternal({ activity, activityId, keys, inbox, headers, specDeterminer, tracerProvider }, span) {
2599
+ async function sendActivityInternal({ activity, activityId, activityType, keys, inbox, headers, specDeterminer, meterProvider, tracerProvider }, span) {
2478
2600
  const logger = (0, _logtape_logtape.getLogger)([
2479
2601
  "fedify",
2480
2602
  "federation",
2481
2603
  "outbox"
2482
2604
  ]);
2605
+ const federationMetrics = getFederationMetrics(meterProvider);
2606
+ const started = performance.now();
2607
+ let deliverySuccess = false;
2483
2608
  headers = new Headers(headers);
2484
2609
  headers.set("Content-Type", "application/activity+json");
2485
2610
  const request = new Request(inbox, {
@@ -2511,29 +2636,38 @@ async function sendActivityInternal({ activity, activityId, keys, inbox, headers
2511
2636
  inbox: inbox.href,
2512
2637
  error
2513
2638
  });
2639
+ federationMetrics.recordDelivery(inbox, getDurationMs(started), false, activityType);
2514
2640
  throw error;
2515
2641
  }
2516
- if (!response.ok) {
2517
- let error;
2518
- try {
2519
- error = await readLimitedResponseBody(response, MAX_ERROR_RESPONSE_BODY_BYTES);
2520
- } catch (_) {
2521
- error = "";
2642
+ try {
2643
+ if (!response.ok) {
2644
+ let error;
2645
+ try {
2646
+ error = await readLimitedResponseBody(response, MAX_ERROR_RESPONSE_BODY_BYTES);
2647
+ } catch (_) {
2648
+ error = "";
2649
+ }
2650
+ logger.error("Failed to send activity {activityId} to {inbox} ({status} {statusText}):\n{error}", {
2651
+ activityId,
2652
+ inbox: inbox.href,
2653
+ status: response.status,
2654
+ statusText: response.statusText,
2655
+ error
2656
+ });
2657
+ throw new SendActivityError(inbox, response.status, `Failed to send activity ${activityId} to ${inbox.href} (${response.status} ${response.statusText}):\n${error}`, error);
2522
2658
  }
2523
- logger.error("Failed to send activity {activityId} to {inbox} ({status} {statusText}):\n{error}", {
2524
- activityId,
2525
- inbox: inbox.href,
2526
- status: response.status,
2527
- statusText: response.statusText,
2528
- error
2529
- });
2530
- throw new SendActivityError(inbox, response.status, `Failed to send activity ${activityId} to ${inbox.href} (${response.status} ${response.statusText}):\n${error}`, error);
2659
+ deliverySuccess = true;
2660
+ const eventAttributes = {
2661
+ "activitypub.inbox.url": inbox.href,
2662
+ "activitypub.activity.id": activityId ?? ""
2663
+ };
2664
+ if (activityType != null) eventAttributes["activitypub.activity.type"] = activityType;
2665
+ const actorId = getActivityActorId(activity);
2666
+ if (actorId != null) eventAttributes["activitypub.actor.id"] = actorId;
2667
+ span.addEvent("activitypub.activity.sent", eventAttributes);
2668
+ } finally {
2669
+ federationMetrics.recordDelivery(inbox, getDurationMs(started), deliverySuccess, activityType);
2531
2670
  }
2532
- span.addEvent("activitypub.activity.sent", {
2533
- "activitypub.activity.json": JSON.stringify(activity),
2534
- "activitypub.inbox.url": inbox.href,
2535
- "activitypub.activity.id": activityId ?? ""
2536
- });
2537
2671
  }
2538
2672
  /**
2539
2673
  * An error that is thrown when an activity fails to send to a remote inbox.
@@ -2743,6 +2877,7 @@ var FederationImpl = class extends FederationBuilderImpl {
2743
2877
  inboxRetryPolicy;
2744
2878
  activityTransformers;
2745
2879
  _tracerProvider;
2880
+ _meterProvider;
2746
2881
  firstKnock;
2747
2882
  inboxChallengePolicy;
2748
2883
  constructor(options) {
@@ -2828,11 +2963,15 @@ var FederationImpl = class extends FederationBuilderImpl {
2828
2963
  this.inboxRetryPolicy = options.inboxRetryPolicy ?? createExponentialBackoffPolicy();
2829
2964
  this.activityTransformers = options.activityTransformers ?? require_transformers.getDefaultActivityTransformers();
2830
2965
  this._tracerProvider = options.tracerProvider;
2966
+ this._meterProvider = options.meterProvider;
2831
2967
  this.firstKnock = options.firstKnock;
2832
2968
  }
2833
2969
  get tracerProvider() {
2834
2970
  return this._tracerProvider ?? _opentelemetry_api.trace.getTracerProvider();
2835
2971
  }
2972
+ get meterProvider() {
2973
+ return this._meterProvider ?? _opentelemetry_api.metrics.getMeterProvider();
2974
+ }
2836
2975
  _initializeRouter() {
2837
2976
  this.router.add("/.well-known/webfinger", "webfinger");
2838
2977
  this.router.add("/.well-known/nodeinfo", "nodeInfoJrd");
@@ -3011,6 +3150,7 @@ var FederationImpl = class extends FederationBuilderImpl {
3011
3150
  sharedInbox: message.sharedInbox,
3012
3151
  headers: new Headers(message.headers),
3013
3152
  specDeterminer: new KvSpecDeterminer(this.kv, this.kvPrefixes.httpMessageSignaturesSpec, this.firstKnock),
3153
+ meterProvider: this.meterProvider,
3014
3154
  tracerProvider: this.tracerProvider
3015
3155
  });
3016
3156
  } catch (error) {
@@ -3018,6 +3158,21 @@ var FederationImpl = class extends FederationBuilderImpl {
3018
3158
  code: _opentelemetry_api.SpanStatusCode.ERROR,
3019
3159
  message: String(error)
3020
3160
  });
3161
+ const remoteHost = (() => {
3162
+ if (error instanceof SendActivityError) return getRemoteHost(error.inbox);
3163
+ try {
3164
+ return getRemoteHost(new URL(message.inbox));
3165
+ } catch (_) {
3166
+ logger.warn("Invalid inbox URL in queued outbox message: {inbox}", logData);
3167
+ return;
3168
+ }
3169
+ })();
3170
+ span.addEvent("activitypub.delivery.failed", {
3171
+ ...remoteHost == null ? {} : { "activitypub.remote.host": remoteHost },
3172
+ "activitypub.delivery.attempt": message.attempt,
3173
+ "activitypub.delivery.permanent_failure": error instanceof SendActivityError && this.permanentFailureStatusCodes.includes(error.statusCode),
3174
+ ...error instanceof SendActivityError ? { "http.response.status_code": error.statusCode } : {}
3175
+ });
3021
3176
  const loaderOptions = this.#getLoaderOptions(message.baseUrl);
3022
3177
  const activity = await _fedify_vocab.Activity.fromJsonLd(message.activity, {
3023
3178
  contextLoader: this.contextLoaderFactory(loaderOptions),
@@ -3033,6 +3188,7 @@ var FederationImpl = class extends FederationBuilderImpl {
3033
3188
  });
3034
3189
  }
3035
3190
  if (error instanceof SendActivityError && this.permanentFailureStatusCodes.includes(error.statusCode)) {
3191
+ getFederationMetrics(this.meterProvider).recordPermanentFailure(error.inbox, error.statusCode);
3036
3192
  logger.warn("Permanent delivery failure for activity {activityId} to {inbox} ({status}); not retrying.", {
3037
3193
  ...logData,
3038
3194
  status: error.statusCode
@@ -3141,7 +3297,13 @@ var FederationImpl = class extends FederationBuilderImpl {
3141
3297
  const { class: cls, listener } = dispatched;
3142
3298
  span.updateName(`activitypub.dispatch_inbox_listener ${cls.name}`);
3143
3299
  try {
3144
- await listener(context.toInboxContext(message.identifier, message.activity, activity.id?.href, (0, _fedify_vocab.getTypeId)(activity).href), activity);
3300
+ const activityType = (0, _fedify_vocab.getTypeId)(activity).href;
3301
+ const started = performance.now();
3302
+ try {
3303
+ await listener(context.toInboxContext(message.identifier, message.activity, activity.id?.href, activityType), activity);
3304
+ } finally {
3305
+ getFederationMetrics(this.meterProvider).recordInboxProcessingDuration(activityType, getDurationMs(started));
3306
+ }
3145
3307
  } catch (error) {
3146
3308
  try {
3147
3309
  await this.inboxErrorHandler?.(context, error);
@@ -3324,6 +3486,7 @@ var FederationImpl = class extends FederationBuilderImpl {
3324
3486
  sharedInbox: inboxes[inbox].sharedInbox,
3325
3487
  headers: collectionSync == null ? void 0 : new Headers({ "Collection-Synchronization": await buildCollectionSynchronizationHeader(collectionSync, inboxes[inbox].actorIds) }),
3326
3488
  specDeterminer: new KvSpecDeterminer(this.kv, this.kvPrefixes.httpMessageSignaturesSpec, this.firstKnock),
3489
+ meterProvider: this.meterProvider,
3327
3490
  tracerProvider: this.tracerProvider
3328
3491
  }));
3329
3492
  await Promise.all(promises);
@@ -3500,15 +3663,18 @@ var FederationImpl = class extends FederationBuilderImpl {
3500
3663
  if (request.method !== "POST" && !acceptsJsonLd(request)) return await onNotAcceptable(request);
3501
3664
  switch (routeName) {
3502
3665
  case "actor":
3503
- context = this.#createContext(request, contextData, { invokedFromActorDispatcher: { identifier: route.values.identifier } });
3666
+ case "actorAlias": {
3667
+ const identifier = route.name.startsWith("actorAlias:") ? route.name.substring(11) : route.values.identifier;
3668
+ context = this.#createContext(request, contextData, { invokedFromActorDispatcher: { identifier } });
3504
3669
  return await handleActor(request, {
3505
- identifier: route.values.identifier,
3670
+ identifier,
3506
3671
  context,
3507
3672
  actorDispatcher: this.actorCallbacks?.dispatcher,
3508
3673
  authorizePredicate: this.actorCallbacks?.authorizePredicate,
3509
3674
  onUnauthorized,
3510
3675
  onNotFound
3511
3676
  });
3677
+ }
3512
3678
  case "object": {
3513
3679
  const typeId = route.name.replace(/^object:/, "");
3514
3680
  const callbacks = this.objectCallbacks[typeId];
@@ -3590,6 +3756,7 @@ var FederationImpl = class extends FederationBuilderImpl {
3590
3756
  signatureTimeWindow: this.signatureTimeWindow,
3591
3757
  skipSignatureVerification: this.skipSignatureVerification,
3592
3758
  inboxChallengePolicy: this.inboxChallengePolicy,
3759
+ meterProvider: this.meterProvider,
3593
3760
  tracerProvider: this.tracerProvider,
3594
3761
  idempotencyStrategy: this.idempotencyStrategy
3595
3762
  });
@@ -3751,13 +3918,16 @@ var ContextImpl = class ContextImpl {
3751
3918
  get tracerProvider() {
3752
3919
  return this.federation.tracerProvider;
3753
3920
  }
3921
+ get meterProvider() {
3922
+ return this.federation.meterProvider;
3923
+ }
3754
3924
  getNodeInfoUri() {
3755
3925
  const path = this.federation.router.build("nodeInfo", {});
3756
3926
  if (path == null) throw new RouterError("No NodeInfo dispatcher registered.");
3757
3927
  return new URL(path, this.canonicalOrigin);
3758
3928
  }
3759
3929
  getActorUri(identifier) {
3760
- const path = this.federation.router.build("actor", { identifier });
3930
+ const path = this.federation.router.build(`actorAlias:${identifier}`, {}) ?? this.federation.router.build("actor", { identifier });
3761
3931
  if (path == null) throw new RouterError("No actor dispatcher registered.");
3762
3932
  return new URL(path, this.canonicalOrigin);
3763
3933
  }
@@ -3823,8 +3993,8 @@ var ContextImpl = class ContextImpl {
3823
3993
  type: "inbox",
3824
3994
  identifier: void 0
3825
3995
  };
3826
- const identifier = route.values.identifier;
3827
- if (route.name === "actor") return {
3996
+ const identifier = route.name.startsWith("actorAlias:") ? route.name.substring(11) : route.values.identifier;
3997
+ if (route.name === "actor" || route.name.startsWith("actorAlias:")) return {
3828
3998
  type: "actor",
3829
3999
  identifier
3830
4000
  };
@@ -4500,6 +4670,7 @@ async function forwardActivityInternal(ctx, loggerCategory, forwarder, recipient
4500
4670
  activityType: ctx.activityType,
4501
4671
  inbox: new URL(inbox),
4502
4672
  sharedInbox: inboxes[inbox].sharedInbox,
4673
+ meterProvider: ctx.meterProvider,
4503
4674
  tracerProvider: ctx.tracerProvider,
4504
4675
  specDeterminer: new KvSpecDeterminer(ctx.federation.kv, ctx.federation.kvPrefixes.httpMessageSignaturesSpec, ctx.federation.firstKnock)
4505
4676
  }));
@@ -1,5 +1,5 @@
1
1
  import "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as FederationImpl } from "./middleware-CEWDB8EB.mjs";
4
+ import { n as FederationImpl } from "./middleware-pb2EqN_r.mjs";
5
5
  export { FederationImpl };