@fedify/fedify 2.3.0-dev.1119 → 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 (116) 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-Ond_h57y.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-cSUMk2da.d.ts → context-DCtsSHDv.d.ts} +4 -293
  15. package/dist/{context-Ch-ZLyTQ.d.cts → context-DI2gRbyN.d.cts} +3 -294
  16. package/dist/{context-BAE7AKLA.mjs → context-DVoTs_wM.mjs} +1 -1
  17. package/dist/{deno-DVsHS7rA.mjs → deno-B_9yJW3w.mjs} +1 -1
  18. package/dist/{docloader-WsWfKaE5.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 +231 -3
  27. package/dist/federation/middleware.test.mjs +88 -18
  28. package/dist/federation/mod.cjs +155 -3
  29. package/dist/federation/mod.d.cts +3 -2
  30. package/dist/federation/mod.d.ts +3 -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-CouJSFVK.js → http-CToqG5ap.js} +252 -20
  42. package/dist/{http-CubOB9wq.cjs → http-CWoeyogl.cjs} +263 -19
  43. package/dist/{http-DUV8ysti.mjs → http-Cyx5SNuu.mjs} +8 -6
  44. package/dist/{http-D6LP89UO.d.ts → http-VyDTd4G3.d.cts} +8 -1
  45. package/dist/{http-D6aw3j2U.d.cts → http-lf8Hsd91.d.ts} +8 -1
  46. package/dist/{key-BoWaYRHm.mjs → key-CkkMJBjF.mjs} +42 -17
  47. package/dist/{kv-cache-DBNpsneh.js → kv-cache-CuCn2xvM.js} +19 -2
  48. package/dist/{kv-cache-Dz31ATUT.cjs → kv-cache-DuEwFYcN.cjs} +19 -2
  49. package/dist/{kv-cache-DihufyAQ.mjs → kv-cache-VHFP42vY.mjs} +19 -1
  50. package/dist/{ld-B5K1mSuG.mjs → ld-k8yqD2a-.mjs} +3 -3
  51. package/dist/{metrics-C4attqv0.mjs → metrics-iRBg8jTk.mjs} +209 -2
  52. package/dist/{middleware-CmsDtIHI.cjs → middleware-BWLUrbS9.cjs} +137 -210
  53. package/dist/{middleware-BDKFRjue.mjs → middleware-CztxpARM.mjs} +1 -1
  54. package/dist/{middleware-Dtjz-hSk.js → middleware-D7FrhN9q.js} +101 -162
  55. package/dist/{middleware-t0jC8I99.mjs → middleware-DQEgdr83.mjs} +64 -36
  56. package/dist/{mod-BDhgfjP7.d.cts → mod-B0hW12_O.d.cts} +1 -1
  57. package/dist/mod-C504qevA.d.cts +173 -0
  58. package/dist/{mod-B-Lin9Sy.d.ts → mod-COIAjwRS.d.ts} +1 -1
  59. package/dist/{mod-DLrRb0dx.d.ts → mod-DFvNJcNb.d.ts} +54 -3
  60. package/dist/mod-wYfuXeDE.d.ts +173 -0
  61. package/dist/{mod-BR_BB0bh.d.cts → mod-yvIXFAEi.d.cts} +54 -3
  62. package/dist/mod.cjs +6 -6
  63. package/dist/mod.d.cts +6 -5
  64. package/dist/mod.d.ts +6 -5
  65. package/dist/mod.js +5 -5
  66. package/dist/mq-D-nlpY04.d.ts +208 -0
  67. package/dist/mq-D8uSFzxe.d.cts +208 -0
  68. package/dist/nodeinfo/client.test.mjs +4 -4
  69. package/dist/nodeinfo/handler.test.mjs +5 -5
  70. package/dist/nodeinfo/types.test.mjs +4 -4
  71. package/dist/otel/exporter.test.mjs +3 -3
  72. package/dist/{outgoing-jsonld-BNL8AC14.mjs → outgoing-jsonld-BgFLCJQ_.mjs} +1 -1
  73. package/dist/{owner-hDxI0ufu.mjs → owner-nmXdvXpc.mjs} +2 -2
  74. package/dist/{proof-BUWfVr6Q.cjs → proof-CcsIJLTn.cjs} +1 -1
  75. package/dist/{proof-DhVuz4bc.mjs → proof-DpwO1T4S.mjs} +5 -5
  76. package/dist/{proof-n60t8o9P.js → proof-NRmtrTDu.js} +1 -1
  77. package/dist/{send-BPhyR5Oo.mjs → send-DvX2tYyZ.mjs} +3 -3
  78. package/dist/sig/accept.test.mjs +1 -1
  79. package/dist/sig/http.test.mjs +13 -9
  80. package/dist/sig/key.test.mjs +104 -7
  81. package/dist/sig/ld.test.mjs +7 -7
  82. package/dist/sig/mod.cjs +2 -2
  83. package/dist/sig/mod.d.cts +2 -2
  84. package/dist/sig/mod.d.ts +2 -2
  85. package/dist/sig/mod.js +2 -2
  86. package/dist/sig/owner.test.mjs +6 -6
  87. package/dist/sig/proof.test.mjs +8 -8
  88. package/dist/{std__assert-BTEgfoJo.mjs → std__assert-BBjXFNOb.mjs} +4 -4
  89. package/dist/testing/mod.d.mts +1 -0
  90. package/dist/testing/mod.mjs +1 -1
  91. package/dist/utils/docloader.test.mjs +7 -7
  92. package/dist/utils/kv-cache.test.mjs +67 -2
  93. package/dist/utils/mod.cjs +1 -1
  94. package/dist/utils/mod.d.cts +1 -1
  95. package/dist/utils/mod.d.ts +1 -1
  96. package/dist/utils/mod.js +1 -1
  97. package/package.json +6 -7
  98. package/dist/mod-C6E8rkcz.d.ts +0 -63
  99. package/dist/mod-P9tE2WmM.d.cts +0 -63
  100. package/dist/router-BT_F5748.mjs +0 -114
  101. /package/dist/{accept-CgDcxvjV.mjs → accept-CceiKpCy.mjs} +0 -0
  102. /package/dist/{activity-listener-BeTGV3wc.mjs → activity-listener-tztVvlNb.mjs} +0 -0
  103. /package/dist/{assert_equals-Ew3jOFa3.mjs → assert_equals-C-ZRDbaf.mjs} +0 -0
  104. /package/dist/{client-Bneh_DYR.mjs → client-B_A6mfn3.mjs} +0 -0
  105. /package/dist/{collection-Cc3DVAhE.mjs → collection-CA3V5zyK.mjs} +0 -0
  106. /package/dist/{esm-sdtqOUPu.mjs → esm-BQRw925N.mjs} +0 -0
  107. /package/dist/{execAsync-Dxb7rNf3.mjs → execAsync-DCBrgFiV.mjs} +0 -0
  108. /package/dist/{getMachineId-linux-Bbhofx-s.mjs → getMachineId-linux-ObI47Hql.mjs} +0 -0
  109. /package/dist/{getMachineId-unsupported-dIOte2Ct.mjs → getMachineId-unsupported-Ddu-PFeh.mjs} +0 -0
  110. /package/dist/{keycache-BeU0LCII.mjs → keycache-BYMd8q7F.mjs} +0 -0
  111. /package/dist/{keys-CSYsOMFG.mjs → keys-C3kae-6B.mjs} +0 -0
  112. /package/dist/{kv-QHE0oeM3.mjs → kv-x2IvBUyq.mjs} +0 -0
  113. /package/dist/{negotiation-DDstyBvc.mjs → negotiation-CDW-_gUU.mjs} +0 -0
  114. /package/dist/{public-audience-c9zmYKgA.mjs → public-audience-N3pyOx2p.mjs} +0 -0
  115. /package/dist/{retry-_VvV0h9f.mjs → retry-v_sGLH1d.mjs} +0 -0
  116. /package/dist/{types-D09GN0uZ.mjs → types-BFowWFTT.mjs} +0 -0
