@fedify/fedify 2.4.0-dev.2099 → 2.4.0-dev.2108

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 (84) hide show
  1. package/dist/{builder-Bno54o_-.mjs → builder-BRlYEsrV.mjs} +28 -4
  2. package/dist/compat/mod.d.cts +1 -1
  3. package/dist/compat/mod.d.ts +1 -1
  4. package/dist/compat/transformers.test.mjs +1 -1
  5. package/dist/{compound-proof-X3SxXVbc.mjs → compound-proof-CHGINiJg.mjs} +2 -2
  6. package/dist/{context-MORIQJIh.d.ts → context-B4F4kGJq.d.ts} +165 -21
  7. package/dist/{context-DlZhxdFT.mjs → context-CoNRxGYp.mjs} +2 -1
  8. package/dist/{context-C43spTGI.d.cts → context-Cqx9M_zO.d.cts} +165 -21
  9. package/dist/{deno-dxdvl2XZ.mjs → deno-CC4RKEEp.mjs} +1 -1
  10. package/dist/{docloader-eBxQDsk9.mjs → docloader-D3_m98fe.mjs} +2 -2
  11. package/dist/federation/builder.test.mjs +1 -1
  12. package/dist/federation/compound-fanout.test.mjs +3 -3
  13. package/dist/federation/handler-compound-proof.test.mjs +4 -4
  14. package/dist/federation/handler.test.mjs +119 -6
  15. package/dist/federation/hashlink-media.test.mjs +2 -2
  16. package/dist/federation/idempotency.test.mjs +2 -2
  17. package/dist/federation/metrics.test.mjs +1 -1
  18. package/dist/federation/middleware.test.mjs +185 -8
  19. package/dist/federation/mod.cjs +1 -1
  20. package/dist/federation/mod.d.cts +3 -3
  21. package/dist/federation/mod.d.ts +3 -3
  22. package/dist/federation/mod.js +1 -1
  23. package/dist/federation/outgoing-proof.test.mjs +5 -5
  24. package/dist/federation/portable-actor.test.d.mts +2 -0
  25. package/dist/federation/portable-actor.test.mjs +446 -0
  26. package/dist/federation/portable-gateway-keys.test.mjs +4 -4
  27. package/dist/federation/portable-inbox.test.mjs +25 -4
  28. package/dist/federation/portable.test.mjs +31 -4
  29. package/dist/federation/send.test.mjs +3 -3
  30. package/dist/federation/tasks/enqueue.test.mjs +2 -2
  31. package/dist/federation/tasks/tasks.test.mjs +3 -3
  32. package/dist/federation/temporal.test.mjs +1 -1
  33. package/dist/federation/webfinger.test.mjs +2 -2
  34. package/dist/{federation-C4Ef3JKa.cjs → federation-dqo6ZzgT.cjs} +115 -23
  35. package/dist/{http-C8cZTE3Y.cjs → http-B7wEqv49.cjs} +1 -1
  36. package/dist/{http-DsgawTd8.mjs → http-CHEYA5fH.mjs} +4 -4
  37. package/dist/{http-D-rbr_Sy.js → http-CaUBCHYJ.js} +1 -1
  38. package/dist/{key-DYfmjnmp.mjs → key-B8u1vdvF.mjs} +2 -2
  39. package/dist/{kv-cache-Dvd-Q-E2.cjs → kv-cache-0pYMPrkL.cjs} +1 -1
  40. package/dist/{kv-cache-EvOgrFsS.mjs → kv-cache-CTdvf_Iq.mjs} +1 -1
  41. package/dist/{kv-cache-DIxwMeNi.js → kv-cache-ibncHN1D.js} +1 -1
  42. package/dist/{ld-B00wWHzc.mjs → ld-BTMJHEGV.mjs} +3 -3
  43. package/dist/{metrics-BP3vdBpb.mjs → metrics-CF1TEvdS.mjs} +1 -1
  44. package/dist/{middleware-Br1_d-Ga.mjs → middleware-B-rZ7oE-.mjs} +91 -23
  45. package/dist/{middleware-CeBVBa61.mjs → middleware-DCMTJT3_.mjs} +1 -1
  46. package/dist/{middleware-CcXMe400.js → middleware-Dl-Y_ZlC.js} +107 -15
  47. package/dist/{mod-BL5BQHCq.d.ts → mod-4s_XgF17.d.ts} +1 -1
  48. package/dist/{mod-DMI4DbOo.d.cts → mod-BuFmStNT.d.cts} +1 -1
  49. package/dist/mod.cjs +5 -5
  50. package/dist/mod.d.cts +4 -4
  51. package/dist/mod.d.ts +4 -4
  52. package/dist/mod.js +5 -5
  53. package/dist/nodeinfo/handler.test.mjs +2 -2
  54. package/dist/{owner-DSzH7wro.cjs → owner-CGnHPl4k.cjs} +1 -1
  55. package/dist/{owner-BJPDRDRq.mjs → owner-CY--JSqO.mjs} +3 -3
  56. package/dist/{owner-U12fDpQW.js → owner-M8dOKEl6.js} +1 -1
  57. package/dist/{portable-key-D0mWbV9G.mjs → portable-key-C0-ghkgM.mjs} +1 -1
  58. package/dist/{proof-ChjBwnep.mjs → proof-DDw0i9b1.mjs} +4 -4
  59. package/dist/{send-yFX0E-ye.mjs → send-CU3sHGPt.mjs} +3 -3
  60. package/dist/sig/compound-proof-discovery.test.mjs +1 -1
  61. package/dist/sig/compound-proof-producer.test.mjs +1 -1
  62. package/dist/sig/compound-proof-verification.test.mjs +2 -2
  63. package/dist/sig/compound-proof.test.mjs +2 -2
  64. package/dist/sig/http.test.mjs +2 -2
  65. package/dist/sig/key.test.mjs +1 -1
  66. package/dist/sig/ld.test.mjs +2 -2
  67. package/dist/sig/mod.cjs +3 -3
  68. package/dist/sig/mod.js +3 -3
  69. package/dist/sig/owner.test.mjs +1 -1
  70. package/dist/sig/portable-collection.test.mjs +2 -2
  71. package/dist/sig/portable-key.test.mjs +3 -3
  72. package/dist/sig/proof.test.mjs +3 -3
  73. package/dist/{sig-B689Nj7y.cjs → sig-C2CORtvg.cjs} +2 -2
  74. package/dist/{sig-C85KqAcx.js → sig-fycq7sOr.js} +2 -2
  75. package/dist/{temporal-Dl9x-Qw4.mjs → temporal-NHiSpGcW.mjs} +1 -1
  76. package/dist/testing/kv.test.mjs +1 -1
  77. package/dist/testing/mod.d.mts +164 -20
  78. package/dist/testing/mod.mjs +2 -2
  79. package/dist/{testing-CO_cEvQc.mjs → testing-BWq1dCzx.mjs} +1 -1
  80. package/dist/utils/docloader.test.mjs +2 -2
  81. package/dist/utils/kv-cache.test.mjs +1 -1
  82. package/dist/utils/mod.cjs +1 -1
  83. package/dist/utils/mod.js +1 -1
  84. package/package.json +6 -6
