@fedify/fedify 1.8.1-pr.315.1091 → 1.8.1-pr.315.1275

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 (203) hide show
  1. package/README.md +16 -10
  2. package/dist/{actor-C_d9cZrz.js → actor-B9oI1pGu.js} +2 -5
  3. package/dist/{actor-1rvS-py8.d.ts → actor-CYyhXZHp.d.ts} +3 -3
  4. package/dist/{actor-DLZ25ttS.js → actor-Cg2FBINf.js} +189 -189
  5. package/dist/{assert-DwEa6glZ.js → assert-MZs1qjMx.js} +2 -2
  6. package/dist/{assert_equals-C5gKCm6A.js → assert_equals-DSbWqCm3.js} +9 -9
  7. package/dist/{assert_instance_of-C9QtN-X9.js → assert_instance_of-DHz7EHNU.js} +2 -2
  8. package/dist/{assert_is_error-DQdKoRgb.js → assert_is_error-BPGph1Jx.js} +2 -2
  9. package/dist/{assert_not_equals-7pyUM3Ib.js → assert_not_equals-f3m3epl3.js} +2 -2
  10. package/dist/{assert_rejects-DceVjUlD.js → assert_rejects-DiIiJbZn.js} +4 -4
  11. package/dist/{assert_throws-DTDC_gwN.js → assert_throws-BOO88avQ.js} +3 -3
  12. package/dist/{authdocloader-CLixqGPW.js → authdocloader-0urt38S6.js} +4 -4
  13. package/dist/{authdocloader-DUnUXs5R.js → authdocloader-BkwhwBf_.js} +4 -5
  14. package/dist/{builder-Js_TKEl1.js → builder-B-wZuoFJ.js} +75 -6
  15. package/dist/{client-DK4qnXK0.d.ts → client-B_KFjN3D.d.ts} +4 -4
  16. package/dist/{client-Cu9HMcIJ.js → client-Cr3DvU-q.js} +3 -3
  17. package/dist/{collection-Dfb0TPno.js → collection-CSzG2j1P.js} +1 -1
  18. package/dist/compat/mod.d.ts +12 -12
  19. package/dist/compat/mod.js +1 -1
  20. package/dist/compat/transformers.test.js +25 -32
  21. package/dist/{context-BhO5LP_t.d.ts → context-BRl3Ndz3.d.ts} +286 -73
  22. package/dist/{denokv-QWKsIqML.js → denokv-2x6-IpXO.js} +1 -1
  23. package/dist/{docloader-BindvZ7y.js → docloader-BLgRerm3.js} +41 -40
  24. package/dist/{docloader-DtGccyuM.d.ts → docloader-DJT1UZH4.d.ts} +5 -2
  25. package/dist/{esm-d-9EVGaP.js → esm-CRotYXVH.js} +15 -15
  26. package/dist/federation/builder.test.js +35 -21
  27. package/dist/federation/collection.test.js +13 -11
  28. package/dist/federation/handler.test.js +341 -40
  29. package/dist/federation/inbox.test.js +8 -12
  30. package/dist/federation/keycache.test.js +9 -12
  31. package/dist/federation/kv.test.js +13 -11
  32. package/dist/federation/middleware.test.js +65 -42
  33. package/dist/federation/mod.d.ts +12 -12
  34. package/dist/federation/mod.js +12 -12
  35. package/dist/federation/mq.test.js +15 -13
  36. package/dist/federation/retry.test.js +7 -5
  37. package/dist/federation/router.test.js +12 -11
  38. package/dist/federation/send.test.js +19 -25
  39. package/dist/{federation-C44ekWNP.js → federation-CMX7WzeL.js} +2 -2
  40. package/dist/{http-BigTqmE7.js → http-BkzChfDi.js} +5 -5
  41. package/dist/{http-Cp-0z2Ja.d.ts → http-CMfQwn0N.d.ts} +6 -6
  42. package/dist/{http-DIyD7he1.js → http-g01-ecph.js} +6 -5
  43. package/dist/{inbox-BB6ajp8P.js → inbox-CpONbSbQ.js} +2 -4
  44. package/dist/{key-D9LuuzMv.js → key-B9Yg9Nqz.js} +4 -5
  45. package/dist/{key-BfI9Ju0m.js → key-C3aLobhY.js} +4 -4
  46. package/dist/{key-DlkWX5Fp.js → key-DdT7xoLD.js} +4 -4
  47. package/dist/key-RnJPgo1m.js +10 -0
  48. package/dist/{keycache-C4C7f09E.js → keycache-BvyhLLHV.js} +2 -2
  49. package/dist/{keys-BjET3ZIs.js → keys-BRSTnUlp.js} +2 -2
  50. package/dist/{kv-DDdb1hMa.d.ts → kv-C7sopW2E.d.ts} +2 -2
  51. package/dist/{kv-D7Yt6pnB.js → kv-CRZrzyXm.js} +1 -1
  52. package/dist/{ld-CYqXYuyr.js → ld-i6KANj32.js} +3 -5
  53. package/dist/{lookup-BYiP0j0F.js → lookup-BGA_VdZm.js} +115 -8
  54. package/dist/{lookup-_XgQq_BY.js → lookup-D5NvwwsS.js} +2 -2
  55. package/dist/{lookup-m3U6KA0u.d.ts → lookup-DXPWo3Hz.d.ts} +3 -3
  56. package/dist/{middleware-e74I4DJ9.js → middleware-BdFHk7bB.js} +629 -24
  57. package/dist/{middleware-VSdfWI3m.js → middleware-Chh21-S_.js} +563 -32
  58. package/dist/middleware-DEwSbDYQ.js +26 -0
  59. package/dist/middleware-DyY-_2Np.js +17 -0
  60. package/dist/{mod-c1I-Ydch.d.ts → mod-Cozftwmt.d.ts} +4 -4
  61. package/dist/{mod-yPzXIjJX.d.ts → mod-DHoWcUrW.d.ts} +6 -6
  62. package/dist/{mod-nlVEnYuj.d.ts → mod-DyY7EVjn.d.ts} +6 -6
  63. package/dist/{mod-BqCBztub.d.ts → mod-DyvbAsBu.d.ts} +6 -6
  64. package/dist/mod.d.ts +15 -15
  65. package/dist/mod.js +12 -12
  66. package/dist/{mq-DYKDDJmp.d.ts → mq-CRGm1e_F.d.ts} +1 -1
  67. package/dist/nodeinfo/client.test.js +15 -15
  68. package/dist/nodeinfo/handler.test.js +30 -39
  69. package/dist/nodeinfo/mod.d.ts +3 -3
  70. package/dist/nodeinfo/mod.js +2 -2
  71. package/dist/nodeinfo/semver.test.js +13 -11
  72. package/dist/nodeinfo/types.test.js +14 -12
  73. package/dist/{owner-BK4eWKBp.d.ts → owner-CfnEgfAc.d.ts} +4 -4
  74. package/dist/{owner-D7RvVquY.js → owner-DSr0c3Yp.js} +3 -4
  75. package/dist/{proof-D4z1cLgw.js → proof-B83O-qBN.js} +4 -6
  76. package/dist/{proof-ChRSmA_D.js → proof-a4fXDkG3.js} +7 -7
  77. package/dist/{retry-BiIhZWgD.js → retry-D4GJ670a.js} +1 -1
  78. package/dist/runtime/authdocloader.test.js +18 -24
  79. package/dist/runtime/docloader.test.js +14 -15
  80. package/dist/runtime/key.test.js +14 -19
  81. package/dist/runtime/langstr.test.js +12 -11
  82. package/dist/runtime/mod.d.ts +5 -5
  83. package/dist/runtime/mod.js +6 -6
  84. package/dist/runtime/multibase/multibase.test.js +12 -11
  85. package/dist/runtime/url.test.js +8 -7
  86. package/dist/{semver-DWClQt_5.js → semver-dArNLkR9.js} +1 -1
  87. package/dist/{send-DmlRAY0X.js → send-QRloWueE.js} +3 -3
  88. package/dist/sig/http.test.js +40 -23
  89. package/dist/sig/key.test.js +15 -21
  90. package/dist/sig/ld.test.js +13 -19
  91. package/dist/sig/mod.d.ts +7 -7
  92. package/dist/sig/mod.js +6 -6
  93. package/dist/sig/owner.test.js +16 -23
  94. package/dist/sig/proof.test.js +16 -22
  95. package/dist/{std__assert-B3iAixc-.js → std__assert-X-_kMxKM.js} +6 -6
  96. package/dist/testing/docloader.test.js +12 -11
  97. package/dist/testing/mod.d.ts +8622 -2
  98. package/dist/testing/mod.js +4 -2
  99. package/dist/testing-A4u9tSVX.js +302 -0
  100. package/dist/{transformers-ghwJuzGY.js → transformers-Dna8Fg7k.js} +4 -4
  101. package/dist/{vocab-dw0HG0EQ.js → type-DHDlfpLg.js} +5246 -185
  102. package/dist/{types-C7C_l-jz.js → types-BIgY6c-l.js} +2 -2
  103. package/dist/{types-DuZ6KMHu.js → types-DbFIDnXK.js} +4 -4
  104. package/dist/vocab/actor.test.js +143 -149
  105. package/dist/vocab/lookup.test.js +13 -20
  106. package/dist/vocab/mod.d.ts +5 -5
  107. package/dist/vocab/mod.js +4 -4
  108. package/dist/vocab/type.test.js +5 -9
  109. package/dist/vocab/vocab.test.js +54 -58
  110. package/dist/{vocab-CI5oydJj.js → vocab-DN6Plgg2.js} +6 -6
  111. package/dist/{vocab-B52eQhpN.d.ts → vocab-KgaI50mH.d.ts} +3 -3
  112. package/dist/webfinger/handler.test.js +30 -39
  113. package/dist/webfinger/lookup.test.js +13 -14
  114. package/dist/webfinger/mod.d.ts +3 -3
  115. package/dist/webfinger/mod.js +2 -2
  116. package/dist/x/cfworkers.d.ts +3 -3
  117. package/dist/x/cfworkers.js +1 -1
  118. package/dist/x/cfworkers.test.js +13 -11
  119. package/dist/x/hono.d.ts +16 -16
  120. package/dist/x/hono.js +3 -3
  121. package/dist/x/sveltekit.d.ts +13 -13
  122. package/dist/x/sveltekit.js +2 -2
  123. package/package.json +3 -3
  124. package/dist/chunk-HsBuZ-b2.js +0 -41
  125. package/dist/context-CXi1nrZE.js +0 -108
  126. package/dist/docloader-Bh-sDknx.js +0 -68
  127. package/dist/docloader-CJ7eOrpZ.js +0 -4514
  128. package/dist/key-DG7lKWv0.js +0 -16
  129. package/dist/langstr-DbWheeIS.js +0 -33
  130. package/dist/lookup-CEbB0_t_.js +0 -133
  131. package/dist/middleware-Dd2mc8-e.js +0 -33
  132. package/dist/middleware-DjA978L0.js +0 -17
  133. package/dist/multibase-DeCHcK8L.js +0 -316
  134. package/dist/router-D3UybECj.js +0 -118
  135. package/dist/testing-BZ0dJ4qn.js +0 -143
  136. package/dist/type-D2s5lmbZ.js +0 -14
  137. package/dist/url-kTAI6_KP.js +0 -68
  138. /package/dist/{vocab → src/vocab}/accept.yaml +0 -0
  139. /package/dist/{vocab → src/vocab}/activity.yaml +0 -0
  140. /package/dist/{vocab → src/vocab}/add.yaml +0 -0
  141. /package/dist/{vocab → src/vocab}/announce.yaml +0 -0
  142. /package/dist/{vocab → src/vocab}/application.yaml +0 -0
  143. /package/dist/{vocab → src/vocab}/arrive.yaml +0 -0
  144. /package/dist/{vocab → src/vocab}/article.yaml +0 -0
  145. /package/dist/{vocab → src/vocab}/audio.yaml +0 -0
  146. /package/dist/{vocab → src/vocab}/block.yaml +0 -0
  147. /package/dist/{vocab → src/vocab}/chatmessage.yaml +0 -0
  148. /package/dist/{vocab → src/vocab}/collection.yaml +0 -0
  149. /package/dist/{vocab → src/vocab}/collectionpage.yaml +0 -0
  150. /package/dist/{vocab → src/vocab}/create.yaml +0 -0
  151. /package/dist/{vocab → src/vocab}/dataintegrityproof.yaml +0 -0
  152. /package/dist/{vocab → src/vocab}/delete.yaml +0 -0
  153. /package/dist/{vocab → src/vocab}/didservice.yaml +0 -0
  154. /package/dist/{vocab → src/vocab}/dislike.yaml +0 -0
  155. /package/dist/{vocab → src/vocab}/document.yaml +0 -0
  156. /package/dist/{vocab → src/vocab}/emoji.yaml +0 -0
  157. /package/dist/{vocab → src/vocab}/emojireact.yaml +0 -0
  158. /package/dist/{vocab → src/vocab}/endpoints.yaml +0 -0
  159. /package/dist/{vocab → src/vocab}/event.yaml +0 -0
  160. /package/dist/{vocab → src/vocab}/export.yaml +0 -0
  161. /package/dist/{vocab → src/vocab}/flag.yaml +0 -0
  162. /package/dist/{vocab → src/vocab}/follow.yaml +0 -0
  163. /package/dist/{vocab → src/vocab}/group.yaml +0 -0
  164. /package/dist/{vocab → src/vocab}/hashtag.yaml +0 -0
  165. /package/dist/{vocab → src/vocab}/ignore.yaml +0 -0
  166. /package/dist/{vocab → src/vocab}/image.yaml +0 -0
  167. /package/dist/{vocab → src/vocab}/intransitiveactivity.yaml +0 -0
  168. /package/dist/{vocab → src/vocab}/invite.yaml +0 -0
  169. /package/dist/{vocab → src/vocab}/join.yaml +0 -0
  170. /package/dist/{vocab → src/vocab}/key.yaml +0 -0
  171. /package/dist/{vocab → src/vocab}/leave.yaml +0 -0
  172. /package/dist/{vocab → src/vocab}/like.yaml +0 -0
  173. /package/dist/{vocab → src/vocab}/link.yaml +0 -0
  174. /package/dist/{vocab → src/vocab}/listen.yaml +0 -0
  175. /package/dist/{vocab → src/vocab}/mention.yaml +0 -0
  176. /package/dist/{vocab → src/vocab}/move.yaml +0 -0
  177. /package/dist/{vocab → src/vocab}/multikey.yaml +0 -0
  178. /package/dist/{vocab → src/vocab}/note.yaml +0 -0
  179. /package/dist/{vocab → src/vocab}/object.yaml +0 -0
  180. /package/dist/{vocab → src/vocab}/offer.yaml +0 -0
  181. /package/dist/{vocab → src/vocab}/orderedcollection.yaml +0 -0
  182. /package/dist/{vocab → src/vocab}/orderedcollectionpage.yaml +0 -0
  183. /package/dist/{vocab → src/vocab}/organization.yaml +0 -0
  184. /package/dist/{vocab → src/vocab}/page.yaml +0 -0
  185. /package/dist/{vocab → src/vocab}/person.yaml +0 -0
  186. /package/dist/{vocab → src/vocab}/place.yaml +0 -0
  187. /package/dist/{vocab → src/vocab}/profile.yaml +0 -0
  188. /package/dist/{vocab → src/vocab}/propertyvalue.yaml +0 -0
  189. /package/dist/{vocab → src/vocab}/question.yaml +0 -0
  190. /package/dist/{vocab → src/vocab}/read.yaml +0 -0
  191. /package/dist/{vocab → src/vocab}/reject.yaml +0 -0
  192. /package/dist/{vocab → src/vocab}/relationship.yaml +0 -0
  193. /package/dist/{vocab → src/vocab}/remove.yaml +0 -0
  194. /package/dist/{vocab → src/vocab}/service.yaml +0 -0
  195. /package/dist/{vocab → src/vocab}/source.yaml +0 -0
  196. /package/dist/{vocab → src/vocab}/tentativeaccept.yaml +0 -0
  197. /package/dist/{vocab → src/vocab}/tentativereject.yaml +0 -0
  198. /package/dist/{vocab → src/vocab}/tombstone.yaml +0 -0
  199. /package/dist/{vocab → src/vocab}/travel.yaml +0 -0
  200. /package/dist/{vocab → src/vocab}/undo.yaml +0 -0
  201. /package/dist/{vocab → src/vocab}/update.yaml +0 -0
  202. /package/dist/{vocab → src/vocab}/video.yaml +0 -0
  203. /package/dist/{vocab → src/vocab}/view.yaml +0 -0
