@fedify/fedify 1.9.0-dev.1668 → 1.9.0-dev.1704

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 (138) hide show
  1. package/dist/{actor-ChSW_rBk.js → actor-B0LpLKRw.js} +7263 -2440
  2. package/dist/{actor-Ch5yFYFG.d.ts → actor-C1Euqngb.d.ts} +1 -1
  3. package/dist/{actor-BHAPrCDB.js → actor-CQzdjHs3.js} +1 -1
  4. package/dist/{actor-fGD4yb1K.cjs → actor-DU96UQUE.cjs} +7263 -2440
  5. package/dist/{actor-CHOM_AN3.d.cts → actor-Ydzhc8dj.d.cts} +1 -1
  6. package/dist/{authdocloader-eSrbn3wM.cjs → authdocloader-BkOerKL-.cjs} +3 -3
  7. package/dist/{authdocloader-CgrKtaQg.js → authdocloader-CzmsYrAn.js} +3 -3
  8. package/dist/{authdocloader-ChsJ9FJN.js → authdocloader-DI67R2Ku.js} +3 -3
  9. package/dist/{builder-DI4-Kpdg.js → builder-D2Oyy8AY.js} +14 -8
  10. package/dist/{client-B8gJ1cw8.js → client-BWusKCWF.js} +1 -1
  11. package/dist/compat/mod.d.cts +7 -7
  12. package/dist/compat/mod.d.ts +7 -7
  13. package/dist/compat/transformers.test.js +16 -16
  14. package/dist/{context-DFruNLny.d.ts → context-C51zGhGC.d.ts} +185 -92
  15. package/dist/{context-KXVF2AhH.d.cts → context-Qnv814-p.d.cts} +185 -92
  16. package/dist/{docloader-CSB8cAnw.cjs → docloader-NcFUThCx.cjs} +1 -1
  17. package/dist/{docloader-Bqh-eFNP.js → docloader-isD0ntZv.js} +1 -1
  18. package/dist/{esm-DTi75ew2.js → esm-BBVcrjH8.js} +1 -1
  19. package/dist/federation/builder.test.js +5 -5
  20. package/dist/federation/collection.test.js +3 -3
  21. package/dist/federation/handler.test.js +17 -17
  22. package/dist/federation/idempotency.test.d.ts +3 -0
  23. package/dist/federation/idempotency.test.js +202 -0
  24. package/dist/federation/inbox.test.js +4 -4
  25. package/dist/federation/keycache.test.js +4 -4
  26. package/dist/federation/kv.test.js +3 -3
  27. package/dist/federation/middleware.test.js +18 -18
  28. package/dist/federation/mod.cjs +10 -10
  29. package/dist/federation/mod.d.cts +7 -7
  30. package/dist/federation/mod.d.ts +7 -7
  31. package/dist/federation/mod.js +10 -10
  32. package/dist/federation/mq.test.js +3 -3
  33. package/dist/federation/retry.test.js +3 -3
  34. package/dist/federation/router.test.js +3 -3
  35. package/dist/federation/send.test.js +10 -10
  36. package/dist/fixtures/media.example.com/avatars/test-avatar.jpg.json +6 -0
  37. package/dist/{http-B_zBcsai.d.cts → http-B1_DzfAU.d.cts} +1 -1
  38. package/dist/{http-BpAVdmaR.js → http-BiKoa3o_.js} +2 -2
  39. package/dist/{http-BDErrXSN.cjs → http-LVXxICJn.cjs} +3 -3
  40. package/dist/{http-DBHpjcjo.js → http-MyYS6o7t.js} +3 -3
  41. package/dist/{http-D8Q4xH0d.d.ts → http-wsGR6KkT.d.ts} +1 -1
  42. package/dist/{inbox-BA9sYsBf.js → inbox-CzGsgKH-.js} +29 -7
  43. package/dist/key-BEz2ThE9.cjs +10 -0
  44. package/dist/{key-DSOJOcRH.js → key-C0SCHEcf.js} +3 -3
  45. package/dist/{key-B27QtSbc.js → key-C5cRHj8g.js} +2 -2
  46. package/dist/{key-sCE-TgxY.js → key-CRhmBE03.js} +2 -2
  47. package/dist/{key-CYpTUnwf.cjs → key-Ci8OyUTB.cjs} +2 -2
  48. package/dist/{key-2rIHnPaA.js → key-DWPlWnFQ.js} +4 -4
  49. package/dist/{keycache-CiW2SvJu.js → keycache-rO8ea311.js} +1 -1
  50. package/dist/{keys-5cHW76LQ.js → keys-CWdCy_3n.js} +1 -1
  51. package/dist/{ld-upnKn3yw.js → ld-BWADNtQr.js} +2 -2
  52. package/dist/{lookup-B61sZAOY.js → lookup-BBTRFcU5.js} +1 -1
  53. package/dist/{lookup-BrrOs_g1.cjs → lookup-CILOZed9.cjs} +1 -1
  54. package/dist/{lookup-CZBG-vCx.js → lookup-RINL4MOa.js} +21 -12
  55. package/dist/{middleware-CyUVZG3t.js → middleware-Bcv0xCjs.js} +43 -40
  56. package/dist/middleware-Be9qUuwL.cjs +17 -0
  57. package/dist/{middleware-CfP7UhQy.js → middleware-BfhSHVoJ.js} +78 -47
  58. package/dist/middleware-CWlljVpG.js +26 -0
  59. package/dist/{middleware-P3jCWk4K.cjs → middleware-DDyUhxsm.cjs} +78 -47
  60. package/dist/middleware-Dm7sDAVJ.js +17 -0
  61. package/dist/{mod-NKH_G-IY.d.cts → mod-BUbqxBev.d.cts} +19 -1
  62. package/dist/{mod-Cy6pkZSn.d.ts → mod-CDObsV1d.d.ts} +19 -1
  63. package/dist/{mod-BAuhKa9d.d.ts → mod-CIbqfZW0.d.ts} +1 -1
  64. package/dist/{mod-YfAcrVbP.d.cts → mod-COTXAYRl.d.cts} +2 -2
  65. package/dist/{mod-B7Pc0I7F.d.ts → mod-DgcYoyZK.d.ts} +2 -2
  66. package/dist/{mod-C3CGxYoF.d.cts → mod-Dt-G9ZOS.d.cts} +1 -1
  67. package/dist/{mod-COw_caPC.d.cts → mod-fjqfsrty.d.cts} +2 -2
  68. package/dist/{mod-CiXjux2r.d.ts → mod-o-hx_hU8.d.ts} +2 -2
  69. package/dist/mod.cjs +10 -10
  70. package/dist/mod.d.cts +10 -10
  71. package/dist/mod.d.ts +10 -10
  72. package/dist/mod.js +10 -10
  73. package/dist/nodeinfo/client.test.js +5 -5
  74. package/dist/nodeinfo/handler.test.js +16 -16
  75. package/dist/nodeinfo/mod.cjs +2 -2
  76. package/dist/nodeinfo/mod.js +2 -2
  77. package/dist/nodeinfo/semver.test.js +3 -3
  78. package/dist/nodeinfo/types.test.js +3 -3
  79. package/dist/{owner-C9Ry0TOI.d.cts → owner-6KSEp9eV.d.cts} +2 -2
  80. package/dist/{owner-D38zBIMc.d.ts → owner-BbeUDvOu.d.ts} +2 -2
  81. package/dist/{owner-zvsMGYzc.js → owner-QEQV9vx-.js} +2 -2
  82. package/dist/{proof-Bt6yHsMN.js → proof-B_9fbF3f.js} +3 -3
  83. package/dist/{proof-BgKYSJ00.js → proof-g2_9VhUQ.js} +2 -2
  84. package/dist/{proof-CC_7UV_j.cjs → proof-v3B5cJ3c.cjs} +3 -3
  85. package/dist/runtime/authdocloader.test.js +9 -9
  86. package/dist/runtime/docloader.test.js +4 -4
  87. package/dist/runtime/key.test.js +5 -5
  88. package/dist/runtime/langstr.test.js +3 -3
  89. package/dist/runtime/link.test.js +3 -3
  90. package/dist/runtime/mod.cjs +6 -6
  91. package/dist/runtime/mod.d.cts +3 -3
  92. package/dist/runtime/mod.d.ts +3 -3
  93. package/dist/runtime/mod.js +6 -6
  94. package/dist/runtime/multibase/multibase.test.js +3 -3
  95. package/dist/runtime/url.test.js +3 -3
  96. package/dist/{send-DlqdAGHP.js → send-cTLNXtTp.js} +2 -2
  97. package/dist/sig/http.test.js +8 -8
  98. package/dist/sig/key.test.js +6 -6
  99. package/dist/sig/ld.test.js +7 -7
  100. package/dist/sig/mod.cjs +6 -6
  101. package/dist/sig/mod.d.cts +5 -5
  102. package/dist/sig/mod.d.ts +5 -5
  103. package/dist/sig/mod.js +6 -6
  104. package/dist/sig/owner.test.js +7 -7
  105. package/dist/sig/proof.test.js +7 -7
  106. package/dist/testing/docloader.test.js +3 -3
  107. package/dist/testing/mod.d.ts +391 -86
  108. package/dist/testing/mod.js +3 -3
  109. package/dist/{testing-CAAJTPCt.js → testing-CNtyBr2m.js} +2 -2
  110. package/dist/{type-BRNRL3aj.js → type-C5udJemk.js} +6943 -2120
  111. package/dist/{types-Dz0NMslg.cjs → types-C9w81XqW.cjs} +1 -1
  112. package/dist/{types-C8yjtF5A.js → types-DHq9gRM4.js} +1 -1
  113. package/dist/vocab/actor.test.js +5 -5
  114. package/dist/vocab/lookup.test.js +255 -5
  115. package/dist/vocab/mod.cjs +4 -4
  116. package/dist/vocab/mod.d.cts +3 -3
  117. package/dist/vocab/mod.d.ts +3 -3
  118. package/dist/vocab/mod.js +4 -4
  119. package/dist/vocab/type.test.js +3 -3
  120. package/dist/vocab/vocab.test.js +397 -8
  121. package/dist/{vocab-BDMmyzZA.cjs → vocab-BoyCE2Rn.cjs} +23 -14
  122. package/dist/{vocab-BEEm2I6u.d.ts → vocab-CDHNj5zp.d.ts} +290 -0
  123. package/dist/{vocab-BzGg7ltX.d.cts → vocab-Cfs0937i.d.cts} +290 -0
  124. package/dist/{vocab-WpDLcZH7.js → vocab-DxoBe7PI.js} +23 -14
  125. package/dist/webfinger/handler.test.js +16 -16
  126. package/dist/webfinger/lookup.test.js +4 -4
  127. package/dist/webfinger/mod.cjs +2 -2
  128. package/dist/webfinger/mod.js +2 -2
  129. package/dist/x/cfworkers.test.js +3 -3
  130. package/dist/x/hono.d.cts +6 -6
  131. package/dist/x/hono.d.ts +6 -6
  132. package/dist/x/sveltekit.d.cts +6 -6
  133. package/dist/x/sveltekit.d.ts +6 -6
  134. package/package.json +1 -1
  135. package/dist/key-Ck4-GNm0.cjs +0 -10
  136. package/dist/middleware-D8O6iKhr.js +0 -26
  137. package/dist/middleware-DI4sIaI4.js +0 -17
  138. package/dist/middleware-lw0MLhVG.cjs +0 -17
