@fedify/fedify 2.3.0-dev.1131 → 2.3.0-dev.1137

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 (104) hide show
  1. package/README.md +3 -0
  2. package/dist/{assert-DikXweDx.mjs → assert-OguE97r2.mjs} +1 -1
  3. package/dist/{assert_instance_of-C4Ri6VuN.mjs → assert_instance_of-DBC5X09g.mjs} +1 -1
  4. package/dist/{assert_not_equals--wG9hV7u.mjs → assert_not_equals-DkVK8oqV.mjs} +1 -1
  5. package/dist/{assert_rejects-DQP-q39h.mjs → assert_rejects-DN60FHPX.mjs} +2 -2
  6. package/dist/{assert_strict_equals-Dmjbg-bA.mjs → assert_strict_equals-XEgZAlrj.mjs} +1 -1
  7. package/dist/{assert_throws-4NwKEy2q.mjs → assert_throws-BOkhLGYc.mjs} +1 -1
  8. package/dist/{builder-DckAhD27.mjs → builder-BCkBXxky.mjs} +60 -41
  9. package/dist/compat/mod.d.cts +1 -1
  10. package/dist/compat/mod.d.ts +1 -1
  11. package/dist/compat/outgoing-jsonld.test.mjs +3 -3
  12. package/dist/compat/public-audience.test.mjs +3 -3
  13. package/dist/compat/transformers.test.mjs +5 -5
  14. package/dist/{context-Cq18Gplu.d.ts → context-DCtsSHDv.d.ts} +2 -86
  15. package/dist/{context-tc6VOOOL.d.cts → context-DI2gRbyN.d.cts} +1 -87
  16. package/dist/{context-BAE7AKLA.mjs → context-DVoTs_wM.mjs} +1 -1
  17. package/dist/{deno--CS-SBS9.mjs → deno-B_9yJW3w.mjs} +1 -1
  18. package/dist/{docloader-k6huZLQL.mjs → docloader-BT89tyFr.mjs} +3 -3
  19. package/dist/federation/builder.test.mjs +138 -10
  20. package/dist/federation/collection.test.mjs +3 -3
  21. package/dist/federation/handler.test.mjs +12 -12
  22. package/dist/federation/idempotency.test.mjs +6 -6
  23. package/dist/federation/inbox.test.mjs +3 -3
  24. package/dist/federation/keycache.test.mjs +5 -5
  25. package/dist/federation/kv.test.mjs +3 -3
  26. package/dist/federation/metrics.test.mjs +4 -4
  27. package/dist/federation/middleware.test.mjs +30 -18
  28. package/dist/federation/mod.cjs +155 -3
  29. package/dist/federation/mod.d.cts +2 -2
  30. package/dist/federation/mod.d.ts +2 -2
  31. package/dist/federation/mod.js +153 -1
  32. package/dist/federation/mq.test.mjs +5 -5
  33. package/dist/federation/negotiation.test.mjs +4 -4
  34. package/dist/federation/retry.test.mjs +3 -3
  35. package/dist/federation/router.test.mjs +190 -9
  36. package/dist/federation/send.test.mjs +16 -16
  37. package/dist/federation/webfinger.test.mjs +5 -5
  38. package/dist/{getMachineId-bsd-BY01PL1n.mjs → getMachineId-bsd-etIyxDet.mjs} +1 -1
  39. package/dist/{getMachineId-darwin-Dr1gkBkp.mjs → getMachineId-darwin-D23zTf4g.mjs} +1 -1
  40. package/dist/{getMachineId-win-QEYwcJiy.mjs → getMachineId-win-Dpap6v5i.mjs} +1 -1
  41. package/dist/{http-cqujdCRz.js → http-CToqG5ap.js} +1 -1
  42. package/dist/{http-CJfvRL7D.cjs → http-CWoeyogl.cjs} +1 -1
  43. package/dist/{http-IywnQdiX.mjs → http-Cyx5SNuu.mjs} +4 -4
  44. package/dist/{key-Df3tMleh.mjs → key-CkkMJBjF.mjs} +2 -2
  45. package/dist/{kv-cache-pEejzYq4.js → kv-cache-CuCn2xvM.js} +1 -1
  46. package/dist/{kv-cache-L0SMQkcd.cjs → kv-cache-DuEwFYcN.cjs} +1 -1
  47. package/dist/{kv-cache-q9Ec2ryS.mjs → kv-cache-VHFP42vY.mjs} +1 -1
  48. package/dist/{ld-BGwiJpl3.mjs → ld-k8yqD2a-.mjs} +3 -3
  49. package/dist/{metrics-BTOMkW8C.mjs → metrics-iRBg8jTk.mjs} +1 -1
  50. package/dist/{middleware-B2rtdpFV.cjs → middleware-BWLUrbS9.cjs} +95 -196
  51. package/dist/{middleware-Dnql59Y8.mjs → middleware-CztxpARM.mjs} +1 -1
  52. package/dist/{middleware-DtOddSVg.js → middleware-D7FrhN9q.js} +59 -148
  53. package/dist/{middleware-BB0IbDow.mjs → middleware-DQEgdr83.mjs} +21 -21
  54. package/dist/mod-C504qevA.d.cts +173 -0
  55. package/dist/mod-wYfuXeDE.d.ts +173 -0
  56. package/dist/mod.cjs +6 -6
  57. package/dist/mod.d.cts +2 -2
  58. package/dist/mod.d.ts +2 -2
  59. package/dist/mod.js +5 -5
  60. package/dist/nodeinfo/client.test.mjs +4 -4
  61. package/dist/nodeinfo/handler.test.mjs +5 -5
  62. package/dist/nodeinfo/types.test.mjs +4 -4
  63. package/dist/otel/exporter.test.mjs +3 -3
  64. package/dist/{outgoing-jsonld-BNL8AC14.mjs → outgoing-jsonld-BgFLCJQ_.mjs} +1 -1
  65. package/dist/{owner-CIt4hvmM.mjs → owner-nmXdvXpc.mjs} +2 -2
  66. package/dist/{proof-B1_u25UV.cjs → proof-CcsIJLTn.cjs} +1 -1
  67. package/dist/{proof-BYlrRSmZ.mjs → proof-DpwO1T4S.mjs} +5 -5
  68. package/dist/{proof-DMGIjHYH.js → proof-NRmtrTDu.js} +1 -1
  69. package/dist/{send-DJFpze7B.mjs → send-DvX2tYyZ.mjs} +3 -3
  70. package/dist/sig/accept.test.mjs +1 -1
  71. package/dist/sig/http.test.mjs +9 -9
  72. package/dist/sig/key.test.mjs +6 -6
  73. package/dist/sig/ld.test.mjs +7 -7
  74. package/dist/sig/mod.cjs +2 -2
  75. package/dist/sig/mod.js +2 -2
  76. package/dist/sig/owner.test.mjs +6 -6
  77. package/dist/sig/proof.test.mjs +8 -8
  78. package/dist/{std__assert-BTEgfoJo.mjs → std__assert-BBjXFNOb.mjs} +4 -4
  79. package/dist/testing/mod.d.mts +1 -0
  80. package/dist/testing/mod.mjs +1 -1
  81. package/dist/utils/docloader.test.mjs +7 -7
  82. package/dist/utils/kv-cache.test.mjs +1 -1
  83. package/dist/utils/mod.cjs +1 -1
  84. package/dist/utils/mod.js +1 -1
  85. package/package.json +7 -8
  86. package/dist/mod-CajNYYkt.d.ts +0 -63
  87. package/dist/mod-DnzgcPcy.d.cts +0 -63
  88. package/dist/router-BT_F5748.mjs +0 -114
  89. /package/dist/{accept-CgDcxvjV.mjs → accept-CceiKpCy.mjs} +0 -0
  90. /package/dist/{activity-listener-BeTGV3wc.mjs → activity-listener-tztVvlNb.mjs} +0 -0
  91. /package/dist/{assert_equals-Ew3jOFa3.mjs → assert_equals-C-ZRDbaf.mjs} +0 -0
  92. /package/dist/{client-Bneh_DYR.mjs → client-B_A6mfn3.mjs} +0 -0
  93. /package/dist/{collection-Cc3DVAhE.mjs → collection-CA3V5zyK.mjs} +0 -0
  94. /package/dist/{esm-sdtqOUPu.mjs → esm-BQRw925N.mjs} +0 -0
  95. /package/dist/{execAsync-Dxb7rNf3.mjs → execAsync-DCBrgFiV.mjs} +0 -0
  96. /package/dist/{getMachineId-linux-Bbhofx-s.mjs → getMachineId-linux-ObI47Hql.mjs} +0 -0
  97. /package/dist/{getMachineId-unsupported-dIOte2Ct.mjs → getMachineId-unsupported-Ddu-PFeh.mjs} +0 -0
  98. /package/dist/{keycache-BeU0LCII.mjs → keycache-BYMd8q7F.mjs} +0 -0
  99. /package/dist/{keys-CSYsOMFG.mjs → keys-C3kae-6B.mjs} +0 -0
  100. /package/dist/{kv-QHE0oeM3.mjs → kv-x2IvBUyq.mjs} +0 -0
  101. /package/dist/{negotiation-DDstyBvc.mjs → negotiation-CDW-_gUU.mjs} +0 -0
  102. /package/dist/{public-audience-c9zmYKgA.mjs → public-audience-N3pyOx2p.mjs} +0 -0
  103. /package/dist/{retry-_VvV0h9f.mjs → retry-v_sGLH1d.mjs} +0 -0
  104. /package/dist/{types-D09GN0uZ.mjs → types-BFowWFTT.mjs} +0 -0
