@fedify/fedify 2.1.0 → 2.1.2

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 (207) hide show
  1. package/dist/{accept-D7sAxyNa.js → accept-Dd__NiUL.mjs} +10 -8
  2. package/dist/{assert-MZs1qjMx.js → assert-ddO5KLpe.mjs} +5 -9
  3. package/dist/{assert_equals-DSbWqCm3.js → assert_equals-Ew3jOFa3.mjs} +55 -69
  4. package/dist/{assert_instance_of-DHz7EHNU.js → assert_instance_of-C4Ri6VuN.mjs} +5 -9
  5. package/dist/{assert_not_equals-f3m3epl3.js → assert_not_equals--wG9hV7u.mjs} +6 -13
  6. package/dist/{assert_rejects-0h7I2Esa.js → assert_rejects-B-qJtC9Z.mjs} +6 -11
  7. package/dist/{assert_throws-rjdMBf31.js → assert_throws-4NwKEy2q.mjs} +5 -10
  8. package/dist/{builder-WiHhZvjW.js → builder-DkJDAzes.mjs} +32 -41
  9. package/dist/{chunk-CGaQZ11T.cjs → chunk-DDcVe30Y.cjs} +23 -24
  10. package/dist/{chunk-DJNbSFdH.js → chunk-nlSIicah.js} +8 -8
  11. package/dist/{client-BxMZiQaD.d.ts → client-AtlibPOU.d.ts} +1 -1
  12. package/dist/{client-CoCIaTNO.js → client-DEpOVgY1.mjs} +9 -13
  13. package/dist/{client-C97KOq3x.d.cts → client-z-8dc-e1.d.cts} +1 -1
  14. package/dist/{collection-CSzG2j1P.js → collection-BD6-SZ6O.mjs} +7 -12
  15. package/dist/compat/mod.cjs +5 -8
  16. package/dist/compat/mod.d.cts +78 -6
  17. package/dist/compat/mod.d.ts +78 -6
  18. package/dist/compat/mod.js +4 -8
  19. package/dist/compat/transformers.test.mjs +62 -0
  20. package/dist/{context-DyJjQQ_H.d.ts → context-BOiMZBu5.d.ts} +9 -18
  21. package/dist/{context-BcqA-0BL.d.cts → context-BhZVy7RB.d.cts} +9 -18
  22. package/dist/{context-Aqenou7c.js → context-Juj6bdHC.mjs} +7 -11
  23. package/dist/deno-C5VMwnFV.mjs +8 -0
  24. package/dist/{docloader-bVO2EvL9.js → docloader-X9mcJ9Tz.mjs} +8 -14
  25. package/dist/{esm-nLm00z9V.js → esm-DVILvP5e.mjs} +50 -89
  26. package/dist/federation/builder.test.d.mts +2 -0
  27. package/dist/federation/{builder.test.js → builder.test.mjs} +21 -44
  28. package/dist/federation/collection.test.d.mts +2 -0
  29. package/dist/federation/collection.test.mjs +21 -0
  30. package/dist/federation/handler.test.d.mts +2 -0
  31. package/dist/federation/{handler.test.js → handler.test.mjs} +69 -131
  32. package/dist/federation/idempotency.test.d.mts +2 -0
  33. package/dist/federation/{idempotency.test.js → idempotency.test.mjs} +31 -63
  34. package/dist/federation/inbox.test.d.mts +2 -0
  35. package/dist/federation/{inbox.test.js → inbox.test.mjs} +8 -12
  36. package/dist/federation/keycache.test.d.mts +2 -0
  37. package/dist/federation/{keycache.test.js → keycache.test.mjs} +13 -19
  38. package/dist/federation/kv.test.d.mts +2 -0
  39. package/dist/federation/{kv.test.js → kv.test.mjs} +11 -22
  40. package/dist/federation/middleware.test.d.mts +2 -0
  41. package/dist/federation/{middleware.test.js → middleware.test.mjs} +173 -262
  42. package/dist/federation/mod.cjs +327 -16
  43. package/dist/federation/mod.d.cts +3 -6
  44. package/dist/federation/mod.d.ts +3 -6
  45. package/dist/federation/mod.js +322 -13
  46. package/dist/federation/mq.test.d.mts +2 -0
  47. package/dist/federation/{mq.test.js → mq.test.mjs} +21 -35
  48. package/dist/federation/negotiation.test.d.mts +2 -0
  49. package/dist/federation/{negotiation.test.js → negotiation.test.mjs} +9 -16
  50. package/dist/federation/retry.test.d.mts +2 -0
  51. package/dist/federation/{retry.test.js → retry.test.mjs} +8 -11
  52. package/dist/federation/router.test.d.mts +2 -0
  53. package/dist/federation/{router.test.js → router.test.mjs} +11 -16
  54. package/dist/federation/send.test.d.mts +2 -0
  55. package/dist/federation/{send.test.js → send.test.mjs} +22 -30
  56. package/dist/federation/webfinger.test.d.mts +2 -0
  57. package/dist/federation/{webfinger.test.js → webfinger.test.mjs} +22 -56
  58. package/dist/{http-DhH623ma.js → http-BLZWcpzg.js} +67 -187
  59. package/dist/{http-CKDim8Tw.js → http-BTLPIzFa.mjs} +37 -45
  60. package/dist/{http-BudnHZE2.d.cts → http-CrGuipxe.d.cts} +1 -6
  61. package/dist/{http-gvnJbMS1.cjs → http-CxodXLwi.cjs} +186 -300
  62. package/dist/{http-Dax_FIBo.d.ts → http-aQzN9Ayi.d.ts} +1 -6
  63. package/dist/{inbox-CA9AUEGa.js → inbox-mcbmhjTW.mjs} +18 -26
  64. package/dist/{key-BsSCz8Z_.js → key-1MaItIGc.mjs} +29 -37
  65. package/dist/{keycache-CpGWAUbj.js → keycache-CCSwkQcY.mjs} +5 -10
  66. package/dist/{keys-BFve7QQv.js → keys-BAK-tUlf.mjs} +5 -9
  67. package/dist/{kv-BL4nlICN.d.cts → kv-CbLNp3zQ.d.cts} +1 -1
  68. package/dist/{kv-DXEUEP6z.d.ts → kv-GFYnFoOl.d.ts} +1 -1
  69. package/dist/{kv-cache-Bw2F2ABq.js → kv-cache-B01V7s3h.mjs} +4 -8
  70. package/dist/{kv-cache-DK4GFVWx.cjs → kv-cache-DjC82_4n.cjs} +27 -34
  71. package/dist/{kv-cache-CxoHCR44.js → kv-cache-GIDK1oLs.js} +6 -13
  72. package/dist/{kv-QzKcOQgP.js → kv-tL2TOE9X.mjs} +6 -10
  73. package/dist/{ld-Bo_Rx0Fc.js → ld-94uHZ1eO.mjs} +17 -31
  74. package/dist/{middleware-BkrUA3da.js → middleware-B5Er10wE.js} +336 -383
  75. package/dist/middleware-CDuHbSVE.mjs +5 -0
  76. package/dist/middleware-CTyq5KB0.cjs +4 -0
  77. package/dist/{middleware-CpAnWzjC.cjs → middleware-CqDJSLoG.cjs} +532 -587
  78. package/dist/{middleware-CZ8jOOa3.js → middleware-DMZGXHm3.mjs} +282 -317
  79. package/dist/{mod-Bx9jcLB8.d.cts → mod-B505FZBC.d.cts} +3 -3
  80. package/dist/{mod-em2Il1eD.d.cts → mod-Bp_CzKd4.d.cts} +2 -2
  81. package/dist/{mod-Cs2dYEwI.d.ts → mod-D7PAuO6k.d.ts} +3 -3
  82. package/dist/{mod-D6MdymW7.d.ts → mod-DKOAow7a.d.ts} +2 -2
  83. package/dist/{mod-Coe7KEgX.d.cts → mod-DoJBjjnO.d.cts} +2 -2
  84. package/dist/{mod-D6dOd--H.d.ts → mod-DvxszxXC.d.ts} +2 -2
  85. package/dist/mod.cjs +29 -74
  86. package/dist/mod.d.cts +11 -14
  87. package/dist/mod.d.ts +11 -15
  88. package/dist/mod.js +17 -71
  89. package/dist/{negotiation-BlAuS_nr.js → negotiation-DnsfFF8I.mjs} +7 -11
  90. package/dist/nodeinfo/client.test.d.mts +2 -0
  91. package/dist/nodeinfo/{client.test.js → client.test.mjs} +22 -40
  92. package/dist/nodeinfo/handler.test.d.mts +2 -0
  93. package/dist/nodeinfo/{handler.test.js → handler.test.mjs} +13 -43
  94. package/dist/nodeinfo/mod.cjs +5 -8
  95. package/dist/nodeinfo/mod.d.cts +2 -3
  96. package/dist/nodeinfo/mod.d.ts +2 -3
  97. package/dist/nodeinfo/mod.js +4 -8
  98. package/dist/nodeinfo/types.test.d.mts +2 -0
  99. package/dist/nodeinfo/{types.test.js → types.test.mjs} +9 -16
  100. package/dist/otel/exporter.test.d.mts +2 -0
  101. package/dist/otel/{exporter.test.js → exporter.test.mjs} +124 -178
  102. package/dist/otel/mod.cjs +15 -20
  103. package/dist/otel/mod.d.cts +2 -2
  104. package/dist/otel/mod.d.ts +2 -2
  105. package/dist/otel/mod.js +8 -14
  106. package/dist/{owner-gd0Q9FuU.d.ts → owner-74ARJ5TL.d.ts} +1 -1
  107. package/dist/{owner-Bj_IbwIT.js → owner-B4aIDhg_.mjs} +11 -16
  108. package/dist/{owner-1AbPBOOZ.d.cts → owner-CptqhsOy.d.cts} +1 -1
  109. package/dist/{proof-u6Y358J-.js → proof-DYZWMWOC.mjs} +21 -33
  110. package/dist/{proof-BhFF_JVj.cjs → proof-DqCjiFwb.cjs} +133 -157
  111. package/dist/{proof-D5BQTIcU.js → proof-j-of9m5W.js} +33 -59
  112. package/dist/{retry-mqLf4b-R.js → retry-B_E3V_Dx.mjs} +4 -7
  113. package/dist/{router-D9eI0s4b.js → router-CrMLXoOr.mjs} +4 -8
  114. package/dist/runtime/mod.cjs +11 -13
  115. package/dist/runtime/mod.d.cts +6 -2
  116. package/dist/runtime/mod.d.ts +0 -1
  117. package/dist/runtime/mod.js +4 -7
  118. package/dist/{send-CE8h59oe.js → send-uLjD0uAe.mjs} +8 -13
  119. package/dist/sig/accept.test.d.mts +2 -0
  120. package/dist/sig/{accept.test.js → accept.test.mjs} +35 -70
  121. package/dist/sig/http.test.d.mts +2 -0
  122. package/dist/sig/{http.test.js → http.test.mjs} +209 -280
  123. package/dist/sig/key.test.d.mts +2 -0
  124. package/dist/sig/{key.test.js → key.test.mjs} +11 -18
  125. package/dist/sig/ld.test.d.mts +2 -0
  126. package/dist/sig/{ld.test.js → ld.test.mjs} +22 -35
  127. package/dist/sig/mod.cjs +6 -9
  128. package/dist/sig/mod.d.cts +3 -3
  129. package/dist/sig/mod.d.ts +3 -3
  130. package/dist/sig/mod.js +5 -9
  131. package/dist/sig/owner.test.d.mts +2 -0
  132. package/dist/sig/{owner.test.js → owner.test.mjs} +19 -34
  133. package/dist/sig/proof.test.d.mts +2 -0
  134. package/dist/sig/{proof.test.js → proof.test.mjs} +16 -27
  135. package/dist/{std__assert-X-_kMxKM.js → std__assert-Duiq_YC9.mjs} +12 -24
  136. package/dist/testing/{mod.d.ts → mod.d.mts} +26 -90
  137. package/dist/testing/mod.mjs +6 -0
  138. package/dist/{transformers-3g8GZwkZ.cjs → transformers-NeAONrAq.cjs} +20 -25
  139. package/dist/{transformers-C3FLHUd6.js → transformers-ve6e2xcg.js} +3 -7
  140. package/dist/{types-CPz01LGH.js → types-DCP0WLdt.mjs} +4 -7
  141. package/dist/{types-Cd_hszr_.cjs → types-KC4QAoxe.cjs} +29 -34
  142. package/dist/{types-C93Ob9cU.js → types-hvL8ElAs.js} +8 -13
  143. package/dist/utils/docloader.test.d.mts +2 -0
  144. package/dist/utils/{docloader.test.js → docloader.test.mjs} +14 -25
  145. package/dist/utils/kv-cache.test.d.mts +2 -0
  146. package/dist/utils/{kv-cache.test.js → kv-cache.test.mjs} +25 -40
  147. package/dist/utils/mod.cjs +5 -9
  148. package/dist/utils/mod.d.cts +1 -3
  149. package/dist/utils/mod.d.ts +1 -3
  150. package/dist/utils/mod.js +4 -9
  151. package/dist/vocab/cjs.test.d.mts +2 -0
  152. package/dist/vocab/cjs.test.mjs +14 -0
  153. package/dist/vocab/mod.cjs +10 -12
  154. package/dist/vocab/mod.js +3 -5
  155. package/package.json +7 -7
  156. package/dist/compat/transformers.test.d.ts +0 -3
  157. package/dist/compat/transformers.test.js +0 -88
  158. package/dist/compat-Bb4NuTUO.js +0 -4
  159. package/dist/compat-DmDDELst.cjs +0 -4
  160. package/dist/deno-BRMCYThi.js +0 -121
  161. package/dist/federation/builder.test.d.ts +0 -3
  162. package/dist/federation/collection.test.d.ts +0 -3
  163. package/dist/federation/collection.test.js +0 -32
  164. package/dist/federation/handler.test.d.ts +0 -3
  165. package/dist/federation/idempotency.test.d.ts +0 -3
  166. package/dist/federation/inbox.test.d.ts +0 -3
  167. package/dist/federation/keycache.test.d.ts +0 -3
  168. package/dist/federation/kv.test.d.ts +0 -3
  169. package/dist/federation/middleware.test.d.ts +0 -3
  170. package/dist/federation/mq.test.d.ts +0 -3
  171. package/dist/federation/negotiation.test.d.ts +0 -3
  172. package/dist/federation/retry.test.d.ts +0 -3
  173. package/dist/federation/router.test.d.ts +0 -3
  174. package/dist/federation/send.test.d.ts +0 -3
  175. package/dist/federation/webfinger.test.d.ts +0 -3
  176. package/dist/federation-Bp3HI26G.cjs +0 -350
  177. package/dist/federation-DaMfqRm4.js +0 -332
  178. package/dist/middleware-BtT_mKsB.cjs +0 -12
  179. package/dist/middleware-CUMoHNCA.js +0 -12
  180. package/dist/middleware-CzeVJTA1.js +0 -27
  181. package/dist/mod-B7QkWzrL.d.cts +0 -80
  182. package/dist/mod-Bh8mqlYw.d.cts +0 -9
  183. package/dist/mod-D6HodEq7.d.ts +0 -7
  184. package/dist/mod-SMHOMNpZ.d.ts +0 -82
  185. package/dist/mod-gq_Xfdz8.d.cts +0 -1
  186. package/dist/nodeinfo/client.test.d.ts +0 -3
  187. package/dist/nodeinfo/handler.test.d.ts +0 -3
  188. package/dist/nodeinfo/types.test.d.ts +0 -3
  189. package/dist/nodeinfo-DoESQxq5.js +0 -4
  190. package/dist/nodeinfo-DuMYTpbZ.cjs +0 -4
  191. package/dist/otel/exporter.test.d.ts +0 -3
  192. package/dist/runtime-c2Njxsry.cjs +0 -17
  193. package/dist/runtime-poamPCMb.js +0 -13
  194. package/dist/sig/accept.test.d.ts +0 -3
  195. package/dist/sig/http.test.d.ts +0 -3
  196. package/dist/sig/key.test.d.ts +0 -3
  197. package/dist/sig/ld.test.d.ts +0 -3
  198. package/dist/sig/owner.test.d.ts +0 -3
  199. package/dist/sig/proof.test.d.ts +0 -3
  200. package/dist/sig-BNhspNOf.js +0 -4
  201. package/dist/sig-vX39WyWI.cjs +0 -4
  202. package/dist/testing/mod.js +0 -10
  203. package/dist/utils/docloader.test.d.ts +0 -3
  204. package/dist/utils/kv-cache.test.d.ts +0 -3
  205. package/dist/utils-BQ9KqEK9.cjs +0 -4
  206. package/dist/utils-Dn5OPdSW.js +0 -4
  207. /package/dist/{mod-AGjRfPjT.d.ts → compat/transformers.test.d.mts} +0 -0
