@fedify/fedify 1.4.0-dev.632 → 1.4.0-dev.633
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/CHANGES.md +16 -0
- package/esm/compat/mod.js +2 -0
- package/esm/compat/transformers.js +85 -0
- package/esm/compat/types.js +1 -0
- package/esm/deno.js +2 -1
- package/esm/federation/middleware.js +7 -7
- package/esm/mod.js +1 -0
- package/esm/vocab/vocab.js +176 -176
- package/package.json +7 -1
- package/types/compat/mod.d.ts +3 -0
- package/types/compat/mod.d.ts.map +1 -0
- package/types/compat/transformers.d.ts +68 -0
- package/types/compat/transformers.d.ts.map +1 -0
- package/types/compat/types.d.ts +7 -0
- package/types/compat/types.d.ts.map +1 -0
- package/types/deno.d.ts +1 -0
- package/types/federation/middleware.d.ts +13 -0
- package/types/federation/middleware.d.ts.map +1 -1
- package/types/mod.d.ts +1 -0
- package/types/mod.d.ts.map +1 -1
package/CHANGES.md
CHANGED
@@ -22,6 +22,17 @@ To be released.
|
|
22
22
|
- `GetAuthenticatedDocumentLoaderOptions` interface became to extend
|
23
23
|
`DocumentLoaderFactoryOptions` interface.
|
24
24
|
|
25
|
+
- Introduced `ActivityTransformer`s for adjusting outgoing activities
|
26
|
+
before sending them so that some ActivityPub implementations with quirks
|
27
|
+
are satisfied.
|
28
|
+
|
29
|
+
- Added `@fedify/fedify/compat` module.
|
30
|
+
- Added `ActivityTransformer` type.
|
31
|
+
- Added `autoIdAssigner()` function.
|
32
|
+
- Added `actorDehydrator()` function.
|
33
|
+
- Added `defaultActivityTransformers` constant.
|
34
|
+
- Added `CreateFederationOptions.activityTransformers` option.
|
35
|
+
|
25
36
|
- The `suppressError` option of Activity Vocabulary APIs,
|
26
37
|
`traverseCollection()` function, and `Context.traverseCollection()` method
|
27
38
|
now suppresses errors occurred JSON-LD processing.
|
@@ -57,6 +68,11 @@ To be released.
|
|
57
68
|
|
58
69
|
- Added `allowPrivateAddress` option to `LookupWebFingerOptions` interface.
|
59
70
|
|
71
|
+
- Added more log messages using the [LogTape] library. Currently the below
|
72
|
+
logger categories are used:
|
73
|
+
|
74
|
+
- `["fedify", "compat", "transformers"]`
|
75
|
+
|
60
76
|
- Added `-t`/`--traverse` option to the `fedify lookup` subcommand. [[#195]]
|
61
77
|
|
62
78
|
- Added `-S`/`--suppress-errors` option to the `fedify lookup` subcommand.
|
@@ -0,0 +1,85 @@
|
|
1
|
+
import * as dntShim from "../_dnt.shims.js";
|
2
|
+
import { getLogger } from "@logtape/logtape";
|
3
|
+
const logger = getLogger(["fedify", "compat", "transformers"]);
|
4
|
+
/**
|
5
|
+
* An activity transformer that assigns a new random ID to an activity if it
|
6
|
+
* does not already have one. This is useful for ensuring that activities
|
7
|
+
* have an ID before they are sent to other servers.
|
8
|
+
*
|
9
|
+
* The generated ID is a URN UUID like:
|
10
|
+
*
|
11
|
+
* ```
|
12
|
+
* urn:uuid:12345678-1234-5678-1234-567812345678
|
13
|
+
* ```
|
14
|
+
* @param activity The activity to assign an ID to.
|
15
|
+
* @return The activity with an ID assigned.
|
16
|
+
* @since 1.4.0
|
17
|
+
*/
|
18
|
+
export function autoIdAssigner(activity) {
|
19
|
+
if (activity.id != null)
|
20
|
+
return activity;
|
21
|
+
const id = new URL(`urn:uuid:${dntShim.crypto.randomUUID()}`);
|
22
|
+
logger.warn("As the activity to send does not have an id, a new id {id} has " +
|
23
|
+
"been generated for it. However, it is recommended to explicitly " +
|
24
|
+
"set the id for the activity.", { id: id.href });
|
25
|
+
return activity.clone({ id });
|
26
|
+
}
|
27
|
+
/**
|
28
|
+
* An activity transformer that dehydrates the actor property of an activity
|
29
|
+
* so that it only contains the actor's URI. For example, suppose we have an
|
30
|
+
* activity like this:
|
31
|
+
*
|
32
|
+
* ```typescript
|
33
|
+
* import { Follow, Person } from "@fedify/fedify/vocab";
|
34
|
+
* const input = new Follow({
|
35
|
+
* id: new URL("http://example.com/activities/1"),
|
36
|
+
* actor: new Person({
|
37
|
+
* id: new URL("http://example.com/actors/1"),
|
38
|
+
* name: "Alice",
|
39
|
+
* preferredUsername: "alice",
|
40
|
+
* }),
|
41
|
+
* object: new Person({
|
42
|
+
* id: new URL("http://example.com/actors/2"),
|
43
|
+
* name: "Bob",
|
44
|
+
* preferredUsername: "bob",
|
45
|
+
* }),
|
46
|
+
* });
|
47
|
+
* ```
|
48
|
+
*
|
49
|
+
* The result of applying this transformer would be:
|
50
|
+
*
|
51
|
+
* ```typescript
|
52
|
+
* import { Follow, Person } from "@fedify/fedify/vocab";
|
53
|
+
* const output = new Follow({
|
54
|
+
* id: new URL("http://example.com/activities/1"),
|
55
|
+
* actor: new URL("http://example.com/actors/1"),
|
56
|
+
* object: new Person({
|
57
|
+
* id: new URL("http://example.com/actors/2"),
|
58
|
+
* name: "Bob",
|
59
|
+
* preferredUsername: "bob",
|
60
|
+
* }),
|
61
|
+
* });
|
62
|
+
* ```
|
63
|
+
*
|
64
|
+
* As some ActivityPub implementations like Threads fail to deal with inlined
|
65
|
+
* actor objects, this transformer can be used to work around this issue.
|
66
|
+
* @param activity The activity to dehydrate the actor property of.
|
67
|
+
* @returns The dehydrated activity.
|
68
|
+
* @since 1.4.0
|
69
|
+
*/
|
70
|
+
export function actorDehydrator(activity) {
|
71
|
+
if (activity.actorIds.length < 1)
|
72
|
+
return activity;
|
73
|
+
return activity.clone({
|
74
|
+
actors: activity.actorIds,
|
75
|
+
});
|
76
|
+
}
|
77
|
+
/**
|
78
|
+
* The default activity transformers that are applied to all outgoing
|
79
|
+
* activities.
|
80
|
+
* @since 1.4.0
|
81
|
+
*/
|
82
|
+
export const defaultActivityTransformers = [
|
83
|
+
autoIdAssigner,
|
84
|
+
actorDehydrator,
|
85
|
+
];
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
package/esm/deno.js
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
export default {
|
2
2
|
"name": "@fedify/fedify",
|
3
|
-
"version": "1.4.0-dev.
|
3
|
+
"version": "1.4.0-dev.633+1856bfff",
|
4
4
|
"license": "MIT",
|
5
5
|
"exports": {
|
6
6
|
".": "./mod.ts",
|
7
|
+
"./compat": "./compat/mod.ts",
|
7
8
|
"./federation": "./federation/mod.ts",
|
8
9
|
"./nodeinfo": "./nodeinfo/mod.ts",
|
9
10
|
"./runtime": "./runtime/mod.ts",
|
@@ -3,6 +3,7 @@ import { verifyObject } from "../mod.js";
|
|
3
3
|
import { getLogger, withContext } from "@logtape/logtape";
|
4
4
|
import { context, propagation, SpanKind, SpanStatusCode, trace, } from "@opentelemetry/api";
|
5
5
|
import { ATTR_HTTP_REQUEST_HEADER, ATTR_HTTP_REQUEST_METHOD, ATTR_HTTP_RESPONSE_HEADER, ATTR_HTTP_RESPONSE_STATUS_CODE, ATTR_URL_FULL, } from "@opentelemetry/semantic-conventions";
|
6
|
+
import { defaultActivityTransformers } from "../compat/transformers.js";
|
6
7
|
import metadata from "../deno.js";
|
7
8
|
import { getNodeInfo } from "../nodeinfo/client.js";
|
8
9
|
import { handleNodeInfo, handleNodeInfoJrd } from "../nodeinfo/handler.js";
|
@@ -66,6 +67,7 @@ export class FederationImpl {
|
|
66
67
|
skipSignatureVerification;
|
67
68
|
outboxRetryPolicy;
|
68
69
|
inboxRetryPolicy;
|
70
|
+
activityTransformers;
|
69
71
|
tracerProvider;
|
70
72
|
constructor(options) {
|
71
73
|
const logger = getLogger(["fedify", "federation"]);
|
@@ -166,6 +168,8 @@ export class FederationImpl {
|
|
166
168
|
createExponentialBackoffPolicy();
|
167
169
|
this.inboxRetryPolicy = options.inboxRetryPolicy ??
|
168
170
|
createExponentialBackoffPolicy();
|
171
|
+
this.activityTransformers = options.activityTransformers ??
|
172
|
+
defaultActivityTransformers;
|
169
173
|
this.tracerProvider = options.tracerProvider ?? trace.getTracerProvider();
|
170
174
|
}
|
171
175
|
#getTracer() {
|
@@ -1092,14 +1096,10 @@ export class FederationImpl {
|
|
1092
1096
|
for (const { privateKey } of keys) {
|
1093
1097
|
validateCryptoKey(privateKey, "private");
|
1094
1098
|
}
|
1095
|
-
|
1096
|
-
|
1097
|
-
activity = activity.clone({ id });
|
1098
|
-
logger.warn("As the activity to send does not have an id, a new id {id} has " +
|
1099
|
-
"been generated for it. However, it is recommended to explicitly " +
|
1100
|
-
"set the id for the activity.", { id: id.href });
|
1099
|
+
for (const activityTransformer of this.activityTransformers) {
|
1100
|
+
activity = activityTransformer(activity);
|
1101
1101
|
}
|
1102
|
-
span?.setAttribute("activitypub.activity.id", activity
|
1102
|
+
span?.setAttribute("activitypub.activity.id", activity?.id?.href ?? "");
|
1103
1103
|
if (activity.actorId == null) {
|
1104
1104
|
logger.error("Activity {activityId} to send does not have an actor.", { activity, activityId: activity?.id?.href });
|
1105
1105
|
throw new TypeError("The activity to send must have at least one actor property.");
|