@fedify/fedify 0.11.0-dev.240 → 0.11.0-dev.241
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGES.md +4 -0
- package/esm/federation/middleware.js +78 -0
- package/esm/vocab/application.yaml +14 -0
- package/esm/vocab/group.yaml +14 -0
- package/esm/vocab/organization.yaml +14 -0
- package/esm/vocab/person.yaml +14 -0
- package/esm/vocab/service.yaml +14 -0
- package/esm/vocab/vocab.js +565 -0
- package/package.json +1 -1
- package/types/federation/context.d.ts +16 -0
- package/types/federation/context.d.ts.map +1 -1
- package/types/federation/middleware.d.ts +13 -0
- package/types/federation/middleware.d.ts.map +1 -1
- package/types/testing/context.d.ts.map +1 -1
- package/types/vocab/vocab.d.ts +90 -0
- package/types/vocab/vocab.d.ts.map +1 -1
package/CHANGES.md
CHANGED
@@ -21,6 +21,10 @@ To be released.
|
|
21
21
|
- Added `{ type: "liked"; handle: string }` case to `ParseUriResult` type.
|
22
22
|
- Renamed `linked` property (which was a typo) to `liked` in
|
23
23
|
`Application`, `Group`, `Organization`, `Person`, and `Service` classes.
|
24
|
+
- Added `Federation.setFeaturedDispatcher()` method.
|
25
|
+
- Added `Context.getFeaturedUri()` method.
|
26
|
+
- Added `{ type: "featured"; handle: string }` case to `ParseUriResult`
|
27
|
+
type.
|
24
28
|
|
25
29
|
- Frequently used JSON-LD contexts are now preloaded. [[74]]
|
26
30
|
|
@@ -48,6 +48,7 @@ export class Federation {
|
|
48
48
|
#followingCallbacks;
|
49
49
|
#followersCallbacks;
|
50
50
|
#likedCallbacks;
|
51
|
+
#featuredCallbacks;
|
51
52
|
#inboxListeners;
|
52
53
|
#inboxErrorHandler;
|
53
54
|
#sharedInboxKeyDispatcher;
|
@@ -334,6 +335,19 @@ export class Federation {
|
|
334
335
|
"URI. Set the property with Context.getLikedUri(handle).");
|
335
336
|
}
|
336
337
|
}
|
338
|
+
if (this.#featuredCallbacks != null &&
|
339
|
+
this.#featuredCallbacks.dispatcher != null) {
|
340
|
+
if (actor?.featuredId == null) {
|
341
|
+
logger.warn("You configured a featured collection dispatcher, but the " +
|
342
|
+
"actor does not have a featured property. Set the property " +
|
343
|
+
"with Context.getFeaturedUri(handle).");
|
344
|
+
}
|
345
|
+
else if (actor.featuredId.href != context.getFeaturedUri(handle).href) {
|
346
|
+
logger.warn("You configured a featured collection dispatcher, but the " +
|
347
|
+
"actor's featured property does not match the featured collection " +
|
348
|
+
"URI. Set the property with Context.getFeaturedUri(handle).");
|
349
|
+
}
|
350
|
+
}
|
337
351
|
if (this.#router.has("inbox")) {
|
338
352
|
if (actor.inboxId == null) {
|
339
353
|
logger.warn("You configured inbox listeners, but the actor does not " +
|
@@ -658,6 +672,50 @@ export class Federation {
|
|
658
672
|
};
|
659
673
|
return setters;
|
660
674
|
}
|
675
|
+
/**
|
676
|
+
* Registers a featured collection dispatcher.
|
677
|
+
* @param path The URI path pattern for the featured collection. The syntax
|
678
|
+
* is based on URI Template
|
679
|
+
* ([RFC 6570](https://tools.ietf.org/html/rfc6570)). The path
|
680
|
+
* must have one variable: `{handle}`.
|
681
|
+
* @param dispatcher A featured collection callback to register.
|
682
|
+
* @returns An object with methods to set other featured collection
|
683
|
+
* callbacks.
|
684
|
+
* @throws {@link RouterError} Thrown if the path pattern is invalid.
|
685
|
+
* @since 0.11.0
|
686
|
+
*/
|
687
|
+
setFeaturedDispatcher(path, dispatcher) {
|
688
|
+
if (this.#router.has("featured")) {
|
689
|
+
throw new RouterError("Featured collection dispatcher already set.");
|
690
|
+
}
|
691
|
+
const variables = this.#router.add(path, "featured");
|
692
|
+
if (variables.size !== 1 || !variables.has("handle")) {
|
693
|
+
throw new RouterError("Path for featured collection dispatcher must have one variable: {handle}");
|
694
|
+
}
|
695
|
+
const callbacks = {
|
696
|
+
dispatcher,
|
697
|
+
};
|
698
|
+
this.#featuredCallbacks = callbacks;
|
699
|
+
const setters = {
|
700
|
+
setCounter(counter) {
|
701
|
+
callbacks.counter = counter;
|
702
|
+
return setters;
|
703
|
+
},
|
704
|
+
setFirstCursor(cursor) {
|
705
|
+
callbacks.firstCursor = cursor;
|
706
|
+
return setters;
|
707
|
+
},
|
708
|
+
setLastCursor(cursor) {
|
709
|
+
callbacks.lastCursor = cursor;
|
710
|
+
return setters;
|
711
|
+
},
|
712
|
+
authorize(predicate) {
|
713
|
+
callbacks.authorizePredicate = predicate;
|
714
|
+
return setters;
|
715
|
+
},
|
716
|
+
};
|
717
|
+
return setters;
|
718
|
+
}
|
661
719
|
/**
|
662
720
|
* Assigns the URL path for the inbox and starts setting inbox listeners.
|
663
721
|
*
|
@@ -994,6 +1052,16 @@ export class Federation {
|
|
994
1052
|
onNotFound,
|
995
1053
|
onNotAcceptable,
|
996
1054
|
});
|
1055
|
+
case "featured":
|
1056
|
+
return await handleCollection(request, {
|
1057
|
+
name: "featured",
|
1058
|
+
handle: route.values.handle,
|
1059
|
+
context,
|
1060
|
+
collectionCallbacks: this.#featuredCallbacks,
|
1061
|
+
onUnauthorized,
|
1062
|
+
onNotFound,
|
1063
|
+
onNotAcceptable,
|
1064
|
+
});
|
997
1065
|
default: {
|
998
1066
|
const response = onNotFound(request);
|
999
1067
|
return response instanceof Promise ? await response : response;
|
@@ -1099,6 +1167,13 @@ class ContextImpl {
|
|
1099
1167
|
}
|
1100
1168
|
return new URL(path, this.#url);
|
1101
1169
|
}
|
1170
|
+
getFeaturedUri(handle) {
|
1171
|
+
const path = this.#router.build("featured", { handle });
|
1172
|
+
if (path == null) {
|
1173
|
+
throw new RouterError("No featured collection path registered.");
|
1174
|
+
}
|
1175
|
+
return new URL(path, this.#url);
|
1176
|
+
}
|
1102
1177
|
parseUri(uri) {
|
1103
1178
|
if (uri.origin !== this.#url.origin)
|
1104
1179
|
return null;
|
@@ -1135,6 +1210,9 @@ class ContextImpl {
|
|
1135
1210
|
else if (route.name === "liked") {
|
1136
1211
|
return { type: "liked", handle: route.values.handle };
|
1137
1212
|
}
|
1213
|
+
else if (route.name === "featured") {
|
1214
|
+
return { type: "featured", handle: route.values.handle };
|
1215
|
+
}
|
1138
1216
|
return null;
|
1139
1217
|
}
|
1140
1218
|
getHandleFromActorUri(actorUri) {
|
@@ -12,6 +12,9 @@ defaultContext:
|
|
12
12
|
- "https://w3id.org/security/multikey/v1"
|
13
13
|
- manuallyApprovesFollowers: "as:manuallyApprovesFollowers"
|
14
14
|
toot: "http://joinmastodon.org/ns#"
|
15
|
+
featured:
|
16
|
+
"@id": "toot:featured"
|
17
|
+
"@type": "@id"
|
15
18
|
discoverable: "toot:discoverable"
|
16
19
|
suspended: "toot:suspended"
|
17
20
|
memorial: "toot:memorial"
|
@@ -143,6 +146,17 @@ properties:
|
|
143
146
|
range:
|
144
147
|
- "https://www.w3.org/ns/activitystreams#Collection"
|
145
148
|
|
149
|
+
- singularName: featured
|
150
|
+
functional: true
|
151
|
+
uri: "http://joinmastodon.org/ns#featured"
|
152
|
+
description: |
|
153
|
+
What is known in Mastodon as "pinned statuses", or statuses that are always
|
154
|
+
featured at the top of people's profiles, is implemented using an extra
|
155
|
+
property `featured` on the actor object that points to a {@link Collection}
|
156
|
+
of objects.
|
157
|
+
range:
|
158
|
+
- "https://www.w3.org/ns/activitystreams#Collection"
|
159
|
+
|
146
160
|
- pluralName: streams
|
147
161
|
singularName: stream
|
148
162
|
singularAccessor: false
|
package/esm/vocab/group.yaml
CHANGED
@@ -12,6 +12,9 @@ defaultContext:
|
|
12
12
|
- "https://w3id.org/security/multikey/v1"
|
13
13
|
- manuallyApprovesFollowers: "as:manuallyApprovesFollowers"
|
14
14
|
toot: "http://joinmastodon.org/ns#"
|
15
|
+
featured:
|
16
|
+
"@id": "toot:featured"
|
17
|
+
"@type": "@id"
|
15
18
|
discoverable: "toot:discoverable"
|
16
19
|
suspended: "toot:suspended"
|
17
20
|
memorial: "toot:memorial"
|
@@ -143,6 +146,17 @@ properties:
|
|
143
146
|
range:
|
144
147
|
- "https://www.w3.org/ns/activitystreams#Collection"
|
145
148
|
|
149
|
+
- singularName: featured
|
150
|
+
functional: true
|
151
|
+
uri: "http://joinmastodon.org/ns#featured"
|
152
|
+
description: |
|
153
|
+
What is known in Mastodon as "pinned statuses", or statuses that are always
|
154
|
+
featured at the top of people's profiles, is implemented using an extra
|
155
|
+
property `featured` on the actor object that points to a {@link Collection}
|
156
|
+
of objects.
|
157
|
+
range:
|
158
|
+
- "https://www.w3.org/ns/activitystreams#Collection"
|
159
|
+
|
146
160
|
- pluralName: streams
|
147
161
|
singularName: stream
|
148
162
|
singularAccessor: false
|
@@ -12,6 +12,9 @@ defaultContext:
|
|
12
12
|
- "https://w3id.org/security/multikey/v1"
|
13
13
|
- manuallyApprovesFollowers: "as:manuallyApprovesFollowers"
|
14
14
|
toot: "http://joinmastodon.org/ns#"
|
15
|
+
featured:
|
16
|
+
"@id": "toot:featured"
|
17
|
+
"@type": "@id"
|
15
18
|
discoverable: "toot:discoverable"
|
16
19
|
suspended: "toot:suspended"
|
17
20
|
memorial: "toot:memorial"
|
@@ -143,6 +146,17 @@ properties:
|
|
143
146
|
range:
|
144
147
|
- "https://www.w3.org/ns/activitystreams#Collection"
|
145
148
|
|
149
|
+
- singularName: featured
|
150
|
+
functional: true
|
151
|
+
uri: "http://joinmastodon.org/ns#featured"
|
152
|
+
description: |
|
153
|
+
What is known in Mastodon as "pinned statuses", or statuses that are always
|
154
|
+
featured at the top of people's profiles, is implemented using an extra
|
155
|
+
property `featured` on the actor object that points to a {@link Collection}
|
156
|
+
of objects.
|
157
|
+
range:
|
158
|
+
- "https://www.w3.org/ns/activitystreams#Collection"
|
159
|
+
|
146
160
|
- pluralName: streams
|
147
161
|
singularName: stream
|
148
162
|
singularAccessor: false
|
package/esm/vocab/person.yaml
CHANGED
@@ -12,6 +12,9 @@ defaultContext:
|
|
12
12
|
- "https://w3id.org/security/multikey/v1"
|
13
13
|
- manuallyApprovesFollowers: "as:manuallyApprovesFollowers"
|
14
14
|
toot: "http://joinmastodon.org/ns#"
|
15
|
+
featured:
|
16
|
+
"@id": "toot:featured"
|
17
|
+
"@type": "@id"
|
15
18
|
discoverable: "toot:discoverable"
|
16
19
|
suspended: "toot:suspended"
|
17
20
|
memorial: "toot:memorial"
|
@@ -143,6 +146,17 @@ properties:
|
|
143
146
|
range:
|
144
147
|
- "https://www.w3.org/ns/activitystreams#Collection"
|
145
148
|
|
149
|
+
- singularName: featured
|
150
|
+
functional: true
|
151
|
+
uri: "http://joinmastodon.org/ns#featured"
|
152
|
+
description: |
|
153
|
+
What is known in Mastodon as "pinned statuses", or statuses that are always
|
154
|
+
featured at the top of people's profiles, is implemented using an extra
|
155
|
+
property `featured` on the actor object that points to a {@link Collection}
|
156
|
+
of objects.
|
157
|
+
range:
|
158
|
+
- "https://www.w3.org/ns/activitystreams#Collection"
|
159
|
+
|
146
160
|
- pluralName: streams
|
147
161
|
singularName: stream
|
148
162
|
singularAccessor: false
|
package/esm/vocab/service.yaml
CHANGED
@@ -12,6 +12,9 @@ defaultContext:
|
|
12
12
|
- "https://w3id.org/security/multikey/v1"
|
13
13
|
- manuallyApprovesFollowers: "as:manuallyApprovesFollowers"
|
14
14
|
toot: "http://joinmastodon.org/ns#"
|
15
|
+
featured:
|
16
|
+
"@id": "toot:featured"
|
17
|
+
"@type": "@id"
|
15
18
|
discoverable: "toot:discoverable"
|
16
19
|
suspended: "toot:suspended"
|
17
20
|
memorial: "toot:memorial"
|
@@ -143,6 +146,17 @@ properties:
|
|
143
146
|
range:
|
144
147
|
- "https://www.w3.org/ns/activitystreams#Collection"
|
145
148
|
|
149
|
+
- singularName: featured
|
150
|
+
functional: true
|
151
|
+
uri: "http://joinmastodon.org/ns#featured"
|
152
|
+
description: |
|
153
|
+
What is known in Mastodon as "pinned statuses", or statuses that are always
|
154
|
+
featured at the top of people's profiles, is implemented using an extra
|
155
|
+
property `featured` on the actor object that points to a {@link Collection}
|
156
|
+
of objects.
|
157
|
+
range:
|
158
|
+
- "https://www.w3.org/ns/activitystreams#Collection"
|
159
|
+
|
146
160
|
- pluralName: streams
|
147
161
|
singularName: stream
|
148
162
|
singularAccessor: false
|