@@ -2,17 +2,16 @@ import { Temporal } from "@js-temporal/polyfill";
2
2
  import { URLPattern } from "urlpattern-polyfill";
3
3
  import { t as __exportAll } from "./chunk-CRNNMoPX.js";
4
4
  import { r as getDefaultActivityTransformers } from "./transformers-BGMIq1cs.js";
5
- import { C as formatAcceptSignature, D as name, O as version, S as recordOutboxEnqueue, a as verifyRequestDetailed, b as recordInboxActivity, d as validateCryptoKey, f as getDurationMs, g as isAbortError, h as instrumentDocumentLoader, i as verifyRequest, m as getRemoteHost, n as parseRfc9421SignatureInput, o as exportJwk, p as getFederationMetrics, t as doubleKnock, u as importJwk, x as recordOutboxActivity, y as recordFanoutRecipients } from "./http-cqujdCRz.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-DMGIjHYH.js";
5
+ import { C as formatAcceptSignature, D as name, O as version, S as recordOutboxEnqueue, a as verifyRequestDetailed, b as recordInboxActivity, d as validateCryptoKey, f as getDurationMs, g as isAbortError, h as instrumentDocumentLoader, i as verifyRequest, m as getRemoteHost, n as parseRfc9421SignatureInput, o as exportJwk, p as getFederationMetrics, t as doubleKnock, u as importJwk, x as recordOutboxActivity, y as recordFanoutRecipients } from "./http-CToqG5ap.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-NRmtrTDu.js";
7
7
  import { n as getNodeInfo, t as nodeInfoToJson } from "./types-CAY3OdLq.js";