package/README.md CHANGED
@@ -123,6 +123,7 @@ Here is the list of packages:
123
123
  | [@fedify/sqlite](/packages/sqlite/) | [JSR][jsr:@fedify/sqlite] | [npm][npm:@fedify/sqlite] | SQLite driver |
124
124
  | [@fedify/sveltekit](/packages/sveltekit/) | [JSR][jsr:@fedify/sveltekit] | [npm][npm:@fedify/sveltekit] | SvelteKit integration |
125
125
  | [@fedify/testing](/packages/testing/) | [JSR][jsr:@fedify/testing] | [npm][npm:@fedify/testing] | Testing utilities |
126
+ | [@fedify/uri-template](/packages/uri-template/) | [JSR][jsr:@fedify/uri-template] | [npm][npm:@fedify/uri-template] | RFC 6570 URI Template library |
126
127
  | [@fedify/vocab](/packages/vocab/) | [JSR][jsr:@fedify/vocab] | [npm][npm:@fedify/vocab] | Activity Vocabulary library |
127
128
  | [@fedify/vocab-runtime](/packages/vocab-runtime/) | [JSR][jsr:@fedify/vocab-runtime] | [npm][npm:@fedify/vocab-runtime] | Runtime library for code-generated vocab |
128
129
  | [@fedify/vocab-tools](/packages/vocab-tools/) | [JSR][jsr:@fedify/vocab-tools] | [npm][npm:@fedify/vocab-tools] | Code generation tools for Activity Vocab |