@@ -3,32 +3,28 @@
3
3
  import { URLPattern } from "urlpattern-polyfill";
4
4
  globalThis.addEventListener = () => {};
5
5
 
6
- import { deno_default, getDocumentLoader, kvCache } from "./docloader-CJ7eOrpZ.js";
7
- import { getNodeInfo } from "./client-Cu9HMcIJ.js";
8
- import { RouterError } from "./router-D3UybECj.js";
9
- import { nodeInfoToJson } from "./types-C7C_l-jz.js";
10
- import { Activity, CryptographicKey, Link, Multikey, Object as Object$1, OrderedCollection, OrderedCollectionPage } from "./vocab-dw0HG0EQ.js";
11
- import { lookupWebFinger } from "./lookup-CEbB0_t_.js";
12
- import { getTypeId } from "./type-D2s5lmbZ.js";
13
- import { exportJwk, importJwk, validateCryptoKey } from "./key-D9LuuzMv.js";
14
- import { verifyRequest } from "./http-BigTqmE7.js";
15
- import { getAuthenticatedDocumentLoader } from "./authdocloader-DUnUXs5R.js";
16
- import { detachSignature, hasSignature, signJsonLd, verifyJsonLd } from "./ld-CYqXYuyr.js";
17
- import { doesActorOwnKey, getKeyOwner } from "./owner-D7RvVquY.js";
18
- import { signObject, verifyObject } from "./proof-D4z1cLgw.js";
19
- import { lookupObject, traverseCollection } from "./lookup-BYiP0j0F.js";
20
- import { routeActivity } from "./inbox-BB6ajp8P.js";
21
- import { FederationBuilderImpl } from "./builder-Js_TKEl1.js";
22
- import { buildCollectionSynchronizationHeader } from "./collection-Dfb0TPno.js";
23
- import { KvKeyCache } from "./keycache-C4C7f09E.js";
24
- import { createExponentialBackoffPolicy } from "./retry-BiIhZWgD.js";
25
- import { extractInboxes, sendActivity } from "./send-DmlRAY0X.js";
6
+ import { Activity, Collection, CollectionPage, CryptographicKey, Link, Multikey, Object as Object$1, OrderedCollection, OrderedCollectionPage, deno_default, getDocumentLoader, getTypeId, kvCache, lookupWebFinger } from "./type-DHDlfpLg.js";
7
+ import { getNodeInfo } from "./client-Cr3DvU-q.js";
8
+ import { RouterError, lookupObject, traverseCollection } from "./lookup-BGA_VdZm.js";
9
+ import { nodeInfoToJson } from "./types-BIgY6c-l.js";
10
+ import { exportJwk, importJwk, validateCryptoKey } from "./key-B9Yg9Nqz.js";
11
+ import { verifyRequest } from "./http-BkzChfDi.js";
12
+ import { getAuthenticatedDocumentLoader } from "./authdocloader-BkwhwBf_.js";
13
+ import { detachSignature, hasSignature, signJsonLd, verifyJsonLd } from "./ld-i6KANj32.js";
14
+ import { doesActorOwnKey, getKeyOwner } from "./owner-DSr0c3Yp.js";
15
+ import { signObject, verifyObject } from "./proof-B83O-qBN.js";
16
+ import { routeActivity } from "./inbox-CpONbSbQ.js";
17
+ import { FederationBuilderImpl } from "./builder-B-wZuoFJ.js";
18
+ import { buildCollectionSynchronizationHeader } from "./collection-CSzG2j1P.js";
19
+ import { KvKeyCache } from "./keycache-BvyhLLHV.js";
20
+ import { createExponentialBackoffPolicy } from "./retry-D4GJ670a.js";
21
+ import { extractInboxes, sendActivity } from "./send-QRloWueE.js";
26
22
  import { getLogger, withContext } from "@logtape/logtape";