8
- import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-pEejzYq4.js";
8
+ import { n as getAuthenticatedDocumentLoader, t as kvCache } from "./kv-cache-CuCn2xvM.js";
9
9
  import { getLogger, withContext } from "@logtape/logtape";
10
+ import { Router, RouterError, assertPath } from "@fedify/uri-template";
10
11
  import { Activity, Collection, CollectionPage, CryptographicKey, Link, Multikey, Object as Object$1, OrderedCollection, OrderedCollectionPage, Tombstone, getTypeId, lookupObject, traverseCollection } from "@fedify/vocab";
11
12
  import { SpanKind, SpanStatusCode, context, metrics, propagation, trace } from "@opentelemetry/api";
12
- import { cloneDeep, uniq } from "es-toolkit";
13
- import { Router } from "uri-template-router";
14
- import { parseTemplate } from "url-template";
15
13
  import { encodeHex } from "byte-encodings/hex";
14
+ import { uniq } from "es-toolkit";
16
15
  import { FetchError, getDocumentLoader } from "@fedify/vocab-runtime";
17
16
  import { ATTR_HTTP_REQUEST_HEADER, ATTR_HTTP_REQUEST_METHOD, ATTR_HTTP_RESPONSE_HEADER, ATTR_HTTP_RESPONSE_STATUS_CODE, ATTR_URL_FULL } from "@opentelemetry/semantic-conventions";
18
17
  import { lookupWebFinger } from "@fedify/webfinger";
@@ -52,126 +51,33 @@ var ActivityListenerSet = class {
52
51
  }
53
52
  };
54
53
  //#endregion
55
- //#region src/federation/router.ts
56
- function cloneInnerRouter(router) {
57
- const clone = new Router();
58
- clone.nid = router.nid;
59
- clone.fsm = cloneDeep(router.fsm);
60
- clone.routeSet = new Set(router.routeSet);
61
- clone.templateRouteMap = new Map(router.templateRouteMap);
62
- clone.valueRouteMap = new Map(router.valueRouteMap);
63
- clone.hierarchy = cloneDeep(router.hierarchy);
64
- return clone;
65
- }
54
+ //#region src/federation/builder.ts
55
+ const ACTOR_ALIAS_PREFIX = "actorAlias:";
66
56
  /**
67
- * URL router and constructor based on URI Template
68
- * ([RFC 6570](https://tools.ietf.org/html/rfc6570)).
57
+ * Route options shared by every dispatcher whose path must expose exactly
58
+ * one `{identifier}` variable bound to a single, non-empty value
59
+ * for `setOutboxDispatcher/Listener()`.
69
60
  */