@@ -1,51 +1,23 @@
1
-
2
- import { Temporal } from "@js-temporal/polyfill";
3
- import { URLPattern } from "urlpattern-polyfill";
4
- globalThis.addEventListener = () => {};
5
-
6
- import { assertEquals } from "../assert_equals-DSbWqCm3.js";
7
- import "../assert-MZs1qjMx.js";
8
- import "../assert_instance_of-DHz7EHNU.js";
9
- import { MemoryKvStore } from "../kv-QzKcOQgP.js";
10
- import "../deno-BRMCYThi.js";
11
- import { createFederation, handleWebFinger } from "../middleware-CZ8jOOa3.js";
12
- import "../client-CoCIaTNO.js";
13
- import "../router-D9eI0s4b.js";
14
- import "../types-CPz01LGH.js";
15
- import "../accept-D7sAxyNa.js";
16
- import "../key-BsSCz8Z_.js";
17
- import "../http-CKDim8Tw.js";
18
- import "../ld-Bo_Rx0Fc.js";
19
- import "../owner-Bj_IbwIT.js";
20
- import "../proof-u6Y358J-.js";
21
- import "../docloader-bVO2EvL9.js";
22
- import "../kv-cache-Bw2F2ABq.js";
23
- import "../inbox-CA9AUEGa.js";
24
- import "../builder-WiHhZvjW.js";
25
- import "../collection-CSzG2j1P.js";
26
- import "../keycache-CpGWAUbj.js";
27
- import "../negotiation-BlAuS_nr.js";
28
- import "../retry-mqLf4b-R.js";
29
- import "../send-CE8h59oe.js";
30
- import "../std__assert-X-_kMxKM.js";
31
- import "../assert_rejects-0h7I2Esa.js";
32
- import "../assert_throws-rjdMBf31.js";
33
- import "../assert_not_equals-f3m3epl3.js";
34
- import { createRequestContext } from "../context-Aqenou7c.js";
1
+ import "@js-temporal/polyfill";
2
+ import "urlpattern-polyfill";
3
+ globalThis.addEventListener = () => {};
4
+ import { n as createRequestContext } from "../context-Juj6bdHC.mjs";
5
+ import { t as assertEquals } from "../assert_equals-Ew3jOFa3.mjs";
6
+ import "../std__assert-Duiq_YC9.mjs";
7
+ import { t as MemoryKvStore } from "../kv-tL2TOE9X.mjs";
8
+ import { a as createFederation, o as handleWebFinger } from "../middleware-DMZGXHm3.mjs";
35
9
  import { test } from "@fedify/fixture";
