@fedify/fedify 1.6.0-dev.775 → 1.6.0-dev.776

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.
@@ -17,12 +17,13 @@ import { getTypeId } from "../vocab/type.js";
17
17
  import { Activity, CryptographicKey, Multikey, } from "../vocab/vocab.js";
18
18
  import { handleWebFinger } from "../webfinger/handler.js";
19
19
  import { lookupWebFinger, } from "../webfinger/lookup.js";
20
+ import { FederationBuilderImpl } from "./builder.js";
20
21
  import { buildCollectionSynchronizationHeader } from "./collection.js";
21
22
  import { handleActor, handleCollection, handleInbox, handleObject, } from "./handler.js";
22
- import { InboxListenerSet, routeActivity } from "./inbox.js";
23
+ import { routeActivity } from "./inbox.js";
23
24
  import { KvKeyCache } from "./keycache.js";
24
25
  import { createExponentialBackoffPolicy } from "./retry.js";
25
- import { Router, RouterError } from "./router.js";
26
+ import { RouterError } from "./router.js";
26
27
  import { extractInboxes, sendActivity } from "./send.js";
27
28
  /**
28
29
  * Create a new {@link Federation} instance.
@@ -33,7 +34,7 @@ import { extractInboxes, sendActivity } from "./send.js";
33
34
  export function createFederation(options) {
34
35
  return new FederationImpl(options);
35
36
  }
36
- export class FederationImpl {
37
+ export class FederationImpl extends FederationBuilderImpl {
37
38
  kv;
38
39
  kvPrefixes;
39
40
  inboxQueue;
@@ -44,22 +45,6 @@ export class FederationImpl {
44
45
  fanoutQueueStarted;
45
46
  manuallyStartQueue;
46
47
  origin;
47
- router;
48
- nodeInfoDispatcher;
49
- actorCallbacks;
50
- objectCallbacks;
51
- objectTypeIds;
52
- inboxPath;
53
- inboxCallbacks;
54
- outboxCallbacks;
55
- followingCallbacks;
56
- followersCallbacks;
57
- likedCallbacks;
58
- featuredCallbacks;
59
- featuredTagsCallbacks;
60
- inboxListeners;
61
- inboxErrorHandler;
62
- sharedInboxKeyDispatcher;
63
48
  documentLoaderFactory;
64
49
  contextLoaderFactory;
65
50
  authenticatedDocumentLoaderFactory;
@@ -73,6 +58,7 @@ export class FederationImpl {
73
58
  activityTransformers;
74
59
  tracerProvider;
75
60
  constructor(options) {
61
+ super();
76
62
  const logger = getLogger(["fedify", "federation"]);
77
63
  this.kv = options.kv;
78
64
  this.kvPrefixes = {
@@ -133,13 +119,10 @@ export class FederationImpl {
133
119
  };
134
120
  }
135
121
  }
136
- this.router = new Router({
137
- trailingSlashInsensitive: options.trailingSlashInsensitive,
138
- });
122
+ this.router.trailingSlashInsensitive = options.trailingSlashInsensitive ??
123
+ false;
139
124
  this.router.add("/.well-known/webfinger", "webfinger");
140
125
  this.router.add("/.well-known/nodeinfo", "nodeInfoJrd");
141
- this.objectCallbacks = {};
142
- this.objectTypeIds = {};
143
126
  if (options.allowPrivateAddress || options.userAgent != null) {
144
127
  if (options.documentLoader != null) {
145
128
  throw new TypeError("Cannot set documentLoader with allowPrivateAddress or " +
@@ -210,7 +193,7 @@ export class FederationImpl {
210
193
  getDefaultActivityTransformers();
211
194
  this.tracerProvider = options.tracerProvider ?? trace.getTracerProvider();
212
195
  }
213
- #getTracer() {
196
+ _getTracer() {
214
197
  return this.tracerProvider.getTracer(metadata.name, metadata.version);
215
198
  }
216
199
  async _startQueueInternal(ctxData, signal, queue) {
@@ -244,7 +227,7 @@ export class FederationImpl {
244
227
  await Promise.all(promises);
245
228
  }
246
229
  #listenQueue(ctxData, message) {
247
- const tracer = this.#getTracer();
230
+ const tracer = this._getTracer();
248
231
  const extractedContext = propagation.extract(context.active(), message.traceContext);
249
232
  return withContext({ messageId: message.id }, async () => {
250
233
  if (message.type === "fanout") {
@@ -472,7 +455,7 @@ export class FederationImpl {
472
455
  return;
473
456
  }
474
457
  }
475
- await this.#getTracer().startActiveSpan("activitypub.dispatch_inbox_listener", { kind: SpanKind.INTERNAL }, async (span) => {
458
+ await this._getTracer().startActiveSpan("activitypub.dispatch_inbox_listener", { kind: SpanKind.INTERNAL }, async (span) => {
476
459
  const dispatched = this.inboxListeners?.dispatchWithClass(activity);
477
460
  if (dispatched == null) {
478
461
  logger.error("Unsupported activity type:\n{activity}", {
@@ -605,592 +588,6 @@ export class FederationImpl {
605
588
  },
606
589
  };
607
590
  }
608
- setNodeInfoDispatcher(path, dispatcher) {
609
- if (this.router.has("nodeInfo")) {
610
- throw new RouterError("NodeInfo dispatcher already set.");
611
- }
612
- const variables = this.router.add(path, "nodeInfo");
613
- if (variables.size !== 0) {
614
- throw new RouterError("Path for NodeInfo dispatcher must have no variables.");
615
- }
616
- this.nodeInfoDispatcher = dispatcher;
617
- }
618
- setActorDispatcher(path, dispatcher) {
619
- if (this.router.has("actor")) {
620
- throw new RouterError("Actor dispatcher already set.");
621
- }
622
- const variables = this.router.add(path, "actor");
623
- if (variables.size !== 1 ||
624
- !(variables.has("identifier") || variables.has("handle"))) {
625
- throw new RouterError("Path for actor dispatcher must have one variable: {identifier}");
626
- }
627
- if (variables.has("handle")) {
628
- getLogger(["fedify", "federation", "actor"]).warn("The {{handle}} variable in the actor dispatcher path is deprecated. " +
629
- "Use {{identifier}} instead.");
630
- }
631
- const callbacks = {
632
- dispatcher: async (context, identifier) => {
633
- const actor = await this.#getTracer().startActiveSpan("activitypub.dispatch_actor", {
634
- kind: SpanKind.SERVER,
635
- attributes: { "fedify.actor.identifier": identifier },
636
- }, async (span) => {
637
- try {
638
- const actor = await dispatcher(context, identifier);
639
- span.setAttribute("activitypub.actor.id", (actor?.id ?? context.getActorUri(identifier)).href);
640
- if (actor == null) {
641
- span.setStatus({ code: SpanStatusCode.ERROR });
642
- }
643
- else {
644
- span.setAttribute("activitypub.actor.type", getTypeId(actor).href);
645
- }
646
- return actor;
647
- }
648
- catch (error) {
649
- span.setStatus({
650
- code: SpanStatusCode.ERROR,
651
- message: String(error),
652
- });
653
- throw error;
654
- }
655
- finally {
656
- span.end();
657
- }
658
- });
659
- if (actor == null)
660
- return null;
661
- const logger = getLogger(["fedify", "federation", "actor"]);
662
- if (actor.id == null) {
663
- logger.warn("Actor dispatcher returned an actor without an id property. " +
664
- "Set the property with Context.getActorUri(identifier).");
665
- }
666
- else if (actor.id.href != context.getActorUri(identifier).href) {
667
- logger.warn("Actor dispatcher returned an actor with an id property that " +
668
- "does not match the actor URI. Set the property with " +
669
- "Context.getActorUri(identifier).");
670
- }
671
- if (this.followingCallbacks != null &&
672
- this.followingCallbacks.dispatcher != null) {
673
- if (actor.followingId == null) {
674
- logger.warn("You configured a following collection dispatcher, but the " +
675
- "actor does not have a following property. Set the property " +
676
- "with Context.getFollowingUri(identifier).");
677
- }
678
- else if (actor.followingId.href != context.getFollowingUri(identifier).href) {
679
- logger.warn("You configured a following collection dispatcher, but the " +
680
- "actor's following property does not match the following " +
681
- "collection URI. Set the property with " +
682
- "Context.getFollowingUri(identifier).");
683
- }
684
- }
685
- if (this.followersCallbacks != null &&
686
- this.followersCallbacks.dispatcher != null) {
687
- if (actor.followersId == null) {
688
- logger.warn("You configured a followers collection dispatcher, but the " +
689
- "actor does not have a followers property. Set the property " +
690
- "with Context.getFollowersUri(identifier).");
691
- }
692
- else if (actor.followersId.href != context.getFollowersUri(identifier).href) {
693
- logger.warn("You configured a followers collection dispatcher, but the " +
694
- "actor's followers property does not match the followers " +
695
- "collection URI. Set the property with " +
696
- "Context.getFollowersUri(identifier).");
697
- }
698
- }
699
- if (this.outboxCallbacks != null &&
700
- this.outboxCallbacks.dispatcher != null) {
701
- if (actor?.outboxId == null) {
702
- logger.warn("You configured an outbox collection dispatcher, but the " +
703
- "actor does not have an outbox property. Set the property " +
704
- "with Context.getOutboxUri(identifier).");
705
- }
706
- else if (actor.outboxId.href != context.getOutboxUri(identifier).href) {
707
- logger.warn("You configured an outbox collection dispatcher, but the " +
708
- "actor's outbox property does not match the outbox collection " +
709
- "URI. Set the property with Context.getOutboxUri(identifier).");
710
- }
711
- }
712
- if (this.likedCallbacks != null &&
713
- this.likedCallbacks.dispatcher != null) {
714
- if (actor?.likedId == null) {
715
- logger.warn("You configured a liked collection dispatcher, but the " +
716
- "actor does not have a liked property. Set the property " +
717
- "with Context.getLikedUri(identifier).");
718
- }
719
- else if (actor.likedId.href != context.getLikedUri(identifier).href) {
720
- logger.warn("You configured a liked collection dispatcher, but the " +
721
- "actor's liked property does not match the liked collection " +
722
- "URI. Set the property with Context.getLikedUri(identifier).");
723
- }
724
- }
725
- if (this.featuredCallbacks != null &&
726
- this.featuredCallbacks.dispatcher != null) {
727
- if (actor?.featuredId == null) {
728
- logger.warn("You configured a featured collection dispatcher, but the " +
729
- "actor does not have a featured property. Set the property " +
730
- "with Context.getFeaturedUri(identifier).");
731
- }
732
- else if (actor.featuredId.href != context.getFeaturedUri(identifier).href) {
733
- logger.warn("You configured a featured collection dispatcher, but the " +
734
- "actor's featured property does not match the featured collection " +
735
- "URI. Set the property with Context.getFeaturedUri(identifier).");
736
- }
737
- }
738
- if (this.featuredTagsCallbacks != null &&
739
- this.featuredTagsCallbacks.dispatcher != null) {
740
- if (actor?.featuredTagsId == null) {
741
- logger.warn("You configured a featured tags collection dispatcher, but the " +
742
- "actor does not have a featuredTags property. Set the property " +
743
- "with Context.getFeaturedTagsUri(identifier).");
744
- }
745
- else if (actor.featuredTagsId.href !=
746
- context.getFeaturedTagsUri(identifier).href) {
747
- logger.warn("You configured a featured tags collection dispatcher, but the " +
748
- "actor's featuredTags property does not match the featured tags " +
749
- "collection URI. Set the property with " +
750
- "Context.getFeaturedTagsUri(identifier).");
751
- }
752
- }
753
- if (this.router.has("inbox")) {
754
- if (actor.inboxId == null) {
755
- logger.warn("You configured inbox listeners, but the actor does not " +
756
- "have an inbox property. Set the property with " +
757
- "Context.getInboxUri(identifier).");
758
- }
759
- else if (actor.inboxId.href != context.getInboxUri(identifier).href) {
760
- logger.warn("You configured inbox listeners, but the actor's inbox " +
761
- "property does not match the inbox URI. Set the property " +
762
- "with Context.getInboxUri(identifier).");
763
- }
764
- if (actor.endpoints == null || actor.endpoints.sharedInbox == null) {
765
- logger.warn("You configured inbox listeners, but the actor does not have " +
766
- "a endpoints.sharedInbox property. Set the property with " +
767
- "Context.getInboxUri().");
768
- }
769
- else if (actor.endpoints.sharedInbox.href != context.getInboxUri().href) {
770
- logger.warn("You configured inbox listeners, but the actor's " +
771
- "endpoints.sharedInbox property does not match the shared inbox " +
772
- "URI. Set the property with Context.getInboxUri().");
773
- }
774
- }
775
- if (callbacks.keyPairsDispatcher != null) {
776
- if (actor.publicKeyId == null) {
777
- logger.warn("You configured a key pairs dispatcher, but the actor does " +
778
- "not have a publicKey property. Set the property with " +
779
- "Context.getActorKeyPairs(identifier).");
780
- }
781
- if (actor.assertionMethodId == null) {
782
- logger.warn("You configured a key pairs dispatcher, but the actor does " +
783
- "not have an assertionMethod property. Set the property " +
784
- "with Context.getActorKeyPairs(identifier).");
785
- }
786
- }
787
- return actor;
788
- },
789
- };
790
- this.actorCallbacks = callbacks;
791
- const setters = {
792
- setKeyPairsDispatcher: (dispatcher) => {
793
- callbacks.keyPairsDispatcher = (ctx, identifier) => this.#getTracer().startActiveSpan("activitypub.dispatch_actor_key_pairs", {
794
- kind: SpanKind.SERVER,
795
- attributes: {
796
- "activitypub.actor.id": ctx.getActorUri(identifier).href,
797
- "fedify.actor.identifier": identifier,
798
- },
799
- }, async (span) => {
800
- try {
801
- return await dispatcher(ctx, identifier);
802
- }
803
- catch (e) {
804
- span.setStatus({
805
- code: SpanStatusCode.ERROR,
806
- message: String(e),
807
- });
808
- throw e;
809
- }
810
- finally {
811
- span.end();
812
- }
813
- });
814
- return setters;
815
- },
816
- mapHandle(mapper) {
817
- callbacks.handleMapper = mapper;
818
- return setters;
819
- },
820
- mapAlias(mapper) {
821
- callbacks.aliasMapper = mapper;
822
- return setters;
823
- },
824
- authorize(predicate) {
825
- callbacks.authorizePredicate = predicate;
826
- return setters;
827
- },
828
- };
829
- return setters;
830
- }
831
- setObjectDispatcher(
832
- // deno-lint-ignore no-explicit-any
833
- cls, path, dispatcher) {
834
- const routeName = `object:${cls.typeId.href}`;
835
- if (this.router.has(routeName)) {
836
- throw new RouterError(`Object dispatcher for ${cls.name} already set.`);
837
- }
838
- const variables = this.router.add(path, routeName);
839
- if (variables.size < 1) {
840
- throw new RouterError("Path for object dispatcher must have at least one variable.");
841
- }
842
- const callbacks = {
843
- dispatcher: (ctx, values) => {
844
- const tracer = this.#getTracer();
845
- return tracer.startActiveSpan("activitypub.dispatch_object", {
846
- kind: SpanKind.SERVER,
847
- attributes: {
848
- "fedify.object.type": cls.typeId.href,
849
- ...globalThis.Object.fromEntries(globalThis.Object.entries(values).map(([k, v]) => [
850
- `fedify.object.values.${k}`,
851
- v,
852
- ])),
853
- },
854
- }, async (span) => {
855
- try {
856
- const object = await dispatcher(ctx, values);
857
- span.setAttribute("activitypub.object.id", (object?.id ?? ctx.getObjectUri(cls, values)).href);
858
- if (object == null) {
859
- span.setStatus({ code: SpanStatusCode.ERROR });
860
- }
861
- else {
862
- span.setAttribute("activitypub.object.type", getTypeId(object).href);
863
- }
864
- return object;
865
- }
866
- catch (e) {
867
- span.setStatus({
868
- code: SpanStatusCode.ERROR,
869
- message: String(e),
870
- });
871
- throw e;
872
- }
873
- finally {
874
- span.end();
875
- }
876
- });
877
- },
878
- parameters: variables,
879
- };
880
- this.objectCallbacks[cls.typeId.href] = callbacks;
881
- this.objectTypeIds[cls.typeId.href] = cls;
882
- const setters = {
883
- authorize(predicate) {
884
- callbacks.authorizePredicate = predicate;
885
- return setters;
886
- },
887
- };
888
- return setters;
889
- }
890
- setInboxDispatcher(path, dispatcher) {
891
- if (this.inboxCallbacks != null) {
892
- throw new RouterError("Inbox dispatcher already set.");
893
- }
894
- if (this.router.has("inbox")) {
895
- if (this.inboxPath !== path) {
896
- throw new RouterError("Inbox dispatcher path must match inbox listener path.");
897
- }
898
- }
899
- else {
900
- const variables = this.router.add(path, "inbox");
901
- if (variables.size !== 1 ||
902
- !(variables.has("identifier") || variables.has("handle"))) {
903
- throw new RouterError("Path for inbox dispatcher must have one variable: {identifier}");
904
- }
905
- if (variables.has("handle")) {
906
- getLogger(["fedify", "federation", "inbox"]).warn("The {{handle}} variable in the inbox dispatcher path is deprecated. " +
907
- "Use {{identifier}} instead.");
908
- }
909
- this.inboxPath = path;
910
- }
911
- const callbacks = { dispatcher };
912
- this.inboxCallbacks = callbacks;
913
- const setters = {
914
- setCounter(counter) {
915
- callbacks.counter = counter;
916
- return setters;
917
- },
918
- setFirstCursor(cursor) {
919
- callbacks.firstCursor = cursor;
920
- return setters;
921
- },
922
- setLastCursor(cursor) {
923
- callbacks.lastCursor = cursor;
924
- return setters;
925
- },
926
- authorize(predicate) {
927
- callbacks.authorizePredicate = predicate;
928
- return setters;
929
- },
930
- };
931
- return setters;
932
- }
933
- setOutboxDispatcher(path, dispatcher) {
934
- if (this.router.has("outbox")) {
935
- throw new RouterError("Outbox dispatcher already set.");
936
- }
937
- const variables = this.router.add(path, "outbox");
938
- if (variables.size !== 1 ||
939
- !(variables.has("identifier") || variables.has("handle"))) {
940
- throw new RouterError("Path for outbox dispatcher must have one variable: {identifier}");
941
- }
942
- if (variables.has("handle")) {
943
- getLogger(["fedify", "federation", "outbox"]).warn("The {{handle}} variable in the outbox dispatcher path is deprecated. " +
944
- "Use {{identifier}} instead.");
945
- }
946
- const callbacks = { dispatcher };
947
- this.outboxCallbacks = callbacks;
948
- const setters = {
949
- setCounter(counter) {
950
- callbacks.counter = counter;
951
- return setters;
952
- },
953
- setFirstCursor(cursor) {
954
- callbacks.firstCursor = cursor;
955
- return setters;
956
- },
957
- setLastCursor(cursor) {
958
- callbacks.lastCursor = cursor;
959
- return setters;
960
- },
961
- authorize(predicate) {
962
- callbacks.authorizePredicate = predicate;
963
- return setters;
964
- },
965
- };
966
- return setters;
967
- }
968
- setFollowingDispatcher(path, dispatcher) {
969
- if (this.router.has("following")) {
970
- throw new RouterError("Following collection dispatcher already set.");
971
- }
972
- const variables = this.router.add(path, "following");
973
- if (variables.size !== 1 ||
974
- !(variables.has("identifier") || variables.has("handle"))) {
975
- throw new RouterError("Path for following collection dispatcher must have one variable: " +
976
- "{identifier}");
977
- }
978
- if (variables.has("handle")) {
979
- getLogger(["fedify", "federation", "collection"]).warn("The {{handle}} variable in the following collection dispatcher path " +
980
- "is deprecated. Use {{identifier}} instead.");
981
- }
982
- const callbacks = { dispatcher };
983
- this.followingCallbacks = callbacks;
984
- const setters = {
985
- setCounter(counter) {
986
- callbacks.counter = counter;
987
- return setters;
988
- },
989
- setFirstCursor(cursor) {
990
- callbacks.firstCursor = cursor;
991
- return setters;
992
- },
993
- setLastCursor(cursor) {
994
- callbacks.lastCursor = cursor;
995
- return setters;
996
- },
997
- authorize(predicate) {
998
- callbacks.authorizePredicate = predicate;
999
- return setters;
1000
- },
1001
- };
1002
- return setters;
1003
- }
1004
- setFollowersDispatcher(path, dispatcher) {
1005
- if (this.router.has("followers")) {
1006
- throw new RouterError("Followers collection dispatcher already set.");
1007
- }
1008
- const variables = this.router.add(path, "followers");
1009
- if (variables.size !== 1 ||
1010
- !(variables.has("identifier") || variables.has("handle"))) {
1011
- throw new RouterError("Path for followers collection dispatcher must have one variable: " +
1012
- "{identifier}");
1013
- }
1014
- if (variables.has("handle")) {
1015
- getLogger(["fedify", "federation", "collection"]).warn("The {{handle}} variable in the followers collection dispatcher path " +
1016
- "is deprecated. Use {{identifier}} instead.");
1017
- }
1018
- const callbacks = { dispatcher };
1019
- this.followersCallbacks = callbacks;
1020
- const setters = {
1021
- setCounter(counter) {
1022
- callbacks.counter = counter;
1023
- return setters;
1024
- },
1025
- setFirstCursor(cursor) {
1026
- callbacks.firstCursor = cursor;
1027
- return setters;
1028
- },
1029
- setLastCursor(cursor) {
1030
- callbacks.lastCursor = cursor;
1031
- return setters;
1032
- },
1033
- authorize(predicate) {
1034
- callbacks.authorizePredicate = predicate;
1035
- return setters;
1036
- },
1037
- };
1038
- return setters;
1039
- }
1040
- setLikedDispatcher(path, dispatcher) {
1041
- if (this.router.has("liked")) {
1042
- throw new RouterError("Liked collection dispatcher already set.");
1043
- }
1044
- const variables = this.router.add(path, "liked");
1045
- if (variables.size !== 1 ||
1046
- !(variables.has("identifier") || variables.has("handle"))) {
1047
- throw new RouterError("Path for liked collection dispatcher must have one variable: " +
1048
- "{identifier}");
1049
- }
1050
- if (variables.has("handle")) {
1051
- getLogger(["fedify", "federation", "collection"]).warn("The {{handle}} variable in the liked collection dispatcher path " +
1052
- "is deprecated. Use {{identifier}} instead.");
1053
- }
1054
- const callbacks = { dispatcher };
1055
- this.likedCallbacks = callbacks;
1056
- const setters = {
1057
- setCounter(counter) {
1058
- callbacks.counter = counter;
1059
- return setters;
1060
- },
1061
- setFirstCursor(cursor) {
1062
- callbacks.firstCursor = cursor;
1063
- return setters;
1064
- },
1065
- setLastCursor(cursor) {
1066
- callbacks.lastCursor = cursor;
1067
- return setters;
1068
- },
1069
- authorize(predicate) {
1070
- callbacks.authorizePredicate = predicate;
1071
- return setters;
1072
- },
1073
- };
1074
- return setters;
1075
- }
1076
- setFeaturedDispatcher(path, dispatcher) {
1077
- if (this.router.has("featured")) {
1078
- throw new RouterError("Featured collection dispatcher already set.");
1079
- }
1080
- const variables = this.router.add(path, "featured");
1081
- if (variables.size !== 1 ||
1082
- !(variables.has("identifier") || variables.has("handle"))) {
1083
- throw new RouterError("Path for featured collection dispatcher must have one variable: " +
1084
- "{identifier}");
1085
- }
1086
- if (variables.has("handle")) {
1087
- getLogger(["fedify", "federation", "collection"]).warn("The {{handle}} variable in the featured collection dispatcher path " +
1088
- "is deprecated. Use {{identifier}} instead.");
1089
- }
1090
- const callbacks = { dispatcher };
1091
- this.featuredCallbacks = callbacks;
1092
- const setters = {
1093
- setCounter(counter) {
1094
- callbacks.counter = counter;
1095
- return setters;
1096
- },
1097
- setFirstCursor(cursor) {
1098
- callbacks.firstCursor = cursor;
1099
- return setters;
1100
- },
1101
- setLastCursor(cursor) {
1102
- callbacks.lastCursor = cursor;
1103
- return setters;
1104
- },
1105
- authorize(predicate) {
1106
- callbacks.authorizePredicate = predicate;
1107
- return setters;
1108
- },
1109
- };
1110
- return setters;
1111
- }
1112
- setFeaturedTagsDispatcher(path, dispatcher) {
1113
- if (this.router.has("featuredTags")) {
1114
- throw new RouterError("Featured tags collection dispatcher already set.");
1115
- }
1116
- const variables = this.router.add(path, "featuredTags");
1117
- if (variables.size !== 1 ||
1118
- !(variables.has("identifier") || variables.has("handle"))) {
1119
- throw new RouterError("Path for featured tags collection dispatcher must have one " +
1120
- "variable: {identifier}");
1121
- }
1122
- if (variables.has("handle")) {
1123
- getLogger(["fedify", "federation", "collection"]).warn("The {{handle}} variable in the featured tags collection dispatcher " +
1124
- "path is deprecated. Use {{identifier}} instead.");
1125
- }
1126
- const callbacks = { dispatcher };
1127
- this.featuredTagsCallbacks = callbacks;
1128
- const setters = {
1129
- setCounter(counter) {
1130
- callbacks.counter = counter;
1131
- return setters;
1132
- },
1133
- setFirstCursor(cursor) {
1134
- callbacks.firstCursor = cursor;
1135
- return setters;
1136
- },
1137
- setLastCursor(cursor) {
1138
- callbacks.lastCursor = cursor;
1139
- return setters;
1140
- },
1141
- authorize(predicate) {
1142
- callbacks.authorizePredicate = predicate;
1143
- return setters;
1144
- },
1145
- };
1146
- return setters;
1147
- }
1148
- setInboxListeners(inboxPath, sharedInboxPath) {
1149
- if (this.inboxListeners != null) {
1150
- throw new RouterError("Inbox listeners already set.");
1151
- }
1152
- if (this.router.has("inbox")) {
1153
- if (this.inboxPath !== inboxPath) {
1154
- throw new RouterError("Inbox listener path must match inbox dispatcher path.");
1155
- }
1156
- }
1157
- else {
1158
- const variables = this.router.add(inboxPath, "inbox");
1159
- if (variables.size !== 1 ||
1160
- !(variables.has("identifier") || variables.has("handle"))) {
1161
- throw new RouterError("Path for inbox must have one variable: {identifier}");
1162
- }
1163
- this.inboxPath = inboxPath;
1164
- if (variables.has("handle")) {
1165
- getLogger(["fedify", "federation", "inbox"]).warn("The {{handle}} variable in the inbox path is deprecated. " +
1166
- "Use {{identifier}} instead.");
1167
- }
1168
- }
1169
- if (sharedInboxPath != null) {
1170
- const siVars = this.router.add(sharedInboxPath, "sharedInbox");
1171
- if (siVars.size !== 0) {
1172
- throw new RouterError("Path for shared inbox must have no variables.");
1173
- }
1174
- }
1175
- const listeners = this.inboxListeners = new InboxListenerSet();
1176
- const setters = {
1177
- on(
1178
- // deno-lint-ignore no-explicit-any
1179
- type, listener) {
1180
- listeners.add(type, listener);
1181
- return setters;
1182
- },
1183
- onError: (handler) => {
1184
- this.inboxErrorHandler = handler;
1185
- return setters;
1186
- },
1187
- setSharedKeyDispatcher: (dispatcher) => {
1188
- this.sharedInboxKeyDispatcher = dispatcher;
1189
- return setters;
1190
- },
1191
- };
1192
- return setters;
1193
- }
1194
591
  async sendActivity(keys, inboxes, activity, options) {
1195
592
  const logger = getLogger(["fedify", "federation", "outbox"]);
1196
593
  const { immediate, collectionSync, context: ctx } = options;
@@ -1339,7 +736,7 @@ export class FederationImpl {
1339
736
  fetch(request, options) {
1340
737
  const requestId = getRequestId(request);
1341
738
  return withContext({ requestId }, async () => {
1342
- const tracer = this.#getTracer();
739
+ const tracer = this._getTracer();
1343
740
  return await tracer.startActiveSpan(request.method, {
1344
741
  kind: SpanKind.SERVER,
1345
742
  attributes: {