27
23
  import { SpanKind, SpanStatusCode, context, propagation, trace } from "@opentelemetry/api";
28
24
  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";
29
25
  import { domainToASCII } from "node:url";
30
26
 
31
- //#region compat/transformers.ts
27
+ //#region src/compat/transformers.ts
32
28
  const logger$1 = getLogger([
33
29
  "fedify",
34
30
  "compat",
@@ -46,7 +42,7 @@ const logger$1 = getLogger([
46
42
  * https://example.com/#Follow/12345678-1234-5678-1234-567812345678
47
43
  * ```
48
44
  *
49
- * @typeParam TContextData The type of the context data.
45
+ * @template TContextData The type of the context data.
50
46
  * @param activity The activity to assign an ID to.
51
47
  * @param context The context of the activity.
52
48
  * @return The activity with an ID assigned.
@@ -97,7 +93,7 @@ function autoIdAssigner(activity, context$1) {
97
93
  *
98
94
  * As some ActivityPub implementations like Threads fail to deal with inlined
99
95
  * actor objects, this transformer can be used to work around this issue.
100
- * @typeParam TContextData The type of the context data.
96
+ * @template TContextData The type of the context data.
101
97
  * @param activity The activity to dehydrate the actor property of.
102
98
  * @param context The context of the activity.
103
99
  * @returns The dehydrated activity.
@@ -110,7 +106,7 @@ function actorDehydrator(activity, _context) {
110
106
  /**
111
107
  * Gets the default activity transformers that are applied to all outgoing
112
108
  * activities.
113
- * @typeParam TContextData The type of the context data.
109
+ * @template TContextData The type of the context data.
114
110
  * @returns The default activity transformers.
115
111
  * @since 1.4.0
116
112
  */
@@ -119,7 +115,7 @@ function getDefaultActivityTransformers() {
119
115
  }
120
116
 
121
117
  //#endregion
122
- //#region nodeinfo/handler.ts
118
+ //#region src/nodeinfo/handler.ts
123
119
  /**
124
120
  * Handles a NodeInfo request. You would not typically call this function
125
121
  * directly, but instead use {@link Federation.handle} method.
@@ -157,7 +153,7 @@ function handleNodeInfoJrd(_request, context$1) {
157
153
  }
158
154
 
159
155
  //#endregion
160
- //#region vocab/constants.ts
156
+ //#region src/vocab/constants.ts
161
157
  /**
162
158
  * The special public collection for [public addressing]. *Do not mutate this
163
159
  * object.*
@@ -169,7 +165,7 @@ function handleNodeInfoJrd(_request, context$1) {
169
165
  const PUBLIC_COLLECTION = new URL("https://www.w3.org/ns/activitystreams#Public");
170
166
 
171
167
  //#endregion
172
- //#region webfinger/handler.ts
168
+ //#region src/webfinger/handler.ts
173
169
  const logger = getLogger([
174
170
  "fedify",
175
171
  "webfinger",
@@ -299,7 +295,7 @@ async function handleWebFingerInternal(request, { context: context$1, host, acto
299
295
  }
300
296
 
301
297
  //#endregion
302
- //#region federation/negotiation.ts
298
+ //#region src/federation/negotiation.ts
303
299
  function compareSpecs(a, b) {
304
300
  return b.q - a.q || (b.s ?? 0) - (a.s ?? 0) || (a.o ?? 0) - (b.o ?? 0) || a.i - b.i || 0;
305
301
  }
@@ -357,7 +353,7 @@ function preferredMediaTypes(accept) {
357
353
  }
358
354
 
359
355
  //#endregion
360
- //#region federation/handler.ts
356
+ //#region src/federation/handler.ts
361
357
  function acceptsJsonLd(request) {
362
358
  const accept = request.headers.get("Accept");
363
359
  const types = accept ? preferredMediaTypes(accept) : ["*/*"];
@@ -365,6 +361,13 @@ function acceptsJsonLd(request) {
365
361
  if (types[0] === "text/html" || types[0] === "application/xhtml+xml") return false;
366
362
  return types.includes("application/activity+json") || types.includes("application/ld+json") || types.includes("application/json");
367
363
  }
364
+ /**
365
+ * Handles an actor request.
366
+ * @template TContextData The context data to pass to the context.
367
+ * @param request The HTTP request.
368
+ * @param parameters The parameters for handling the actor.
369
+ * @returns A promise that resolves to an HTTP response.
370
+ */
368
371
  async function handleActor(request, { identifier, context: context$1, actorDispatcher, authorizePredicate, onNotFound, onNotAcceptable, onUnauthorized }) {
369
372
  const logger$2 = getLogger([
370
373
  "fedify",
@@ -408,6 +411,13 @@ async function handleActor(request, { identifier, context: context$1, actorDispa
408
411
  Vary: "Accept"
409
412
  } });
410
413
  }
414
+ /**
415
+ * Handles an object request.
416
+ * @template TContextData The context data to pass to the context.
417
+ * @param request The HTTP request.
418
+ * @param parameters The parameters for handling the object.
419
+ * @returns A promise that resolves to an HTTP response.
420
+ */
411
421
  async function handleObject(request, { values, context: context$1, objectDispatcher, authorizePredicate, onNotFound, onNotAcceptable, onUnauthorized }) {
412
422
  if (objectDispatcher == null) return await onNotFound(request);
413
423
  const object = await objectDispatcher(context$1, values);
@@ -440,6 +450,16 @@ async function handleObject(request, { values, context: context$1, objectDispatc
440
450
  Vary: "Accept"
441
451
  } });
442
452
  }
453
+ /**
454
+ * Handles a collection request.
455
+ * @template TItem The type of items in the collection.
456
+ * @template TContext The type of the context, extending {@link RequestContext}.
457
+ * @template TContextData The context data to pass to the `TContext`.
458
+ * @template TFilter The type of the filter.
459
+ * @param request The HTTP request.
460
+ * @param parameters The parameters for handling the collection.
461
+ * @returns A promise that resolves to an HTTP response.
462
+ */
443
463
  async function handleCollection(request, { name, identifier, uriGetter, filter, filterPredicate, context: context$1, collectionCallbacks, tracerProvider, onUnauthorized, onNotFound, onNotAcceptable }) {
444
464
  const spanName = name.trim().replace(/\s+/g, "_");
445
465
  tracerProvider = tracerProvider ?? trace.getTracerProvider();
@@ -581,6 +601,14 @@ async function handleCollection(request, { name, identifier, uriGetter, filter,
581
601
  Vary: "Accept"
582
602
  } });
583
603
  }
604
+ /**
605
+ * Filters collection items based on the provided predicate.
606
+ * @template TItem The type of items to filter.
607
+ * @param items The items to filter.
608
+ * @param collectionName The name of the collection for logging purposes.
609
+ * @param filterPredicate Optional predicate function to filter items.
610
+ * @returns The filtered items as Objects, Links, or URLs.
611
+ */
584
612
  function filterCollectionItems(items, collectionName, filterPredicate) {
585
613
  const result = [];
586
614
  let logged = false;
@@ -604,6 +632,13 @@ function filterCollectionItems(items, collectionName, filterPredicate) {
604
632
  }
605
633
  return result;
606
634
  }
635
+ /**
636
+ * Handles an inbox request for ActivityPub activities.
637
+ * @template TContextData The context data to pass to the context.
638
+ * @param request The HTTP request.
639
+ * @param options The parameters for handling the inbox.
640
+ * @returns A promise that resolves to an HTTP response.
641
+ */
607
642
  async function handleInbox(request, options) {
608
643
  const tracerProvider = options.tracerProvider ?? trace.getTracerProvider();
609
644
  const tracer = tracerProvider.getTracer(deno_default.name, deno_default.version);
@@ -625,6 +660,14 @@ async function handleInbox(request, options) {
625
660
  }
626
661
  });
627
662
  }
663
+ /**
664
+ * Internal function for handling inbox requests with detailed processing.
665
+ * @template TContextData The context data to pass to the context.
666
+ * @param request The HTTP request.
667
+ * @param options The parameters for handling the inbox.
668
+ * @param span The OpenTelemetry span for tracing.
669
+ * @returns A promise that resolves to an HTTP response.
670
+ */
628
671
  async function handleInboxInternal(request, { recipient, context: ctx, inboxContextFactory, kv, kvPrefixes, queue, actorDispatcher, inboxListeners, inboxErrorHandler, onNotFound, signatureTimeWindow, skipSignatureVerification, tracerProvider }, span) {
629
672
  const logger$2 = getLogger([
630
673
  "fedify",
@@ -855,6 +898,447 @@ async function handleInboxInternal(request, { recipient, context: ctx, inboxCont
855
898
  });
856
899
  }
857
900
  /**
901
+ * Handles a custom collection request.
902
+ * @template TItem The type of items in the collection.
903
+ * @template TParams The parameter names of the requested URL.
904
+ * @template TContext The type of the context, extending {@link RequestContext}.
905
+ * @template TContextData The context data to pass to the `TContext`.
906
+ * @param request The HTTP request.
907
+ * @param handleParams Parameters for handling the collection.
908
+ * @returns A promise that resolves to an HTTP response.
909
+ * @since 1.8.0
910
+ */
911
+ const handleCustomCollection = exceptWrapper(_handleCustomCollection);
912
+ async function _handleCustomCollection(request, { name, values, context: context$1, tracerProvider, collectionCallbacks: callbacks, filterPredicate }) {
913
+ verifyDefined(callbacks);
914
+ verifyJsonLdRequest(request);
915
+ await authIfNeeded(context$1, values, callbacks);
916
+ const cursor = new URL(request.url).searchParams.get("cursor");
917
+ return await new CustomCollectionHandler(name, values, context$1, callbacks, tracerProvider, Collection, CollectionPage, filterPredicate).fetchCollection(cursor).toJsonLd().then(respondAsActivity);
918
+ }
919
+ /**
920
+ * Handles an ordered collection request.
921
+ * @template TItem The type of items in the collection.
922
+ * @template TParams The parameter names of the requested URL.
923
+ * @template TContext The type of the context, extending {@link RequestContext}.
924
+ * @template TContextData The context data to pass to the `TContext`.
925
+ * @param request The HTTP request.
926
+ * @param handleParams Parameters for handling the collection.
927
+ * @returns A promise that resolves to an HTTP response.
928
+ * @since 1.8.0
929
+ */
930
+ const handleOrderedCollection = exceptWrapper(_handleOrderedCollection);
931
+ async function _handleOrderedCollection(request, { name, values, context: context$1, tracerProvider, collectionCallbacks: callbacks, filterPredicate }) {
932
+ verifyDefined(callbacks);
933
+ verifyJsonLdRequest(request);
934
+ await authIfNeeded(context$1, values, callbacks);
935
+ const cursor = new URL(request.url).searchParams.get("cursor");
936
+ return await new CustomCollectionHandler(name, values, context$1, callbacks, tracerProvider, OrderedCollection, OrderedCollectionPage, filterPredicate).fetchCollection(cursor).toJsonLd().then(respondAsActivity);
937
+ }
938
+ /**
939
+ * Handling custom collections with support for pagination and filtering.
940
+ * The main flow is on `getCollection`, `dispatch`.
941
+ *
942
+ * @template TItem The type of items in the collection.
943
+ * @template TParams The parameter names of the requested URL.
944
+ * @template TContext The type of the context. {@link Context} or {@link RequestContext}.
945
+ * @template TContextData The context data to pass to the `TContext`.
946
+ * @template TCollection The type of the collection, extending {@link Collection}.
947
+ * @template TCollectionPage The type of the collection page, extending {@link CollectionPage}.
948
+ * @since 1.8.0
949
+ */
950
+ var CustomCollectionHandler = class {
951
+ /**
952
+ * The tracer for telemetry.
953
+ * @type {Tracer}
954
+ */
955
+ #tracer;
956
+ /**
957
+ * The ID of the collection.
958
+ * @type {URL}
959
+ */
960
+ #id;
961
+ /**
962
+ * Store total count of items in the collection.
963
+ * Use `this.totalItems` to access the total items count.
964
+ * It is a promise because it may require an asynchronous operation to count items.
965
+ * @type {Promise<number | null> | undefined}
966
+ */
967
+ #totalItems = void 0;
968
+ /**
969
+ * The first cursor for pagination.
970
+ * It is a promise because it may require an asynchronous operation to get the first cursor.
971
+ * @type {Promise<string | null> | undefined}
972
+ */
973
+ #dispatcher;
974
+ #collection = null;
975
+ /**
976
+ * Creates a new CustomCollection instance.
977
+ * @param {string} name The name of the collection.
978
+ * @param {TParams} values The parameter values for the collection.
979
+ * @param {TContext} context The request context.
980
+ * @param {CustomCollectionCallbacks} callbacks The collection callbacks.
981
+ * @param {TracerProvider} tracerProvider The tracer provider for telemetry.
982
+ * @param {ConstructorWithTypeId<TCollection>} Collection The Collection constructor.
983
+ * @param {ConstructorWithTypeId<TCollectionPage>} CollectionPage The CollectionPage constructor.
984
+ * @param {(item: TItem) => boolean} filterPredicate Optional filter predicate for items.
985
+ */
986
+ constructor(name, values, context$1, callbacks, tracerProvider = trace.getTracerProvider(), Collection$1, CollectionPage$1, filterPredicate) {
987
+ this.name = name;
988
+ this.values = values;
989
+ this.context = context$1;
990
+ this.callbacks = callbacks;
991
+ this.tracerProvider = tracerProvider;
992
+ this.Collection = Collection$1;
993
+ this.CollectionPage = CollectionPage$1;
994
+ this.filterPredicate = filterPredicate;
995
+ this.name = this.name.trim().replace(/\s+/g, "_");
996
+ this.#tracer = this.tracerProvider.getTracer(deno_default.name, deno_default.version);
997
+ this.#id = new URL(this.context.url);
998
+ this.#dispatcher = callbacks.dispatcher.bind(callbacks);
999
+ }
1000
+ /**
1001
+ * Converts the collection to JSON-LD format.
1002
+ * @returns A promise that resolves to the JSON-LD representation.
1003
+ */
1004
+ async toJsonLd() {
1005
+ return (await this.collection).toJsonLd(this.context);
1006
+ }
1007
+ /**
1008
+ * Fetches the collection with optional cursor for pagination.
1009
+ * This method is defined for method chaining and to show processing flow properly.
1010
+ * So it is no problem to call `toJsonLd` directly on the instance.
1011
+ * @param cursor The cursor for pagination, or null for the first page.
1012
+ * @returns The CustomCollection instance for method chaining.
1013
+ */
1014
+ fetchCollection(cursor = null) {
1015
+ this.#collection = this.getCollection(cursor);
1016
+ return this;
1017
+ }
1018
+ /**
1019
+ * Gets the collection or collection page based on the cursor.
1020
+ * @param {string | null} cursor The cursor for pagination, or null for the main collection.
1021
+ * @returns {Promise<TCollection | TCollectionPage>} A promise that resolves to a Collection or CollectionPage.
1022
+ */
1023
+ async getCollection(cursor = null) {
1024
+ if (cursor !== null) {
1025
+ const props$1 = await this.getPageProps(cursor);
1026
+ return new this.CollectionPage(props$1);
1027
+ }
1028
+ const firstCursor = await this.firstCursor;
1029
+ const props = typeof firstCursor === "string" ? await this.getProps(firstCursor) : await this.getPropsWithoutCursor();
1030
+ return new this.Collection(props);
1031
+ }
1032
+ /**
1033
+ * Gets the properties for a collection page.
1034
+ * Returns the page properties including items, previous and next cursors.
1035
+ * @param {string} cursor The cursor for the page.
1036
+ * @returns A promise that resolves to the page properties.
1037
+ */
1038
+ async getPageProps(cursor) {
1039
+ const id = this.#id;
1040
+ const pages = await this.getPages({ cursor });
1041
+ const { prevCursor, nextCursor } = pages;
1042
+ const partOf = new URL(id);
1043
+ partOf.searchParams.delete("cursor");
1044
+ return {
1045
+ id,
1046
+ partOf,
1047
+ items: this.filterItems(pages.items),
1048
+ prev: this.appendToUrl(prevCursor),
1049
+ next: this.appendToUrl(nextCursor)
1050
+ };
1051
+ }
1052
+ /**
1053
+ * Gets the properties for a collection with cursors.
1054
+ * Returns the first cursor and last cursor as URL, along with total items count.
1055
+ * @param {string} firstCursor The first cursor for pagination.
1056
+ * @returns A promise that resolves to the collection properties.
1057
+ */
1058
+ async getProps(firstCursor) {
1059
+ const lastCursor = await this.callbacks.lastCursor?.(this.context, this.values);
1060
+ return {
1061
+ id: this.#id,
1062
+ first: this.appendToUrl(firstCursor),
1063
+ last: this.appendToUrl(lastCursor),
1064
+ totalItems: await this.totalItems
1065
+ };
1066
+ }
1067
+ /**
1068
+ * Gets the properties for a collection of all items and the count.
1069
+ * @returns A promise that resolves to the collection properties.
1070
+ */
1071
+ async getPropsWithoutCursor() {
1072
+ const totalItems = await this.totalItems;
1073
+ const pages = await this.getPages({ totalItems });
1074
+ return {
1075
+ id: this.#id,
1076
+ totalItems,
1077
+ items: this.filterItems(pages.items)
1078
+ };
1079
+ }
1080
+ /**
1081
+ * Gets a page of items from the collection.
1082
+ * Wraps the dispatcher in a span for telemetry.
1083
+ * @param options Options for getting the page, including cursor and total items.
1084
+ * @returns A promise that resolves to the page items.
1085
+ */
1086
+ async getPages({ cursor = null, totalItems = null }) {
1087
+ return await this.#tracer.startActiveSpan(`${this.ATTRS.DISPATCH_COLLECTION} ${this.name}`, this.spanOptions(SpanKind.SERVER, cursor), this.spanPages({
1088
+ cursor,
1089
+ totalItems
1090
+ }));
1091
+ }
1092
+ /**
1093
+ * Creates span options for telemetry.
1094
+ * @param {SpanKind} kind The span kind.
1095
+ * @param {string | null} cursor The optional cursor value.
1096
+ * @returns {SpanOptions}The span options.
1097
+ */
1098
+ spanOptions = (kind, cursor) => ({
1099
+ kind,
1100
+ attributes: {
1101
+ [this.ATTRS.ID]: this.#id.href,
1102
+ [this.ATTRS.TYPE]: this.Collection.typeId.href,
1103
+ ...cursor ? { [this.ATTRS.CURSOR]: cursor } : {}
1104
+ }
1105
+ });
1106
+ /**
1107
+ * Creates a function to wrap the dispatcher so tracing can be applied.
1108
+ * @param params Parameters including cursor and total items.
1109
+ * @returns {(span: Span) => Promise<PageItems<TItem>>} A function that handles the span operation.
1110
+ */
1111
+ spanPages = ({ totalItems = null, cursor = null }) => async (span) => {
1112
+ try {
1113
+ if (totalItems !== null) span.setAttribute(this.ATTRS.TOTAL_ITEMS, totalItems);
1114
+ const page = await this.dispatch(cursor);
1115
+ span.setAttribute(this.ATTRS.ITEMS, page.items.length);
1116
+ return page;
1117
+ } catch (e) {
1118
+ const message = e instanceof Error ? e.message : String(e);
1119
+ span.setStatus({
1120
+ code: SpanStatusCode.ERROR,
1121
+ message
1122
+ });
1123
+ throw e;
1124
+ } finally {
1125
+ span.end();
1126
+ }
1127
+ };
1128
+ /**
1129
+ * Dispatches the collection request to get items.
1130
+ * @param {string | null} cursor The cursor for pagination, or null for the first page.
1131
+ * @returns {Promise<PageItems<TItem>>} A promise that resolves to the page items.
1132
+ */
1133
+ async dispatch(cursor = null) {
1134
+ return await this.#dispatcher(this.context, this.values, cursor) ?? new ItemsNotFoundError().throw();
1135
+ }
1136
+ /**
1137
+ * Filters the items in the collection.
1138
+ * @param {TItem[]} items The items to filter.
1139
+ * @returns {(Object | Link | URL)[]} The filtered items.
1140
+ */
1141
+ filterItems(items) {
1142
+ return filterCollectionItems(items, this.name, this.filterPredicate);
1143
+ }
1144
+ /**
1145
+ * Appends a cursor to the URL if it exists.
1146
+ * @param {string | null | undefined} cursor The cursor to append, or null/undefined.
1147
+ * @returns The URL with cursor appended, or null if cursor is null/undefined.
1148
+ */
1149
+ appendToUrl(cursor) {
1150
+ return appendCursorIfExists(this.context.url, cursor);
1151
+ }
1152
+ /**
1153
+ * Gets the stored collection or collection page.
1154
+ * @returns {Promise<TCollection | TCollectionPage>} A promise that resolves to
1155
+ the collection or collection page.
1156
+ */
1157
+ get collection() {
1158
+ if (this.#collection === null) this.#collection = this.getCollection();
1159
+ return this.#collection;
1160
+ }
1161
+ /**
1162
+ * Gets the total number of items in the collection.
1163
+ * @returns {Promise<number | null>} A promise that
1164
+ resolves to the total items count, or null if not available.
1165
+ */
1166
+ get totalItems() {
1167
+ if (this.#totalItems === void 0) this.totalItems = this.callbacks.counter?.(this.context, this.values);
1168
+ return this.#totalItems;
1169
+ }
1170
+ /**
1171
+ * Sets the total number of items in the collection.
1172
+ * @param value The total items count or a promise that resolves to it.
1173
+ */
1174
+ set totalItems(value) {
1175
+ const toNumber = (value$1) => value$1 == null ? null : Number(value$1);
1176
+ this.#totalItems = value instanceof Promise ? value.then(toNumber) : Promise.resolve(toNumber(value));
1177
+ }
1178
+ /**
1179
+ * Gets the first cursor for pagination.
1180
+ * @returns {Promise<string | null>} A promise that resolves to the first cursor,
1181
+ or null if not available.
1182
+ */
1183
+ get firstCursor() {
1184
+ const cursor = this.callbacks.firstCursor?.(this.context, this.values);
1185
+ return Promise.resolve(cursor ?? null);
1186
+ }
1187
+ /**
1188
+ * Attribute constants for telemetry spans.
1189
+ */
1190
+ ATTRS = {
1191
+ DISPATCH_COLLECTION: "activitypub.dispatch_collection",
1192
+ CURSOR: "fedify.collection.cursor",
1193
+ ID: "activitypub.collection.id",
1194
+ ITEMS: "fedify.collection.items",
1195
+ TOTAL_ITEMS: "activitypub.collection.total_items",
1196
+ TYPE: "activitypub.collection.type"
1197
+ };
1198
+ };
1199
+ /**
1200
+ * A wrapper function that catches specific errors and handles them appropriately.
1201
+ * @template TParams The type of parameters that extend ErrorHandlers.
1202
+ * @param handler The handler function to wrap.
1203
+ * @returns A wrapped handler function that catches and handles specific errors.
1204
+ * @since 1.8.0
1205
+ */
1206
+ function exceptWrapper(handler) {
1207
+ return async (request, handlerParams) => {
1208
+ try {
1209
+ return await handler(request, handlerParams);
1210
+ } catch (error) {
1211
+ const { onNotFound, onNotAcceptable, onUnauthorized } = handlerParams;
1212
+ switch (error?.constructor) {
1213
+ case ItemsNotFoundError: return await onNotFound(request);
1214
+ case NotAcceptableError: return await onNotAcceptable(request);
1215
+ case UnauthorizedError: return await onUnauthorized(request);
1216
+ default: throw error;
1217
+ }
1218
+ }
1219
+ };
1220
+ }
1221
+ /**
1222
+ * Verifies that a value is defined (not undefined).
1223
+ * @template T The type of the value, excluding undefined.
1224
+ * @param callbacks The value to verify.
1225
+ * @throws {ItemsNotFoundError} If the value is undefined.
1226
+ * @since 1.8.0
1227
+ */
1228
+ const verifyDefined = (callbacks) => {
1229
+ if (callbacks === void 0) throw new ItemsNotFoundError();
1230
+ };
1231
+ /**
1232
+ * Verifies that a request accepts JSON-LD content type.
1233
+ * @param request The HTTP request to verify.
1234
+ * @throws {NotAcceptableError} If the request doesn't accept JSON-LD.
1235
+ * @since 1.8.0
1236
+ */
1237
+ const verifyJsonLdRequest = (request) => {
1238
+ if (!acceptsJsonLd(request)) throw new NotAcceptableError();
1239
+ };
1240
+ /**
1241
+ * Performs authorization if needed based on the authorization predicate.
1242
+ * @template TContextData The context data type.
1243
+ * @param {RequestContext<TContextData>} context The request context.
1244
+ * @param {Record<string, string>} values The parameter values.
1245
+ * @param options Options containing the authorization predicate.
1246
+ * @throws {UnauthorizedError} If authorization fails.
1247
+ * @since 1.8.0
1248
+ */
1249
+ const authIfNeeded = async (context$1, values, { authorizePredicate: authorize = void 0 }) => {
1250
+ if (authorize === void 0) return;
1251
+ const key = (await context$1.getSignedKey())?.clone({}, warning.key) ?? null;
1252
+ const keyOwner = (await context$1.getSignedKeyOwner())?.clone({}, warning.keyOwner) ?? null;
1253
+ if (!await authorize(context$1, values, key, keyOwner)) throw new UnauthorizedError();
1254
+ };
1255
+ /** Warning messages for `authIfNeeded`. */
1256
+ const warning = {
1257
+ key: { $warning: {
1258
+ category: [
1259
+ "fedify",
1260
+ "federation",
1261
+ "collection"
1262
+ ],
1263
+ message: "The third parameter of AuthorizePredicate is deprecated in favor of RequestContext.getSignedKey() method. The third parameter will be removed in a future release."
1264
+ } },
1265
+ keyOwner: { $warning: {
1266
+ category: [
1267
+ "fedify",
1268
+ "federation",
1269
+ "collection"
1270
+ ],
1271
+ message: "The fourth parameter of AuthorizePredicate is deprecated in favor of RequestContext.getSignedKeyOwner() method. The fourth parameter will be removed in a future release."
1272
+ } }
1273
+ };
1274
+ /**
1275
+ * Appends a cursor parameter to a URL if the cursor exists.
1276
+ * @template Cursor The type of the cursor (string, null, or undefined).
1277
+ * @param {URL} url The base URL to append the cursor to.
1278
+ * @param {string | null | undefined} cursor The cursor value to append.
1279
+ * @returns The URL with cursor appended if cursor is a string, null otherwise.
1280
+ * @since 1.8.0
1281
+ */
1282
+ const appendCursorIfExists = (url, cursor) => {
1283
+ if (cursor === null || cursor === void 0) return null;
1284
+ const copied = new URL(url);
1285
+ copied.searchParams.set("cursor", cursor);
1286
+ return copied;
1287
+ };
1288
+ /**
1289
+ * Creates an HTTP response for ActivityPub data.
1290
+ * @param {unknown} data The data to serialize as JSON-LD.
1291
+ * @returns {Response} An HTTP response with the data as ActivityPub JSON.
1292
+ * @since 1.8.0
1293
+ */
1294
+ const respondAsActivity = (data) => new Response(JSON.stringify(data), { headers: {
1295
+ "Content-Type": "application/activity+json",
1296
+ Vary: "Accept"
1297
+ } });
1298
+ /**
1299
+ * Base class for handler errors.
1300
+ * @since 1.8.0
1301
+ */
1302
+ var HandlerError = class extends Error {
1303
+ constructor(message) {
1304
+ super(message);
1305
+ }
1306
+ /**
1307
+ * Throws this error.
1308
+ * @returns Never returns, always throws.
1309
+ */
1310
+ throw() {
1311
+ throw this;
1312
+ }
1313
+ };
1314
+ /**
1315
+ * Error thrown when items are not found in a collection.
1316
+ * @since 1.8.0
1317
+ */
1318
+ var ItemsNotFoundError = class extends HandlerError {
1319
+ constructor() {
1320
+ super("Items not found in the collection.");
1321
+ }
1322
+ };
1323
+ /**
1324
+ * Error thrown when the request is not acceptable (e.g., wrong content type).
1325
+ * @since 1.8.0
1326
+ */
1327
+ var NotAcceptableError = class extends HandlerError {
1328
+ constructor() {
1329
+ super("The request is not acceptable.");
1330
+ }
1331
+ };
1332
+ /**
1333
+ * Error thrown when access to a collection is unauthorized.
1334
+ * @since 1.8.0
1335
+ */
1336
+ var UnauthorizedError = class extends HandlerError {
1337
+ constructor() {
1338
+ super("Unauthorized access to the collection.");
1339
+ }
1340
+ };
1341
+ /**
858
1342
  * Responds with the given object in JSON-LD format.
859
1343
  *
860
1344
  * @param object The object to respond with.
@@ -882,7 +1366,7 @@ async function respondWithObjectIfAcceptable(object, request, options) {
882
1366
  }
883
1367
 
884
1368
  //#endregion
885
- //#region federation/middleware.ts
1369
+ //#region src/federation/middleware.ts
886
1370
  /**
887
1371
  * Create a new {@link Federation} instance.
888
1372
  * @param parameters Parameters for initializing the instance.
@@ -1734,6 +2218,34 @@ var FederationImpl = class extends FederationBuilderImpl {
1734
2218
  onNotFound,
1735
2219
  onNotAcceptable
1736
2220
  });
2221
+ case "collection": {
2222
+ const name = route.name.replace(/^collection:/, "");
2223
+ const callbacks = this.collectionCallbacks[name];
2224
+ return await handleCustomCollection(request, {
2225
+ name,
2226
+ context: context$1,
2227
+ values: route.values,
2228
+ collectionCallbacks: callbacks,
2229
+ tracerProvider: this.tracerProvider,
2230
+ onUnauthorized,
2231
+ onNotFound,
2232
+ onNotAcceptable
2233
+ });
2234
+ }
2235
+ case "orderedCollection": {
2236
+ const name = route.name.replace(/^orderedCollection:/, "");
2237
+ const callbacks = this.collectionCallbacks[name];
2238
+ return await handleOrderedCollection(request, {
2239
+ name,
2240
+ context: context$1,
2241
+ values: route.values,
2242
+ collectionCallbacks: callbacks,
2243
+ tracerProvider: this.tracerProvider,
2244
+ onUnauthorized,
2245
+ onNotFound,
2246
+ onNotAcceptable
2247
+ });
2248
+ }
1737
2249
  default: {
1738
2250
  const response = onNotFound(request);
1739
2251
  return response instanceof Promise ? await response : response;
@@ -1874,6 +2386,11 @@ var ContextImpl = class ContextImpl {
1874
2386
  if (path == null) throw new RouterError("No featured tags collection path registered.");
1875
2387
  return new URL(path, this.canonicalOrigin);
1876
2388
  }
2389
+ getCollectionUri(name, values) {
2390
+ const path = this.federation.getCollectionPath(name, values);
2391
+ if (path === null) throw new RouterError(`No collection dispatcher registered for "${String(name)}".`);
2392
+ return new URL(path, this.canonicalOrigin);
2393
+ }
1877
2394
  parseUri(uri) {
1878
2395
  if (uri == null) return null;
1879
2396
  if (uri.origin !== this.origin && uri.origin !== this.canonicalOrigin) return null;
@@ -1961,6 +2478,20 @@ var ContextImpl = class ContextImpl {
1961
2478
  return identifier;
1962
2479
  }
1963
2480
  };
2481
+ const collectionTypes = ["collection", "orderedCollection"];
2482
+ const collectionRegex = /* @__PURE__ */ new RegExp(`^(${collectionTypes.join("|")}):(.*)$`);
2483
+ const match = route.name.match(collectionRegex);
2484
+ if (match !== null) {
2485
+ const [, type, name] = match;
2486
+ const cls = this.federation.collectionTypeIds[name];
2487
+ return {
2488
+ type,
2489
+ name,
2490
+ class: cls,
2491
+ typeId: cls.typeId,
2492
+ values: route.values
2493
+ };
2494
+ }
1964
2495
  return null;
1965
2496
  }
1966
2497
  async getActorKeyPairs(identifier) {
@@ -2375,7 +2906,7 @@ var RequestContextImpl = class RequestContextImpl extends ContextImpl {
2375
2906
  #invokedFromActorDispatcher;
2376
2907
  #invokedFromObjectDispatcher;
2377
2908
  request;
2378
- url;
2909
+ url = void 0;
2379
2910
  constructor(options) {
2380
2911
  super(options);
2381
2912
  this.#invokedFromActorDispatcher = options.invokedFromActorDispatcher;
@@ -2680,4 +3211,4 @@ function getRequestId(request) {
2680
3211
  }
2681
3212
 
2682
3213
  //#endregion
2683
- export { ContextImpl, FederationImpl, InboxContextImpl, KvSpecDeterminer, acceptsJsonLd, actorDehydrator, autoIdAssigner, createFederation, handleActor, handleCollection, handleInbox, handleNodeInfo, handleNodeInfoJrd, handleObject, handleWebFinger, respondWithObject, respondWithObjectIfAcceptable };
3214
+ export { ContextImpl, FederationImpl, InboxContextImpl, KvSpecDeterminer, acceptsJsonLd, actorDehydrator, autoIdAssigner, createFederation, handleActor, handleCollection, handleCustomCollection, handleInbox, handleNodeInfo, handleNodeInfoJrd, handleObject, handleWebFinger, respondWithObject, respondWithObjectIfAcceptable };