70
- var Router$1 = class Router$1 {
71
- #router;
72
- #templates;
73
- #templateStrings;
74
- /**
75
- * Whether to ignore trailing slashes when matching paths.
76
- * @since 1.6.0
77
- */
78
- trailingSlashInsensitive;
79
- /**
80
- * Create a new {@link Router}.
81
- * @param options Options for the router.
82
- */
83
- constructor(options = {}) {
84
- this.#router = new Router();
85
- this.#templates = {};
86
- this.#templateStrings = {};
87
- this.trailingSlashInsensitive = options.trailingSlashInsensitive ?? false;
88
- }
89
- clone() {
90
- const clone = new Router$1({ trailingSlashInsensitive: this.trailingSlashInsensitive });
91
- clone.#router = cloneInnerRouter(this.#router);
92
- clone.#templates = { ...this.#templates };
93
- clone.#templateStrings = { ...this.#templateStrings };
94
- return clone;
95
- }
96
- /**
97
- * Checks if a path name exists in the router.
98
- * @param name The name of the path.
99
- * @returns `true` if the path name exists, otherwise `false`.
100
- */
101
- has(name) {
102
- return name in this.#templates;
103
- }
104
- /**
105
- * Adds a new path rule to the router.
106
- * @param template The path pattern.
107
- * @param name The name of the path.
108
- * @returns The names of the variables in the path pattern.
109
- */
110
- add(template, name) {
111
- if (!template.startsWith("/")) throw new RouterError("Path must start with a slash.");
112
- const rule = this.#router.addTemplate(template, {}, name);
113
- this.#templates[name] = parseTemplate(template);
114
- this.#templateStrings[name] = template;
115
- return new Set(rule.variables.map((v) => v.varname));
116
- }
117
- /**
118
- * Resolves a path name and values from a URL, if any match.
119
- * @param url The URL to resolve.
120
- * @returns The name of the path and its values, if any match. Otherwise,
121
- * `null`.
122
- */
123
- route(url) {
124
- let match = this.#router.resolveURI(url);
125
- if (match == null) {
126
- if (!this.trailingSlashInsensitive) return null;
127
- url = url.endsWith("/") ? url.replace(/\/+$/, "") : `${url}/`;
128
- match = this.#router.resolveURI(url);
129
- if (match == null) return null;
130
- }
131
- return {
132
- name: match.matchValue,
133
- template: this.#templateStrings[match.matchValue],
134
- values: match.params
135
- };
136
- }
137
- /**
138
- * Constructs a URL/path from a path name and values.
139
- * @param name The name of the path.
140
- * @param values The values to expand the path with.
141
- * @returns The URL/path, if the name exists. Otherwise, `null`.
142
- */
143
- build(name, values) {
144
- if (name in this.#templates) return this.#templates[name].expand(values);
145
- return null;
146
- }
61
+ const identifierSingular = {
62
+ exact: true,
63
+ variables: { identifier: { operatables: [""] } }
147
64
  };
148
65
  /**
149
- * An error thrown by the {@link Router}.
66
+ * Route options shared by every dispatcher whose path must expose
67
+ * `{identifier}` and `{+identifier}` variables bound to the same single,
68
+ * non-empty value for following setters:
69
+ * - `setActorDispatcher()` (actor path)
70
+ * - `setInboxDispatcher/Listener()` (inbox path)
71
+ * - `setFollowingDispatcher()` (following path)
72
+ * - `setFollowersDispatcher()` (followers path)
73
+ * - `setLikedDispatcher()` (liked path)
74
+ * - `setFeaturedDispatcher()` (featured path)
75
+ * - `setFeaturedTagsDispatcher()` (featured tags path)
150
76
  */
151
- var RouterError = class extends Error {
152
- /**
153
- * Create a new {@link RouterError}.
154
- * @param message The error message.
155
- */
156
- constructor(message) {
157
- super(message);
158
- this.name = "RouterError";
159
- }
77
+ const identifierSingularAllowPlus = {
78
+ exact: true,
79
+ variables: { identifier: { operatables: ["", "+"] } }
160
80
  };
161
- //#endregion
162
- //#region src/federation/builder.ts
163
- const ACTOR_ALIAS_PREFIX = "actorAlias:";
164
- function validateSingleIdentifierVariablePath(path, errorMessage) {
165
- const operatorMatches = globalThis.Array.from(path.matchAll(/{([+#./;?&]?)([A-Za-z_][A-Za-z0-9_]*)}/g));
166
- if (operatorMatches.length !== 1 || operatorMatches[0]?.[2] !== "identifier") throw new RouterError(errorMessage);
167
- if (operatorMatches.some((match) => [
168
- "?",
169
- "&",
170
- "#"
171
- ].includes(match[1]) && match[2] === "identifier")) throw new RouterError(errorMessage);
172
- const variables = new Router$1().add(path, "outbox");
173
- if (variables.size !== 1 || !variables.has("identifier")) throw new RouterError(errorMessage);
174
- }
175
81
  var FederationBuilderImpl = class {
176
82
  router;
177
83
  actorCallbacks;
@@ -204,7 +110,7 @@ var FederationBuilderImpl = class {
204
110
  */
205
111
  #symbolRegistry = /* @__PURE__ */ new Map();
206
112
  constructor() {
207
- this.router = new Router$1();
113
+ this.router = new Router();
208
114
  this.objectCallbacks = {};
209
115
  this.objectTypeIds = {};
210
116
  this.collectionCallbacks = {};
@@ -247,8 +153,8 @@ var FederationBuilderImpl = class {
247
153
  }
248
154
  setActorDispatcher(path, dispatcher) {
249
155
  if (this.router.has("actor")) throw new RouterError("Actor dispatcher already set.");
250
- const variables = this.router.add(path, "actor");
251
- if (variables.size !== 1 || !variables.has("identifier")) throw new RouterError("Path for actor dispatcher must have one variable: {identifier}");
156
+ assertPath(path);
157
+ this.router.add(path, "actor", identifierSingularAllowPlus);
252
158
  const callbacks = { dispatcher: async (context, identifier) => {
253
159
  const actor = await this._getTracer().startActiveSpan("activitypub.dispatch_actor", {
254
160
  kind: SpanKind.SERVER,
@@ -350,7 +256,7 @@ var FederationBuilderImpl = class {
350
256
  mapActorAlias: (path, identifier) => {
351
257
  if (identifier === "") throw new RouterError("Identifier cannot be empty.");
352
258
  if (this.router.has(`actorAlias:${identifier}`)) throw new RouterError(`Actor alias for "${identifier}" already set.`);
353
- if (new Router$1().add(path, "temp").size > 0) throw new RouterError("Path for actor alias must have no variables.");
259
+ if (Router.variables(path).size > 0) throw new RouterError("Path for actor alias must have no variables.");
354
260
  const existingRoute = this.router.route(path);
355
261
  if (existingRoute != null) throw new RouterError(`Actor alias path "${path}" conflicts with existing route "${existingRoute.name}".`);
356
262
  this.router.add(path, `${ACTOR_ALIAS_PREFIX}${identifier}`);
@@ -365,7 +271,8 @@ var FederationBuilderImpl = class {
365
271
  }
366
272
  setNodeInfoDispatcher(path, dispatcher) {
367
273
  if (this.router.has("nodeInfo")) throw new RouterError("NodeInfo dispatcher already set.");
368
- if (this.router.add(path, "nodeInfo").size !== 0) throw new RouterError("Path for NodeInfo dispatcher must have no variables.");
274
+ if (Router.variables(path).size !== 0) throw new RouterError("Path for NodeInfo dispatcher must have no variables.");
275
+ this.router.add(path, "nodeInfo");
369
276
  this.nodeInfoDispatcher = dispatcher;
370
277
  }
371
278
  setWebFingerLinksDispatcher(dispatcher) {
@@ -374,8 +281,9 @@ var FederationBuilderImpl = class {
374
281
  setObjectDispatcher(cls, path, dispatcher) {
375
282
  const routeName = `object:${cls.typeId.href}`;
376
283
  if (this.router.has(routeName)) throw new RouterError(`Object dispatcher for ${cls.name} already set.`);
377
- const variables = this.router.add(path, routeName);
378
- if (variables.size < 1) throw new RouterError("Path for object dispatcher must have at least one variable.");
284
+ assertPath(path);
285
+ const variables = Router.variables(path);
286
+ this.router.add(path, routeName);
379
287
  const callbacks = {
380
288
  dispatcher: (ctx, values) => {
381
289
  return this._getTracer().startActiveSpan("activitypub.dispatch_object", {
@@ -417,8 +325,8 @@ var FederationBuilderImpl = class {
417
325
  if (this.router.has("inbox")) {
418
326
  if (this.inboxPath !== path) throw new RouterError("Inbox dispatcher path must match inbox listener path.");
419
327
  } else {
420
- const variables = this.router.add(path, "inbox");
421
- if (variables.size !== 1 || !variables.has("identifier")) throw new RouterError("Path for inbox dispatcher must have one variable: {identifier}");
328
+ assertPath(path);
329
+ this.router.add(path, "inbox", identifierSingularAllowPlus);
422
330
  this.inboxPath = path;
423
331
  }
424
332
  const callbacks = { dispatcher };
@@ -448,8 +356,8 @@ var FederationBuilderImpl = class {
448
356
  if (this.router.has("outbox")) {
449
357
  if (this.outboxPath !== path) throw new RouterError("Outbox dispatcher path must match outbox listener path.");
450
358
  } else {
451
- validateSingleIdentifierVariablePath(path, "Path for outbox dispatcher must have one variable: {identifier}");
452
- this.router.add(path, "outbox");
359
+ assertPath(path);
360
+ this.router.add(path, "outbox", identifierSingular);
453
361
  this.outboxPath = path;
454
362
  }
455
363
  const callbacks = { dispatcher };
@@ -479,8 +387,8 @@ var FederationBuilderImpl = class {
479
387
  if (this.router.has("outbox")) {
480
388
  if (this.outboxPath !== outboxPath) throw new RouterError("Outbox listener path must match outbox dispatcher path.");
481
389
  } else {
482
- validateSingleIdentifierVariablePath(outboxPath, "Path for outbox must have one variable: {identifier}");
483
- this.router.add(outboxPath, "outbox");
390
+ assertPath(outboxPath);
391
+ this.router.add(outboxPath, "outbox", identifierSingular);
484
392
  this.outboxPath = outboxPath;
485
393
  }
486
394
  const listeners = this.outboxListeners = new ActivityListenerSet();
@@ -502,8 +410,8 @@ var FederationBuilderImpl = class {
502
410
  }
503
411
  setFollowingDispatcher(path, dispatcher) {
504
412
  if (this.router.has("following")) throw new RouterError("Following collection dispatcher already set.");
505
- const variables = this.router.add(path, "following");
506
- if (variables.size !== 1 || !variables.has("identifier")) throw new RouterError("Path for following collection dispatcher must have one variable: {identifier}");
413
+ assertPath(path);
414
+ this.router.add(path, "following", identifierSingularAllowPlus);
507
415
  const callbacks = { dispatcher };
508
416
  this.followingCallbacks = callbacks;
509
417
  const setters = {
@@ -528,8 +436,8 @@ var FederationBuilderImpl = class {
528
436
  }
529
437
  setFollowersDispatcher(path, dispatcher) {
530
438
  if (this.router.has("followers")) throw new RouterError("Followers collection dispatcher already set.");
531
- const variables = this.router.add(path, "followers");
532
- if (variables.size !== 1 || !variables.has("identifier")) throw new RouterError("Path for followers collection dispatcher must have one variable: {identifier}");
439
+ assertPath(path);
440
+ this.router.add(path, "followers", identifierSingularAllowPlus);
533
441
  const callbacks = { dispatcher };
534
442
  this.followersCallbacks = callbacks;
535
443
  const setters = {
@@ -554,8 +462,8 @@ var FederationBuilderImpl = class {
554
462
  }
555
463
  setLikedDispatcher(path, dispatcher) {
556
464
  if (this.router.has("liked")) throw new RouterError("Liked collection dispatcher already set.");
557
- const variables = this.router.add(path, "liked");
558
- if (variables.size !== 1 || !variables.has("identifier")) throw new RouterError("Path for liked collection dispatcher must have one variable: {identifier}");
465
+ assertPath(path);
466
+ this.router.add(path, "liked", identifierSingularAllowPlus);
559
467
  const callbacks = { dispatcher };
560
468
  this.likedCallbacks = callbacks;
561
469
  const setters = {
@@ -580,8 +488,8 @@ var FederationBuilderImpl = class {
580
488
  }
581
489
  setFeaturedDispatcher(path, dispatcher) {
582
490
  if (this.router.has("featured")) throw new RouterError("Featured collection dispatcher already set.");
583
- const variables = this.router.add(path, "featured");
584
- if (variables.size !== 1 || !variables.has("identifier")) throw new RouterError("Path for featured collection dispatcher must have one variable: {identifier}");
491
+ assertPath(path);
492
+ this.router.add(path, "featured", identifierSingularAllowPlus);
585
493
  const callbacks = { dispatcher };
586
494
  this.featuredCallbacks = callbacks;
587
495
  const setters = {
@@ -606,8 +514,8 @@ var FederationBuilderImpl = class {
606
514
  }
607
515
  setFeaturedTagsDispatcher(path, dispatcher) {
608
516
  if (this.router.has("featuredTags")) throw new RouterError("Featured tags collection dispatcher already set.");
609
- const variables = this.router.add(path, "featuredTags");
610
- if (variables.size !== 1 || !variables.has("identifier")) throw new RouterError("Path for featured tags collection dispatcher must have one variable: {identifier}");
517
+ assertPath(path);
518
+ this.router.add(path, "featuredTags", identifierSingularAllowPlus);
611
519
  const callbacks = { dispatcher };
612
520
  this.featuredTagsCallbacks = callbacks;
613
521
  const setters = {
@@ -635,12 +543,13 @@ var FederationBuilderImpl = class {
635
543
  if (this.router.has("inbox")) {
636
544
  if (this.inboxPath !== inboxPath) throw new RouterError("Inbox listener path must match inbox dispatcher path.");
637
545
  } else {
638
- const variables = this.router.add(inboxPath, "inbox");
639
- if (variables.size !== 1 || !variables.has("identifier")) throw new RouterError("Path for inbox must have one variable: {identifier}");
546
+ assertPath(inboxPath);
547
+ this.router.add(inboxPath, "inbox", identifierSingularAllowPlus);
640
548
  this.inboxPath = inboxPath;
641
549
  }
642
550
  if (sharedInboxPath != null) {
643
- if (this.router.add(sharedInboxPath, "sharedInbox").size !== 0) throw new RouterError("Path for shared inbox must have no variables.");
551
+ if (Router.variables(sharedInboxPath).size !== 0) throw new RouterError("Path for shared inbox must have no variables.");
552
+ this.router.add(sharedInboxPath, "sharedInbox");
644
553
  }
645
554
  const listeners = this.inboxListeners = new ActivityListenerSet();
646
555
  const setters = {
@@ -678,7 +587,9 @@ var FederationBuilderImpl = class {
678
587
  const routeName = `${collectionType}:${this.#uniqueCollectionId(name)}`;
679
588
  if (this.router.has(routeName)) throw new RouterError(`Collection dispatcher for ${strName} already set.`);
680
589
  if (this.collectionCallbacks[name] != null) throw new RouterError(`Collection dispatcher for ${strName} already set.`);
681
- if (this.router.add(path, routeName).size < 1) throw new RouterError("Path for collection dispatcher must have at least one variable.");
590
+ assertPath(path);
591
+ if (Router.variables(path).size < 1) throw new RouterError("Path for collection dispatcher must have at least one variable.");
592
+ this.router.add(path, routeName);
682
593
  const callbacks = { dispatcher };
683
594
  this.collectionCallbacks[name] = callbacks;
684
595
  this.collectionTypeIds[name] = itemType;
@@ -5002,4 +4913,4 @@ function getRequestId(request) {
5002
4913
  return `req_${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`;
5003
4914
  }
5004
4915
  //#endregion
5005
- export { createExponentialBackoffPolicy as a, buildCollectionSynchronizationHeader as c, Router$1 as d, RouterError as f, SendActivityError as i, digest as l, middleware_exports as n, respondWithObject as o, handleWebFinger as r, respondWithObjectIfAcceptable as s, createFederation as t, createFederationBuilder as u };
4916
+ export { createExponentialBackoffPolicy as a, buildCollectionSynchronizationHeader as c, SendActivityError as i, digest as l, middleware_exports as n, respondWithObject as o, handleWebFinger as r, respondWithObjectIfAcceptable as s, createFederation as t, createFederationBuilder as u };
@@ -1,33 +1,33 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as RouterError } from "./router-BT_F5748.mjs";
5
- import { n as version, t as name } from "./deno--CS-SBS9.mjs";
6
- import { a as instrumentDocumentLoader, d as recordInboxActivity, i as getRemoteHost, m as recordOutboxEnqueue, n as getDurationMs, o as isAbortError, p as recordOutboxActivity, r as getFederationMetrics, u as recordFanoutRecipients } from "./metrics-BTOMkW8C.mjs";
7
- import { t as formatAcceptSignature } from "./accept-CgDcxvjV.mjs";
8
- import { a as importJwk, o as validateCryptoKey, t as exportJwk } from "./key-Df3tMleh.mjs";
9
- import { l as verifyRequest, o as parseRfc9421SignatureInput, u as verifyRequestDetailed } from "./http-IywnQdiX.mjs";
10
- import { t as getAuthenticatedDocumentLoader } from "./docloader-k6huZLQL.mjs";
11
- import { n as kvCache } from "./kv-cache-q9Ec2ryS.mjs";
12
- import { a as signJsonLd, i as hasSignatureLike, o as verifyJsonLd, r as detachSignature } from "./ld-BGwiJpl3.mjs";
13
- import { n as getKeyOwner, t as doesActorOwnKey } from "./owner-CIt4hvmM.mjs";
14
- import { r as normalizeOutgoingActivityJsonLd } from "./outgoing-jsonld-BNL8AC14.mjs";
15
- import { i as verifyObject, n as hasProofLike, r as signObject } from "./proof-BYlrRSmZ.mjs";
16
- import { t as getNodeInfo } from "./client-Bneh_DYR.mjs";
17
- import { t as nodeInfoToJson } from "./types-D09GN0uZ.mjs";
18
- import { n as FederationBuilderImpl, t as ACTOR_ALIAS_PREFIX } from "./builder-DckAhD27.mjs";
19
- import { t as buildCollectionSynchronizationHeader } from "./collection-Cc3DVAhE.mjs";
20
- import { t as KvKeyCache } from "./keycache-BeU0LCII.mjs";
21
- import { t as acceptsJsonLd } from "./negotiation-DDstyBvc.mjs";
22
- import { t as createExponentialBackoffPolicy } from "./retry-_VvV0h9f.mjs";
23
- import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "./send-DJFpze7B.mjs";
4
+ import { n as version, t as name } from "./deno-B_9yJW3w.mjs";
5
+ import { a as instrumentDocumentLoader, d as recordInboxActivity, i as getRemoteHost, m as recordOutboxEnqueue, n as getDurationMs, o as isAbortError, p as recordOutboxActivity, r as getFederationMetrics, u as recordFanoutRecipients } from "./metrics-iRBg8jTk.mjs";
6
+ import { t as formatAcceptSignature } from "./accept-CceiKpCy.mjs";
7
+ import { a as importJwk, o as validateCryptoKey, t as exportJwk } from "./key-CkkMJBjF.mjs";
8
+ import { l as verifyRequest, o as parseRfc9421SignatureInput, u as verifyRequestDetailed } from "./http-Cyx5SNuu.mjs";
9
+ import { t as getAuthenticatedDocumentLoader } from "./docloader-BT89tyFr.mjs";
10
+ import { n as kvCache } from "./kv-cache-VHFP42vY.mjs";
11
+ import { a as signJsonLd, i as hasSignatureLike, o as verifyJsonLd, r as detachSignature } from "./ld-k8yqD2a-.mjs";
12
+ import { n as getKeyOwner, t as doesActorOwnKey } from "./owner-nmXdvXpc.mjs";
13
+ import { r as normalizeOutgoingActivityJsonLd } from "./outgoing-jsonld-BgFLCJQ_.mjs";
14
+ import { i as verifyObject, n as hasProofLike, r as signObject } from "./proof-DpwO1T4S.mjs";
15
+ import { t as getNodeInfo } from "./client-B_A6mfn3.mjs";
16
+ import { t as nodeInfoToJson } from "./types-BFowWFTT.mjs";
17
+ import { n as FederationBuilderImpl, t as ACTOR_ALIAS_PREFIX } from "./builder-BCkBXxky.mjs";
18
+ import { t as buildCollectionSynchronizationHeader } from "./collection-CA3V5zyK.mjs";
19
+ import { t as KvKeyCache } from "./keycache-BYMd8q7F.mjs";
20
+ import { t as acceptsJsonLd } from "./negotiation-CDW-_gUU.mjs";
21
+ import { t as createExponentialBackoffPolicy } from "./retry-v_sGLH1d.mjs";
22
+ import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "./send-DvX2tYyZ.mjs";
24
23
  import { getLogger, withContext } from "@logtape/logtape";
24
+ import { RouterError } from "@fedify/uri-template";
25
25
  import { Activity, Collection, CollectionPage, CryptographicKey, Link, Multikey, Object as Object$1, OrderedCollection, OrderedCollectionPage, Tombstone, getTypeId, lookupObject, traverseCollection } from "@fedify/vocab";
26
26
  import { lookupWebFinger } from "@fedify/webfinger";
27
27
  import { SpanKind, SpanStatusCode, context, metrics, propagation, trace } from "@opentelemetry/api";
28
- import { uniq } from "es-toolkit";
29
28
  import { FetchError, getDocumentLoader } from "@fedify/vocab-runtime";
30
29
  import { ATTR_HTTP_REQUEST_HEADER, ATTR_HTTP_REQUEST_METHOD, ATTR_HTTP_RESPONSE_HEADER, ATTR_HTTP_RESPONSE_STATUS_CODE, ATTR_URL_FULL } from "@opentelemetry/semantic-conventions";
30
+ import { uniq } from "es-toolkit";
31
31
  import { domainToASCII } from "node:url";
32
32
  //#region src/compat/transformers.ts
33
33
  const logger$1 = getLogger([
@@ -0,0 +1,173 @@
1
+ /// <reference lib="esnext.temporal" />
2
+ import { G as ActorHandleMapper, U as ActorAliasMapper, W as ActorDispatcher, ft as WebFingerLinksDispatcher, l as RequestContext } from "./context-DI2gRbyN.cjs";
3
+ import { Span, Tracer } from "@opentelemetry/api";
4
+ import { RouterError, RouterOptions, RouterRouteResult } from "@fedify/uri-template";
5
+
6
+ //#region src/federation/router.d.ts
7
+ /**
8
+ * Options for the {@link Router}.
9
+ * @since 0.12.0
10
+ * @deprecated Import `RouterOptions` from `@fedify/uri-template` instead.
11
+ */
12
+ interface RouterOptions$1 extends RouterOptions {}
13
+ /**
14
+ * The result of {@link Router.route} method.
15
+ * @since 1.3.0
16
+ * @deprecated Import `RouterRouteResult` from `@fedify/uri-template` instead.
17
+ */
18
+ interface RouterRouteResult$1 extends RouterRouteResult<Record<never, never>> {}
19
+ /**
20
+ * URL router and constructor based on URI Template
21
+ * ([RFC 6570](https://tools.ietf.org/html/rfc6570)).
22
+ *
23
+ * @deprecated Import `Router` from `@fedify/uri-template` instead. This class
24
+ * remains only for compatibility with older Fedify code. The
25
+ * `@fedify/uri-template` router is the replacement implementation
26
+ * and should be used directly in new code.
27
+ */
28
+ declare class Router {
29
+ #private;
30
+ /**
31
+ * Create a new {@link Router}.
32
+ * @param options Options for the router.
33
+ * @deprecated Use `new Router(options)` from `@fedify/uri-template`
34
+ * instead.
35
+ */
36
+ constructor(options?: RouterOptions);
37
+ /**
38
+ * Whether to ignore trailing slashes when matching paths.
39
+ * @deprecated Use `Router` from `@fedify/uri-template` instead. This
40
+ * accessor forwards to the underlying `@fedify/uri-template`
41
+ * router so that post-construction mutation keeps working as
42
+ * in older Fedify code.
43
+ */
44
+ get trailingSlashInsensitive(): boolean;
45
+ set trailingSlashInsensitive(value: boolean);
46
+ /**
47
+ * Clones this router.
48
+ * @deprecated Use `Router` from `@fedify/uri-template` instead.
49
+ */
50
+ clone(): Router;
51
+ /**
52
+ * Checks if a path name exists in the router.
53
+ * @param name The name of the path.
54
+ * @returns `true` if the path name exists, otherwise `false`.
55
+ * @deprecated Use `Router` from `@fedify/uri-template` instead.
56
+ */
57
+ has(name: string): boolean;
58
+ /**
59
+ * Adds a new path rule to the router.
60
+ * @param template The path pattern.
61
+ * @param name The name of the path.
62
+ * @returns The names of the variables in the path pattern.
63
+ * @deprecated Use `Router` from `@fedify/uri-template` instead. In this
64
+ * compatibility class, `add()` both registers the route and
65
+ * returns the variables in the path pattern. In
66
+ * `@fedify/uri-template`, these two responsibilities are split:
67
+ * `router.add(template, name)` registers the route and returns
68
+ * `void`, while the pure static method
69
+ * `Router.variables(template)` returns the variable names. To
70
+ * migrate, call `Router.variables(template)` when variables are
71
+ * needed, then call `router.add(template, name)` to register the
72
+ * route.
73
+ */
74
+ add(template: string, name: string): Set<string>;
75
+ /**
76
+ * Resolves a path name and values from a URL, if any match.
77
+ * @param url The URL to resolve.
78
+ * @returns The name of the path and its values, if any match. Otherwise,
79
+ * `null`.
80
+ * @deprecated Use `Router` from `@fedify/uri-template` instead. Unlike the
81
+ * stricter `@fedify/uri-template` router, this compatibility
82
+ * method keeps the old Fedify 2.x contract of returning `null`
83
+ * (rather than throwing) for inputs that are not router paths.
84
+ */
85
+ route(url: string): RouterRouteResult$1 | null;
86
+ /**
87
+ * Constructs a URL/path from a path name and values.
88
+ * @param name The name of the path.
89
+ * @param values The values to expand the path with.
90
+ * @returns The URL/path, if the name exists. Otherwise, `null`.
91
+ * @deprecated Use `Router` from `@fedify/uri-template` instead.
92
+ */
93
+ build(name: string, values: Record<string, string>): string | null;
94
+ }
95
+ /**
96
+ * An error thrown by the {@link Router}.
97
+ * @deprecated Import `RouterError` from `@fedify/uri-template` instead.
98
+ */
99
+ declare class RouterError$1 extends RouterError {
100
+ /**
101
+ * Treats every `RouterError` from `@fedify/uri-template` as an instance of
102
+ * this deprecated class.
103
+ *
104
+ * @deprecated Import `RouterError` from `@fedify/uri-template` instead.
105
+ */
106
+ static override [Symbol.hasInstance](instance: unknown): boolean;
107
+ /**
108
+ * Create a new {@link RouterError}.
109
+ * @param message The error message.
110
+ * @deprecated Import `RouterError` from `@fedify/uri-template` instead.
111
+ */
112
+ constructor(message: string);
113
+ }
114
+ //#endregion
115
+ //#region src/federation/webfinger.d.ts
116
+ /**
117
+ * Parameters for {@link handleWebFinger}.
118
+ */
119
+ interface WebFingerHandlerParameters<TContextData> {
120
+ /**
121
+ * The request context.
122
+ */
123
+ context: RequestContext<TContextData>;
124
+ /**
125
+ * The canonical hostname of the server, if it's explicitly configured.
126
+ * @since 1.5.0
127
+ */
128
+ host?: string;
129
+ /**
130
+ * The callback for dispatching the actor.
131
+ */
132
+ actorDispatcher?: ActorDispatcher<TContextData>;
133
+ /**
134
+ * The callback for mapping a WebFinger username to the corresponding actor's
135
+ * internal identifier, or `null` if the username is not found.
136
+ * @since 0.15.0
137
+ */
138
+ actorHandleMapper?: ActorHandleMapper<TContextData>;
139
+ /**
140
+ * The callback for mapping a WebFinger query to the corresponding actor's
141
+ * internal identifier or username, or `null` if the query is not found.
142
+ * @since 1.4.0
143
+ */
144
+ actorAliasMapper?: ActorAliasMapper<TContextData>;
145
+ /**
146
+ * The callback for dispatching the Links of webFinger.
147
+ */
148
+ webFingerLinksDispatcher?: WebFingerLinksDispatcher<TContextData>;
149
+ /**
150
+ * The function to call when the actor is not found.
151
+ */
152
+ onNotFound(request: Request): Response | Promise<Response>;
153
+ /**
154
+ * The OpenTelemetry tracer.
155
+ * @since 1.3.0
156
+ */
157
+ tracer?: Tracer;
158
+ /**
159
+ * The span for the request.
160
+ * @since 1.3.0
161
+ */
162
+ span?: Span;
163
+ }
164
+ /**
165
+ * Handles a WebFinger request. You would not typically call this function
166
+ * directly, but instead use {@link Federation.fetch} method.
167
+ * @param request The WebFinger request to handle.
168
+ * @param parameters The parameters for handling the request.
169
+ * @returns The response to the request.
170
+ */
171
+ declare function handleWebFinger<TContextData>(request: Request, options: WebFingerHandlerParameters<TContextData>): Promise<Response>;
172
+ //#endregion
173
+ export { RouterOptions$1 as a, RouterError$1 as i, handleWebFinger as n, RouterRouteResult$1 as o, Router as r, WebFingerHandlerParameters as t };