@@ -1,7 +1,7 @@
1
1
  import "temporal-polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as version, t as name } from "./deno-dxdvl2XZ.mjs";
4
+ import { n as version, t as name } from "./deno-CC4RKEEp.mjs";
5
5
  import { s as isPortableId } from "./portable-key-id-Bva5iT3W.mjs";
6
6
  import { t as ActivityListenerSet } from "./activity-listener-C-BSbKI7.mjs";
7
7
  import { getLogger } from "@logtape/logtape";
@@ -89,7 +89,7 @@ var FederationBuilderImpl = class {
89
89
  * specified.
90
90
  */
91
91
  async build(options) {
92
- const { FederationImpl } = await import("./middleware-CeBVBa61.mjs");
92
+ const { FederationImpl } = await import("./middleware-DCMTJT3_.mjs");
93
93
  const f = new FederationImpl(options);
94
94
  const trailingSlashInsensitiveValue = f.router.trailingSlashInsensitive;
95
95
  f.router = this.router.clone();
@@ -297,8 +297,8 @@ var FederationBuilderImpl = class {
297
297
  const variables = Router.variables(path);
298
298
  this.router.add(path, routeName);
299
299
  const callbacks = {
300
- dispatcher: (ctx, values) => {
301
- return this._getTracer().startActiveSpan("activitypub.dispatch_object", {
300
+ dispatcher: async (ctx, values) => {
301
+ const object = await this._getTracer().startActiveSpan("activitypub.dispatch_object", {
302
302
  kind: SpanKind.SERVER,
303
303
  attributes: {
304
304
  "fedify.object.type": cls.typeId.href,
@@ -321,6 +321,8 @@ var FederationBuilderImpl = class {
321
321
  span.end();
322
322
  }
323
323
  });
324
+ if (object instanceof Tombstone) warnMismatchedTombstoneId(ctx, cls, values, object);
325
+ return object;
324
326
  },
325
327
  parameters: variables
326
328
  };
@@ -690,6 +692,28 @@ var FederationBuilderImpl = class {
690
692
  function createFederationBuilder() {
691
693
  return new FederationBuilderImpl();
692
694
  }
695
+ function warnMismatchedTombstoneId(context, cls, values, tombstone) {
696
+ const logger = getLogger([
697
+ "fedify",
698
+ "federation",
699
+ "object"
700
+ ]);
701
+ if (tombstone.id == null) {
702
+ logger.warn("Object dispatcher for {class} returned a tombstone without an id property. Set the property with Context.getObjectUri().", {
703
+ class: cls.name,
704
+ values
705
+ });
706
+ return;
707
+ }
708
+ if (tombstone.id.protocol === "ap:" || tombstone.id.protocol === "ap+ef61:") return;
709
+ const expected = context.getObjectUri(cls, values);
710
+ if (tombstone.id.href !== expected.href) logger.warn("Object dispatcher for {class} returned a tombstone with an id property {tombstoneId} that does not match the object URI {objectUri}. Set the property with Context.getObjectUri().", {
711
+ class: cls.name,
712
+ values,
713
+ tombstoneId: tombstone.id.href,
714
+ objectUri: expected.href
715
+ });
716
+ }
693
717
  /**
694
718
  * Warns about an FEP-ef61 portable actor identified by a compatible identifier
695
719
  * that is malformed, or is not on the actor's first gateway, where FEP-ef61
@@ -1,5 +1,5 @@
1
1
  /// <reference lib="esnext.temporal" />
2
- import { Xt as ActivityTransformer, n as Context } from "../context-C43spTGI.cjs";
2
+ import { Zt as ActivityTransformer, n as Context } from "../context-Cqx9M_zO.cjs";
3
3
  import { Activity } from "@fedify/vocab";
4
4
 
5
5
  //#region src/compat/transformers.d.ts
@@ -1,5 +1,5 @@
1
1
  /// <reference lib="esnext.temporal" />
2
- import { Xt as ActivityTransformer, n as Context } from "../context-MORIQJIh.js";
2
+ import { Zt as ActivityTransformer, n as Context } from "../context-B4F4kGJq.js";
3
3
  import { Activity } from "@fedify/vocab";
4
4
 
5
5
  //#region src/compat/transformers.d.ts
@@ -5,7 +5,7 @@ import { t as MemoryKvStore } from "../kv-DCHkaJ9-.mjs";
5
5
  import { t as assertEquals } from "../assert_equals-Z6IcEbWU.mjs";
6
6
  import { t as assertInstanceOf } from "../assert_instance_of-mrXWWNY-.mjs";
7
7
  import { t as assert } from "../assert-D1Eafmd_.mjs";
8
- import { E as autoIdAssigner, T as actorDehydrator, n as FederationImpl } from "../middleware-Br1_d-Ga.mjs";
8
+ import { E as autoIdAssigner, T as actorDehydrator, n as FederationImpl } from "../middleware-B-rZ7oE-.mjs";
9
9
  import { Follow, Person } from "@fedify/vocab";
10
10
  import { test } from "@fedify/fixture";
11
11
  //#region src/compat/transformers.test.ts
@@ -3,8 +3,8 @@ import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
4
  import { s as isPortableId, t as getCanonicalPortableId } from "./portable-key-id-Bva5iT3W.mjs";
5
5
  import { n as preloadedOnlyDocumentLoader } from "./public-audience--klBIOk1.mjs";
6
- import { c as getNormalizationContextLoader } from "./ld-B00wWHzc.mjs";
7
- import { a as verifyMapLocalProof, c as verifyPortableObjectProofPolicy } from "./proof-ChjBwnep.mjs";
6
+ import { c as getNormalizationContextLoader } from "./ld-BTMJHEGV.mjs";
7
+ import { a as verifyMapLocalProof, c as verifyPortableObjectProofPolicy } from "./proof-DDw0i9b1.mjs";
8
8
  import { fromCompatibleEf61Id, parseIri } from "@fedify/vocab-runtime";
9
9
  import jsonld from "@fedify/vocab-runtime/jsonld";
10
10
  //#region src/sig/compound-proof.ts
@@ -182,14 +182,18 @@ type ActorAliasMapper<TContextData> = (context: RequestContext<TContextData>, re
182
182
  username: string;
183
183
  } | null>;
184
184
  /**
185
- * A callback that dispatches an object.
185
+ * A callback that dispatches an object or a {@link Tombstone}.
186
+ *
187
+ * Return a {@link Tombstone} if the object has been deleted; Fedify then
188
+ * responds with `410 Gone` and the serialized tombstone. Return `null` if
189
+ * the object is not found.
186
190
  *
187
191
  * @template TContextData The context data to pass to the {@link Context}.
188
192
  * @template TObject The type of object to dispatch.
189
193
  * @template TParam The parameter names of the requested URL.
190
194
  * @since 0.7.0
191
195
  */
192
- type ObjectDispatcher<TContextData, TObject extends Object$1, TParam extends string> = (context: RequestContext<TContextData>, values: Record<TParam, string>) => TObject | null | Promise<TObject | null>;
196
+ type ObjectDispatcher<TContextData, TObject extends Object$1, TParam extends string> = (context: RequestContext<TContextData>, values: Record<TParam, string>) => TObject | Tombstone | null | Promise<TObject | Tombstone | null>;
193
197
  /**
194
198
  * A callback that dispatches a collection.
195
199
  *
@@ -1540,7 +1544,9 @@ interface Federatable<TContextData> extends TaskRegistry<TContextData> {
1540
1544
  * based on URI Template
1541
1545
  * ([RFC 6570](https://tools.ietf.org/html/rfc6570)). The path
1542
1546
  * must have one or more variables.
1543
- * @param dispatcher An object dispatcher callback to register.
1547
+ * @param dispatcher An object dispatcher callback to register. It may
1548
+ * return an object, a `Tombstone` if the object has been
1549
+ * deleted, or `null` if the object is not found.
1544
1550
  */
1545
1551
  setObjectDispatcher<TObject extends Object$1, TParam extends string>(cls: ConstructorWithTypeId<TObject>, path: `${string}{${TParam}}${string}{${TParam}}${string}{${TParam}}${string}{${TParam}}${string}{${TParam}}${string}{${TParam}}${string}`, dispatcher: ObjectDispatcher<TContextData, TObject, TParam>): ObjectCallbackSetters<TContextData, TObject, TParam>;
1546
1552
  /**
@@ -1554,7 +1560,9 @@ interface Federatable<TContextData> extends TaskRegistry<TContextData> {
1554
1560
  * based on URI Template
1555
1561
  * ([RFC 6570](https://tools.ietf.org/html/rfc6570)). The path
1556
1562
  * must have one or more variables.
1557
- * @param dispatcher An object dispatcher callback to register.
1563
+ * @param dispatcher An object dispatcher callback to register. It may
1564
+ * return an object, a `Tombstone` if the object has been
1565
+ * deleted, or `null` if the object is not found.
1558
1566
  */
1559
1567
  setObjectDispatcher<TObject extends Object$1, TParam extends string>(cls: ConstructorWithTypeId<TObject>, path: `${string}{${TParam}}${string}{${TParam}}${string}{${TParam}}${string}{${TParam}}${string}{${TParam}}${string}`, dispatcher: ObjectDispatcher<TContextData, TObject, TParam>): ObjectCallbackSetters<TContextData, TObject, TParam>;
1560
1568
  /**
@@ -1568,7 +1576,9 @@ interface Federatable<TContextData> extends TaskRegistry<TContextData> {
1568
1576
  * based on URI Template
1569
1577
  * ([RFC 6570](https://tools.ietf.org/html/rfc6570)). The path
1570
1578
  * must have one or more variables.
1571
- * @param dispatcher An object dispatcher callback to register.
1579
+ * @param dispatcher An object dispatcher callback to register. It may
1580
+ * return an object, a `Tombstone` if the object has been
1581
+ * deleted, or `null` if the object is not found.
1572
1582
  */
1573
1583
  setObjectDispatcher<TObject extends Object$1, TParam extends string>(cls: ConstructorWithTypeId<TObject>, path: `${string}{${TParam}}${string}{${TParam}}${string}{${TParam}}${string}{${TParam}}${string}`, dispatcher: ObjectDispatcher<TContextData, TObject, TParam>): ObjectCallbackSetters<TContextData, TObject, TParam>;
1574
1584
  /**
@@ -1582,7 +1592,9 @@ interface Federatable<TContextData> extends TaskRegistry<TContextData> {
1582
1592
  * based on URI Template
1583
1593
  * ([RFC 6570](https://tools.ietf.org/html/rfc6570)). The path
1584
1594
  * must have one or more variables.
1585
- * @param dispatcher An object dispatcher callback to register.
1595
+ * @param dispatcher An object dispatcher callback to register. It may
1596
+ * return an object, a `Tombstone` if the object has been
1597
+ * deleted, or `null` if the object is not found.
1586
1598
  */
1587
1599
  setObjectDispatcher<TObject extends Object$1, TParam extends string>(cls: ConstructorWithTypeId<TObject>, path: `${string}${Rfc6570Expression<TParam>}${string}${Rfc6570Expression<TParam>}${string}${Rfc6570Expression<TParam>}${string}`, dispatcher: ObjectDispatcher<TContextData, TObject, TParam>): ObjectCallbackSetters<TContextData, TObject, TParam>;
1588
1600
  /**
@@ -1596,7 +1608,9 @@ interface Federatable<TContextData> extends TaskRegistry<TContextData> {
1596
1608
  * based on URI Template
1597
1609
  * ([RFC 6570](https://tools.ietf.org/html/rfc6570)). The path
1598
1610
  * must have one or more variables.
1599
- * @param dispatcher An object dispatcher callback to register.
1611
+ * @param dispatcher An object dispatcher callback to register. It may
1612
+ * return an object, a `Tombstone` if the object has been
1613
+ * deleted, or `null` if the object is not found.
1600
1614
  */
1601
1615
  setObjectDispatcher<TObject extends Object$1, TParam extends string>(cls: ConstructorWithTypeId<TObject>, path: `${string}${Rfc6570Expression<TParam>}${string}${Rfc6570Expression<TParam>}${string}`, dispatcher: ObjectDispatcher<TContextData, TObject, TParam>): ObjectCallbackSetters<TContextData, TObject, TParam>;
1602
1616
  /**
@@ -1610,7 +1624,9 @@ interface Federatable<TContextData> extends TaskRegistry<TContextData> {
1610
1624
  * based on URI Template
1611
1625
  * ([RFC 6570](https://tools.ietf.org/html/rfc6570)). The path
1612
1626
  * must have one or more variables.
1613
- * @param dispatcher An object dispatcher callback to register.
1627
+ * @param dispatcher An object dispatcher callback to register. It may
1628
+ * return an object, a `Tombstone` if the object has been
1629
+ * deleted, or `null` if the object is not found.
1614
1630
  */
1615
1631
  setObjectDispatcher<TObject extends Object$1, TParam extends string>(cls: ConstructorWithTypeId<TObject>, path: `${string}${Rfc6570Expression<TParam>}${string}`, dispatcher: ObjectDispatcher<TContextData, TObject, TParam>): ObjectCallbackSetters<TContextData, TObject, TParam>;
1616
1632
  /**
@@ -2927,6 +2943,37 @@ interface Context<TContextData> {
2927
2943
  */
2928
2944
  getActorUri(identifier: string): URL;
2929
2945
  /**
2946
+ * Builds the [FEP-ef61] portable ID of an actor with the given identifier
2947
+ * under the given DID authority.
2948
+ *
2949
+ * The path is the same as the one {@link Context.getActorUri} builds, but
2950
+ * the result is an `ap+ef61:` URI whose authority is the DID, e.g.,
2951
+ * `ap+ef61://did:key:z6Mk.../users/alice`. Such an actor can be served
2952
+ * through the FEP-ef61 gateway endpoint,
2953
+ * `/.well-known/apgateway/did:key:z6Mk.../users/alice`, by the same actor
2954
+ * dispatcher.
2955
+ *
2956
+ * The returned `URL` keeps the DID authority percent-encoded, because
2957
+ * the `URL` class cannot represent the canonical form. Use `formatIri()`
2958
+ * from `@fedify/vocab-runtime` to get the canonical string, e.g.,
2959
+ * `ap+ef61://did:key:z6Mk.../users/alice`.
2960
+ *
2961
+ * [FEP-ef61]: https://w3id.org/fep/ef61
2962
+ *
2963
+ * @param identifier The actor's identifier.
2964
+ * @param authority The DID that controls the actor, e.g.,
2965
+ * `did:key:z6Mk...`. It must be a bare DID, without
2966
+ * a path, query, or fragment. A `did:key` DID must be
2967
+ * encoded in base58-btc, as FEP-ef61 requires; see
2968
+ * `exportDidKey()` from `@fedify/vocab-runtime`.
2969
+ * @returns The actor's portable ID.
2970
+ * @throws {RouterError} If no actor dispatcher is available.
2971
+ * @throws {TypeError} If the authority is not a DID, or it is a `did:key`
2972
+ * DID that is not encoded in base58-btc.
2973
+ * @since 2.4.0
2974
+ */
2975
+ getPortableActorUri(identifier: string, authority: string): URL;
2976
+ /**
2930
2977
  * Builds the URI of an object with the given class and values.
2931
2978
  * @param cls The class of the object.
2932
2979
  * @param values The values to pass to the object dispatcher.
@@ -2961,7 +3008,9 @@ interface Context<TContextData> {
2961
3008
  * a path, query, or fragment.
2962
3009
  * @returns The object's portable ID.
2963
3010
  * @throws {RouterError} If no object dispatcher is available for the class.
2964
- * @throws {TypeError} If values are invalid or the authority is not a DID.
3011
+ * @throws {TypeError} If values are invalid, or the authority is not a DID
3012
+ * or is a `did:key` DID that is not encoded in
3013
+ * base58-btc.
2965
3014
  * @since 2.4.0
2966
3015
  */
2967
3016
  getPortableObjectUri<TObject extends Object$1>(cls: ConstructorWithTypeId<TObject>, values: Record<string, string>, authority: string): URL;
@@ -2990,7 +3039,8 @@ interface Context<TContextData> {
2990
3039
  * a path, query, or fragment.
2991
3040
  * @returns The inbox's portable ID.
2992
3041
  * @throws {RouterError} If no inbox path is registered.
2993
- * @throws {TypeError} If the authority is not a DID.
3042
+ * @throws {TypeError} If the authority is not a DID, or it is a `did:key`
3043
+ * DID that is not encoded in base58-btc.
2994
3044
  * @since 2.4.0
2995
3045
  */
2996
3046
  getPortableInboxUri(identifier: string, authority: string): URL;
@@ -3357,6 +3407,23 @@ interface GetActorOptions {
3357
3407
  readonly tombstone?: "suppress" | "passthrough";
3358
3408
  }
3359
3409
  /**
3410
+ * Options for {@link RequestContext.getObject}.
3411
+ * @since 2.4.0
3412
+ */
3413
+ interface GetObjectOptions {
3414
+ /**
3415
+ * Controls how tombstoned objects are returned.
3416
+ *
3417
+ * By default, or if set to `"suppress"`, a {@link Tombstone} is returned as
3418
+ * `null`, unless it is an instance of the requested class, e.g., when
3419
+ * the requested class is `Object` or `Tombstone` itself. In that case,
3420
+ * the tombstone is returned as is, as it is an object of the requested
3421
+ * class. Set this to `"passthrough"` to always receive a {@link Tombstone}
3422
+ * result instead of `null`.
3423
+ */
3424
+ readonly tombstone?: "suppress" | "passthrough";
3425
+ }
3426
+ /**
3360
3427
  * A context for a request.
3361
3428
  */
3362
3429
  interface RequestContext<TContextData> extends Context<TContextData> {
@@ -3371,12 +3438,13 @@ interface RequestContext<TContextData> extends Context<TContextData> {
3371
3438
  /**
3372
3439
  * Information about the [FEP-ef61] portable object requested through
3373
3440
  * the gateway endpoint, e.g.,
3374
- * `GET /.well-known/apgateway/did:key:z6Mk.../notes/123`. It is
3375
- * `undefined` for ordinary requests.
3441
+ * `GET /.well-known/apgateway/did:key:z6Mk.../notes/123`, which is served
3442
+ * by an object dispatcher or the actor dispatcher. It is `undefined` for
3443
+ * ordinary requests.
3376
3444
  *
3377
3445
  * The authority comes from the request path, so it is not evidence that
3378
- * this server hosts objects for the DID. An object dispatcher has to check
3379
- * that by itself.
3446
+ * this server hosts objects for the DID. An object dispatcher or the actor
3447
+ * dispatcher has to check that by itself.
3380
3448
  *
3381
3449
  * It describes the incoming request, so it stays the same in contexts
3382
3450
  * derived from this one, e.g., by {@link RequestContext.getObject}.
@@ -3386,6 +3454,31 @@ interface RequestContext<TContextData> extends Context<TContextData> {
3386
3454
  */
3387
3455
  readonly portableRequest?: PortableRequest;
3388
3456
  /**
3457
+ * Builds the [FEP-ef61] portable ID of an actor with the given identifier.
3458
+ * It works the same as {@link Context.getPortableActorUri}, except that
3459
+ * the authority can be omitted while handling a portable gateway request.
3460
+ * In that case, the DID in {@link RequestContext.portableRequest} is used.
3461
+ *
3462
+ * The DID in the request comes from the request path, so the default is
3463
+ * only a convenience for building IDs; it is not evidence that this server
3464
+ * hosts the actor for the DID.
3465
+ *
3466
+ * [FEP-ef61]: https://w3id.org/fep/ef61
3467
+ *
3468
+ * @param identifier The actor's identifier.
3469
+ * @param authority The DID that controls the actor, e.g.,
3470
+ * `did:key:z6Mk...`. It must be a bare DID, without
3471
+ * a path, query, or fragment. Defaults to the DID of
3472
+ * the requested portable object.
3473
+ * @returns The actor's portable ID.
3474
+ * @throws {RouterError} If no actor dispatcher is available.
3475
+ * @throws {TypeError} If the authority is not a DID, it is a `did:key` DID
3476
+ * that is not encoded in base58-btc, or the authority
3477
+ * is omitted outside a portable gateway request.
3478
+ * @since 2.4.0
3479
+ */
3480
+ getPortableActorUri(identifier: string, authority?: string): URL;
3481
+ /**
3389
3482
  * Builds the [FEP-ef61] portable ID of an object with the given class and
3390
3483
  * values. It works the same as {@link Context.getPortableObjectUri}, except
3391
3484
  * that the authority can be omitted while handling a portable gateway
@@ -3402,9 +3495,10 @@ interface RequestContext<TContextData> extends Context<TContextData> {
3402
3495
  * the requested portable object.
3403
3496
  * @returns The object's portable ID.
3404
3497
  * @throws {RouterError} If no object dispatcher is available for the class.
3405
- * @throws {TypeError} If values are invalid, the authority is not a DID, or
3406
- * the authority is omitted outside a portable gateway
3407
- * request.
3498
+ * @throws {TypeError} If values are invalid, the authority is not a DID,
3499
+ * it is a `did:key` DID that is not encoded in
3500
+ * base58-btc, or the authority is omitted outside
3501
+ * a portable gateway request.
3408
3502
  * @since 2.4.0
3409
3503
  */
3410
3504
  getPortableObjectUri<TObject extends Object$1>(cls: ConstructorWithTypeId<TObject>, values: Record<string, string>, authority?: string): URL;
@@ -3426,8 +3520,9 @@ interface RequestContext<TContextData> extends Context<TContextData> {
3426
3520
  * the requested portable object, if any.
3427
3521
  * @returns The inbox's portable ID.
3428
3522
  * @throws {RouterError} If no inbox path is registered.
3429
- * @throws {TypeError} If the authority is not a DID, or the authority is
3430
- * omitted outside a portable gateway request.
3523
+ * @throws {TypeError} If the authority is not a DID, it is a `did:key` DID
3524
+ * that is not encoded in base58-btc, or the authority
3525
+ * is omitted outside a portable gateway request.
3431
3526
  * @since 2.4.0
3432
3527
  */
3433
3528
  getPortableInboxUri(identifier: string, authority?: string): URL;
@@ -3493,13 +3588,62 @@ interface RequestContext<TContextData> extends Context<TContextData> {
3493
3588
  * @param cls The class to instantiate.
3494
3589
  * @param values The values to pass to the object dispatcher.
3495
3590
  * @returns The object of the given class with the given values, or `null`
3496
- * if the object is not found.
3591
+ * if the object is not found. Tombstoned objects are suppressed
3592
+ * unless the tombstone is an instance of `cls`.
3497
3593
  * @throws {Error} If no object dispatcher is available for the class.
3498
3594
  * @throws {TypeError} If values are invalid.
3499
3595
  * @since 0.7.0
3500
3596
  */
3501
3597
  getObject<TObject extends Object$1>(cls: ConstructorWithTypeId<TObject>, values: Record<string, string>): Promise<TObject | null>;
3502
3598
  /**
3599
+ * Gets an object of the given class, or a {@link Tombstone}, with the given
3600
+ * values.
3601
+ * @param cls The class to instantiate.
3602
+ * @param values The values to pass to the object dispatcher.
3603
+ * @param options Options for getting the object. Set `options.tombstone`
3604
+ * to `"passthrough"` to receive tombstoned objects instead
3605
+ * of `null`.
3606
+ * @returns The object of the given class with the given values,
3607
+ * a tombstone, or `null` if the object is not found.
3608
+ * @throws {Error} If no object dispatcher is available for the class.
3609
+ * @throws {TypeError} If values are invalid.
3610
+ * @since 2.4.0
3611
+ */
3612
+ getObject<TObject extends Object$1>(cls: ConstructorWithTypeId<TObject>, values: Record<string, string>, options: GetObjectOptions & {
3613
+ readonly tombstone: "passthrough";
3614
+ }): Promise<TObject | Tombstone | null>;
3615
+ /**
3616
+ * Gets an object of the given class with the given values.
3617
+ * @param cls The class to instantiate.
3618
+ * @param values The values to pass to the object dispatcher.
3619
+ * @param options Options for getting the object.
3620
+ * @returns The object of the given class with the given values, or `null`
3621
+ * if the object is not found. Tombstoned objects are suppressed
3622
+ * unless `options.tombstone` is `"passthrough"` or the tombstone
3623
+ * is an instance of `cls`.
3624
+ * @throws {Error} If no object dispatcher is available for the class.
3625
+ * @throws {TypeError} If values are invalid.
3626
+ * @since 2.4.0
3627
+ */
3628
+ getObject<TObject extends Object$1>(cls: ConstructorWithTypeId<TObject>, values: Record<string, string>, options: GetObjectOptions & {
3629
+ readonly tombstone?: "suppress" | undefined;
3630
+ }): Promise<TObject | null>;
3631
+ /**
3632
+ * Gets an object of the given class, or a {@link Tombstone}, with the given
3633
+ * values.
3634
+ * @param cls The class to instantiate.
3635
+ * @param values The values to pass to the object dispatcher.
3636
+ * @param options Options for getting the object.
3637
+ * @returns The object of the given class with the given values,
3638
+ * a tombstone, or `null` if the object is not found. This broad
3639
+ * overload is used when the caller passes an options value whose
3640
+ * `tombstone` mode is not known statically.
3641
+ * @throws {Error} If no object dispatcher is available for the class.
3642
+ * @throws {TypeError} If values are invalid.
3643
+ * @since 2.4.0
3644
+ */
3645
+ getObject<TObject extends Object$1>(cls: ConstructorWithTypeId<TObject>, values: Record<string, string>, options: GetObjectOptions): Promise<TObject | Tombstone | null>;
3646
+ /**
3503
3647
  * Gets the public key of the sender, if any exists and it is verified.
3504
3648
  * Otherwise, `null` is returned.
3505
3649
  *
@@ -3906,4 +4050,4 @@ interface ActorKeyPair extends CryptoKeyPair {
3906
4050
  readonly multikey: Multikey;
3907
4051
  }
3908
4052
  //#endregion
3909
- export { InProcessMessageQueueOptions as $, ObjectCallbackSetters as A, InboxErrorHandler as At, TaskDefinition as B, PortableActorIdMapper as Bt, FederationOptions as C, CollectionCursor as Ct, InboxChallengePolicy as D, CustomCollectionDispatcher as Dt, IdempotencyStrategy as E, CustomCollectionCursor as Et, FederationOrigin as F, ObjectDispatcher as Ft, CreateExponentialBackoffPolicyOptions as G, SendActivityError as Gt, TaskEnqueueOptions as H, UnverifiedActivityHandler as Ht, FederationQueueOptions as I, OutboxErrorHandler as It, createExponentialBackoffPolicy as J, buildCollectionSynchronizationHeader as Jt, RetryContext as K, SenderKeyPair as Kt, createFederation as L, OutboxListener as Lt, PortableInboxForwardingOptions as M, MediaUploaderCallback as Mt, Rfc6570Expression as N, NodeInfoDispatcher as Nt, InboxListenerSetters as O, HashlinkMediaDispatcher as Ot, FederationKvPrefixes as P, ObjectAuthorizePredicate as Pt, InProcessMessageQueue as Q, Message as R, OutboxListenerErrorHandler as Rt, FederationFetchOptions as S, CollectionCounter as St, IdempotencyKeyCallback as T, CustomCollectionCounter as Tt, TaskHandler as U, UnverifiedActivityReason as Ut, TaskDefinitionOptions as V, SharedInboxKeyDispatcher as Vt, TaskRegistry as W, WebFingerLinksDispatcher as Wt, respondWithObject as X, ActivityTransformer as Xt, RespondWithObjectOptions as Y, digest as Yt, respondWithObjectIfAcceptable as Z, CustomCollectionCallbackSetters as _, ActorAliasMapper as _t, GetSignedKeyOptions as a, CircuitBreaker as at, FederationBenchmarkOptions as b, ActorKeyPairsDispatcher as bt, ParseUriResult as c, CircuitBreakerCreateOptions as ct, RouteActivityOptions as d, CircuitBreakerOptions as dt, MessageQueue as et, SendActivityOptions as f, CircuitBreakerState as ft, ConstructorWithTypeId as g, parseCircuitBreakerKvState as gt, CollectionCallbackSetters as h, normalizeCircuitBreakerOptions as ht, GetActorOptions as i, ParallelMessageQueue as it, OutboxListenerSetters as j, InboxListener as jt, MediaUploaderSetters as k, HashlinkMediaRequest as kt, PortableRequest as l, CircuitBreakerFailurePolicy as lt, ActorCallbackSetters as m, NormalizedCircuitBreakerOptions as mt, Context as n, MessageQueueEnqueueOptions as nt, InboxContext as o, CircuitBreakerActivityDrop as ot, SendActivityOptionsForCollection as p, CircuitBreakerStateChange as pt, RetryPolicy as q, PageItems as qt, ForwardActivityOptions as r, MessageQueueListenOptions as rt, OutboxContext as s, CircuitBreakerBeforeSendDecision as st, ActorKeyPair as t, MessageQueueDepth as tt, RequestContext as u, CircuitBreakerKvState as ut, Federatable as v, ActorDispatcher as vt, FederationStartQueueOptions as w, CollectionDispatcher as wt, FederationBuilder as x, AuthorizePredicate as xt, Federation as y, ActorHandleMapper as yt, createFederationBuilder as z, OutboxPermanentFailureHandler as zt };
4053
+ export { InProcessMessageQueue as $, MediaUploaderSetters as A, HashlinkMediaRequest as At, createFederationBuilder as B, OutboxPermanentFailureHandler as Bt, FederationFetchOptions as C, CollectionCounter as Ct, IdempotencyStrategy as D, CustomCollectionCursor as Dt, IdempotencyKeyCallback as E, CustomCollectionCounter as Et, FederationKvPrefixes as F, ObjectAuthorizePredicate as Ft, TaskRegistry as G, WebFingerLinksDispatcher as Gt, TaskDefinitionOptions as H, SharedInboxKeyDispatcher as Ht, FederationOrigin as I, ObjectDispatcher as It, RetryPolicy as J, PageItems as Jt, CreateExponentialBackoffPolicyOptions as K, SendActivityError as Kt, FederationQueueOptions as L, OutboxErrorHandler as Lt, OutboxListenerSetters as M, InboxListener as Mt, PortableInboxForwardingOptions as N, MediaUploaderCallback as Nt, InboxChallengePolicy as O, CustomCollectionDispatcher as Ot, Rfc6570Expression as P, NodeInfoDispatcher as Pt, respondWithObjectIfAcceptable as Q, createFederation as R, OutboxListener as Rt, FederationBuilder as S, AuthorizePredicate as St, FederationStartQueueOptions as T, CollectionDispatcher as Tt, TaskEnqueueOptions as U, UnverifiedActivityHandler as Ut, TaskDefinition as V, PortableActorIdMapper as Vt, TaskHandler as W, UnverifiedActivityReason as Wt, RespondWithObjectOptions as X, digest as Xt, createExponentialBackoffPolicy as Y, buildCollectionSynchronizationHeader as Yt, respondWithObject as Z, ActivityTransformer as Zt, ConstructorWithTypeId as _, parseCircuitBreakerKvState as _t, GetObjectOptions as a, ParallelMessageQueue as at, Federation as b, ActorHandleMapper as bt, OutboxContext as c, CircuitBreakerBeforeSendDecision as ct, RequestContext as d, CircuitBreakerKvState as dt, InProcessMessageQueueOptions as et, RouteActivityOptions as f, CircuitBreakerOptions as ft, CollectionCallbackSetters as g, normalizeCircuitBreakerOptions as gt, ActorCallbackSetters as h, NormalizedCircuitBreakerOptions as ht, GetActorOptions as i, MessageQueueListenOptions as it, ObjectCallbackSetters as j, InboxErrorHandler as jt, InboxListenerSetters as k, HashlinkMediaDispatcher as kt, ParseUriResult as l, CircuitBreakerCreateOptions as lt, SendActivityOptionsForCollection as m, CircuitBreakerStateChange as mt, Context as n, MessageQueueDepth as nt, GetSignedKeyOptions as o, CircuitBreaker as ot, SendActivityOptions as p, CircuitBreakerState as pt, RetryContext as q, SenderKeyPair as qt, ForwardActivityOptions as r, MessageQueueEnqueueOptions as rt, InboxContext as s, CircuitBreakerActivityDrop as st, ActorKeyPair as t, MessageQueue as tt, PortableRequest as u, CircuitBreakerFailurePolicy as ut, CustomCollectionCallbackSetters as v, ActorAliasMapper as vt, FederationOptions as w, CollectionCursor as wt, FederationBenchmarkOptions as x, ActorKeyPairsDispatcher as xt, Federatable as y, ActorDispatcher as yt, Message as z, OutboxListenerErrorHandler as zt };
@@ -8,7 +8,7 @@ import { lookupWebFinger } from "@fedify/webfinger";
8
8
  import { metrics, trace } from "@opentelemetry/api";
9
9
  //#region src/testing/context.ts
10
10
  function createContext(values) {
11
- const { federation, url = new URL("http://example.com/"), canonicalOrigin, data, documentLoader, contextLoader, meterProvider, tracerProvider, clone, getNodeInfoUri, getActorUri, getObjectUri, getPortableObjectUri, getPortableInboxUri, getCollectionUri, getOutboxUri, getMediaUploaderUri, getInboxUri, getFollowingUri, getFollowersUri, getLikedUri, getFeaturedUri, getFeaturedTagsUri, parseUri, getActorKeyPairs, getDocumentLoader, lookupObject: lookupObject$1, traverseCollection: traverseCollection$1, lookupNodeInfo, lookupWebFinger: lookupWebFinger$1, sendActivity, routeActivity, enqueueTask, enqueueTaskMany } = values;
11
+ const { federation, url = new URL("http://example.com/"), canonicalOrigin, data, documentLoader, contextLoader, meterProvider, tracerProvider, clone, getNodeInfoUri, getActorUri, getPortableActorUri, getObjectUri, getPortableObjectUri, getPortableInboxUri, getCollectionUri, getOutboxUri, getMediaUploaderUri, getInboxUri, getFollowingUri, getFollowersUri, getLikedUri, getFeaturedUri, getFeaturedTagsUri, parseUri, getActorKeyPairs, getDocumentLoader, lookupObject: lookupObject$1, traverseCollection: traverseCollection$1, lookupNodeInfo, lookupWebFinger: lookupWebFinger$1, sendActivity, routeActivity, enqueueTask, enqueueTaskMany } = values;
12
12
  function throwRouterError() {
13
13
  throw new RouterError("Not implemented");
14
14
  }
@@ -29,6 +29,7 @@ function createContext(values) {
29
29
  })),
30
30
  getNodeInfoUri: getNodeInfoUri ?? throwRouterError,
31
31
  getActorUri: getActorUri ?? throwRouterError,
32
+ getPortableActorUri: getPortableActorUri ?? throwRouterError,
32
33
  getObjectUri: getObjectUri ?? throwRouterError,
33
34
  getPortableObjectUri: getPortableObjectUri ?? throwRouterError,
34
35
  getPortableInboxUri: getPortableInboxUri ?? throwRouterError,