Skip to content

Commit 86cf0ae

Browse files
committed
Context.federation property
1 parent 95a0d54 commit 86cf0ae

8 files changed

Lines changed: 66 additions & 1 deletion

File tree

CHANGES.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ To be released. Note that 1.6.0 was skipped due to a mistake in the versioning.
1111
- Added `Context.lookupWebFinger()` method to make WebFinger lookups
1212
accessible from the context. [[#227]]
1313

14+
- Added `Context.federation` property to access the `Federation`
15+
object from the context. [[#235]]
16+
1417
- Introduced `FederationBuilder` for creating a federation instance with
1518
a builder pattern.
1619

@@ -39,6 +42,7 @@ To be released. Note that 1.6.0 was skipped due to a mistake in the versioning.
3942
[RFC 9421]: https://www.rfc-editor.org/rfc/rfc9421
4043
[#208]: https://github.com/fedify-dev/fedify/issues/208
4144
[#227]: https://github.com/fedify-dev/fedify/issues/227
45+
[#235]: https://github.com/fedify-dev/fedify/pull/235
4246

4347

4448
Version 1.5.3

docs/manual/federation.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,29 @@ export const federation = await builder.build({
420420
});
421421
~~~~
422422

423+
If you want to access the `Federation` object inside dispatchers or listeners
424+
before the `FederationBuilder` instantiates it, you can use
425+
the `Context.federation` property. The `Context.federation` property refers
426+
to the `Federation` object that is to be instantiated by the `FederationBuilder`
427+
and is available in the `Context` object passed to the dispatchers and
428+
listeners. For example, you can access the `Federation` object like this:
429+
430+
~~~~ typescript twoslash
431+
import { type FederationBuilder, Person } from "@fedify/fedify";
432+
const builder = null as unknown as FederationBuilder<void>;
433+
// ---cut-before---
434+
builder.setActorDispatcher(
435+
"/users/{handle}",
436+
async (ctx, handle) => {
437+
const federation = ctx.federation; // Access the `Federation` object
438+
// Omitted for brevity
439+
// ---cut-start---
440+
return new Person({});
441+
// ---cut-end---
442+
}
443+
);
444+
~~~~
445+
423446

424447
The `~Federation.fetch()` API
425448
-----------------------------

fedify/federation/context.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import type {
1818
} from "../vocab/vocab.ts";
1919
import type { ResourceDescriptor } from "../webfinger/jrd.ts";
2020
import type { LookupWebFingerOptions } from "../webfinger/lookup.ts";
21+
import type { Federation } from "./federation.ts";
2122
import type { SenderKeyPair } from "./send.ts";
2223

2324
/**
@@ -77,6 +78,12 @@ export interface Context<TContextData> {
7778
*/
7879
readonly contextLoader: DocumentLoader;
7980

81+
/**
82+
* The federation object that this context belongs to.
83+
* @since 1.6.0
84+
*/
85+
readonly federation: Federation<TContextData>;
86+
8087
/**
8188
* Builds the URI of the NodeInfo document.
8289
* @returns The NodeInfo URI.

fedify/federation/handler.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import {
3636
respondWithObjectIfAcceptable,
3737
} from "./handler.ts";
3838
import { MemoryKvStore } from "./kv.ts";
39+
import { createFederation } from "./middleware.ts";
3940

4041
test("acceptsJsonLd()", () => {
4142
assert(acceptsJsonLd(
@@ -68,7 +69,9 @@ test("acceptsJsonLd()", () => {
6869
});
6970

7071
test("handleActor()", async () => {
72+
const federation = createFederation<void>({ kv: new MemoryKvStore() });
7173
let context = createRequestContext<void>({
74+
federation,
7275
data: undefined,
7376
url: new URL("https://example.com/"),
7477
getActorUri(identifier) {
@@ -332,7 +335,9 @@ test("handleActor()", async () => {
332335
});
333336

334337
test("handleObject()", async () => {
338+
const federation = createFederation<void>({ kv: new MemoryKvStore() });
335339
let context = createRequestContext<void>({
340+
federation,
336341
data: undefined,
337342
url: new URL("https://example.com/"),
338343
getObjectUri(_cls, values) {
@@ -591,7 +596,9 @@ test("handleObject()", async () => {
591596
});
592597

593598
test("handleCollection()", async () => {
599+
const federation = createFederation<void>({ kv: new MemoryKvStore() });
594600
let context = createRequestContext<void>({
601+
federation,
595602
data: undefined,
596603
url: new URL("https://example.com/"),
597604
getActorUri(identifier) {
@@ -1142,7 +1149,9 @@ test("handleInbox()", async () => {
11421149
method: "POST",
11431150
body: JSON.stringify(await activity.toJsonLd()),
11441151
});
1152+
const federation = createFederation<void>({ kv: new MemoryKvStore() });
11451153
const unsignedContext = createRequestContext({
1154+
federation,
11461155
request: unsignedRequest,
11471156
url: new URL(unsignedRequest.url),
11481157
data: undefined,
@@ -1221,6 +1230,7 @@ test("handleInbox()", async () => {
12211230
rsaPublicKey3.id!,
12221231
);
12231232
const signedContext = createRequestContext({
1233+
federation,
12241234
request: signedRequest,
12251235
url: new URL(signedRequest.url),
12261236
data: undefined,
@@ -1291,6 +1301,7 @@ test("handleInbox()", async () => {
12911301
rsaPublicKey3.id!,
12921302
);
12931303
const signedInvalidContext = createRequestContext({
1304+
federation,
12941305
request: signedInvalidRequest,
12951306
url: new URL(signedInvalidRequest.url),
12961307
data: undefined,

fedify/federation/middleware.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ test("Federation.createContext()", async (t) => {
235235
assertEquals(ctx.hostname, "example.com");
236236
assertStrictEquals(ctx.documentLoader, documentLoader);
237237
assertStrictEquals(ctx.contextLoader, mockDocumentLoader);
238+
assertStrictEquals(ctx.federation, federation);
238239
assertThrows(() => ctx.getNodeInfoUri(), RouterError);
239240
assertThrows(() => ctx.getActorUri("handle"), RouterError);
240241
assertThrows(

fedify/nodeinfo/handler.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
import { assertEquals } from "@std/assert";
22
import type { NodeInfoDispatcher } from "../federation/callback.ts";
3+
import { MemoryKvStore } from "../federation/kv.ts";
4+
import { createFederation } from "../federation/middleware.ts";
35
import { createRequestContext } from "../testing/context.ts";
46
import { test } from "../testing/mod.ts";
57
import { handleNodeInfo, handleNodeInfoJrd } from "./handler.ts";
68
import { parseSemVer } from "./semver.ts";
79

810
test("handleNodeInfo()", async () => {
911
const request = new Request("https://example.com/nodeinfo/2.1");
12+
const federation = createFederation<void>({ kv: new MemoryKvStore() });
1013
const context = createRequestContext<void>({
14+
federation,
1115
data: undefined,
1216
request,
1317
url: new URL(request.url),
@@ -59,7 +63,9 @@ test("handleNodeInfo()", async () => {
5963

6064
test("handleNodeInfoJrd()", async () => {
6165
const request = new Request("https://example.com/.well-known/nodeinfo");
66+
const federation = createFederation<void>({ kv: new MemoryKvStore() });
6267
let context = createRequestContext<void>({
68+
federation,
6369
data: undefined,
6470
request,
6571
url: new URL(request.url),

fedify/testing/context.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type {
44
InboxContext,
55
RequestContext,
66
} from "../federation/context.ts";
7+
import type { Federation } from "../federation/federation.ts";
78
import { RouterError } from "../federation/router.ts";
89
import {
910
lookupObject as globalLookupObject,
@@ -14,6 +15,7 @@ import { mockDocumentLoader } from "./docloader.ts";
1415

1516
export function createContext<TContextData>(
1617
{
18+
federation,
1719
url,
1820
canonicalOrigin,
1921
data,
@@ -39,13 +41,18 @@ export function createContext<TContextData>(
3941
lookupWebFinger,
4042
sendActivity,
4143
routeActivity,
42-
}: Partial<Context<TContextData>> & { url?: URL; data: TContextData },
44+
}: Partial<Context<TContextData>> & {
45+
url?: URL;
46+
data: TContextData;
47+
federation: Federation<TContextData>;
48+
},
4349
): Context<TContextData> {
4450
function throwRouteError(): URL {
4551
throw new RouterError("Not implemented");
4652
}
4753
url ??= new URL("http://example.com/");
4854
return {
55+
federation,
4956
data,
5057
origin: url.origin,
5158
canonicalOrigin: canonicalOrigin ?? url.origin,
@@ -106,6 +113,7 @@ export function createRequestContext<TContextData>(
106113
args: Partial<RequestContext<TContextData>> & {
107114
url: URL;
108115
data: TContextData;
116+
federation: Federation<TContextData>;
109117
},
110118
): RequestContext<TContextData> {
111119
return {
@@ -127,6 +135,7 @@ export function createInboxContext<TContextData>(
127135
url?: URL;
128136
data: TContextData;
129137
recipient?: string | null;
138+
federation: Federation<TContextData>;
130139
},
131140
): InboxContext<TContextData> {
132141
return {

fedify/webfinger/handler.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import type {
55
ActorHandleMapper,
66
} from "../federation/callback.ts";
77
import type { RequestContext } from "../federation/context.ts";
8+
import { MemoryKvStore } from "../federation/kv.ts";
9+
import { createFederation } from "../federation/middleware.ts";
810
import { createRequestContext } from "../testing/context.ts";
911
import { test } from "../testing/mod.ts";
1012
import type { Actor } from "../vocab/actor.ts";
@@ -15,7 +17,9 @@ test("handleWebFinger()", async (t) => {
1517
const url = new URL("https://example.com/.well-known/webfinger");
1618

1719
function createContext(url: URL): RequestContext<void> {
20+
const federation = createFederation<void>({ kv: new MemoryKvStore() });
1821
const context = createRequestContext<void>({
22+
federation,
1923
url,
2024
data: undefined,
2125
getActorUri(identifier) {

0 commit comments

Comments
 (0)