36
10
  import { Image, Link, Person } from "@fedify/vocab";
37
-
38
11
  //#region src/federation/webfinger.test.ts
39
12
  test("handleWebFinger()", async (t) => {
40
13
  const url = new URL("https://example.com/.well-known/webfinger");
41
- function createContext(url$1) {
42
- const federation = createFederation({ kv: new MemoryKvStore() });
14
+ function createContext(url) {
43
15
  const context = createRequestContext({
44
- federation,
45
- url: url$1,
16
+ federation: createFederation({ kv: new MemoryKvStore() }),
17
+ url,
46
18
  data: void 0,
47
19
  getActorUri(identifier) {
48
- return new URL(`${url$1.origin}/users/${identifier}`);
20
+ return new URL(`${url.origin}/users/${identifier}`);
49
21
  },
50
22
  async getActor(handle) {
51
23
  return await actorDispatcher(context, handle);
@@ -55,10 +27,9 @@ test("handleWebFinger()", async (t) => {
55
27
  if (uri.protocol === "acct:") return null;
56
28
  if (!uri.pathname.startsWith("/users/")) return null;
57
29
  const paths = uri.pathname.split("/");
58
- const identifier = paths[paths.length - 1];
59
30
  return {
60
31
  type: "actor",
61
- identifier
32
+ identifier: paths[paths.length - 1]
62
33
  };
63
34
  }
64
35
  });
@@ -90,11 +61,10 @@ test("handleWebFinger()", async (t) => {
90
61
  await t.step("no actor dispatcher", async () => {
91
62
  const context = createContext(url);
92
63
  const request = context.request;
93
- const response = await handleWebFinger(request, {
64
+ assertEquals((await handleWebFinger(request, {
94
65
  context,
95
66
  onNotFound
96
- });
97
- assertEquals(response.status, 404);
67
+ })).status, 404);
98
68
  assertEquals(onNotFoundCalled, request);
99
69
  });
100
70
  onNotFoundCalled = null;
@@ -114,8 +84,7 @@ test("handleWebFinger()", async (t) => {
114
84
  const u = new URL(url);
115
85
  u.searchParams.set("resource", " invalid ");
116
86
  const context = createContext(u);
117
- const request = new Request(u);
118
- const response = await handleWebFinger(request, {
87
+ const response = await handleWebFinger(new Request(u), {
119
88
  context,
120
89
  actorDispatcher,
121
90
  onNotFound
@@ -221,12 +190,11 @@ test("handleWebFinger()", async (t) => {
221
190
  u.searchParams.set("resource", "acct:no-one@example.com");
222
191
  const context = createContext(u);
223
192
  const request = context.request;
224
- const response = await handleWebFinger(request, {
193
+ assertEquals((await handleWebFinger(request, {
225
194
  context,
226
195
  actorDispatcher,
227
196
  onNotFound
228
- });
229
- assertEquals(response.status, 404);
197
+ })).status, 404);
230
198
  assertEquals(onNotFoundCalled, request);
231
199
  });
232
200
  onNotFoundCalled = null;
@@ -522,16 +490,14 @@ test("handleWebFinger()", async (t) => {
522
490
  onNotFound
523
491
  });
524
492
  assertEquals(response.status, 200);
525
- const result = await response.json();
526
- const expectedWithCustomLinks = {
493
+ assertEquals(await response.json(), {
527
494
  ...expected,
528
495
  links: [...expected.links, {
529
496
  rel: "http://ostatus.org/schema/1.0/subscribe",
530
497
  template: "https://example.com/follow?acct={uri}"
531
498
  }]
532
- };
533
- assertEquals(result, expectedWithCustomLinks);
499
+ });
534
500
  });
535
501
  });
536
-
537
- //#endregion
502
+ //#endregion
503
+ export {};
@@ -1,133 +1,25 @@
1
-
2
- import { Temporal } from "@js-temporal/polyfill";
3
- import { URLPattern } from "urlpattern-polyfill";
4
-
1
+ import { Temporal } from "@js-temporal/polyfill";
2
+ import "urlpattern-polyfill";
5
3
  import { getLogger } from "@logtape/logtape";
6
4
  import { CryptographicKey, Object as Object$1, isActor } from "@fedify/vocab";
7
5
  import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
8
6
  import { encodeHex } from "byte-encodings/hex";
9
7
  import { Item, decodeDict, encodeDict, encodeItem } from "structured-field-values";
8
+ import { FetchError, getDocumentLoader } from "@fedify/vocab-runtime";
10
9
  import { ATTR_HTTP_REQUEST_HEADER, ATTR_HTTP_REQUEST_METHOD, ATTR_URL_FULL } from "@opentelemetry/semantic-conventions";
11
10
  import { decodeBase64, encodeBase64 } from "byte-encodings/base64";
12
- import { FetchError, getDocumentLoader } from "@fedify/vocab-runtime";
13
-
14
11
  //#region deno.json
15
12
  var name = "@fedify/fedify";
16
- var version = "2.1.0";
17
- var license = "MIT";
18
- var exports = {
19
- ".": "./src/mod.ts",
20
- "./compat": "./src/compat/mod.ts",
21
- "./federation": "./src/federation/mod.ts",
22
- "./nodeinfo": "./src/nodeinfo/mod.ts",
23
- "./otel": "./src/otel/mod.ts",
24
- "./runtime": "./src/runtime/mod.ts",
25
- "./sig": "./src/sig/mod.ts",
26
- "./utils": "./src/utils/mod.ts",
27
- "./vocab": "./src/vocab/mod.ts"
28
- };
29
- var imports = {
30
- "@multiformats/base-x": "npm:@multiformats/base-x@^4.0.1",
31
- "@std/assert": "jsr:@std/assert@^0.226.0",
32
- "@std/url": "jsr:@std/url@^0.225.1",
33
- "asn1js": "npm:asn1js@^3.0.7",
34
- "fast-check": "npm:fast-check@^3.22.0",
35
- "fetch-mock": "npm:fetch-mock@^12.5.2",
36
- "json-canon": "npm:json-canon@^1.0.1",
37
- "jsonld": "npm:jsonld@^9.0.0",
38
- "pkijs": "npm:pkijs@^3.3.3",
39
- "structured-field-values": "npm:structured-field-values@^2.0.4",
40
- "uri-template-router": "npm:uri-template-router@^1.0.0",
41
- "url-template": "npm:url-template@^3.1.1"
42
- };
43
- var exclude = [
44
- ".test-report.xml",
45
- "apidoc/",
46
- "dist/",
47
- "node_modules/",
48
- "npm/",
49
- "pnpm-lock.yaml",
50
- "src/cfworkers/dist/",
51
- "src/cfworkers/fixtures/",
52
- "src/cfworkers/imports.ts",
53
- "src/cfworkers/README.md",
54
- "src/cfworkers/server.ts",
55
- "src/cfworkers/server.js",
56
- "src/cfworkers/server.js.map"
57
- ];
58
- var publish = { "exclude": [
59
- "**/*.test.ts",
60
- "src/testing/",
61
- "tsdown.config.ts",
62
- "scripts/",
63
- "wrangler.toml"
64
- ] };
65
- var tasks = {
66
- "codegen": "deno task -f @fedify/vocab compile",
67
- "cache": {
68
- "command": "deno cache src/mod.ts",
69
- "dependencies": ["codegen"]
70
- },
71
- "check": {
72
- "command": "deno fmt --check && deno lint && deno check src/**/*.ts",
73
- "dependencies": ["codegen"]
74
- },
75
- "test": {
76
- "command": "deno test --check --doc --allow-read --allow-write --allow-env --unstable-kv --trace-leaks --parallel",
77
- "dependencies": ["codegen"]
78
- },
79
- "coverage": "deno task test --clean --coverage && deno coverage --html coverage",
80
- "bench": {
81
- "command": "deno bench --allow-read --allow-write --allow-net --allow-env --allow-run --unstable-kv",
82
- "dependencies": ["codegen"]
83
- },
84
- "apidoc": {
85
- "command": "deno doc --html --name=Fedify --output=apidoc/ src/mod.ts",
86
- "dependencies": ["codegen"]
87
- },
88
- "publish": {
89
- "command": "deno publish",
90
- "dependencies": ["codegen"]
91
- },
92
- "pnpm:install": "pnpm install --silent",
93
- "pnpm:build": {
94
- "command": "pnpm exec tsdown",
95
- "dependencies": ["pnpm:build-vocab"]
96
- },
97
- "test:node": {
98
- "command": "cd dist/ && node --test",
99
- "dependencies": ["pnpm:build"]
100
- },
101
- "test:bun": {
102
- "command": "cd dist/ && bun test --timeout 60000",
103
- "dependencies": ["pnpm:build"]
104
- },
105
- "test:cfworkers": {
106
- "command": "pnpm exec wrangler deploy --dry-run --outdir src/cfworkers && node --import=tsx src/cfworkers/client.ts",
107
- "dependencies": ["pnpm:build"]
108
- },
109
- "test-all": { "dependencies": [
110
- "check",
111
- "test",
112
- "test:node",
113
- "test:bun",
114
- "test:cfworkers"
115
- ] }
116
- };
117
- var deno_default = {
118
- name,
119
- version,
120
- license,
121
- exports,
122
- imports,
123
- exclude,
124
- publish,
125
- tasks
126
- };
127
-
13
+ var version = "2.1.2";
128
14
  //#endregion
129
15
  //#region src/sig/accept.ts
130
16
  /**
17
+ * `Accept-Signature` header parsing, serialization, and validation utilities
18
+ * for RFC 9421 §5 challenge-response negotiation.
19
+ *
20
+ * @module
21
+ */
22
+ /**
131
23
  * Parses an `Accept-Signature` header value (RFC 9421 §5.1) into an
132
24
  * array of {@link AcceptSignatureMember} objects.
133
25
  *
@@ -258,7 +150,6 @@ function fulfillAcceptSignature(entry, localKeyId, localAlg) {
258
150
  expires: entry.parameters.expires
259
151
  };
260
152
  }
261
-
262
153
  //#endregion
263
154
  //#region src/sig/key.ts
264
155
  /**
@@ -274,8 +165,7 @@ function validateCryptoKey(key, type) {
274
165
  if (!key.extractable) throw new TypeError("The key is not extractable.");
275
166
  if (key.algorithm.name !== "RSASSA-PKCS1-v1_5" && key.algorithm.name !== "Ed25519") throw new TypeError("Currently only RSASSA-PKCS1-v1_5 and Ed25519 keys are supported. More algorithms will be added in the future!");
276
167
  if (key.algorithm.name === "RSASSA-PKCS1-v1_5") {
277
- const algorithm = key.algorithm;
278
- if (algorithm.hash.name !== "SHA-256") throw new TypeError("For compatibility with the existing Fediverse software (e.g., Mastodon), hash algorithm for RSASSA-PKCS1-v1_5 keys must be SHA-256.");
168
+ if (key.algorithm.hash.name !== "SHA-256") throw new TypeError("For compatibility with the existing Fediverse software (e.g., Mastodon), hash algorithm for RSASSA-PKCS1-v1_5 keys must be SHA-256.");
279
169
  }
280
170
  }
281
171
  /**
@@ -342,8 +232,7 @@ async function importJwk(jwk, type) {
342
232
  }
343
233
  async function withFetchKeySpan(keyId, tracerProvider, fetcher) {
344
234
  tracerProvider ??= trace.getTracerProvider();
345
- const tracer = tracerProvider.getTracer(deno_default.name, deno_default.version);
346
- return await tracer.startActiveSpan("activitypub.fetch_key", {
235
+ return await tracerProvider.getTracer(name, version).startActiveSpan("activitypub.fetch_key", {
347
236
  kind: SpanKind.CLIENT,
348
237
  attributes: {
349
238
  "http.method": "GET",
@@ -404,41 +293,41 @@ function fetchKey(keyId, cls, options = {}) {
404
293
  async function fetchKeyDetailed(keyId, cls, options = {}) {
405
294
  const cacheKey = typeof keyId === "string" ? new URL(keyId) : keyId;
406
295
  return await withFetchKeySpan(cacheKey, options.tracerProvider, async () => {
407
- return await fetchKeyWithResult(cacheKey, cls, options, async (cacheKey$1, keyId$1, keyCache, logger) => {
408
- const fetchError = await keyCache?.getFetchError?.(cacheKey$1);
296
+ return await fetchKeyWithResult(cacheKey, cls, options, async (cacheKey, keyId, keyCache, logger) => {
297
+ const fetchError = await keyCache?.getFetchError?.(cacheKey);
409
298
  if (fetchError != null) {
410
- logger.debug("Entry {keyId} found in cache with preserved fetch failure details.", { keyId: keyId$1 });
299
+ logger.debug("Entry {keyId} found in cache with preserved fetch failure details.", { keyId });
411
300
  return {
412
301
  key: null,
413
302
  cached: true,
414
303
  fetchError
415
304
  };
416
305
  }
417
- logger.debug("Entry {keyId} found in cache, but no fetch failure details are available.", { keyId: keyId$1 });
306
+ logger.debug("Entry {keyId} found in cache, but no fetch failure details are available.", { keyId });
418
307
  return {
419
308
  key: null,
420
309
  cached: true
421
310
  };
422
- }, async (error, cacheKey$1, keyId$1, keyCache, logger) => {
311
+ }, async (error, cacheKey, keyId, keyCache, logger) => {
423
312
  logger.debug("Failed to fetch key {keyId}.", {
424
- keyId: keyId$1,
313
+ keyId,
425
314
  error
426
315
  });
427
- await keyCache?.set(cacheKey$1, null);
316
+ await keyCache?.set(cacheKey, null);
428
317
  if (error instanceof FetchError && error.response != null) {
429
- const fetchError$1 = {
318
+ const fetchError = {
430
319
  status: error.response.status,
431
320
  response: error.response.clone()
432
321
  };
433
- await keyCache?.setFetchError?.(cacheKey$1, fetchError$1);
322
+ await keyCache?.setFetchError?.(cacheKey, fetchError);
434
323
  return {
435
324
  key: null,
436
325
  cached: false,
437
- fetchError: fetchError$1
326
+ fetchError
438
327
  };
439
328
  }
440
329
  const fetchError = { error: error instanceof Error ? error : new Error(String(error)) };
441
- await keyCache?.setFetchError?.(cacheKey$1, fetchError);
330
+ await keyCache?.setFetchError?.(cacheKey, fetchError);
442
331
  return {
443
332
  key: null,
444
333
  cached: false,
@@ -484,8 +373,8 @@ async function resolveFetchedKey(document, cacheKey, keyId, cls, { documentLoade
484
373
  contextLoader,
485
374
  tracerProvider
486
375
  });
487
- } catch (e$1) {
488
- if (e$1 instanceof TypeError) {
376
+ } catch (e) {
377
+ if (e instanceof TypeError) {
489
378
  logger.debug("Failed to verify; key {keyId} returned an invalid object.", { keyId });
490
379
  await keyCache?.set(cacheKey, null);
491
380
  await clearFetchErrorMetadata(cacheKey, keyCache);
@@ -494,7 +383,7 @@ async function resolveFetchedKey(document, cacheKey, keyId, cls, { documentLoade
494
383
  cached: false
495
384
  };
496
385
  }
497
- throw e$1;
386
+ throw e;
498
387
  }
499
388
  }
500
389
  let key = null;
@@ -575,40 +464,38 @@ async function fetchKeyWithResult(cacheKey, cls, options, onCachedUnavailable, o
575
464
  logger.debug("Fetching key {keyId} to verify signature...", { keyId });
576
465
  let document;
577
466
  try {
578
- const remoteDocument = await (options.documentLoader ?? getDocumentLoader())(keyId);
579
- document = remoteDocument.document;
467
+ document = (await (options.documentLoader ?? getDocumentLoader())(keyId)).document;
580
468
  } catch (error) {
581
469
  return await onFetchError(error, cacheKey, keyId, keyCache, logger);
582
470
  }
583
471
  return await resolveFetchedKey(document, cacheKey, keyId, cls, options, logger);
584
472
  }
585
473
  async function fetchKeyInternal(keyId, cls, options = {}) {
586
- const cacheKey = typeof keyId === "string" ? new URL(keyId) : keyId;
587
- return await fetchKeyWithResult(cacheKey, cls, options, (_cacheKey, _keyId, _keyCache, _logger) => {
474
+ return await fetchKeyWithResult(typeof keyId === "string" ? new URL(keyId) : keyId, cls, options, (_cacheKey, _keyId, _keyCache, _logger) => {
588
475
  return {
589
476
  key: null,
590
477
  cached: true
591
478
  };
592
- }, async (error, cacheKey$1, keyId$1, keyCache, logger) => {
479
+ }, async (error, cacheKey, keyId, keyCache, logger) => {
593
480
  logger.debug("Failed to fetch key {keyId}.", {
594
- keyId: keyId$1,
481
+ keyId,
595
482
  error
596
483
  });
597
- await keyCache?.set(cacheKey$1, null);
598
- if (error instanceof FetchError && error.response != null) await keyCache?.setFetchError?.(cacheKey$1, {
484
+ await keyCache?.set(cacheKey, null);
485
+ if (error instanceof FetchError && error.response != null) await keyCache?.setFetchError?.(cacheKey, {
599
486
  status: error.response.status,
600
487
  response: error.response.clone()
601
488
  });
602
- else await keyCache?.setFetchError?.(cacheKey$1, { error: error instanceof Error ? error : new Error(String(error)) });
489
+ else await keyCache?.setFetchError?.(cacheKey, { error: error instanceof Error ? error : new Error(String(error)) });
603
490
  return {
604
491
  key: null,
605
492
  cached: false
606
493
  };
607
494
  });
608
495
  }
609
-
610
496
  //#endregion
611
497
  //#region src/sig/http.ts
498
+ const DEFAULT_MAX_REDIRECTION = 20;
612
499
  /**
613
500
  * Signs a request using the given private key.
614
501
  * @param request The request to sign.
@@ -620,9 +507,7 @@ async function fetchKeyInternal(keyId, cls, options = {}) {
620
507
  */
621
508
  async function signRequest(request, privateKey, keyId, options = {}) {
622
509
  validateCryptoKey(privateKey, "private");
623
- const tracerProvider = options.tracerProvider ?? trace.getTracerProvider();
624
- const tracer = tracerProvider.getTracer(deno_default.name, deno_default.version);
625
- return await tracer.startActiveSpan("http_signatures.sign", async (span) => {
510
+ return await (options.tracerProvider ?? trace.getTracerProvider()).getTracer(name, version).startActiveSpan("http_signatures.sign", async (span) => {
626
511
  try {
627
512
  const spec = options.spec ?? "draft-cavage-http-signatures-12";
628
513
  let signed;
@@ -631,7 +516,7 @@ async function signRequest(request, privateKey, keyId, options = {}) {
631
516
  if (span.isRecording()) {
632
517
  span.setAttribute(ATTR_HTTP_REQUEST_METHOD, signed.method);
633
518
  span.setAttribute(ATTR_URL_FULL, signed.url);
634
- for (const [name$1, value] of signed.headers) span.setAttribute(ATTR_HTTP_REQUEST_HEADER(name$1), value);
519
+ for (const [name, value] of signed.headers) span.setAttribute(ATTR_HTTP_REQUEST_HEADER(name), value);
635
520
  span.setAttribute("http_signatures.key_id", keyId.href);
636
521
  }
637
522
  return signed;
@@ -659,8 +544,8 @@ async function signRequestDraft(request, privateKey, keyId, span, currentTime, b
659
544
  }
660
545
  if (!headers.has("Date")) headers.set("Date", currentTime == null ? (/* @__PURE__ */ new Date()).toUTCString() : new Date(currentTime.toString()).toUTCString());
661
546
  const serialized = [["(request-target)", `${request.method.toLowerCase()} ${url.pathname}`], ...headers];
662
- const headerNames = serialized.map(([name$1]) => name$1);
663
- const message = serialized.map(([name$1, value]) => `${name$1}: ${value.trim()}`).join("\n");
547
+ const headerNames = serialized.map(([name]) => name);
548
+ const message = serialized.map(([name, value]) => `${name}: ${value.trim()}`).join("\n");
664
549
  const signature = await crypto.subtle.sign("RSASSA-PKCS1-v1_5", privateKey, new TextEncoder().encode(message));
665
550
  const sigHeader = `keyId="${keyId.href}",algorithm="rsa-sha256",headers="${headerNames.join(" ")}",signature="${encodeBase64(signature)}"`;
666
551
  headers.set("Signature", sigHeader);
@@ -730,9 +615,7 @@ const derivedComponents = {
730
615
  * @returns The formatted signature string.
731
616
  */
732
617
  function formatRfc9421Signature(signature, components, parameters, label = "sig1") {
733
- const signatureInputValue = `${label}=(${components.map((c) => formatComponentId(c)).join(" ")});${parameters}`;
734
- const signatureValue = `${label}=:${encodeBase64(signature)}:`;
735
- return [signatureInputValue, signatureValue];
618
+ return [`${label}=(${components.map((c) => formatComponentId(c)).join(" ")});${parameters}`, `${label}=:${encodeBase64(signature)}:`];
736
619
  }
737
620
  /**
738
621
  * Parse RFC 9421 Signature-Input header.
@@ -838,12 +721,11 @@ async function signRequestRfc9421(request, privateKey, keyId, span, currentTime,
838
721
  value: "content-digest",
839
722
  params: {}
840
723
  }] : []];
841
- const expires = rfc9421Options?.expires === true ? (currentTime.epochMilliseconds / 1e3 | 0) + 3600 : void 0;
842
724
  const signatureParams = formatRfc9421SignatureParameters({
843
725
  algorithm: "rsa-v1_5-sha256",
844
726
  keyId,
845
727
  created,
846
- expires,
728
+ expires: rfc9421Options?.expires === true ? (currentTime.epochMilliseconds / 1e3 | 0) + 3600 : void 0,
847
729
  nonce: rfc9421Options?.nonce,
848
730
  tag: rfc9421Options?.tag
849
731
  });
@@ -953,13 +835,11 @@ async function verifyRequest(request, options = {}) {
953
835
  * @since 2.1.0
954
836
  */
955
837
  async function verifyRequestDetailed(request, options = {}) {
956
- const tracerProvider = options.tracerProvider ?? trace.getTracerProvider();
957
- const tracer = tracerProvider.getTracer(deno_default.name, deno_default.version);
958
- return await tracer.startActiveSpan("http_signatures.verify", async (span) => {
838
+ return await (options.tracerProvider ?? trace.getTracerProvider()).getTracer(name, version).startActiveSpan("http_signatures.verify", async (span) => {
959
839
  if (span.isRecording()) {
960
840
  span.setAttribute(ATTR_HTTP_REQUEST_METHOD, request.method);
961
841
  span.setAttribute(ATTR_URL_FULL, request.url);
962
- for (const [name$1, value] of request.headers) span.setAttribute(ATTR_HTTP_REQUEST_HEADER(name$1), value);
842
+ for (const [name, value] of request.headers) span.setAttribute(ATTR_HTTP_REQUEST_HEADER(name), value);
963
843
  }
964
844
  try {
965
845
  let spec = options.spec;
@@ -1147,11 +1027,10 @@ async function verifyRequestDraft(request, span, { documentLoader, contextLoader
1147
1027
  logger.debug("Failed to verify; required headers missing in the Signature header: {headers}.", { headers });
1148
1028
  return invalidSignatureResult(keyIdUrl);
1149
1029
  }
1150
- const message = headerNames.map((name$1) => `${name$1}: ` + (name$1 === "(request-target)" ? `${request.method.toLowerCase()} ${new URL(request.url).pathname}` : name$1 === "(created)" ? sigValues.created ?? "" : name$1 === "(expires)" ? sigValues.expires ?? "" : name$1 === "host" ? request.headers.get("host") ?? new URL(request.url).host : request.headers.get(name$1))).join("\n");
1030
+ const message = headerNames.map((name) => `${name}: ` + (name === "(request-target)" ? `${request.method.toLowerCase()} ${new URL(request.url).pathname}` : name === "(created)" ? sigValues.created ?? "" : name === "(expires)" ? sigValues.expires ?? "" : name === "host" ? request.headers.get("host") ?? new URL(request.url).host : request.headers.get(name))).join("\n");
1151
1031
  const sig = decodeBase64(signature);
1152
1032
  span?.setAttribute("http_signatures.signature", encodeHex(sig));
1153
- const verified = await crypto.subtle.verify("RSASSA-PKCS1-v1_5", key.publicKey, sig, new TextEncoder().encode(message));
1154
- if (!verified) {
1033
+ if (!await crypto.subtle.verify("RSASSA-PKCS1-v1_5", key.publicKey, sig, new TextEncoder().encode(message))) {
1155
1034
  if (cached) {
1156
1035
  logger.debug("Failed to verify with the cached key {keyId}; signature {signature} is invalid. Retrying with the freshly fetched key...", {
1157
1036
  keyId,
@@ -1165,7 +1044,7 @@ async function verifyRequestDraft(request, span, { documentLoader, contextLoader
1165
1044
  currentTime,
1166
1045
  keyCache: {
1167
1046
  get: () => Promise.resolve(void 0),
1168
- set: async (keyId$1, key$1) => await keyCache?.set(keyId$1, key$1)
1047
+ set: async (keyId, key) => await keyCache?.set(keyId, key)
1169
1048
  }
1170
1049
  });
1171
1050
  }
@@ -1327,9 +1206,7 @@ async function verifyRequestRfc9421(request, span, { documentLoader, contextLoad
1327
1206
  failure = invalidSignatureResult(keyId);
1328
1207
  continue;
1329
1208
  }
1330
- const body = await request.arrayBuffer();
1331
- const digestValid = await verifyRfc9421ContentDigest(contentDigestHeader, body);
1332
- if (!digestValid) {
1209
+ if (!await verifyRfc9421ContentDigest(contentDigestHeader, await request.arrayBuffer())) {
1333
1210
  logger.debug("Failed to verify; Content-Digest verification failed.", { contentDigest: contentDigestHeader });
1334
1211
  failure = invalidSignatureResult(keyId);
1335
1212
  continue;
@@ -1387,8 +1264,7 @@ async function verifyRequestRfc9421(request, span, { documentLoader, contextLoad
1387
1264
  const signatureBaseBytes = new TextEncoder().encode(signatureBase);
1388
1265
  span?.setAttribute("http_signatures.signature", encodeHex(sigBytes));
1389
1266
  try {
1390
- const verified = await crypto.subtle.verify(algorithm, key.publicKey, sigBytes.slice(), signatureBaseBytes);
1391
- if (verified) return {
1267
+ if (await crypto.subtle.verify(algorithm, key.publicKey, sigBytes.slice(), signatureBaseBytes)) return {
1392
1268
  verified: true,
1393
1269
  key,
1394
1270
  signatureLabel: sigName
@@ -1402,7 +1278,7 @@ async function verifyRequestRfc9421(request, span, { documentLoader, contextLoad
1402
1278
  currentTime,
1403
1279
  keyCache: {
1404
1280
  get: () => Promise.resolve(void 0),
1405
- set: async (keyId$1, key$1) => await keyCache?.set(keyId$1, key$1)
1281
+ set: async (keyId, key) => await keyCache?.set(keyId, key)
1406
1282
  },
1407
1283
  spec: "rfc9421"
1408
1284
  });
@@ -1459,7 +1335,11 @@ function createRedirectRequest(request, location, body) {
1459
1335
  * @since 1.6.0
1460
1336
  */
1461
1337
  async function doubleKnock(request, identity, options = {}) {
1338
+ return await doubleKnockInternal(request, identity, options);
1339
+ }
1340
+ async function doubleKnockInternal(request, identity, options, redirected = 0, visited = /* @__PURE__ */ new Set()) {
1462
1341
  const { specDeterminer, log, tracerProvider, signal } = options;
1342
+ visited.add(request.url);
1463
1343
  const origin = new URL(request.url).origin;
1464
1344
  const firstTrySpec = specDeterminer == null ? "rfc9421" : await specDeterminer.determineSpec(origin);
1465
1345
  const body = options.body !== void 0 ? options.body : request.method !== "GET" && request.method !== "HEAD" ? await request.clone().arrayBuffer() : null;
@@ -1474,11 +1354,13 @@ async function doubleKnock(request, identity, options = {}) {
1474
1354
  signal
1475
1355
  });
1476
1356
  if (response.status >= 300 && response.status < 400 && response.headers.has("Location")) {
1477
- const location = response.headers.get("Location");
1478
- return doubleKnock(createRedirectRequest(request, location, body), identity, {
1357
+ if (redirected >= DEFAULT_MAX_REDIRECTION) throw new FetchError(request.url, `Too many redirections (${redirected + 1})`);
1358
+ const redirectRequest = createRedirectRequest(request, response.headers.get("Location"), body);
1359
+ if (visited.has(redirectRequest.url)) throw new FetchError(request.url, `Redirect loop detected: ${redirectRequest.url}`);
1360
+ return doubleKnockInternal(redirectRequest, identity, {
1479
1361
  ...options,
1480
1362
  body
1481
- });
1363
+ }, redirected + 1, visited);
1482
1364
  } else if (response.status === 400 || response.status === 401 || response.status > 401) {
1483
1365
  const logger = getLogger([
1484
1366
  "fedify",
@@ -1521,13 +1403,10 @@ async function doubleKnock(request, identity, options = {}) {
1521
1403
  redirect: "manual",
1522
1404
  signal
1523
1405
  });
1524
- if (response.status >= 300 && response.status < 400 && response.headers.has("Location")) {
1525
- const location = response.headers.get("Location");
1526
- return doubleKnock(createRedirectRequest(request, location, body), identity, {
1527
- ...options,
1528
- body
1529
- });
1530
- }
1406
+ if (response.status >= 300 && response.status < 400 && response.headers.has("Location")) return doubleKnock(createRedirectRequest(request, response.headers.get("Location"), body), identity, {
1407
+ ...options,
1408
+ body
1409
+ });
1531
1410
  }
1532
1411
  if (fulfilled && response.status < 300) {
1533
1412
  await specDeterminer?.rememberSpec(origin, "rfc9421");
@@ -1553,11 +1432,13 @@ async function doubleKnock(request, identity, options = {}) {
1553
1432
  signal
1554
1433
  });
1555
1434
  if (response.status >= 300 && response.status < 400 && response.headers.has("Location")) {
1556
- const location = response.headers.get("Location");
1557
- return doubleKnock(createRedirectRequest(request, location, body), identity, {
1435
+ if (redirected >= DEFAULT_MAX_REDIRECTION) throw new FetchError(request.url, `Too many redirections (${redirected + 1})`);
1436
+ const redirectRequest = createRedirectRequest(request, response.headers.get("Location"), body);
1437
+ if (visited.has(redirectRequest.url)) throw new FetchError(request.url, `Redirect loop detected: ${redirectRequest.url}`);
1438
+ return doubleKnockInternal(redirectRequest, identity, {
1558
1439
  ...options,
1559
1440
  body
1560
- });
1441
+ }, redirected + 1, visited);
1561
1442
  } else if (response.status !== 400 && response.status !== 401) await specDeterminer?.rememberSpec(origin, spec);
1562
1443
  } else await specDeterminer?.rememberSpec(origin, firstTrySpec);
1563
1444
  return response;
@@ -1589,6 +1470,5 @@ function timingSafeEqual(a, b) {
1589
1470
  result |= lenA ^ lenB;
1590
1471
  return result === 0;
1591
1472
  }
1592
-
1593
1473
  //#endregion
1594
- export { deno_default, doubleKnock, exportJwk, fetchKey, fetchKeyDetailed, formatAcceptSignature, fulfillAcceptSignature, generateCryptoKeyPair, importJwk, parseAcceptSignature, parseRfc9421SignatureInput, signRequest, validateAcceptSignature, validateCryptoKey, verifyRequest, verifyRequestDetailed };
1474
+ export { version as _, verifyRequestDetailed as a, fetchKeyDetailed as c, validateCryptoKey as d, formatAcceptSignature as f, name as g, validateAcceptSignature as h, verifyRequest as i, generateCryptoKeyPair as l, parseAcceptSignature as m, parseRfc9421SignatureInput as n, exportJwk as o, fulfillAcceptSignature as p, signRequest as r, fetchKey as s, doubleKnock as t, importJwk as u };