@@ -3,15 +3,15 @@
3
3
  import { URLPattern } from "urlpattern-polyfill";
4
4
 
5
5
  import { getDefaultActivityTransformers } from "./transformers-BFT6d7J5.js";
6
- import { deno_default, getDocumentLoader, kvCache } from "./docloader-Bqh-eFNP.js";
7
- import { Activity, Collection, CollectionPage, CryptographicKey, Link, Multikey, Object as Object$1, OrderedCollection, OrderedCollectionPage, getTypeId } from "./actor-ChSW_rBk.js";
8
- import { lookupWebFinger } from "./lookup-B61sZAOY.js";
9
- import { exportJwk, importJwk, validateCryptoKey } from "./key-sCE-TgxY.js";
10
- import { doubleKnock, verifyRequest } from "./http-DBHpjcjo.js";
11
- import { detachSignature, doesActorOwnKey, getKeyOwner, hasSignature, signJsonLd, signObject, verifyJsonLd, verifyObject } from "./proof-Bt6yHsMN.js";
12
- import { getNodeInfo, nodeInfoToJson } from "./types-C8yjtF5A.js";
13
- import { getAuthenticatedDocumentLoader } from "./authdocloader-ChsJ9FJN.js";
14
- import { lookupObject, traverseCollection } from "./vocab-WpDLcZH7.js";
6
+ import { deno_default, getDocumentLoader, kvCache } from "./docloader-isD0ntZv.js";
7
+ import { Activity, Collection, CollectionPage, CryptographicKey, Link, Multikey, Object as Object$1, OrderedCollection, OrderedCollectionPage, getTypeId } from "./actor-B0LpLKRw.js";
8
+ import { lookupWebFinger } from "./lookup-BBTRFcU5.js";
9
+ import { exportJwk, importJwk, validateCryptoKey } from "./key-CRhmBE03.js";
10
+ import { doubleKnock, verifyRequest } from "./http-MyYS6o7t.js";
11
+ import { detachSignature, doesActorOwnKey, getKeyOwner, hasSignature, signJsonLd, signObject, verifyJsonLd, verifyObject } from "./proof-B_9fbF3f.js";
12
+ import { getNodeInfo, nodeInfoToJson } from "./types-DHq9gRM4.js";
13
+ import { getAuthenticatedDocumentLoader } from "./authdocloader-DI67R2Ku.js";
14
+ import { lookupObject, traverseCollection } from "./vocab-DxoBe7PI.js";
15
15
  import { getLogger, withContext } from "@logtape/logtape";