@@ -176,6 +177,8 @@ Here is the list of packages:
176
177
  [npm:@fedify/sveltekit]: https://www.npmjs.com/package/@fedify/sveltekit
177
178
  [jsr:@fedify/testing]: https://jsr.io/@fedify/testing
178
179
  [npm:@fedify/testing]: https://www.npmjs.com/package/@fedify/testing
180
+ [jsr:@fedify/uri-template]: https://jsr.io/@fedify/uri-template
181
+ [npm:@fedify/uri-template]: https://www.npmjs.com/package/@fedify/uri-template
179
182
  [jsr:@fedify/vocab]: https://jsr.io/@fedify/vocab
180
183
  [npm:@fedify/vocab]: https://www.npmjs.com/package/@fedify/vocab
181
184
  [jsr:@fedify/vocab-runtime]: https://jsr.io/@fedify/vocab-runtime
@@ -1,7 +1,7 @@
1
1
  import "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { l as AssertionError } from "./assert_equals-Ew3jOFa3.mjs";
4
+ import { l as AssertionError } from "./assert_equals-C-ZRDbaf.mjs";
5
5
  //#region ../../node_modules/.pnpm/@jsr+std__assert@0.226.0/node_modules/@jsr/std__assert/assert.js
6
6
  /**
7
7
  * Make an assertion, error will be thrown if `expr` does not have truthy value.
@@ -1,7 +1,7 @@
1
1
  import "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { l as AssertionError } from "./assert_equals-Ew3jOFa3.mjs";
4
+ import { l as AssertionError } from "./assert_equals-C-ZRDbaf.mjs";
5
5
  //#region ../../node_modules/.pnpm/@jsr+std__assert@0.226.0/node_modules/@jsr/std__assert/assert_instance_of.js
6
6
  /**
7
7
  * Make an assertion that `obj` is an instance of `type`.
@@ -1,7 +1,7 @@
1
1
  import "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { c as equal, l as AssertionError } from "./assert_equals-Ew3jOFa3.mjs";
4
+ import { c as equal, l as AssertionError } from "./assert_equals-C-ZRDbaf.mjs";
5
5
  //#region ../../node_modules/.pnpm/@jsr+std__assert@0.226.0/node_modules/@jsr/std__assert/assert_not_equals.js
6
6
  /**
7
7
  * Make an assertion that `actual` and `expected` are not equal, deeply.
@@ -1,8 +1,8 @@
1
1
  import "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { l as AssertionError, s as format } from "./assert_equals-Ew3jOFa3.mjs";
5
- import { n as assertIsError } from "./assert_throws-4NwKEy2q.mjs";
4
+ import { l as AssertionError, s as format } from "./assert_equals-C-ZRDbaf.mjs";
5
+ import { n as assertIsError } from "./assert_throws-BOkhLGYc.mjs";
6
6
  //#region ../../node_modules/.pnpm/@jsr+std__assert@0.226.0/node_modules/@jsr/std__assert/assert_false.js
7
7
  /**
8
8
  * Make an assertion, error will be thrown if `expr` have truthy value.
@@ -1,7 +1,7 @@
1
1
  import "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { a as red, i as buildMessage, l as AssertionError, n as diffStr, r as diff, s as format } from "./assert_equals-Ew3jOFa3.mjs";
4
+ import { a as red, i as buildMessage, l as AssertionError, n as diffStr, r as diff, s as format } from "./assert_equals-C-ZRDbaf.mjs";
5
5
  //#region ../../node_modules/.pnpm/@jsr+std__assert@0.226.0/node_modules/@jsr/std__assert/assert_strict_equals.js
6
6
  /**
7
7
  * Make an assertion that `actual` and `expected` are equal using
@@ -1,7 +1,7 @@
1
1
  import "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { l as AssertionError, o as stripAnsiCode } from "./assert_equals-Ew3jOFa3.mjs";
4
+ import { l as AssertionError, o as stripAnsiCode } from "./assert_equals-C-ZRDbaf.mjs";
5
5
  //#region ../../node_modules/.pnpm/@jsr+std__assert@0.226.0/node_modules/@jsr/std__assert/assert_is_error.js
6
6
  /**
7
7
  * Make an assertion that `error` is an `Error`.
@@ -1,25 +1,39 @@
1
1
  import "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as RouterError, t as Router } from "./router-BT_F5748.mjs";
5
- import { n as version, t as name } from "./deno-DVsHS7rA.mjs";
6
- import { t as ActivityListenerSet } from "./activity-listener-BeTGV3wc.mjs";
4
+ import { n as version, t as name } from "./deno-B_9yJW3w.mjs";
5
+ import { t as ActivityListenerSet } from "./activity-listener-tztVvlNb.mjs";
7
6
  import { getLogger } from "@logtape/logtape";
7
+ import { Router, RouterError, assertPath } from "@fedify/uri-template";
8
8
  import { Tombstone, getTypeId } from "@fedify/vocab";
9
9
  import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
10
10
  //#region src/federation/builder.ts
11
11
  const ACTOR_ALIAS_PREFIX = "actorAlias:";
12
- function validateSingleIdentifierVariablePath(path, errorMessage) {
13
- const operatorMatches = globalThis.Array.from(path.matchAll(/{([+#./;?&]?)([A-Za-z_][A-Za-z0-9_]*)}/g));
14
- if (operatorMatches.length !== 1 || operatorMatches[0]?.[2] !== "identifier") throw new RouterError(errorMessage);
15
- if (operatorMatches.some((match) => [
16
- "?",
17
- "&",
18
- "#"
19
- ].includes(match[1]) && match[2] === "identifier")) throw new RouterError(errorMessage);
20
- const variables = new Router().add(path, "outbox");
21
- if (variables.size !== 1 || !variables.has("identifier")) throw new RouterError(errorMessage);
22
- }
12
+ /**
13
+ * Route options shared by every dispatcher whose path must expose exactly
14
+ * one `{identifier}` variable bound to a single, non-empty value
15
+ * for `setOutboxDispatcher/Listener()`.
16
+ */
17
+ const identifierSingular = {
18
+ exact: true,
19
+ variables: { identifier: { operatables: [""] } }
20
+ };
21
+ /**
22
+ * Route options shared by every dispatcher whose path must expose
23
+ * `{identifier}` and `{+identifier}` variables bound to the same single,
24
+ * non-empty value for following setters:
25
+ * - `setActorDispatcher()` (actor path)
26
+ * - `setInboxDispatcher/Listener()` (inbox path)
27
+ * - `setFollowingDispatcher()` (following path)
28
+ * - `setFollowersDispatcher()` (followers path)
29
+ * - `setLikedDispatcher()` (liked path)
30
+ * - `setFeaturedDispatcher()` (featured path)
31
+ * - `setFeaturedTagsDispatcher()` (featured tags path)
32
+ */
33
+ const identifierSingularAllowPlus = {
34
+ exact: true,
35
+ variables: { identifier: { operatables: ["", "+"] } }
36
+ };
23
37
  var FederationBuilderImpl = class {
24
38
  router;
25
39
  actorCallbacks;
@@ -59,7 +73,7 @@ var FederationBuilderImpl = class {
59
73
  this.collectionTypeIds = {};
60
74
  }
61
75
  async build(options) {
62
- const { FederationImpl } = await import("./middleware-BDKFRjue.mjs");
76
+ const { FederationImpl } = await import("./middleware-CztxpARM.mjs");
63
77
  const f = new FederationImpl(options);
64
78
  const trailingSlashInsensitiveValue = f.router.trailingSlashInsensitive;
65
79
  f.router = this.router.clone();
@@ -95,8 +109,8 @@ var FederationBuilderImpl = class {
95
109
  }
96
110
  setActorDispatcher(path, dispatcher) {
97
111
  if (this.router.has("actor")) throw new RouterError("Actor dispatcher already set.");
98
- const variables = this.router.add(path, "actor");
99
- if (variables.size !== 1 || !variables.has("identifier")) throw new RouterError("Path for actor dispatcher must have one variable: {identifier}");
112
+ assertPath(path);
113
+ this.router.add(path, "actor", identifierSingularAllowPlus);
100
114
  const callbacks = { dispatcher: async (context, identifier) => {
101
115
  const actor = await this._getTracer().startActiveSpan("activitypub.dispatch_actor", {
102
116
  kind: SpanKind.SERVER,
@@ -198,7 +212,7 @@ var FederationBuilderImpl = class {
198
212
  mapActorAlias: (path, identifier) => {
199
213
  if (identifier === "") throw new RouterError("Identifier cannot be empty.");
200
214
  if (this.router.has(`actorAlias:${identifier}`)) throw new RouterError(`Actor alias for "${identifier}" already set.`);
201
- if (new Router().add(path, "temp").size > 0) throw new RouterError("Path for actor alias must have no variables.");
215
+ if (Router.variables(path).size > 0) throw new RouterError("Path for actor alias must have no variables.");
202
216
  const existingRoute = this.router.route(path);
203
217
  if (existingRoute != null) throw new RouterError(`Actor alias path "${path}" conflicts with existing route "${existingRoute.name}".`);
204
218
  this.router.add(path, `${ACTOR_ALIAS_PREFIX}${identifier}`);
@@ -213,7 +227,8 @@ var FederationBuilderImpl = class {
213
227
  }
214
228
  setNodeInfoDispatcher(path, dispatcher) {
215
229
  if (this.router.has("nodeInfo")) throw new RouterError("NodeInfo dispatcher already set.");
216
- if (this.router.add(path, "nodeInfo").size !== 0) throw new RouterError("Path for NodeInfo dispatcher must have no variables.");
230
+ if (Router.variables(path).size !== 0) throw new RouterError("Path for NodeInfo dispatcher must have no variables.");
231
+ this.router.add(path, "nodeInfo");
217
232
  this.nodeInfoDispatcher = dispatcher;
218
233
  }
219
234
  setWebFingerLinksDispatcher(dispatcher) {
@@ -222,8 +237,9 @@ var FederationBuilderImpl = class {
222
237
  setObjectDispatcher(cls, path, dispatcher) {
223
238
  const routeName = `object:${cls.typeId.href}`;
224
239
  if (this.router.has(routeName)) throw new RouterError(`Object dispatcher for ${cls.name} already set.`);
225
- const variables = this.router.add(path, routeName);
226
- if (variables.size < 1) throw new RouterError("Path for object dispatcher must have at least one variable.");
240
+ assertPath(path);
241
+ const variables = Router.variables(path);
242
+ this.router.add(path, routeName);
227
243
  const callbacks = {
228
244
  dispatcher: (ctx, values) => {
229
245
  return this._getTracer().startActiveSpan("activitypub.dispatch_object", {
@@ -265,8 +281,8 @@ var FederationBuilderImpl = class {
265
281
  if (this.router.has("inbox")) {
266
282
  if (this.inboxPath !== path) throw new RouterError("Inbox dispatcher path must match inbox listener path.");
267
283
  } else {
268
- const variables = this.router.add(path, "inbox");
269
- if (variables.size !== 1 || !variables.has("identifier")) throw new RouterError("Path for inbox dispatcher must have one variable: {identifier}");
284
+ assertPath(path);
285
+ this.router.add(path, "inbox", identifierSingularAllowPlus);
270
286
  this.inboxPath = path;
271
287
  }
272
288
  const callbacks = { dispatcher };
@@ -296,8 +312,8 @@ var FederationBuilderImpl = class {
296
312
  if (this.router.has("outbox")) {
297
313
  if (this.outboxPath !== path) throw new RouterError("Outbox dispatcher path must match outbox listener path.");
298
314
  } else {
299
- validateSingleIdentifierVariablePath(path, "Path for outbox dispatcher must have one variable: {identifier}");
300
- this.router.add(path, "outbox");
315
+ assertPath(path);
316
+ this.router.add(path, "outbox", identifierSingular);
301
317
  this.outboxPath = path;
302
318
  }
303
319
  const callbacks = { dispatcher };
@@ -327,8 +343,8 @@ var FederationBuilderImpl = class {
327
343
  if (this.router.has("outbox")) {
328
344
  if (this.outboxPath !== outboxPath) throw new RouterError("Outbox listener path must match outbox dispatcher path.");
329
345
  } else {
330
- validateSingleIdentifierVariablePath(outboxPath, "Path for outbox must have one variable: {identifier}");
331
- this.router.add(outboxPath, "outbox");
346
+ assertPath(outboxPath);
347
+ this.router.add(outboxPath, "outbox", identifierSingular);
332
348
  this.outboxPath = outboxPath;
333
349
  }
334
350
  const listeners = this.outboxListeners = new ActivityListenerSet();
@@ -350,8 +366,8 @@ var FederationBuilderImpl = class {
350
366
  }
351
367
  setFollowingDispatcher(path, dispatcher) {
352
368
  if (this.router.has("following")) throw new RouterError("Following collection dispatcher already set.");
353
- const variables = this.router.add(path, "following");
354
- if (variables.size !== 1 || !variables.has("identifier")) throw new RouterError("Path for following collection dispatcher must have one variable: {identifier}");
369
+ assertPath(path);
370
+ this.router.add(path, "following", identifierSingularAllowPlus);
355
371
  const callbacks = { dispatcher };
356
372
  this.followingCallbacks = callbacks;
357
373
  const setters = {
@@ -376,8 +392,8 @@ var FederationBuilderImpl = class {
376
392
  }
377
393
  setFollowersDispatcher(path, dispatcher) {
378
394
  if (this.router.has("followers")) throw new RouterError("Followers collection dispatcher already set.");
379
- const variables = this.router.add(path, "followers");
380
- if (variables.size !== 1 || !variables.has("identifier")) throw new RouterError("Path for followers collection dispatcher must have one variable: {identifier}");
395
+ assertPath(path);
396
+ this.router.add(path, "followers", identifierSingularAllowPlus);
381
397
  const callbacks = { dispatcher };
382
398
  this.followersCallbacks = callbacks;
383
399
  const setters = {
@@ -402,8 +418,8 @@ var FederationBuilderImpl = class {
402
418
  }
403
419
  setLikedDispatcher(path, dispatcher) {
404
420
  if (this.router.has("liked")) throw new RouterError("Liked collection dispatcher already set.");
405
- const variables = this.router.add(path, "liked");
406
- if (variables.size !== 1 || !variables.has("identifier")) throw new RouterError("Path for liked collection dispatcher must have one variable: {identifier}");
421
+ assertPath(path);
422
+ this.router.add(path, "liked", identifierSingularAllowPlus);
407
423
  const callbacks = { dispatcher };
408
424
  this.likedCallbacks = callbacks;
409
425
  const setters = {
@@ -428,8 +444,8 @@ var FederationBuilderImpl = class {
428
444
  }
429
445
  setFeaturedDispatcher(path, dispatcher) {
430
446
  if (this.router.has("featured")) throw new RouterError("Featured collection dispatcher already set.");
431
- const variables = this.router.add(path, "featured");
432
- if (variables.size !== 1 || !variables.has("identifier")) throw new RouterError("Path for featured collection dispatcher must have one variable: {identifier}");
447
+ assertPath(path);
448
+ this.router.add(path, "featured", identifierSingularAllowPlus);
433
449
  const callbacks = { dispatcher };
434
450
  this.featuredCallbacks = callbacks;
435
451
  const setters = {
@@ -454,8 +470,8 @@ var FederationBuilderImpl = class {
454
470
  }
455
471
  setFeaturedTagsDispatcher(path, dispatcher) {
456
472
  if (this.router.has("featuredTags")) throw new RouterError("Featured tags collection dispatcher already set.");
457
- const variables = this.router.add(path, "featuredTags");
458
- if (variables.size !== 1 || !variables.has("identifier")) throw new RouterError("Path for featured tags collection dispatcher must have one variable: {identifier}");
473
+ assertPath(path);
474
+ this.router.add(path, "featuredTags", identifierSingularAllowPlus);
459
475
  const callbacks = { dispatcher };
460
476
  this.featuredTagsCallbacks = callbacks;
461
477
  const setters = {
@@ -483,12 +499,13 @@ var FederationBuilderImpl = class {
483
499
  if (this.router.has("inbox")) {
484
500
  if (this.inboxPath !== inboxPath) throw new RouterError("Inbox listener path must match inbox dispatcher path.");
485
501
  } else {
486
- const variables = this.router.add(inboxPath, "inbox");
487
- if (variables.size !== 1 || !variables.has("identifier")) throw new RouterError("Path for inbox must have one variable: {identifier}");
502
+ assertPath(inboxPath);
503
+ this.router.add(inboxPath, "inbox", identifierSingularAllowPlus);
488
504
  this.inboxPath = inboxPath;
489
505
  }
490
506
  if (sharedInboxPath != null) {
491
- if (this.router.add(sharedInboxPath, "sharedInbox").size !== 0) throw new RouterError("Path for shared inbox must have no variables.");
507
+ if (Router.variables(sharedInboxPath).size !== 0) throw new RouterError("Path for shared inbox must have no variables.");
508
+ this.router.add(sharedInboxPath, "sharedInbox");
492
509
  }
493
510
  const listeners = this.inboxListeners = new ActivityListenerSet();
494
511
  const setters = {
@@ -526,7 +543,9 @@ var FederationBuilderImpl = class {
526
543
  const routeName = `${collectionType}:${this.#uniqueCollectionId(name)}`;
527
544
  if (this.router.has(routeName)) throw new RouterError(`Collection dispatcher for ${strName} already set.`);
528
545
  if (this.collectionCallbacks[name] != null) throw new RouterError(`Collection dispatcher for ${strName} already set.`);
529
- if (this.router.add(path, routeName).size < 1) throw new RouterError("Path for collection dispatcher must have at least one variable.");
546
+ assertPath(path);
547
+ if (Router.variables(path).size < 1) throw new RouterError("Path for collection dispatcher must have at least one variable.");
548
+ this.router.add(path, routeName);
530
549
  const callbacks = { dispatcher };
531
550
  this.collectionCallbacks[name] = callbacks;
532
551
  this.collectionTypeIds[name] = itemType;
@@ -1,5 +1,5 @@
1
1
  /// <reference lib="esnext.temporal" />
2
- import { kt as ActivityTransformer, n as Context } from "../context-Ch-ZLyTQ.cjs";
2
+ import { n as Context, vt as ActivityTransformer } from "../context-DI2gRbyN.cjs";
3
3
  import { Activity } from "@fedify/vocab";
4
4
 
5
5
  //#region src/compat/transformers.d.ts
@@ -1,5 +1,5 @@
1
1
  /// <reference lib="esnext.temporal" />
2
- import { kt as ActivityTransformer, n as Context } from "../context-cSUMk2da.js";
2
+ import { n as Context, vt as ActivityTransformer } from "../context-DCtsSHDv.js";
3
3
  import { Activity } from "@fedify/vocab";
4
4
 
5
5
  //#region src/compat/transformers.d.ts
@@ -1,9 +1,9 @@
1
1
  import "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
5
- import { t as assertStrictEquals } from "../assert_strict_equals-Dmjbg-bA.mjs";
6
- import { n as normalizeAttachmentArrays, r as normalizeOutgoingActivityJsonLd, t as isPreloadedContextAttachmentSafe } from "../outgoing-jsonld-BNL8AC14.mjs";
4
+ import { t as assertEquals } from "../assert_equals-C-ZRDbaf.mjs";
5
+ import { t as assertStrictEquals } from "../assert_strict_equals-XEgZAlrj.mjs";
6
+ import { n as normalizeAttachmentArrays, r as normalizeOutgoingActivityJsonLd, t as isPreloadedContextAttachmentSafe } from "../outgoing-jsonld-BgFLCJQ_.mjs";
7
7
  import { Create, Document, Note, PUBLIC_COLLECTION } from "@fedify/vocab";
8
8
  import { mockDocumentLoader, test } from "@fedify/fixture";
9
9
  //#region src/compat/outgoing-jsonld.test.ts
@@ -1,9 +1,9 @@
1
1
  import "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
5
- import { t as assertNotEquals } from "../assert_not_equals--wG9hV7u.mjs";
6
- import { t as normalizePublicAudience } from "../public-audience-c9zmYKgA.mjs";
4
+ import { t as assertEquals } from "../assert_equals-C-ZRDbaf.mjs";
5
+ import { t as assertNotEquals } from "../assert_not_equals-DkVK8oqV.mjs";
6
+ import { t as normalizePublicAudience } from "../public-audience-N3pyOx2p.mjs";
7
7
  import { Create, Note, PUBLIC_COLLECTION } from "@fedify/vocab";
8
8
  import { test } from "@fedify/fixture";
9
9
  import { getDocumentLoader, preloadedContexts } from "@fedify/vocab-runtime";
@@ -1,11 +1,11 @@
1
1
  import "@js-temporal/polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
5
- import { t as assertInstanceOf } from "../assert_instance_of-C4Ri6VuN.mjs";
6
- import { t as assert } from "../assert-DikXweDx.mjs";
7
- import { t as MemoryKvStore } from "../kv-QHE0oeM3.mjs";
8
- import { n as FederationImpl, v as actorDehydrator, y as autoIdAssigner } from "../middleware-t0jC8I99.mjs";
4
+ import { t as assertEquals } from "../assert_equals-C-ZRDbaf.mjs";
5
+ import { t as assertInstanceOf } from "../assert_instance_of-DBC5X09g.mjs";
6
+ import { t as assert } from "../assert-OguE97r2.mjs";
7
+ import { t as MemoryKvStore } from "../kv-x2IvBUyq.mjs";
8
+ import { n as FederationImpl, v as actorDehydrator, y as autoIdAssigner } from "../middleware-DQEgdr83.mjs";
9
9
  import { Follow, Person } from "@fedify/vocab";
10
10
  import { test } from "@fedify/fixture";
11
11
  //#region src/compat/transformers.test.ts