@fedify/relay 2.0.0-dev.109 → 2.0.0-dev.150
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.
- package/README.md +9 -6
- package/dist/mod.cjs +23 -8
- package/dist/mod.d.cts +43 -2
- package/dist/mod.d.ts +43 -2
- package/dist/mod.js +23 -8
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -102,7 +102,7 @@ import { MemoryKvStore } from "@fedify/fedify";
|
|
|
102
102
|
// Create a Mastodon-style relay
|
|
103
103
|
const relay = createRelay("mastodon", {
|
|
104
104
|
kv: new MemoryKvStore(),
|
|
105
|
-
|
|
105
|
+
origin: "https://relay.example.com",
|
|
106
106
|
// Required: Set a subscription handler to approve/reject subscriptions
|
|
107
107
|
subscriptionHandler: async (ctx, actor) => {
|
|
108
108
|
// For an open relay, simply return true
|
|
@@ -124,7 +124,7 @@ You can also create a LitePub-style relay by changing the type:
|
|
|
124
124
|
~~~~ typescript
|
|
125
125
|
const relay = createRelay("litepub", {
|
|
126
126
|
kv: new MemoryKvStore(),
|
|
127
|
-
|
|
127
|
+
origin: "https://relay.example.com",
|
|
128
128
|
subscriptionHandler: async (ctx, actor) => true,
|
|
129
129
|
});
|
|
130
130
|
~~~~
|
|
@@ -137,7 +137,7 @@ subscription requests. For an open relay that accepts all subscriptions:
|
|
|
137
137
|
~~~~ typescript
|
|
138
138
|
const relay = createRelay("mastodon", {
|
|
139
139
|
kv: new MemoryKvStore(),
|
|
140
|
-
|
|
140
|
+
origin: "https://relay.example.com",
|
|
141
141
|
subscriptionHandler: async (ctx, actor) => true, // Accept all
|
|
142
142
|
});
|
|
143
143
|
~~~~
|
|
@@ -147,7 +147,7 @@ You can also implement custom approval logic:
|
|
|
147
147
|
~~~~ typescript
|
|
148
148
|
const relay = createRelay("mastodon", {
|
|
149
149
|
kv: new MemoryKvStore(),
|
|
150
|
-
|
|
150
|
+
origin: "https://relay.example.com",
|
|
151
151
|
subscriptionHandler: async (ctx, actor) => {
|
|
152
152
|
// Example: Only allow subscriptions from specific domains
|
|
153
153
|
const domain = new URL(actor.id!).hostname;
|
|
@@ -200,7 +200,7 @@ import { MemoryKvStore } from "@fedify/fedify";
|
|
|
200
200
|
const app = new Hono();
|
|
201
201
|
const relay = createRelay("mastodon", {
|
|
202
202
|
kv: new MemoryKvStore(),
|
|
203
|
-
|
|
203
|
+
origin: "https://relay.example.com",
|
|
204
204
|
subscriptionHandler: async (ctx, actor) => true,
|
|
205
205
|
});
|
|
206
206
|
|
|
@@ -284,6 +284,8 @@ Public interface for ActivityPub relay implementations.
|
|
|
284
284
|
followers of the relay
|
|
285
285
|
- `getFollower(actorId: string): Promise<RelayFollower | null>`: Gets
|
|
286
286
|
a specific follower by actor ID
|
|
287
|
+
- `getActorUri(): Promise<URL>`: Gets the URI of the relay actor
|
|
288
|
+
- `getSharedInboxUri(): Promise<URL>`: Gets the shared inbox URI of the relay
|
|
287
289
|
|
|
288
290
|
#### Relay types
|
|
289
291
|
|
|
@@ -299,7 +301,8 @@ The relay type is specified when calling `createRelay()`:
|
|
|
299
301
|
Configuration options for the relay:
|
|
300
302
|
|
|
301
303
|
- `kv: KvStore` (required): Key–value store for persisting relay data
|
|
302
|
-
- `
|
|
304
|
+
- `origin: string` (required): Relay's origin URL (e.g.,
|
|
305
|
+
`"https://relay.example.com"`)
|
|
303
306
|
- `name?: string`: Relay's display name (defaults to `"ActivityPub Relay"`)
|
|
304
307
|
- `subscriptionHandler: SubscriptionRequestHandler` (required): Handler for
|
|
305
308
|
subscription approval/rejection
|
package/dist/mod.cjs
CHANGED
|
@@ -140,11 +140,7 @@ var BaseRelay = class {
|
|
|
140
140
|
this.federationBuilder = relayBuilder$1;
|
|
141
141
|
}
|
|
142
142
|
async fetch(request) {
|
|
143
|
-
|
|
144
|
-
this.federation = await this.federationBuilder.build(this.options);
|
|
145
|
-
this.setupInboxListeners();
|
|
146
|
-
}
|
|
147
|
-
return await this.federation.fetch(request, { contextData: this.options });
|
|
143
|
+
return await (await this.#getFederation()).fetch(request, { contextData: this.options });
|
|
148
144
|
}
|
|
149
145
|
/**
|
|
150
146
|
* Helper method to parse and validate follower data from storage.
|
|
@@ -177,7 +173,7 @@ var BaseRelay = class {
|
|
|
177
173
|
*
|
|
178
174
|
* const relay = createRelay("mastodon", {
|
|
179
175
|
* kv: new MemoryKvStore(),
|
|
180
|
-
*
|
|
176
|
+
* origin: "https://relay.example.com",
|
|
181
177
|
* subscriptionHandler: async (ctx, actor) => true,
|
|
182
178
|
* });
|
|
183
179
|
*
|
|
@@ -211,7 +207,7 @@ var BaseRelay = class {
|
|
|
211
207
|
*
|
|
212
208
|
* const relay = createRelay("mastodon", {
|
|
213
209
|
* kv: new MemoryKvStore(),
|
|
214
|
-
*
|
|
210
|
+
* origin: "https://relay.example.com",
|
|
215
211
|
* subscriptionHandler: async (ctx, actor) => true,
|
|
216
212
|
* });
|
|
217
213
|
*
|
|
@@ -230,6 +226,25 @@ var BaseRelay = class {
|
|
|
230
226
|
const followerData = await this.options.kv.get(["follower", actorId]);
|
|
231
227
|
return await this.parseFollowerData(actorId, followerData);
|
|
232
228
|
}
|
|
229
|
+
async #getFederation() {
|
|
230
|
+
if (this.federation == null) {
|
|
231
|
+
this.federation = await this.federationBuilder.build(this.options);
|
|
232
|
+
this.setupInboxListeners();
|
|
233
|
+
}
|
|
234
|
+
return this.federation;
|
|
235
|
+
}
|
|
236
|
+
async #createContext() {
|
|
237
|
+
const context = (await this.#getFederation()).createContext(new URL(this.options.origin), this.options);
|
|
238
|
+
return context;
|
|
239
|
+
}
|
|
240
|
+
async getActorUri() {
|
|
241
|
+
const context = await this.#createContext();
|
|
242
|
+
return context.getActorUri(RELAY_SERVER_ACTOR);
|
|
243
|
+
}
|
|
244
|
+
async getSharedInboxUri() {
|
|
245
|
+
const context = await this.#createContext();
|
|
246
|
+
return context.getInboxUri();
|
|
247
|
+
}
|
|
233
248
|
};
|
|
234
249
|
|
|
235
250
|
//#endregion
|
|
@@ -419,7 +434,7 @@ var MastodonRelay = class extends BaseRelay {
|
|
|
419
434
|
*
|
|
420
435
|
* const relay = createRelay("mastodon", {
|
|
421
436
|
* kv: new MemoryKvStore(),
|
|
422
|
-
*
|
|
437
|
+
* origin: "https://relay.example.com",
|
|
423
438
|
* subscriptionHandler: async (ctx, actor) => true,
|
|
424
439
|
* });
|
|
425
440
|
* ```
|
package/dist/mod.d.cts
CHANGED
|
@@ -16,12 +16,41 @@ type SubscriptionRequestHandler = (ctx: Context<RelayOptions>, clientActor: Acto
|
|
|
16
16
|
* Configuration options for the ActivityPub relay.
|
|
17
17
|
*/
|
|
18
18
|
interface RelayOptions {
|
|
19
|
+
/**
|
|
20
|
+
* Key-value store for persisting relay data such as follower information
|
|
21
|
+
* and cryptographic keys.
|
|
22
|
+
*/
|
|
19
23
|
kv: KvStore;
|
|
20
|
-
|
|
24
|
+
/**
|
|
25
|
+
* The origin URL where the relay is hosted.
|
|
26
|
+
* Must be a full URL including the protocol (e.g., `"https://relay.example.com"`).
|
|
27
|
+
*/
|
|
28
|
+
origin: string;
|
|
29
|
+
/**
|
|
30
|
+
* Display name for the relay actor.
|
|
31
|
+
* Defaults to `"ActivityPub Relay"`.
|
|
32
|
+
*/
|
|
21
33
|
name?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Factory function for creating a document loader to fetch remote
|
|
36
|
+
* ActivityPub objects.
|
|
37
|
+
*/
|
|
22
38
|
documentLoaderFactory?: DocumentLoaderFactory;
|
|
39
|
+
/**
|
|
40
|
+
* Factory function for creating an authenticated document loader
|
|
41
|
+
* that signs HTTP requests when fetching remote objects.
|
|
42
|
+
*/
|
|
23
43
|
authenticatedDocumentLoaderFactory?: AuthenticatedDocumentLoaderFactory;
|
|
44
|
+
/**
|
|
45
|
+
* Message queue for background activity processing.
|
|
46
|
+
* Recommended for production to handle activity forwarding asynchronously.
|
|
47
|
+
*/
|
|
24
48
|
queue?: MessageQueue;
|
|
49
|
+
/**
|
|
50
|
+
* Handler function that determines whether to approve or reject
|
|
51
|
+
* subscription requests from remote actors.
|
|
52
|
+
* Return `true` to approve or `false` to reject.
|
|
53
|
+
*/
|
|
25
54
|
subscriptionHandler: SubscriptionRequestHandler;
|
|
26
55
|
}
|
|
27
56
|
/**
|
|
@@ -73,6 +102,18 @@ interface Relay {
|
|
|
73
102
|
* @returns The follower entry if found, null otherwise
|
|
74
103
|
*/
|
|
75
104
|
getFollower(actorId: string): Promise<RelayFollower | null>;
|
|
105
|
+
/**
|
|
106
|
+
* Gets the URI of the relay actor.
|
|
107
|
+
*
|
|
108
|
+
* @returns The URI of the relay actor
|
|
109
|
+
*/
|
|
110
|
+
getActorUri(): Promise<URL>;
|
|
111
|
+
/**
|
|
112
|
+
* Gets the shared inbox URI of the relay.
|
|
113
|
+
*
|
|
114
|
+
* @returns The shared inbox URI
|
|
115
|
+
*/
|
|
116
|
+
getSharedInboxUri(): Promise<URL>;
|
|
76
117
|
}
|
|
77
118
|
/**
|
|
78
119
|
* Type predicate to check if a value is valid RelayFollowerData from KV store.
|
|
@@ -98,7 +139,7 @@ interface Relay {
|
|
|
98
139
|
*
|
|
99
140
|
* const relay = createRelay("mastodon", {
|
|
100
141
|
* kv: new MemoryKvStore(),
|
|
101
|
-
*
|
|
142
|
+
* origin: "https://relay.example.com",
|
|
102
143
|
* subscriptionHandler: async (ctx, actor) => true,
|
|
103
144
|
* });
|
|
104
145
|
* ```
|
package/dist/mod.d.ts
CHANGED
|
@@ -17,12 +17,41 @@ type SubscriptionRequestHandler = (ctx: Context<RelayOptions>, clientActor: Acto
|
|
|
17
17
|
* Configuration options for the ActivityPub relay.
|
|
18
18
|
*/
|
|
19
19
|
interface RelayOptions {
|
|
20
|
+
/**
|
|
21
|
+
* Key-value store for persisting relay data such as follower information
|
|
22
|
+
* and cryptographic keys.
|
|
23
|
+
*/
|
|
20
24
|
kv: KvStore;
|
|
21
|
-
|
|
25
|
+
/**
|
|
26
|
+
* The origin URL where the relay is hosted.
|
|
27
|
+
* Must be a full URL including the protocol (e.g., `"https://relay.example.com"`).
|
|
28
|
+
*/
|
|
29
|
+
origin: string;
|
|
30
|
+
/**
|
|
31
|
+
* Display name for the relay actor.
|
|
32
|
+
* Defaults to `"ActivityPub Relay"`.
|
|
33
|
+
*/
|
|
22
34
|
name?: string;
|
|
35
|
+
/**
|
|
36
|
+
* Factory function for creating a document loader to fetch remote
|
|
37
|
+
* ActivityPub objects.
|
|
38
|
+
*/
|
|
23
39
|
documentLoaderFactory?: DocumentLoaderFactory;
|
|
40
|
+
/**
|
|
41
|
+
* Factory function for creating an authenticated document loader
|
|
42
|
+
* that signs HTTP requests when fetching remote objects.
|
|
43
|
+
*/
|
|
24
44
|
authenticatedDocumentLoaderFactory?: AuthenticatedDocumentLoaderFactory;
|
|
45
|
+
/**
|
|
46
|
+
* Message queue for background activity processing.
|
|
47
|
+
* Recommended for production to handle activity forwarding asynchronously.
|
|
48
|
+
*/
|
|
25
49
|
queue?: MessageQueue;
|
|
50
|
+
/**
|
|
51
|
+
* Handler function that determines whether to approve or reject
|
|
52
|
+
* subscription requests from remote actors.
|
|
53
|
+
* Return `true` to approve or `false` to reject.
|
|
54
|
+
*/
|
|
26
55
|
subscriptionHandler: SubscriptionRequestHandler;
|
|
27
56
|
}
|
|
28
57
|
/**
|
|
@@ -74,6 +103,18 @@ interface Relay {
|
|
|
74
103
|
* @returns The follower entry if found, null otherwise
|
|
75
104
|
*/
|
|
76
105
|
getFollower(actorId: string): Promise<RelayFollower | null>;
|
|
106
|
+
/**
|
|
107
|
+
* Gets the URI of the relay actor.
|
|
108
|
+
*
|
|
109
|
+
* @returns The URI of the relay actor
|
|
110
|
+
*/
|
|
111
|
+
getActorUri(): Promise<URL>;
|
|
112
|
+
/**
|
|
113
|
+
* Gets the shared inbox URI of the relay.
|
|
114
|
+
*
|
|
115
|
+
* @returns The shared inbox URI
|
|
116
|
+
*/
|
|
117
|
+
getSharedInboxUri(): Promise<URL>;
|
|
77
118
|
}
|
|
78
119
|
/**
|
|
79
120
|
* Type predicate to check if a value is valid RelayFollowerData from KV store.
|
|
@@ -99,7 +140,7 @@ interface Relay {
|
|
|
99
140
|
*
|
|
100
141
|
* const relay = createRelay("mastodon", {
|
|
101
142
|
* kv: new MemoryKvStore(),
|
|
102
|
-
*
|
|
143
|
+
* origin: "https://relay.example.com",
|
|
103
144
|
* subscriptionHandler: async (ctx, actor) => true,
|
|
104
145
|
* });
|
|
105
146
|
* ```
|
package/dist/mod.js
CHANGED
|
@@ -117,11 +117,7 @@ var BaseRelay = class {
|
|
|
117
117
|
this.federationBuilder = relayBuilder$1;
|
|
118
118
|
}
|
|
119
119
|
async fetch(request) {
|
|
120
|
-
|
|
121
|
-
this.federation = await this.federationBuilder.build(this.options);
|
|
122
|
-
this.setupInboxListeners();
|
|
123
|
-
}
|
|
124
|
-
return await this.federation.fetch(request, { contextData: this.options });
|
|
120
|
+
return await (await this.#getFederation()).fetch(request, { contextData: this.options });
|
|
125
121
|
}
|
|
126
122
|
/**
|
|
127
123
|
* Helper method to parse and validate follower data from storage.
|
|
@@ -154,7 +150,7 @@ var BaseRelay = class {
|
|
|
154
150
|
*
|
|
155
151
|
* const relay = createRelay("mastodon", {
|
|
156
152
|
* kv: new MemoryKvStore(),
|
|
157
|
-
*
|
|
153
|
+
* origin: "https://relay.example.com",
|
|
158
154
|
* subscriptionHandler: async (ctx, actor) => true,
|
|
159
155
|
* });
|
|
160
156
|
*
|
|
@@ -188,7 +184,7 @@ var BaseRelay = class {
|
|
|
188
184
|
*
|
|
189
185
|
* const relay = createRelay("mastodon", {
|
|
190
186
|
* kv: new MemoryKvStore(),
|
|
191
|
-
*
|
|
187
|
+
* origin: "https://relay.example.com",
|
|
192
188
|
* subscriptionHandler: async (ctx, actor) => true,
|
|
193
189
|
* });
|
|
194
190
|
*
|
|
@@ -207,6 +203,25 @@ var BaseRelay = class {
|
|
|
207
203
|
const followerData = await this.options.kv.get(["follower", actorId]);
|
|
208
204
|
return await this.parseFollowerData(actorId, followerData);
|
|
209
205
|
}
|
|
206
|
+
async #getFederation() {
|
|
207
|
+
if (this.federation == null) {
|
|
208
|
+
this.federation = await this.federationBuilder.build(this.options);
|
|
209
|
+
this.setupInboxListeners();
|
|
210
|
+
}
|
|
211
|
+
return this.federation;
|
|
212
|
+
}
|
|
213
|
+
async #createContext() {
|
|
214
|
+
const context = (await this.#getFederation()).createContext(new URL(this.options.origin), this.options);
|
|
215
|
+
return context;
|
|
216
|
+
}
|
|
217
|
+
async getActorUri() {
|
|
218
|
+
const context = await this.#createContext();
|
|
219
|
+
return context.getActorUri(RELAY_SERVER_ACTOR);
|
|
220
|
+
}
|
|
221
|
+
async getSharedInboxUri() {
|
|
222
|
+
const context = await this.#createContext();
|
|
223
|
+
return context.getInboxUri();
|
|
224
|
+
}
|
|
210
225
|
};
|
|
211
226
|
|
|
212
227
|
//#endregion
|
|
@@ -396,7 +411,7 @@ var MastodonRelay = class extends BaseRelay {
|
|
|
396
411
|
*
|
|
397
412
|
* const relay = createRelay("mastodon", {
|
|
398
413
|
* kv: new MemoryKvStore(),
|
|
399
|
-
*
|
|
414
|
+
* origin: "https://relay.example.com",
|
|
400
415
|
* subscriptionHandler: async (ctx, actor) => true,
|
|
401
416
|
* });
|
|
402
417
|
* ```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fedify/relay",
|
|
3
|
-
"version": "2.0.0-dev.
|
|
3
|
+
"version": "2.0.0-dev.150+7daa59dd",
|
|
4
4
|
"description": "ActivityPub relay support for Fedify",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Fedify",
|
|
@@ -52,13 +52,13 @@
|
|
|
52
52
|
"@logtape/logtape": "^1.3.5"
|
|
53
53
|
},
|
|
54
54
|
"peerDependencies": {
|
|
55
|
-
"@fedify/fedify": "^2.0.0-dev.
|
|
55
|
+
"@fedify/fedify": "^2.0.0-dev.150+7daa59dd"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"tsdown": "^0.12.9",
|
|
59
59
|
"typescript": "^5.9.3",
|
|
60
|
-
"@fedify/
|
|
61
|
-
"@fedify/
|
|
60
|
+
"@fedify/vocab-runtime": "^2.0.0-dev.150+7daa59dd",
|
|
61
|
+
"@fedify/testing": "^2.0.0-dev.150+7daa59dd"
|
|
62
62
|
},
|
|
63
63
|
"scripts": {
|
|
64
64
|
"build": "deno task codegen && tsdown",
|