16
16
  import { SpanKind, SpanStatusCode, context, propagation, trace } from "@opentelemetry/api";
17
17
  import { encodeHex } from "byte-encodings/hex";
@@ -55,17 +55,39 @@ var InboxListenerSet = class InboxListenerSet {
55
55
  return this.dispatchWithClass(activity)?.listener ?? null;
56
56
  }
57
57
  };
58
- async function routeActivity({ context: ctx, json, activity, recipient, inboxListeners, inboxContextFactory, inboxErrorHandler, kv, kvPrefixes, queue, span, tracerProvider }) {
58
+ let warnedAboutDefaultIdempotency = false;
59
+ async function routeActivity({ context: ctx, json, activity, recipient, inboxListeners, inboxContextFactory, inboxErrorHandler, kv, kvPrefixes, queue, span, tracerProvider, idempotencyStrategy }) {
59
60
  const logger$1 = getLogger([
60
61
  "fedify",
61
62
  "federation",
62
63
  "inbox"
63
64
  ]);
64
- const cacheKey = activity.id == null ? null : [
65
- ...kvPrefixes.activityIdempotence,
66
- ctx.origin,
67
- activity.id.href
68
- ];
65
+ let cacheKey = null;
66
+ if (activity.id != null) {
67
+ const inboxContext = inboxContextFactory(recipient, json, activity.id?.href, getTypeId(activity).href);
68
+ const strategy = idempotencyStrategy ?? "per-origin";
69
+ if (idempotencyStrategy === void 0 && !warnedAboutDefaultIdempotency) {
70
+ logger$1.warn("Using default idempotency strategy 'per-origin'. This default will change to 'per-inbox' in Fedify 2.0. Please explicitly set the idempotency strategy using .withIdempotency().");
71
+ warnedAboutDefaultIdempotency = true;
72
+ }
73
+ let keyString;
74
+ if (typeof strategy === "function") {
75
+ const result = await strategy(inboxContext, activity);
76
+ keyString = result;
77
+ } else switch (strategy) {
78
+ case "global":
79
+ keyString = activity.id.href;
80
+ break;
81
+ case "per-origin":
82
+ keyString = `${ctx.origin}\n${activity.id.href}`;
83
+ break;
84
+ case "per-inbox":
85
+ keyString = `${ctx.origin}\n${activity.id.href}\n${recipient == null ? "sharedInbox" : `inbox\n${recipient}`}`;
86
+ break;
87
+ default: keyString = `${ctx.origin}\n${activity.id.href}`;
88
+ }
89
+ if (keyString != null) cacheKey = [...kvPrefixes.activityIdempotence, keyString];
90
+ }
69
91
  if (cacheKey != null) {
70
92
  const cached = await kv.get(cacheKey);
71
93
  if (cached === true) {
@@ -307,6 +329,7 @@ var FederationBuilderImpl = class {
307
329
  inboxListeners;
308
330
  inboxErrorHandler;
309
331
  sharedInboxKeyDispatcher;
332
+ idempotencyStrategy;
310
333
  collectionTypeIds;
311
334
  collectionCallbacks;
312
335
  /**
@@ -321,7 +344,7 @@ var FederationBuilderImpl = class {
321
344
  this.collectionTypeIds = {};
322
345
  }
323
346
  async build(options) {
324
- const { FederationImpl: FederationImpl$1 } = await import("./middleware-DI4sIaI4.js");
347
+ const { FederationImpl: FederationImpl$1 } = await import("./middleware-Dm7sDAVJ.js");
325
348
  const f = new FederationImpl$1(options);
326
349
  const trailingSlashInsensitiveValue = f.router.trailingSlashInsensitive;
327
350
  f.router = this.router.clone();
@@ -343,6 +366,7 @@ var FederationBuilderImpl = class {
343
366
  f.inboxListeners = this.inboxListeners?.clone();
344
367
  f.inboxErrorHandler = this.inboxErrorHandler;
345
368
  f.sharedInboxKeyDispatcher = this.sharedInboxKeyDispatcher;
369
+ f.idempotencyStrategy = this.idempotencyStrategy;
346
370
  return f;
347
371
  }
348
372
  _getTracer() {
@@ -765,15 +789,19 @@ var FederationBuilderImpl = class {
765
789
  setSharedKeyDispatcher: (dispatcher) => {
766
790
  this.sharedInboxKeyDispatcher = dispatcher;
767
791
  return setters;
792
+ },
793
+ withIdempotency: (strategy) => {
794
+ this.idempotencyStrategy = strategy;
795
+ return setters;
768
796
  }
769
797
  };
770
798
  return setters;
771
799
  }
772
- setCollectionDispatcher(name, ...args) {
773
- return this.#setCustomCollectionDispatcher(name, "collection", ...args);
800
+ setCollectionDispatcher(name, itemType, path, dispatcher) {
801
+ return this.#setCustomCollectionDispatcher(name, "collection", itemType, path, dispatcher);
774
802
  }
775
- setOrderedCollectionDispatcher(name, ...args) {
776
- return this.#setCustomCollectionDispatcher(name, "orderedCollection", ...args);
803
+ setOrderedCollectionDispatcher(name, itemType, path, dispatcher) {
804
+ return this.#setCustomCollectionDispatcher(name, "orderedCollection", itemType, path, dispatcher);
777
805
  }
778
806
  #setCustomCollectionDispatcher(name, collectionType, itemType, path, dispatcher) {
779
807
  const strName = String(name);
@@ -1296,7 +1324,8 @@ async function handleInbox(request, options) {
1296
1324
  * @param span The OpenTelemetry span for tracing.
1297
1325
  * @returns A promise that resolves to an HTTP response.
1298
1326
  */
1299
- async function handleInboxInternal(request, { recipient, context: ctx, inboxContextFactory, kv, kvPrefixes, queue, actorDispatcher, inboxListeners, inboxErrorHandler, onNotFound, signatureTimeWindow, skipSignatureVerification, tracerProvider }, span) {
1327
+ async function handleInboxInternal(request, parameters, span) {
1328
+ const { recipient, context: ctx, inboxContextFactory, kv, kvPrefixes, queue, actorDispatcher, inboxListeners, inboxErrorHandler, onNotFound, signatureTimeWindow, skipSignatureVerification, tracerProvider } = parameters;
1300
1329
  const logger$1 = getLogger([
1301
1330
  "fedify",
1302
1331
  "federation",
@@ -1498,7 +1527,8 @@ async function handleInboxInternal(request, { recipient, context: ctx, inboxCont
1498
1527
  kvPrefixes,
1499
1528
  queue,
1500
1529
  span,
1501
- tracerProvider
1530
+ tracerProvider,
1531
+ idempotencyStrategy: parameters.idempotencyStrategy
1502
1532
  });
1503
1533
  if (routeResult === "alreadyProcessed") return new Response(`Activity <${activity.id}> has already been processed.`, {
1504
1534
  status: 202,
@@ -1528,7 +1558,7 @@ async function handleInboxInternal(request, { recipient, context: ctx, inboxCont
1528
1558
  /**
1529
1559
  * Handles a custom collection request.
1530
1560
  * @template TItem The type of items in the collection.
1531
- * @template TParams The parameter names of the requested URL.
1561
+ * @template TParam The parameter names of the requested URL.
1532
1562
  * @template TContext The type of the context, extending {@link RequestContext}.
1533
1563
  * @template TContextData The context data to pass to the `TContext`.
1534
1564
  * @param request The HTTP request.
@@ -1547,7 +1577,7 @@ async function _handleCustomCollection(request, { name, values, context: context
1547
1577
  /**
1548
1578
  * Handles an ordered collection request.
1549
1579
  * @template TItem The type of items in the collection.
1550
- * @template TParams The parameter names of the requested URL.
1580
+ * @template TParam The parameter names of the requested URL.
1551
1581
  * @template TContext The type of the context, extending {@link RequestContext}.
1552
1582
  * @template TContextData The context data to pass to the `TContext`.
1553
1583
  * @param request The HTTP request.
@@ -1568,7 +1598,7 @@ async function _handleOrderedCollection(request, { name, values, context: contex
1568
1598
  * The main flow is on `getCollection`, `dispatch`.
1569
1599
  *
1570
1600
  * @template TItem The type of items in the collection.
1571
- * @template TParams The parameter names of the requested URL.
1601
+ * @template TParam The parameter names of the requested URL.
1572
1602
  * @template TContext The type of the context. {@link Context} or {@link RequestContext}.
1573
1603
  * @template TContextData The context data to pass to the `TContext`.
1574
1604
  * @template TCollection The type of the collection, extending {@link Collection}.
@@ -1602,14 +1632,14 @@ var CustomCollectionHandler = class {
1602
1632
  #collection = null;
1603
1633
  /**
1604
1634
  * Creates a new CustomCollection instance.
1605
- * @param {string} name The name of the collection.
1606
- * @param {TParams} values The parameter values for the collection.
1607
- * @param {TContext} context The request context.
1608
- * @param {CustomCollectionCallbacks} callbacks The collection callbacks.
1609
- * @param {TracerProvider} tracerProvider The tracer provider for telemetry.
1610
- * @param {ConstructorWithTypeId<TCollection>} Collection The Collection constructor.
1611
- * @param {ConstructorWithTypeId<TCollectionPage>} CollectionPage The CollectionPage constructor.
1612
- * @param {(item: TItem) => boolean} filterPredicate Optional filter predicate for items.
1635
+ * @param name The name of the collection.
1636
+ * @param values The parameter values for the collection.
1637
+ * @param context The request context.
1638
+ * @param callbacks The collection callbacks.
1639
+ * @param tracerProvider The tracer provider for telemetry.
1640
+ * @param Collection The Collection constructor.
1641
+ * @param CollectionPage The CollectionPage constructor.
1642
+ * @param filterPredicate Optional filter predicate for items.
1613
1643
  */
1614
1644
  constructor(name, values, context$1, callbacks, tracerProvider = trace.getTracerProvider(), Collection$1, CollectionPage$1, filterPredicate) {
1615
1645
  this.name = name;
@@ -1734,7 +1764,7 @@ var CustomCollectionHandler = class {
1734
1764
  /**
1735
1765
  * Creates a function to wrap the dispatcher so tracing can be applied.
1736
1766
  * @param params Parameters including cursor and total items.
1737
- * @returns {(span: Span) => Promise<PageItems<TItem>>} A function that handles the span operation.
1767
+ * @returns A function that handles the span operation.
1738
1768
  */
1739
1769
  spanPages = ({ totalItems = null, cursor = null }) => async (span) => {
1740
1770
  try {
@@ -1755,23 +1785,23 @@ var CustomCollectionHandler = class {
1755
1785
  };
1756
1786
  /**
1757
1787
  * Dispatches the collection request to get items.
1758
- * @param {string | null} cursor The cursor for pagination, or null for the first page.
1759
- * @returns {Promise<PageItems<TItem>>} A promise that resolves to the page items.
1788
+ * @param cursor The cursor for pagination, or null for the first page.
1789
+ * @returns A promise that resolves to the page items.
1760
1790
  */
1761
1791
  async dispatch(cursor = null) {
1762
1792
  return await this.#dispatcher(this.context, this.values, cursor) ?? new ItemsNotFoundError().throw();
1763
1793
  }
1764
1794
  /**
1765
1795
  * Filters the items in the collection.
1766
- * @param {TItem[]} items The items to filter.
1767
- * @returns {(Object | Link | URL)[]} The filtered items.
1796
+ * @param items The items to filter.
1797
+ * @returns The filtered items.
1768
1798
  */
1769
1799
  filterItems(items) {
1770
1800
  return filterCollectionItems(items, this.name, this.filterPredicate);
1771
1801
  }
1772
1802
  /**
1773
1803
  * Appends a cursor to the URL if it exists.
1774
- * @param {string | null | undefined} cursor The cursor to append, or null/undefined.
1804
+ * @param cursor The cursor to append, or null/undefined.
1775
1805
  * @returns The URL with cursor appended, or null if cursor is null/undefined.
1776
1806
  */
1777
1807
  appendToUrl(cursor) {
@@ -1779,8 +1809,7 @@ var CustomCollectionHandler = class {
1779
1809
  }
1780
1810
  /**
1781
1811
  * Gets the stored collection or collection page.
1782
- * @returns {Promise<TCollection | TCollectionPage>} A promise that resolves to
1783
- the collection or collection page.
1812
+ * @returns A promise that resolves to the collection or collection page.
1784
1813
  */
1785
1814
  get collection() {
1786
1815
  if (this.#collection === null) this.#collection = this.getCollection();
@@ -1788,8 +1817,8 @@ var CustomCollectionHandler = class {
1788
1817
  }
1789
1818
  /**
1790
1819
  * Gets the total number of items in the collection.
1791
- * @returns {Promise<number | null>} A promise that
1792
- resolves to the total items count, or null if not available.
1820
+ * @returns A promise that resolves to the total items count,
1821
+ * or null if not available.
1793
1822
  */
1794
1823
  get totalItems() {
1795
1824
  if (this.#totalItems === void 0) this.totalItems = this.callbacks.counter?.(this.context, this.values);
@@ -1805,8 +1834,8 @@ var CustomCollectionHandler = class {
1805
1834
  }
1806
1835
  /**
1807
1836
  * Gets the first cursor for pagination.
1808
- * @returns {Promise<string | null>} A promise that resolves to the first cursor,
1809
- or null if not available.
1837
+ * @returns A promise that resolves to the first cursor,
1838
+ * or null if not available.
1810
1839
  */
1811
1840
  get firstCursor() {
1812
1841
  const cursor = this.callbacks.firstCursor?.(this.context, this.values);
@@ -3095,7 +3124,8 @@ var FederationImpl = class extends FederationBuilderImpl {
3095
3124
  onNotFound,
3096
3125
  signatureTimeWindow: this.signatureTimeWindow,
3097
3126
  skipSignatureVerification: this.skipSignatureVerification,
3098
- tracerProvider: this.tracerProvider
3127
+ tracerProvider: this.tracerProvider,
3128
+ idempotencyStrategy: this.idempotencyStrategy
3099
3129
  });
3100
3130
  case "following": return await handleCollection(request, {
3101
3131
  name: "following",
@@ -3845,7 +3875,8 @@ var ContextImpl = class ContextImpl {
3845
3875
  kvPrefixes: this.federation.kvPrefixes,
3846
3876
  queue: this.federation.inboxQueue,
3847
3877
  span,
3848
- tracerProvider: options.tracerProvider ?? this.tracerProvider
3878
+ tracerProvider: options.tracerProvider ?? this.tracerProvider,
3879
+ idempotencyStrategy: this.federation.idempotencyStrategy
3849
3880
  });
3850
3881
  return routeResult === "alreadyProcessed" || routeResult === "enqueued" || routeResult === "unsupportedActivity" || routeResult === "success";
3851
3882
  }
@@ -0,0 +1,26 @@
1
+
2
+ import { Temporal } from "@js-temporal/polyfill";
3
+ import { URLPattern } from "urlpattern-polyfill";
4
+ globalThis.addEventListener = () => {};
5
+
6
+ import "./type-C5udJemk.js";
7
+ import { ContextImpl, FederationImpl, InboxContextImpl, KvSpecDeterminer, createFederation } from "./middleware-Bcv0xCjs.js";
8
+ import "./semver-dArNLkR9.js";
9
+ import "./client-BWusKCWF.js";
10
+ import "./lookup-RINL4MOa.js";
11
+ import "./types-BIgY6c-l.js";
12
+ import "./actor-CQzdjHs3.js";
13
+ import "./key-C5cRHj8g.js";
14
+ import "./http-BiKoa3o_.js";
15
+ import "./authdocloader-CzmsYrAn.js";
16
+ import "./ld-BWADNtQr.js";
17
+ import "./owner-QEQV9vx-.js";
18
+ import "./proof-g2_9VhUQ.js";
19
+ import "./inbox-CzGsgKH-.js";
20
+ import "./builder-D2Oyy8AY.js";
21
+ import "./collection-CSzG2j1P.js";
22
+ import "./keycache-rO8ea311.js";
23
+ import "./retry-D4GJ670a.js";
24
+ import "./send-cTLNXtTp.js";
25
+
26
+ export { FederationImpl };
@@ -4,15 +4,15 @@
4
4
 
5
5
  const require_chunk = require('./chunk-DqRYRqnO.cjs');
6
6
  const require_transformers = require('./transformers-CoBS-oFG.cjs');
7
- const require_docloader = require('./docloader-CSB8cAnw.cjs');
8
- const require_actor = require('./actor-fGD4yb1K.cjs');
9
- const require_lookup = require('./lookup-BrrOs_g1.cjs');
10
- const require_key = require('./key-CYpTUnwf.cjs');
11
- const require_http = require('./http-BDErrXSN.cjs');
12
- const require_proof = require('./proof-CC_7UV_j.cjs');
13
- const require_types = require('./types-Dz0NMslg.cjs');
14
- const require_authdocloader = require('./authdocloader-eSrbn3wM.cjs');
15
- const require_vocab = require('./vocab-BDMmyzZA.cjs');
7
+ const require_docloader = require('./docloader-NcFUThCx.cjs');
8
+ const require_actor = require('./actor-DU96UQUE.cjs');
9
+ const require_lookup = require('./lookup-CILOZed9.cjs');
10
+ const require_key = require('./key-Ci8OyUTB.cjs');
11
+ const require_http = require('./http-LVXxICJn.cjs');
12
+ const require_proof = require('./proof-v3B5cJ3c.cjs');
13
+ const require_types = require('./types-C9w81XqW.cjs');
14
+ const require_authdocloader = require('./authdocloader-BkOerKL-.cjs');
15
+ const require_vocab = require('./vocab-BoyCE2Rn.cjs');
16
16
  const __logtape_logtape = require_chunk.__toESM(require("@logtape/logtape"));
17
17
  const __opentelemetry_api = require_chunk.__toESM(require("@opentelemetry/api"));
18
18
  const byte_encodings_hex = require_chunk.__toESM(require("byte-encodings/hex"));
@@ -56,17 +56,39 @@ var InboxListenerSet = class InboxListenerSet {
56
56
  return this.dispatchWithClass(activity)?.listener ?? null;
57
57
  }
58
58
  };
59
- async function routeActivity({ context: ctx, json, activity, recipient, inboxListeners, inboxContextFactory, inboxErrorHandler, kv, kvPrefixes, queue, span, tracerProvider }) {
59
+ let warnedAboutDefaultIdempotency = false;
60
+ async function routeActivity({ context: ctx, json, activity, recipient, inboxListeners, inboxContextFactory, inboxErrorHandler, kv, kvPrefixes, queue, span, tracerProvider, idempotencyStrategy }) {
60
61
  const logger$1 = (0, __logtape_logtape.getLogger)([
61
62
  "fedify",
62
63
  "federation",
63
64
  "inbox"
64
65
  ]);
65
- const cacheKey = activity.id == null ? null : [
66
- ...kvPrefixes.activityIdempotence,
67
- ctx.origin,
68
- activity.id.href
69
- ];
66
+ let cacheKey = null;
67
+ if (activity.id != null) {
68
+ const inboxContext = inboxContextFactory(recipient, json, activity.id?.href, require_actor.getTypeId(activity).href);
69
+ const strategy = idempotencyStrategy ?? "per-origin";
70
+ if (idempotencyStrategy === void 0 && !warnedAboutDefaultIdempotency) {
71
+ logger$1.warn("Using default idempotency strategy 'per-origin'. This default will change to 'per-inbox' in Fedify 2.0. Please explicitly set the idempotency strategy using .withIdempotency().");
72
+ warnedAboutDefaultIdempotency = true;
73
+ }
74
+ let keyString;
75
+ if (typeof strategy === "function") {
76
+ const result = await strategy(inboxContext, activity);
77
+ keyString = result;
78
+ } else switch (strategy) {
79
+ case "global":
80
+ keyString = activity.id.href;
81
+ break;
82
+ case "per-origin":
83
+ keyString = `${ctx.origin}\n${activity.id.href}`;
84
+ break;
85
+ case "per-inbox":
86
+ keyString = `${ctx.origin}\n${activity.id.href}\n${recipient == null ? "sharedInbox" : `inbox\n${recipient}`}`;
87
+ break;
88
+ default: keyString = `${ctx.origin}\n${activity.id.href}`;
89
+ }
90
+ if (keyString != null) cacheKey = [...kvPrefixes.activityIdempotence, keyString];
91
+ }
70
92
  if (cacheKey != null) {
71
93
  const cached = await kv.get(cacheKey);
72
94
  if (cached === true) {
@@ -308,6 +330,7 @@ var FederationBuilderImpl = class {
308
330
  inboxListeners;
309
331
  inboxErrorHandler;
310
332
  sharedInboxKeyDispatcher;
333
+ idempotencyStrategy;
311
334
  collectionTypeIds;
312
335
  collectionCallbacks;
313
336
  /**
@@ -322,7 +345,7 @@ var FederationBuilderImpl = class {
322
345
  this.collectionTypeIds = {};
323
346
  }
324
347
  async build(options) {
325
- const { FederationImpl: FederationImpl$1 } = await Promise.resolve().then(() => require("./middleware-lw0MLhVG.cjs"));
348
+ const { FederationImpl: FederationImpl$1 } = await Promise.resolve().then(() => require("./middleware-Be9qUuwL.cjs"));
326
349
  const f = new FederationImpl$1(options);
327
350
  const trailingSlashInsensitiveValue = f.router.trailingSlashInsensitive;
328
351
  f.router = this.router.clone();
@@ -344,6 +367,7 @@ var FederationBuilderImpl = class {
344
367
  f.inboxListeners = this.inboxListeners?.clone();
345
368
  f.inboxErrorHandler = this.inboxErrorHandler;
346
369
  f.sharedInboxKeyDispatcher = this.sharedInboxKeyDispatcher;
370
+ f.idempotencyStrategy = this.idempotencyStrategy;
347
371
  return f;
348
372
  }
349
373
  _getTracer() {
@@ -766,15 +790,19 @@ var FederationBuilderImpl = class {
766
790
  setSharedKeyDispatcher: (dispatcher) => {
767
791
  this.sharedInboxKeyDispatcher = dispatcher;
768
792
  return setters;
793
+ },
794
+ withIdempotency: (strategy) => {
795
+ this.idempotencyStrategy = strategy;
796
+ return setters;
769
797
  }
770
798
  };
771
799
  return setters;
772
800
  }
773
- setCollectionDispatcher(name, ...args) {
774
- return this.#setCustomCollectionDispatcher(name, "collection", ...args);
801
+ setCollectionDispatcher(name, itemType, path, dispatcher) {
802
+ return this.#setCustomCollectionDispatcher(name, "collection", itemType, path, dispatcher);
775
803
  }
776
- setOrderedCollectionDispatcher(name, ...args) {
777
- return this.#setCustomCollectionDispatcher(name, "orderedCollection", ...args);
804
+ setOrderedCollectionDispatcher(name, itemType, path, dispatcher) {
805
+ return this.#setCustomCollectionDispatcher(name, "orderedCollection", itemType, path, dispatcher);
778
806
  }
779
807
  #setCustomCollectionDispatcher(name, collectionType, itemType, path, dispatcher) {
780
808
  const strName = String(name);
@@ -1297,7 +1325,8 @@ async function handleInbox(request, options) {
1297
1325
  * @param span The OpenTelemetry span for tracing.
1298
1326
  * @returns A promise that resolves to an HTTP response.
1299
1327
  */
1300
- async function handleInboxInternal(request, { recipient, context: ctx, inboxContextFactory, kv, kvPrefixes, queue, actorDispatcher, inboxListeners, inboxErrorHandler, onNotFound, signatureTimeWindow, skipSignatureVerification, tracerProvider }, span) {
1328
+ async function handleInboxInternal(request, parameters, span) {
1329
+ const { recipient, context: ctx, inboxContextFactory, kv, kvPrefixes, queue, actorDispatcher, inboxListeners, inboxErrorHandler, onNotFound, signatureTimeWindow, skipSignatureVerification, tracerProvider } = parameters;
1301
1330
  const logger$1 = (0, __logtape_logtape.getLogger)([
1302
1331
  "fedify",
1303
1332
  "federation",
@@ -1499,7 +1528,8 @@ async function handleInboxInternal(request, { recipient, context: ctx, inboxCont
1499
1528
  kvPrefixes,
1500
1529
  queue,
1501
1530
  span,
1502
- tracerProvider
1531
+ tracerProvider,
1532
+ idempotencyStrategy: parameters.idempotencyStrategy
1503
1533
  });
1504
1534
  if (routeResult === "alreadyProcessed") return new Response(`Activity <${activity.id}> has already been processed.`, {
1505
1535
  status: 202,
@@ -1529,7 +1559,7 @@ async function handleInboxInternal(request, { recipient, context: ctx, inboxCont
1529
1559
  /**
1530
1560
  * Handles a custom collection request.
1531
1561
  * @template TItem The type of items in the collection.
1532
- * @template TParams The parameter names of the requested URL.
1562
+ * @template TParam The parameter names of the requested URL.
1533
1563
  * @template TContext The type of the context, extending {@link RequestContext}.
1534
1564
  * @template TContextData The context data to pass to the `TContext`.
1535
1565
  * @param request The HTTP request.
@@ -1548,7 +1578,7 @@ async function _handleCustomCollection(request, { name, values, context: context
1548
1578
  /**
1549
1579
  * Handles an ordered collection request.
1550
1580
  * @template TItem The type of items in the collection.
1551
- * @template TParams The parameter names of the requested URL.
1581
+ * @template TParam The parameter names of the requested URL.
1552
1582
  * @template TContext The type of the context, extending {@link RequestContext}.
1553
1583
  * @template TContextData The context data to pass to the `TContext`.
1554
1584
  * @param request The HTTP request.
@@ -1569,7 +1599,7 @@ async function _handleOrderedCollection(request, { name, values, context: contex
1569
1599
  * The main flow is on `getCollection`, `dispatch`.
1570
1600
  *
1571
1601
  * @template TItem The type of items in the collection.
1572
- * @template TParams The parameter names of the requested URL.
1602
+ * @template TParam The parameter names of the requested URL.
1573
1603
  * @template TContext The type of the context. {@link Context} or {@link RequestContext}.
1574
1604
  * @template TContextData The context data to pass to the `TContext`.
1575
1605
  * @template TCollection The type of the collection, extending {@link Collection}.
@@ -1603,14 +1633,14 @@ var CustomCollectionHandler = class {
1603
1633
  #collection = null;
1604
1634
  /**
1605
1635
  * Creates a new CustomCollection instance.
1606
- * @param {string} name The name of the collection.
1607
- * @param {TParams} values The parameter values for the collection.
1608
- * @param {TContext} context The request context.
1609
- * @param {CustomCollectionCallbacks} callbacks The collection callbacks.
1610
- * @param {TracerProvider} tracerProvider The tracer provider for telemetry.
1611
- * @param {ConstructorWithTypeId<TCollection>} Collection The Collection constructor.
1612
- * @param {ConstructorWithTypeId<TCollectionPage>} CollectionPage The CollectionPage constructor.
1613
- * @param {(item: TItem) => boolean} filterPredicate Optional filter predicate for items.
1636
+ * @param name The name of the collection.
1637
+ * @param values The parameter values for the collection.
1638
+ * @param context The request context.
1639
+ * @param callbacks The collection callbacks.
1640
+ * @param tracerProvider The tracer provider for telemetry.
1641
+ * @param Collection The Collection constructor.
1642
+ * @param CollectionPage The CollectionPage constructor.
1643
+ * @param filterPredicate Optional filter predicate for items.
1614
1644
  */
1615
1645
  constructor(name, values, context$2, callbacks, tracerProvider = __opentelemetry_api.trace.getTracerProvider(), Collection$1, CollectionPage$1, filterPredicate) {
1616
1646
  this.name = name;
@@ -1735,7 +1765,7 @@ var CustomCollectionHandler = class {
1735
1765
  /**
1736
1766
  * Creates a function to wrap the dispatcher so tracing can be applied.
1737
1767
  * @param params Parameters including cursor and total items.
1738
- * @returns {(span: Span) => Promise<PageItems<TItem>>} A function that handles the span operation.
1768
+ * @returns A function that handles the span operation.
1739
1769
  */
1740
1770
  spanPages = ({ totalItems = null, cursor = null }) => async (span) => {
1741
1771
  try {
@@ -1756,23 +1786,23 @@ var CustomCollectionHandler = class {
1756
1786
  };
1757
1787
  /**
1758
1788
  * Dispatches the collection request to get items.
1759
- * @param {string | null} cursor The cursor for pagination, or null for the first page.
1760
- * @returns {Promise<PageItems<TItem>>} A promise that resolves to the page items.
1789
+ * @param cursor The cursor for pagination, or null for the first page.
1790
+ * @returns A promise that resolves to the page items.
1761
1791
  */
1762
1792
  async dispatch(cursor = null) {
1763
1793
  return await this.#dispatcher(this.context, this.values, cursor) ?? new ItemsNotFoundError().throw();
1764
1794
  }
1765
1795
  /**
1766
1796
  * Filters the items in the collection.
1767
- * @param {TItem[]} items The items to filter.
1768
- * @returns {(Object | Link | URL)[]} The filtered items.
1797
+ * @param items The items to filter.
1798
+ * @returns The filtered items.
1769
1799
  */
1770
1800
  filterItems(items) {
1771
1801
  return filterCollectionItems(items, this.name, this.filterPredicate);
1772
1802
  }
1773
1803
  /**
1774
1804
  * Appends a cursor to the URL if it exists.
1775
- * @param {string | null | undefined} cursor The cursor to append, or null/undefined.
1805
+ * @param cursor The cursor to append, or null/undefined.
1776
1806
  * @returns The URL with cursor appended, or null if cursor is null/undefined.
1777
1807
  */
1778
1808
  appendToUrl(cursor) {
@@ -1780,8 +1810,7 @@ var CustomCollectionHandler = class {
1780
1810
  }
1781
1811
  /**
1782
1812
  * Gets the stored collection or collection page.
1783
- * @returns {Promise<TCollection | TCollectionPage>} A promise that resolves to
1784
- the collection or collection page.
1813
+ * @returns A promise that resolves to the collection or collection page.
1785
1814
  */
1786
1815
  get collection() {
1787
1816
  if (this.#collection === null) this.#collection = this.getCollection();
@@ -1789,8 +1818,8 @@ var CustomCollectionHandler = class {
1789
1818
  }
1790
1819
  /**
1791
1820
  * Gets the total number of items in the collection.
1792
- * @returns {Promise<number | null>} A promise that
1793
- resolves to the total items count, or null if not available.
1821
+ * @returns A promise that resolves to the total items count,
1822
+ * or null if not available.
1794
1823
  */
1795
1824
  get totalItems() {
1796
1825
  if (this.#totalItems === void 0) this.totalItems = this.callbacks.counter?.(this.context, this.values);
@@ -1806,8 +1835,8 @@ var CustomCollectionHandler = class {
1806
1835
  }
1807
1836
  /**
1808
1837
  * Gets the first cursor for pagination.
1809
- * @returns {Promise<string | null>} A promise that resolves to the first cursor,
1810
- or null if not available.
1838
+ * @returns A promise that resolves to the first cursor,
1839
+ * or null if not available.
1811
1840
  */
1812
1841
  get firstCursor() {
1813
1842
  const cursor = this.callbacks.firstCursor?.(this.context, this.values);
@@ -3096,7 +3125,8 @@ var FederationImpl = class extends FederationBuilderImpl {
3096
3125
  onNotFound,
3097
3126
  signatureTimeWindow: this.signatureTimeWindow,
3098
3127
  skipSignatureVerification: this.skipSignatureVerification,
3099
- tracerProvider: this.tracerProvider
3128
+ tracerProvider: this.tracerProvider,
3129
+ idempotencyStrategy: this.idempotencyStrategy
3100
3130
  });
3101
3131
  case "following": return await handleCollection(request, {
3102
3132
  name: "following",
@@ -3846,7 +3876,8 @@ var ContextImpl = class ContextImpl {
3846
3876
  kvPrefixes: this.federation.kvPrefixes,
3847
3877
  queue: this.federation.inboxQueue,
3848
3878
  span,
3849
- tracerProvider: options.tracerProvider ?? this.tracerProvider
3879
+ tracerProvider: options.tracerProvider ?? this.tracerProvider,
3880
+ idempotencyStrategy: this.federation.idempotencyStrategy
3850
3881
  });
3851
3882
  return routeResult === "alreadyProcessed" || routeResult === "enqueued" || routeResult === "unsupportedActivity" || routeResult === "success";
3852
3883
  }
@@ -0,0 +1,17 @@
1
+
2
+ import { Temporal } from "@js-temporal/polyfill";
3
+ import { URLPattern } from "urlpattern-polyfill";
4
+
5
+ import "./transformers-BFT6d7J5.js";
6
+ import "./docloader-isD0ntZv.js";
7
+ import "./actor-B0LpLKRw.js";
8
+ import { ContextImpl, FederationImpl, InboxContextImpl, KvSpecDeterminer, createFederation } from "./middleware-BfhSHVoJ.js";
9
+ import "./lookup-BBTRFcU5.js";
10
+ import "./key-CRhmBE03.js";
11
+ import "./http-MyYS6o7t.js";
12
+ import "./proof-B_9fbF3f.js";
13
+ import "./types-DHq9gRM4.js";
14
+ import "./authdocloader-DI67R2Ku.js";
15
+ import "./vocab-DxoBe7PI.js";
16
+
17
+ export { FederationImpl };
@@ -1,5 +1,5 @@
1
1
  import { DocumentLoader, GetUserAgentOptions } from "./docloader-D-MrRyHl.cjs";
2
- import { Collection, Link, Object as Object$1 } from "./vocab-BzGg7ltX.cjs";
2
+ import { Collection, Link, Object as Object$1 } from "./vocab-Cfs0937i.cjs";
3
3
  import { TracerProvider } from "@opentelemetry/api";
4
4
 
5
5
  //#region src/vocab/lookup.d.ts
@@ -18,6 +18,24 @@ interface LookupObjectOptions {
18
18
  * @since 0.8.0
19
19
  */
20
20
  contextLoader?: DocumentLoader;
21
+ /**
22
+ * Whether to allow fetching an object with an `@id` having a different
23
+ * origin than the object's URL. This is not recommended, as it may
24
+ * lead to security issues. Only use this option if you know what you
25
+ * are doing.
26
+ *
27
+ * How to handle the case when an object's `@id` has a different origin
28
+ * than the object's URL:
29
+ *
30
+ * - `"ignore"` (default): Do not return the object, and log a warning.
31
+ * - `"throw"`: Throw an error.
32
+ * - `"trust"`: Bypass the check and return the object anyway. This
33
+ * is not recommended, as it may lead to security issues. Only use
34
+ * this option if you know what you are doing.
35
+ *
36
+ * @since 1.9.0
37
+ */
38
+ crossOrigin?: "ignore" | "throw" | "trust";
21
39
  /**
22
40
  * The options for making `User-Agent` header.
23
41
  * If a string is given, it is used as the `User-Agent` header value.
@@ -1,7 +1,7 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  import { URLPattern } from "urlpattern-polyfill";
3
3
  import { DocumentLoader, GetUserAgentOptions } from "./docloader-CxWcuWqQ.js";
4
- import { Collection, Link, Object as Object$1 } from "./vocab-BEEm2I6u.js";
4
+ import { Collection, Link, Object as Object$1 } from "./vocab-CDHNj5zp.js";
5
5
  import { TracerProvider } from "@opentelemetry/api";
6
6
 
7
7
  //#region src/vocab/lookup.d.ts
@@ -20,6 +20,24 @@ interface LookupObjectOptions {
20
20
  * @since 0.8.0
21
21
  */
22
22
  contextLoader?: DocumentLoader;
23
+ /**
24
+ * Whether to allow fetching an object with an `@id` having a different
25
+ * origin than the object's URL. This is not recommended, as it may
26
+ * lead to security issues. Only use this option if you know what you
27
+ * are doing.
28
+ *
29
+ * How to handle the case when an object's `@id` has a different origin
30
+ * than the object's URL:
31
+ *
32
+ * - `"ignore"` (default): Do not return the object, and log a warning.
33
+ * - `"throw"`: Throw an error.
34
+ * - `"trust"`: Bypass the check and return the object anyway. This
35
+ * is not recommended, as it may lead to security issues. Only use
36
+ * this option if you know what you are doing.
37
+ *
38
+ * @since 1.9.0
39
+ */
40
+ crossOrigin?: "ignore" | "throw" | "trust";
23
41
  /**
24
42
  * The options for making `User-Agent` header.
25
43
  * If a string is given, it is used as the `User-Agent` header value.