@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,10 +1,10 @@
1
1
  const { URLPattern } = require("urlpattern-polyfill");
2
2
  const require_rolldown_runtime = require("./rolldown-runtime-Dmm3t92W.cjs");
3
3
  const require_transformers = require("./transformers-BalCrSsr.cjs");
4
- const require_http = require("./http-C8cZTE3Y.cjs");
4
+ const require_http = require("./http-B7wEqv49.cjs");
5
5
  const require_types = require("./types-Be2zbyeG.cjs");
6
- const require_owner = require("./owner-DSzH7wro.cjs");
7
- const require_kv_cache = require("./kv-cache-Dvd-Q-E2.cjs");
6
+ const require_owner = require("./owner-CGnHPl4k.cjs");
7
+ const require_kv_cache = require("./kv-cache-0pYMPrkL.cjs");
8
8
  let _logtape_logtape = require("@logtape/logtape");
9
9
  let _fedify_uri_template = require("@fedify/uri-template");
10
10
  let _fedify_vocab = require("@fedify/vocab");
@@ -342,8 +342,8 @@ var FederationBuilderImpl = class {
342
342
  const variables = _fedify_uri_template.Router.variables(path);
343
343
  this.router.add(path, routeName);
344
344
  const callbacks = {
345
- dispatcher: (ctx, values) => {
346
- return this._getTracer().startActiveSpan("activitypub.dispatch_object", {
345
+ dispatcher: async (ctx, values) => {
346
+ const object = await this._getTracer().startActiveSpan("activitypub.dispatch_object", {
347
347
  kind: _opentelemetry_api.SpanKind.SERVER,
348
348
  attributes: {
349
349
  "fedify.object.type": cls.typeId.href,
@@ -366,6 +366,8 @@ var FederationBuilderImpl = class {
366
366
  span.end();
367
367
  }
368
368
  });
369
+ if (object instanceof _fedify_vocab.Tombstone) warnMismatchedTombstoneId(ctx, cls, values, object);
370
+ return object;
369
371
  },
370
372
  parameters: variables
371
373
  };
@@ -735,6 +737,28 @@ var FederationBuilderImpl = class {
735
737
  function createFederationBuilder() {
736
738
  return new FederationBuilderImpl();
737
739
  }
740
+ function warnMismatchedTombstoneId(context, cls, values, tombstone) {
741
+ const logger = (0, _logtape_logtape.getLogger)([
742
+ "fedify",
743
+ "federation",
744
+ "object"
745
+ ]);
746
+ if (tombstone.id == null) {
747
+ logger.warn("Object dispatcher for {class} returned a tombstone without an id property. Set the property with Context.getObjectUri().", {
748
+ class: cls.name,
749
+ values
750
+ });
751
+ return;
752
+ }
753
+ if (tombstone.id.protocol === "ap:" || tombstone.id.protocol === "ap+ef61:") return;
754
+ const expected = context.getObjectUri(cls, values);
755
+ 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().", {
756
+ class: cls.name,
757
+ values,
758
+ tombstoneId: tombstone.id.href,
759
+ objectUri: expected.href
760
+ });
761
+ }
738
762
  /**
739
763
  * Warns about an FEP-ef61 portable actor identified by a compatible identifier
740
764
  * that is malformed, or is not on the actor's first gateway, where FEP-ef61
@@ -2411,6 +2435,8 @@ function acceptsJsonLd(request) {
2411
2435
  const PORTABLE_OBJECT_CONTENT_TYPE = "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"";
2412
2436
  const GATEWAY_OBJECT_PATH_PATTERN = /^\/\.well-known\/apgateway\/did(?::|%3A)/i;
2413
2437
  const BARE_DID_PATTERN = /^did:[a-z0-9]+:[^/?#]+$/i;
2438
+ const DID_KEY_PREFIX = "did:key:";
2439
+ const BASE58BTC_MULTIBASE_PATTERN = /^z[1-9A-HJ-NP-Za-km-z]+$/;
2414
2440
  const GATEWAY_PATH_PREFIX = "/.well-known/apgateway/";
2415
2441
  const HASHLINK_SCHEME_PATTERN = /^hl(?::|%3A)/i;
2416
2442
  /**
@@ -2446,6 +2472,15 @@ function parsePortableGatewayRequest(url) {
2446
2472
  throw error;
2447
2473
  }
2448
2474
  const authority = (0, _fedify_vocab_runtime.getFe34Origin)(id);
2475
+ try {
2476
+ assertBase58BtcDidKey(authority);
2477
+ } catch (error) {
2478
+ if (error instanceof TypeError) return {
2479
+ type: "malformed",
2480
+ error
2481
+ };
2482
+ throw error;
2483
+ }
2449
2484
  const href = id.href;
2450
2485
  return {
2451
2486
  type: "object",
@@ -2464,12 +2499,26 @@ function parsePortableGatewayRequest(url) {
2464
2499
  * @param authority The bare DID, e.g., `did:key:z6Mk...`.
2465
2500
  * @param path The object path, e.g., `/notes/123`.
2466
2501
  * @returns The portable ID.
2467
- * @throws {TypeError} If the authority is not a bare DID.
2502
+ * @throws {TypeError} If the authority is not a bare DID, or it is
2503
+ * a `did:key` DID that is not encoded in base58-btc.
2468
2504
  */
2469
2505
  function buildPortableUri(authority, path) {
2470
2506
  if (typeof authority !== "string" || !BARE_DID_PATTERN.test(authority)) throw new TypeError("The authority of a portable ID must be a DID without a path, query, or fragment.");
2471
- (0, _fedify_vocab_runtime.getFe34Origin)(authority);
2472
- return (0, _fedify_vocab_runtime.parseIri)(`ap+ef61://${authority}${path}`);
2507
+ const did = (0, _fedify_vocab_runtime.getFe34Origin)(authority);
2508
+ assertBase58BtcDidKey(did);
2509
+ return (0, _fedify_vocab_runtime.parseIri)(`ap+ef61://${did}${path}`);
2510
+ }
2511
+ /**
2512
+ * Checks that a normalized DID, if it is a `did:key` DID, is encoded in
2513
+ * base58-btc, as FEP-ef61 requires so that the same key does not yield two
2514
+ * portable IDs. This only checks the encoding, not whether the DID is
2515
+ * a valid key.
2516
+ * @param did The DID normalized by `getFe34Origin()`.
2517
+ * @throws {TypeError} If the DID is a `did:key` DID that is not encoded in
2518
+ * base58-btc.
2519
+ */
2520
+ function assertBase58BtcDidKey(did) {
2521
+ if (did.startsWith(DID_KEY_PREFIX) && !BASE58BTC_MULTIBASE_PATTERN.test(did.slice(8))) throw new TypeError("The did:key authority of a portable ID must be encoded in base58-btc, i.e., start with z.");
2473
2522
  }
2474
2523
  /**
2475
2524
  * Recognizes an FEP-ef61 gateway request for a resource addressed by
@@ -3402,6 +3451,13 @@ async function handleObject(request, { values, context, objectDispatcher, author
3402
3451
  if (!await authorizePredicate(context, values)) return await onUnauthorized(request);
3403
3452
  }
3404
3453
  const jsonLd = await object.toJsonLd(context);
3454
+ if (object instanceof _fedify_vocab.Tombstone) return new Response(request.method === "HEAD" ? null : JSON.stringify(jsonLd), {
3455
+ status: 410,
3456
+ headers: {
3457
+ "Content-Type": "application/activity+json",
3458
+ Vary: "Accept"
3459
+ }
3460
+ });
3405
3461
  return new Response(JSON.stringify(jsonLd), { headers: {
3406
3462
  "Content-Type": "application/activity+json",
3407
3463
  Vary: "Accept"
@@ -3409,8 +3465,9 @@ async function handleObject(request, { values, context, objectDispatcher, author
3409
3465
  }
3410
3466
  /**
3411
3467
  * Handles an FEP-ef61 gateway request for a portable object through an object
3412
- * dispatcher. The object is served only if its ID canonically matches the
3413
- * requested portable ID and it satisfies the FEP-ef61 proof policy.
3468
+ * dispatcher, or the actor dispatcher adapted to one. The object is served
3469
+ * only if its ID canonically matches the requested portable ID and it
3470
+ * satisfies the FEP-ef61 proof policy.
3414
3471
  * @template TContextData The context data to pass to the context.
3415
3472
  * @param request The HTTP request.
3416
3473
  * @param parameters The parameters for handling the portable object.
@@ -3534,13 +3591,13 @@ function recordCollectionMetrics(meterProvider, base, result, options = {}) {
3534
3591
  * @param parameters The parameters for handling the collection.
3535
3592
  * @returns A promise that resolves to an HTTP response.
3536
3593
  */
3537
- async function handleCollection(request, { name: name$1, identifier, uriGetter, filter, filterPredicate, context, collectionCallbacks, tracerProvider, meterProvider, onUnauthorized, onNotFound }) {
3538
- const spanName = name$1.trim().replace(/\s+/g, "_");
3594
+ async function handleCollection(request, { name: name$2, identifier, uriGetter, filter, filterPredicate, context, collectionCallbacks, tracerProvider, meterProvider, onUnauthorized, onNotFound }) {
3595
+ const spanName = name$2.trim().replace(/\s+/g, "_");
3539
3596
  tracerProvider = tracerProvider ?? _opentelemetry_api.trace.getTracerProvider();
3540
3597
  const tracer = tracerProvider.getTracer(require_http.name, require_http.version);
3541
3598
  const cursor = new URL(request.url).searchParams.get("cursor");
3542
3599
  const metricBase = {
3543
- kind: getCollectionMetricKind(name$1),
3600
+ kind: getCollectionMetricKind(name$2),
3544
3601
  page: cursor != null,
3545
3602
  dispatcher: "built_in"
3546
3603
  };
@@ -3581,7 +3638,7 @@ async function handleCollection(request, { name: name$1, identifier, uriGetter,
3581
3638
  span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
3582
3639
  return await onNotFound(request);
3583
3640
  }
3584
- const items = filterCollectionItems(page.items, name$1, filterPredicate);
3641
+ const items = filterCollectionItems(page.items, name$2, filterPredicate);
3585
3642
  itemCount = items.length;
3586
3643
  span.setAttribute("fedify.collection.items", itemCount);
3587
3644
  return items;
@@ -3621,7 +3678,7 @@ async function handleCollection(request, { name: name$1, identifier, uriGetter,
3621
3678
  } else {
3622
3679
  const uri = new URL(baseUri);
3623
3680
  uri.searchParams.set("cursor", cursor);
3624
- const pageOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection_page ${name$1}`, {
3681
+ const pageOrResponse = await tracer.startActiveSpan(`activitypub.dispatch_collection_page ${name$2}`, {
3625
3682
  kind: _opentelemetry_api.SpanKind.SERVER,
3626
3683
  attributes: {
3627
3684
  "activitypub.collection.id": uri.href,
@@ -3637,7 +3694,7 @@ async function handleCollection(request, { name: name$1, identifier, uriGetter,
3637
3694
  span.setStatus({ code: _opentelemetry_api.SpanStatusCode.ERROR });
3638
3695
  return await onNotFound(request);
3639
3696
  }
3640
- const items = filterCollectionItems(page.items, name$1, filterPredicate);
3697
+ const items = filterCollectionItems(page.items, name$2, filterPredicate);
3641
3698
  itemCount = items.length;
3642
3699
  span.setAttribute("fedify.collection.items", itemCount);
3643
3700
  return {
@@ -4825,8 +4882,8 @@ var CustomCollectionHandler = class {
4825
4882
  * @param CollectionPage The CollectionPage constructor.
4826
4883
  * @param filterPredicate Optional filter predicate for items.
4827
4884
  */
4828
- constructor(name$2, values, context, callbacks, tracerProvider = _opentelemetry_api.trace.getTracerProvider(), meterProvider, Collection, CollectionPage, filterPredicate) {
4829
- this.name = name$2;
4885
+ constructor(name$1, values, context, callbacks, tracerProvider = _opentelemetry_api.trace.getTracerProvider(), meterProvider, Collection, CollectionPage, filterPredicate) {
4886
+ this.name = name$1;
4830
4887
  this.values = values;
4831
4888
  this.context = context;
4832
4889
  this.callbacks = callbacks;
@@ -8240,17 +8297,39 @@ var FederationImpl = class extends FederationBuilderImpl {
8240
8297
  });
8241
8298
  }
8242
8299
  const route = this.router.route(portable.path);
8243
- if (route == null || !route.name.startsWith("object:")) {
8300
+ const isActor = route != null && (route.name === "actor" || route.name.startsWith("actorAlias:"));
8301
+ if (route == null || !isActor && !route.name.startsWith("object:")) {
8244
8302
  metricState.endpoint = "not_found";
8245
8303
  return await onNotFound(request);
8246
8304
  }
8247
8305
  metricState.routeTemplate = PORTABLE_GATEWAY_ROUTE_PREFIX + route.template;
8248
- metricState.endpoint = "object";
8306
+ metricState.endpoint = isActor ? "actor" : "object";
8249
8307
  span.updateName(`${request.method} ${metricState.routeTemplate}`);
8250
8308
  if (!acceptsJsonLd(request)) {
8251
8309
  metricState.endpoint = "not_acceptable";
8252
8310
  return await onNotAcceptable(request);
8253
8311
  }
8312
+ if (isActor) {
8313
+ const identifier = route.name.startsWith("actorAlias:") ? route.name.substring(11) : route.values.identifier;
8314
+ const context = this.#createContext(request, contextData, {
8315
+ invokedFromActorDispatcher: { identifier },
8316
+ portableRequest: portable.portableRequest
8317
+ });
8318
+ const actorDispatcher = this.actorCallbacks?.dispatcher;
8319
+ const authorizePredicate = this.actorCallbacks?.authorizePredicate;
8320
+ return await handlePortableObject(request, {
8321
+ values: { identifier },
8322
+ context,
8323
+ objectDispatcher: actorDispatcher == null ? void 0 : async (ctx) => {
8324
+ const actor = await actorDispatcher(ctx, identifier);
8325
+ return actor instanceof _fedify_vocab.Tombstone ? null : actor;
8326
+ },
8327
+ authorizePredicate: authorizePredicate == null ? void 0 : (ctx) => authorizePredicate(ctx, identifier),
8328
+ canonicalId: portable.canonicalId,
8329
+ onUnauthorized,
8330
+ onNotFound
8331
+ });
8332
+ }
8254
8333
  const typeId = route.name.replace(/^object:/, "");
8255
8334
  const callbacks = this.objectCallbacks[typeId];
8256
8335
  const cls = this.objectTypeIds[typeId];
@@ -8614,9 +8693,17 @@ var ContextImpl = class ContextImpl {
8614
8693
  return new URL(path, this.canonicalOrigin);
8615
8694
  }
8616
8695
  getActorUri(identifier) {
8696
+ return new URL(this.#getActorPath(identifier), this.canonicalOrigin);
8697
+ }
8698
+ getPortableActorUri(identifier, authority) {
8699
+ const path = this.#getActorPath(identifier);
8700
+ if (authority == null) throw new TypeError("The authority of a portable ID is required outside an FEP-ef61 gateway request.");
8701
+ return buildPortableUri(authority, path);
8702
+ }
8703
+ #getActorPath(identifier) {
8617
8704
  const path = this.federation.router.build(`actorAlias:${identifier}`, {}) ?? this.federation.router.build("actor", { identifier });
8618
8705
  if (path == null) throw new _fedify_uri_template.RouterError("No actor dispatcher registered.");
8619
- return new URL(path, this.canonicalOrigin);
8706
+ return path;
8620
8707
  }
8621
8708
  getObjectUri(cls, values) {
8622
8709
  return new URL(this.#getObjectPath(cls, values), this.canonicalOrigin);
@@ -9259,6 +9346,9 @@ var RequestContextImpl = class RequestContextImpl extends ContextImpl {
9259
9346
  request: this.request
9260
9347
  });
9261
9348
  }
9349
+ getPortableActorUri(identifier, authority) {
9350
+ return super.getPortableActorUri(identifier, authority ?? this.portableRequest?.authority);
9351
+ }
9262
9352
  getPortableObjectUri(cls, values, authority) {
9263
9353
  return super.getPortableObjectUri(cls, values, authority ?? this.portableRequest?.authority);
9264
9354
  }
@@ -9282,7 +9372,7 @@ var RequestContextImpl = class RequestContextImpl extends ContextImpl {
9282
9372
  if (actor instanceof _fedify_vocab.Tombstone && options?.tombstone !== "passthrough") return null;
9283
9373
  return actor;
9284
9374
  }
9285
- async getObject(cls, values) {
9375
+ async getObject(cls, values, options) {
9286
9376
  const callbacks = this.federation.objectCallbacks[cls.typeId.href];
9287
9377
  if (callbacks == null) throw new Error("No object dispatcher registered.");
9288
9378
  for (const param of callbacks.parameters) if (!(param in values)) throw new TypeError(`Missing parameter: ${param}`);
@@ -9292,13 +9382,15 @@ var RequestContextImpl = class RequestContextImpl extends ContextImpl {
9292
9382
  actorDispatcherClass: this.#invokedFromObjectDispatcher.cls.name,
9293
9383
  actorDispatcherValues: this.#invokedFromObjectDispatcher.values
9294
9384
  });
9295
- return await callbacks.dispatcher(new RequestContextImpl({
9385
+ const object = await callbacks.dispatcher(new RequestContextImpl({
9296
9386
  ...this,
9297
9387
  invokedFromObjectDispatcher: {
9298
9388
  cls,
9299
9389
  values
9300
9390
  }
9301
9391
  }), values);
9392
+ if (object instanceof _fedify_vocab.Tombstone && !(object instanceof cls) && options?.tombstone !== "passthrough") return null;
9393
+ return object;
9302
9394
  }
9303
9395
  #signedKey = void 0;
9304
9396
  async getSignedKey(options = {}) {
@@ -16,7 +16,7 @@ json_canon = require_rolldown_runtime.__toESM(json_canon, 1);
16
16
  let _opentelemetry_semantic_conventions = require("@opentelemetry/semantic-conventions");
17
17
  //#region deno.json
18
18
  var name = "@fedify/fedify";
19
- var version = "2.4.0-dev.2099+cd074fe2";
19
+ var version = "2.4.0-dev.2108+159ea471";
20
20
  //#endregion
21
21
  //#region src/sig/portable-key-id.ts
22
22
  const COMPATIBLE_KEY_ID_PATH_PATTERN = /^\/\.well-known\/apgateway\/did(?::|%3A)/i;
@@ -1,11 +1,11 @@
1
1
  import { Temporal } from "temporal-polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as version, t as name } from "./deno-dxdvl2XZ.mjs";
5
- import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-BP3vdBpb.mjs";
4
+ import { n as version, t as name } from "./deno-CC4RKEEp.mjs";
5
+ import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-CF1TEvdS.mjs";
6
6
  import { i as validateAcceptSignature, n as fulfillAcceptSignature, r as parseAcceptSignature } from "./accept-CPVqki78.mjs";
7
- import { i as fetchKeyDetailed, s as validateCryptoKey } from "./key-DYfmjnmp.mjs";
8
- import { n as verifyPortableGatewayKeyDocument } from "./portable-key-D0mWbV9G.mjs";
7
+ import { i as fetchKeyDetailed, s as validateCryptoKey } from "./key-B8u1vdvF.mjs";
8
+ import { n as verifyPortableGatewayKeyDocument } from "./portable-key-C0-ghkgM.mjs";
9
9
  import { getLogger } from "@logtape/logtape";
10
10
  import { CryptographicKey } from "@fedify/vocab";
11
11
  import { SpanStatusCode, trace } from "@opentelemetry/api";
@@ -14,7 +14,7 @@ import serialize from "json-canon";
14
14
  import { ATTR_HTTP_REQUEST_HEADER, ATTR_HTTP_REQUEST_METHOD, ATTR_URL_FULL } from "@opentelemetry/semantic-conventions";
15
15
  //#region deno.json
16
16
  var name = "@fedify/fedify";
17
- var version = "2.4.0-dev.2099+cd074fe2";
17
+ var version = "2.4.0-dev.2108+159ea471";
18
18
  //#endregion
19
19
  //#region src/sig/portable-key-id.ts
20
20
  const COMPATIBLE_KEY_ID_PATH_PATTERN = /^\/\.well-known\/apgateway\/did(?::|%3A)/i;
@@ -1,8 +1,8 @@
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";
5
- import { _ as recordKeyLookup, n as getDurationMs, t as classifyFetchError } from "./metrics-BP3vdBpb.mjs";
4
+ import { n as version, t as name } from "./deno-CC4RKEEp.mjs";
5
+ import { _ as recordKeyLookup, n as getDurationMs, t as classifyFetchError } from "./metrics-CF1TEvdS.mjs";
6
6
  import { a as isCompatibleKeyId, o as isPortableActorDocument, s as isPortableId } from "./portable-key-id-Bva5iT3W.mjs";
7
7
  import { getLogger } from "@logtape/logtape";
8
8
  import { CryptographicKey, Multikey, Object as Object$1, isActor } from "@fedify/vocab";
@@ -1,5 +1,5 @@
1
1
  const { URLPattern } = require("urlpattern-polyfill");
2
- const require_http = require("./http-C8cZTE3Y.cjs");
2
+ const require_http = require("./http-B7wEqv49.cjs");
3
3
  let _logtape_logtape = require("@logtape/logtape");
4
4
  let _fedify_vocab_runtime = require("@fedify/vocab-runtime");
5
5
  let es_toolkit = require("es-toolkit");
@@ -1,7 +1,7 @@
1
1
  import { Temporal } from "temporal-polyfill";
2
2
  import { URLPattern } from "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { p as recordDocumentCache } from "./metrics-BP3vdBpb.mjs";
4
+ import { p as recordDocumentCache } from "./metrics-CF1TEvdS.mjs";
5
5
  import { getLogger } from "@logtape/logtape";
6
6
  import { preloadedContexts } from "@fedify/vocab-runtime";
7
7
  //#region src/utils/kv-cache.ts
@@ -1,6 +1,6 @@
1
1
  import { Temporal } from "temporal-polyfill";
2
2
  import { URLPattern } from "urlpattern-polyfill";
3
- import { H as validateCryptoKey, et as recordDocumentCache, t as doubleKnock } from "./http-D-rbr_Sy.js";
3
+ import { H as validateCryptoKey, et as recordDocumentCache, t as doubleKnock } from "./http-CaUBCHYJ.js";
4
4
  import { getLogger } from "@logtape/logtape";
5
5
  import { UrlError, createActivityPubRequest, getRemoteDocument, logRequest, preloadedContexts, validatePublicUrl } from "@fedify/vocab-runtime";
6
6
  import { curry } from "es-toolkit";
@@ -1,9 +1,9 @@
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";
5
- import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-BP3vdBpb.mjs";
6
- import { r as fetchKey, s as validateCryptoKey } from "./key-DYfmjnmp.mjs";
4
+ import { n as version, t as name } from "./deno-CC4RKEEp.mjs";
5
+ import { n as getDurationMs, r as getFederationMetrics, s as measureSignatureKeyFetch } from "./metrics-CF1TEvdS.mjs";
6
+ import { r as fetchKey, s as validateCryptoKey } from "./key-B8u1vdvF.mjs";
7
7
  import { getLogger } from "@logtape/logtape";
8
8
  import { Activity, CryptographicKey, Object as Object$1, getTypeId } from "@fedify/vocab";
9
9
  import { SpanStatusCode, trace } from "@opentelemetry/api";
@@ -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 { metrics } from "@opentelemetry/api";
6
6
  import { FetchError } from "@fedify/vocab-runtime";
7
7
  //#region src/federation/metrics.ts
@@ -1,28 +1,28 @@
1
1
  import { Temporal } from "temporal-polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as version, t as name } from "./deno-dxdvl2XZ.mjs";
5
- import { a as instrumentDocumentLoader, b as recordWebFingerHandle, c as recordCircuitBreakerStateChange, d as recordCollectionRequest, f as recordCollectionTotalItems, g as recordInboxActivity, h as recordFanoutRecipients, i as getRemoteHost, l as recordCollectionDispatchDuration, n as getDurationMs, o as isAbortError, r as getFederationMetrics, u as recordCollectionPageItems, v as recordOutboxActivity, x as registerQueueDepthGauge, y as recordOutboxEnqueue } from "./metrics-BP3vdBpb.mjs";
4
+ import { n as version, t as name } from "./deno-CC4RKEEp.mjs";
5
+ import { a as instrumentDocumentLoader, b as recordWebFingerHandle, c as recordCircuitBreakerStateChange, d as recordCollectionRequest, f as recordCollectionTotalItems, g as recordInboxActivity, h as recordFanoutRecipients, i as getRemoteHost, l as recordCollectionDispatchDuration, n as getDurationMs, o as isAbortError, r as getFederationMetrics, u as recordCollectionPageItems, v as recordOutboxActivity, x as registerQueueDepthGauge, y as recordOutboxEnqueue } from "./metrics-CF1TEvdS.mjs";
6
6
  import { t as formatAcceptSignature } from "./accept-CPVqki78.mjs";
7
7
  import { a as isCompatibleKeyId, c as isPortableUri, i as hasPortableActor, n as getGatewayKeyBase, r as getPortableDid, s as isPortableId, t as getCanonicalPortableId } from "./portable-key-id-Bva5iT3W.mjs";
8
- import { o as importJwk, s as validateCryptoKey, t as exportJwk } from "./key-DYfmjnmp.mjs";
8
+ import { o as importJwk, s as validateCryptoKey, t as exportJwk } from "./key-B8u1vdvF.mjs";
9
9
  import { r as normalizeOutgoingActivityJsonLd } from "./outgoing-jsonld-4IJqPYos.mjs";
10
- import { _ as wrapContextLoaderForJsonLd, a as compactJsonLd, c as getNormalizationContextLoader, d as isClearlyMalformedContextReference, f as isInvalidUrlTypeError, l as hasSignature, m as verifyCompactJsonLd, p as signJsonLd, r as assertSafeJsonLd, s as detachSignature, t as InvalidContextReferenceError, u as hasSignatureLike } from "./ld-B00wWHzc.mjs";
11
- import { i as signObject, l as verifyPortableObjectProofWithRoot, o as verifyObject, r as hasProofLike, s as verifyPortableObjectProof, t as InvalidPortableObjectIdError } from "./proof-ChjBwnep.mjs";
12
- import { a as listRequestSignatures, c as selectRequestSignature, d as verifyRequest, f as verifyRequestDetailed, s as parseRfc9421SignatureInput } from "./http-DsgawTd8.mjs";
13
- import { t as getAuthenticatedDocumentLoader } from "./docloader-eBxQDsk9.mjs";
14
- import { n as kvCache } from "./kv-cache-EvOgrFsS.mjs";
10
+ import { _ as wrapContextLoaderForJsonLd, a as compactJsonLd, c as getNormalizationContextLoader, d as isClearlyMalformedContextReference, f as isInvalidUrlTypeError, l as hasSignature, m as verifyCompactJsonLd, p as signJsonLd, r as assertSafeJsonLd, s as detachSignature, t as InvalidContextReferenceError, u as hasSignatureLike } from "./ld-BTMJHEGV.mjs";
11
+ import { i as signObject, l as verifyPortableObjectProofWithRoot, o as verifyObject, r as hasProofLike, s as verifyPortableObjectProof, t as InvalidPortableObjectIdError } from "./proof-DDw0i9b1.mjs";
12
+ import { a as listRequestSignatures, c as selectRequestSignature, d as verifyRequest, f as verifyRequestDetailed, s as parseRfc9421SignatureInput } from "./http-CHEYA5fH.mjs";
13
+ import { t as getAuthenticatedDocumentLoader } from "./docloader-D3_m98fe.mjs";
14
+ import { n as kvCache } from "./kv-cache-CTdvf_Iq.mjs";
15
15
  import { d as readBoundedText, l as BodyTooLargeError, t as getNodeInfo, u as MAX_BODY_SIZE } from "./client-DpnpgjyX.mjs";
16
16
  import { t as nodeInfoToJson } from "./types-DE_LV1JB.mjs";
17
- import { n as getKeyOwner, t as doesActorOwnKey } from "./owner-BJPDRDRq.mjs";
18
- import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "./send-yFX0E-ye.mjs";
19
- import { n as FederationBuilderImpl, t as ACTOR_ALIAS_PREFIX } from "./builder-Bno54o_-.mjs";
17
+ import { n as getKeyOwner, t as doesActorOwnKey } from "./owner-CY--JSqO.mjs";
18
+ import { n as extractInboxes, r as sendActivity, t as SendActivityError } from "./send-CU3sHGPt.mjs";
19
+ import { n as FederationBuilderImpl, t as ACTOR_ALIAS_PREFIX } from "./builder-BRlYEsrV.mjs";
20
20
  import { t as CircuitBreaker } from "./circuit-breaker-C5NqoLBJ.mjs";
21
21
  import { t as buildCollectionSynchronizationHeader } from "./collection-CnnP1UAv.mjs";
22
- import { a as verifyCompoundPortableObjectProofs, i as inspectCompoundPortableObjectApplicability, r as findUnsupportedCompoundProofShape, t as containsCompoundPortableObject } from "./compound-proof-X3SxXVbc.mjs";
22
+ import { a as verifyCompoundPortableObjectProofs, i as inspectCompoundPortableObjectApplicability, r as findUnsupportedCompoundProofShape, t as containsCompoundPortableObject } from "./compound-proof-CHGINiJg.mjs";
23
23
  import { t as KvKeyCache } from "./keycache-BUDHB5rY.mjs";
24
24
  import { t as acceptsJsonLd } from "./negotiation-CCocWT_N.mjs";
25
- import { t as hasMalformedKnownTemporalLiteral } from "./temporal-Dl9x-Qw4.mjs";
25
+ import { t as hasMalformedKnownTemporalLiteral } from "./temporal-NHiSpGcW.mjs";
26
26
  import { t as createExponentialBackoffPolicy } from "./retry-zX5xw5e0.mjs";
27
27
  import { t as TaskCodec } from "./codec-C6rTrpIp.mjs";
28
28
  import { getLogger, withContext } from "@logtape/logtape";
@@ -522,6 +522,8 @@ async function routeActivity({ context: ctx, json, originalJson, normalizedActiv
522
522
  const PORTABLE_OBJECT_CONTENT_TYPE = "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"";
523
523
  const GATEWAY_OBJECT_PATH_PATTERN = /^\/\.well-known\/apgateway\/did(?::|%3A)/i;
524
524
  const BARE_DID_PATTERN = /^did:[a-z0-9]+:[^/?#]+$/i;
525
+ const DID_KEY_PREFIX = "did:key:";
526
+ const BASE58BTC_MULTIBASE_PATTERN = /^z[1-9A-HJ-NP-Za-km-z]+$/;
525
527
  const GATEWAY_PATH_PREFIX = "/.well-known/apgateway/";
526
528
  const HASHLINK_SCHEME_PATTERN = /^hl(?::|%3A)/i;
527
529
  /**
@@ -557,6 +559,15 @@ function parsePortableGatewayRequest(url) {
557
559
  throw error;
558
560
  }
559
561
  const authority = getFe34Origin(id);
562
+ try {
563
+ assertBase58BtcDidKey(authority);
564
+ } catch (error) {
565
+ if (error instanceof TypeError) return {
566
+ type: "malformed",
567
+ error
568
+ };
569
+ throw error;
570
+ }
560
571
  const href = id.href;
561
572
  return {
562
573
  type: "object",
@@ -575,12 +586,26 @@ function parsePortableGatewayRequest(url) {
575
586
  * @param authority The bare DID, e.g., `did:key:z6Mk...`.
576
587
  * @param path The object path, e.g., `/notes/123`.
577
588
  * @returns The portable ID.
578
- * @throws {TypeError} If the authority is not a bare DID.
589
+ * @throws {TypeError} If the authority is not a bare DID, or it is
590
+ * a `did:key` DID that is not encoded in base58-btc.
579
591
  */
580
592
  function buildPortableUri(authority, path) {
581
593
  if (typeof authority !== "string" || !BARE_DID_PATTERN.test(authority)) throw new TypeError("The authority of a portable ID must be a DID without a path, query, or fragment.");
582
- getFe34Origin(authority);
583
- return parseIri(`ap+ef61://${authority}${path}`);
594
+ const did = getFe34Origin(authority);
595
+ assertBase58BtcDidKey(did);
596
+ return parseIri(`ap+ef61://${did}${path}`);
597
+ }
598
+ /**
599
+ * Checks that a normalized DID, if it is a `did:key` DID, is encoded in
600
+ * base58-btc, as FEP-ef61 requires so that the same key does not yield two
601
+ * portable IDs. This only checks the encoding, not whether the DID is
602
+ * a valid key.
603
+ * @param did The DID normalized by `getFe34Origin()`.
604
+ * @throws {TypeError} If the DID is a `did:key` DID that is not encoded in
605
+ * base58-btc.
606
+ */
607
+ function assertBase58BtcDidKey(did) {
608
+ if (did.startsWith(DID_KEY_PREFIX) && !BASE58BTC_MULTIBASE_PATTERN.test(did.slice(8))) throw new TypeError("The did:key authority of a portable ID must be encoded in base58-btc, i.e., start with z.");
584
609
  }
585
610
  /**
586
611
  * Recognizes an FEP-ef61 gateway request for a resource addressed by
@@ -1131,6 +1156,13 @@ async function handleObject(request, { values, context, objectDispatcher, author
1131
1156
  if (!await authorizePredicate(context, values)) return await onUnauthorized(request);
1132
1157
  }
1133
1158
  const jsonLd = await object.toJsonLd(context);
1159
+ if (object instanceof Tombstone) return new Response(request.method === "HEAD" ? null : JSON.stringify(jsonLd), {
1160
+ status: 410,
1161
+ headers: {
1162
+ "Content-Type": "application/activity+json",
1163
+ Vary: "Accept"
1164
+ }
1165
+ });
1134
1166
  return new Response(JSON.stringify(jsonLd), { headers: {
1135
1167
  "Content-Type": "application/activity+json",
1136
1168
  Vary: "Accept"
@@ -1138,8 +1170,9 @@ async function handleObject(request, { values, context, objectDispatcher, author
1138
1170
  }
1139
1171
  /**
1140
1172
  * Handles an FEP-ef61 gateway request for a portable object through an object
1141
- * dispatcher. The object is served only if its ID canonically matches the
1142
- * requested portable ID and it satisfies the FEP-ef61 proof policy.
1173
+ * dispatcher, or the actor dispatcher adapted to one. The object is served
1174
+ * only if its ID canonically matches the requested portable ID and it
1175
+ * satisfies the FEP-ef61 proof policy.
1143
1176
  * @template TContextData The context data to pass to the context.
1144
1177
  * @param request The HTTP request.
1145
1178
  * @param parameters The parameters for handling the portable object.
@@ -5469,17 +5502,39 @@ var FederationImpl = class extends FederationBuilderImpl {
5469
5502
  });
5470
5503
  }
5471
5504
  const route = this.router.route(portable.path);
5472
- if (route == null || !route.name.startsWith("object:")) {
5505
+ const isActor = route != null && (route.name === "actor" || route.name.startsWith("actorAlias:"));
5506
+ if (route == null || !isActor && !route.name.startsWith("object:")) {
5473
5507
  metricState.endpoint = "not_found";
5474
5508
  return await onNotFound(request);
5475
5509
  }
5476
5510
  metricState.routeTemplate = PORTABLE_GATEWAY_ROUTE_PREFIX + route.template;
5477
- metricState.endpoint = "object";
5511
+ metricState.endpoint = isActor ? "actor" : "object";
5478
5512
  span.updateName(`${request.method} ${metricState.routeTemplate}`);
5479
5513
  if (!acceptsJsonLd(request)) {
5480
5514
  metricState.endpoint = "not_acceptable";
5481
5515
  return await onNotAcceptable(request);
5482
5516
  }
5517
+ if (isActor) {
5518
+ const identifier = route.name.startsWith("actorAlias:") ? route.name.substring(ACTOR_ALIAS_PREFIX.length) : route.values.identifier;
5519
+ const context = this.#createContext(request, contextData, {
5520
+ invokedFromActorDispatcher: { identifier },
5521
+ portableRequest: portable.portableRequest
5522
+ });
5523
+ const actorDispatcher = this.actorCallbacks?.dispatcher;
5524
+ const authorizePredicate = this.actorCallbacks?.authorizePredicate;
5525
+ return await handlePortableObject(request, {
5526
+ values: { identifier },
5527
+ context,
5528
+ objectDispatcher: actorDispatcher == null ? void 0 : async (ctx) => {
5529
+ const actor = await actorDispatcher(ctx, identifier);
5530
+ return actor instanceof Tombstone ? null : actor;
5531
+ },
5532
+ authorizePredicate: authorizePredicate == null ? void 0 : (ctx) => authorizePredicate(ctx, identifier),
5533
+ canonicalId: portable.canonicalId,
5534
+ onUnauthorized,
5535
+ onNotFound
5536
+ });
5537
+ }
5483
5538
  const typeId = route.name.replace(/^object:/, "");
5484
5539
  const callbacks = this.objectCallbacks[typeId];
5485
5540
  const cls = this.objectTypeIds[typeId];
@@ -5843,9 +5898,17 @@ var ContextImpl = class ContextImpl {
5843
5898
  return new URL(path, this.canonicalOrigin);
5844
5899
  }
5845
5900
  getActorUri(identifier) {
5901
+ return new URL(this.#getActorPath(identifier), this.canonicalOrigin);
5902
+ }
5903
+ getPortableActorUri(identifier, authority) {
5904
+ const path = this.#getActorPath(identifier);
5905
+ if (authority == null) throw new TypeError("The authority of a portable ID is required outside an FEP-ef61 gateway request.");
5906
+ return buildPortableUri(authority, path);
5907
+ }
5908
+ #getActorPath(identifier) {
5846
5909
  const path = this.federation.router.build(`actorAlias:${identifier}`, {}) ?? this.federation.router.build("actor", { identifier });
5847
5910
  if (path == null) throw new RouterError("No actor dispatcher registered.");
5848
- return new URL(path, this.canonicalOrigin);
5911
+ return path;
5849
5912
  }
5850
5913
  getObjectUri(cls, values) {
5851
5914
  return new URL(this.#getObjectPath(cls, values), this.canonicalOrigin);
@@ -6488,6 +6551,9 @@ var RequestContextImpl = class RequestContextImpl extends ContextImpl {
6488
6551
  request: this.request
6489
6552
  });
6490
6553
  }
6554
+ getPortableActorUri(identifier, authority) {
6555
+ return super.getPortableActorUri(identifier, authority ?? this.portableRequest?.authority);
6556
+ }
6491
6557
  getPortableObjectUri(cls, values, authority) {
6492
6558
  return super.getPortableObjectUri(cls, values, authority ?? this.portableRequest?.authority);
6493
6559
  }
@@ -6511,7 +6577,7 @@ var RequestContextImpl = class RequestContextImpl extends ContextImpl {
6511
6577
  if (actor instanceof Tombstone && options?.tombstone !== "passthrough") return null;
6512
6578
  return actor;
6513
6579
  }
6514
- async getObject(cls, values) {
6580
+ async getObject(cls, values, options) {
6515
6581
  const callbacks = this.federation.objectCallbacks[cls.typeId.href];
6516
6582
  if (callbacks == null) throw new Error("No object dispatcher registered.");
6517
6583
  for (const param of callbacks.parameters) if (!(param in values)) throw new TypeError(`Missing parameter: ${param}`);
@@ -6521,13 +6587,15 @@ var RequestContextImpl = class RequestContextImpl extends ContextImpl {
6521
6587
  actorDispatcherClass: this.#invokedFromObjectDispatcher.cls.name,
6522
6588
  actorDispatcherValues: this.#invokedFromObjectDispatcher.values
6523
6589
  });
6524
- return await callbacks.dispatcher(new RequestContextImpl({
6590
+ const object = await callbacks.dispatcher(new RequestContextImpl({
6525
6591
  ...this,
6526
6592
  invokedFromObjectDispatcher: {
6527
6593
  cls,
6528
6594
  values
6529
6595
  }
6530
6596
  }), values);
6597
+ if (object instanceof Tombstone && !(object instanceof cls) && options?.tombstone !== "passthrough") return null;
6598
+ return object;
6531
6599
  }
6532
6600
  #signedKey = void 0;
6533
6601
  async getSignedKey(options = {}) {
@@ -1,5 +1,5 @@
1
1
  import "temporal-polyfill";
2
2
  import "urlpattern-polyfill";
3
3
  globalThis.addEventListener = () => {};
4
- import { n as FederationImpl } from "./middleware-Br1_d-Ga.mjs";
4
+ import { n as FederationImpl } from "./middleware-B-rZ7oE-.mjs";
5
5
  export { FederationImpl };