@fedify/fedify 2.3.15-dev.2482 → 2.3.15
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/dist/{builder-CocMrVkL.mjs → builder-B6vSXYxn.mjs} +2 -2
- package/dist/{client-CAM_bQXx.d.cts → client-BIBzqEIp.d.cts} +0 -1
- package/dist/{client-1He2YuBF.mjs → client-DpUNYKla.mjs} +113 -64
- package/dist/{client-CSddvgWN.d.ts → client-jE7oGvRh.d.ts} +0 -1
- package/dist/compat/mod.d.cts +1 -1
- package/dist/compat/mod.d.ts +1 -1
- package/dist/compat/transformers.test.mjs +1 -1
- package/dist/{context-MOrCC7yl.d.cts → context-CE_Tj_Oc.d.cts} +28 -2
- package/dist/{context-BWbdE_MZ.d.ts → context-H_5tZXg-.d.ts} +28 -2
- package/dist/{deno-po8iekMB.mjs → deno-BCuL3mid.mjs} +1 -1
- package/dist/docloader-D2dr1_6B.mjs +125 -0
- package/dist/federation/builder.test.mjs +1 -1
- package/dist/federation/handler.test.mjs +5 -5
- package/dist/federation/idempotency.test.mjs +2 -2
- package/dist/federation/inbox.test.mjs +1 -1
- package/dist/federation/metrics.test.mjs +1 -1
- package/dist/federation/middleware.test.mjs +390 -29
- package/dist/federation/mod.cjs +1 -1
- package/dist/federation/mod.d.cts +2 -2
- package/dist/federation/mod.d.ts +2 -2
- package/dist/federation/mod.js +1 -1
- package/dist/federation/send.test.mjs +498 -88
- package/dist/federation/temporal.test.mjs +1 -1
- package/dist/federation/webfinger.test.mjs +1 -1
- package/dist/{http-Cdu8BGtv.js → http-BkjxY3U0.js} +172 -103
- package/dist/{http-BNCLeQJ-.mjs → http-CSDcThvz.mjs} +196 -98
- package/dist/{http-DQmNpfym.d.ts → http-CZPYFK3b.d.cts} +1 -2
- package/dist/{http-DiWQB8Mr.d.cts → http-DmP0sr2l.d.ts} +1 -2
- package/dist/{http-WcSdFbt1.cjs → http-gOkAiIe1.cjs} +173 -104
- package/dist/{inbox-g1sd_Vjn.mjs → inbox-BHxez4d5.mjs} +2 -2
- package/dist/{key-BR2TRTXR.mjs → key-D8IMQ72M.mjs} +2 -2
- package/dist/{kv-cache-Bw_gduSm.cjs → kv-cache-Alm5UmJa.cjs} +59 -17
- package/dist/{kv-cache-8SigUtvX.mjs → kv-cache-Blr9nDDp.mjs} +1 -1
- package/dist/{kv-cache-C0AqpjoS.js → kv-cache-CkXgU-ak.js} +60 -18
- package/dist/{ld-CSNsWdYE.mjs → ld-CVxxE1Pp.mjs} +3 -3
- package/dist/{metrics-BS7YzLVA.mjs → metrics-SYIZHFf_.mjs} +1 -1
- package/dist/{middleware-D-SL8Bkj.cjs → middleware-4yPyyoF5.cjs} +236 -98
- package/dist/{middleware-B1RRLN7m.mjs → middleware-CfskJGfV.mjs} +80 -40
- package/dist/{middleware-Dlo7NnZl.mjs → middleware-D3JWfiCu.mjs} +1 -1
- package/dist/{middleware-WL-JfDiK.js → middleware-DhN7c65B.js} +237 -99
- package/dist/{mod-LmD03uRA.d.ts → mod-CDFFESfL.d.ts} +1 -1
- package/dist/{mod-Bid79LFU.d.cts → mod-C_gFmeNq.d.cts} +1 -1
- package/dist/{mod-Co1M3Ux0.d.cts → mod-DDVkmZ_h.d.cts} +2 -8
- package/dist/{mod-B6PwkUMU.d.cts → mod-DDjtbkZO.d.cts} +1 -1
- package/dist/{mod-Br8yJNcE.d.ts → mod-DMjhnFbg.d.ts} +2 -8
- package/dist/{mod-TLEvgT1i.d.ts → mod-HQXFvOHs.d.ts} +1 -1
- package/dist/mod.cjs +5 -5
- package/dist/mod.d.cts +6 -6
- package/dist/mod.d.ts +6 -6
- package/dist/mod.js +5 -5
- package/dist/nodeinfo/client.test.mjs +337 -19
- package/dist/nodeinfo/handler.test.mjs +1 -1
- package/dist/nodeinfo/mod.cjs +1 -1
- package/dist/nodeinfo/mod.d.cts +1 -1
- package/dist/nodeinfo/mod.d.ts +1 -1
- package/dist/nodeinfo/mod.js +1 -1
- package/dist/otel/exporter.test.mjs +292 -30
- package/dist/otel/mod.cjs +36 -30
- package/dist/otel/mod.d.cts +13 -0
- package/dist/otel/mod.d.ts +13 -0
- package/dist/otel/mod.js +36 -30
- package/dist/{owner-DeggvxcG.mjs → owner-BluLVPf0.mjs} +2 -2
- package/dist/{proof-teNNYmFh.cjs → proof-CR-HwI0l.cjs} +1 -1
- package/dist/{proof-DMcUrrp8.mjs → proof-Co6nQBVR.mjs} +3 -3
- package/dist/{proof-v-IzWx7x.js → proof-Dg0d9QBo.js} +1 -1
- package/dist/{send-BsthcvPG.mjs → send-D_DnqOFA.mjs} +171 -73
- package/dist/sig/http.test.mjs +528 -2
- package/dist/sig/key.test.mjs +2 -2
- package/dist/sig/ld.test.mjs +2 -2
- package/dist/sig/mod.cjs +2 -2
- package/dist/sig/mod.d.cts +2 -2
- package/dist/sig/mod.d.ts +2 -2
- package/dist/sig/mod.js +2 -2
- package/dist/sig/owner.test.mjs +1 -1
- package/dist/sig/proof.test.mjs +1 -1
- package/dist/{temporal-Cji8Y8eQ.mjs → temporal-B8FUNkXB.mjs} +1 -1
- package/dist/testing/mod.d.mts +26 -0
- package/dist/{types-miAYfiGO.js → types-B1_pRFE_.js} +112 -63
- package/dist/{types-DRPjmHVV.cjs → types-DOvyymM4.cjs} +111 -62
- package/dist/utils/docloader.test.mjs +318 -34
- package/dist/utils/kv-cache.test.mjs +1 -1
- package/dist/utils/mod.cjs +1 -1
- package/dist/utils/mod.d.cts +1 -1
- package/dist/utils/mod.d.ts +1 -1
- package/dist/utils/mod.js +1 -1
- package/package.json +8 -8
- package/dist/docloader-BVj35vgR.mjs +0 -83
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import "@js-temporal/polyfill";
|
|
2
2
|
import "urlpattern-polyfill";
|
|
3
3
|
globalThis.addEventListener = () => {};
|
|
4
|
-
import { n as version, t as name } from "./deno-
|
|
5
|
-
import { n as getDurationMs, r as getFederationMetrics } from "./metrics-
|
|
6
|
-
import {
|
|
4
|
+
import { n as version, t as name } from "./deno-BCuL3mid.mjs";
|
|
5
|
+
import { n as getDurationMs, r as getFederationMetrics } from "./metrics-SYIZHFf_.mjs";
|
|
6
|
+
import { r as doubleKnockScoped } from "./http-CSDcThvz.mjs";
|
|
7
7
|
import { getLogger } from "@logtape/logtape";
|
|
8
8
|
import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
|
|
9
|
-
import { FetchError, UrlError
|
|
9
|
+
import { FetchError, UrlError } from "@fedify/vocab-runtime";
|
|
10
|
+
import { openDirectFetch, openPublicFetch } from "@fedify/vocab-runtime/internal";
|
|
10
11
|
//#region src/federation/send.ts
|
|
11
12
|
/**
|
|
12
13
|
* Extracts the inbox URLs from recipients.
|
|
@@ -39,9 +40,10 @@ function extractInboxes({ recipients, preferSharedInbox, excludeBaseUris }) {
|
|
|
39
40
|
*
|
|
40
41
|
* @param parameters The parameters for sending the activity.
|
|
41
42
|
* See also {@link SendActivityParameters}.
|
|
43
|
+
* @param deps The dependencies, for tests.
|
|
42
44
|
* @throws {Error} If the activity fails to send.
|
|
43
45
|
*/
|
|
44
|
-
function sendActivity(options) {
|
|
46
|
+
function sendActivity(options, deps = {}) {
|
|
45
47
|
const tracerProvider = options.tracerProvider ?? trace.getTracerProvider();
|
|
46
48
|
return tracerProvider.getTracer(name, version).startActiveSpan("activitypub.send_activity", {
|
|
47
49
|
kind: SpanKind.CLIENT,
|
|
@@ -53,7 +55,7 @@ function sendActivity(options) {
|
|
|
53
55
|
await sendActivityInternal({
|
|
54
56
|
...options,
|
|
55
57
|
tracerProvider
|
|
56
|
-
}, span);
|
|
58
|
+
}, span, deps);
|
|
57
59
|
} catch (e) {
|
|
58
60
|
span.setStatus({
|
|
59
61
|
code: SpanStatusCode.ERROR,
|
|
@@ -106,13 +108,14 @@ async function readLimitedResponseBody(response, maxBytes) {
|
|
|
106
108
|
totalBytes += value.length;
|
|
107
109
|
}
|
|
108
110
|
} finally {
|
|
111
|
+
if (truncated) reader.cancel().catch(() => {});
|
|
109
112
|
reader.releaseLock();
|
|
110
113
|
}
|
|
111
114
|
let result = chunks.join("");
|
|
112
115
|
if (truncated) result += "… (truncated)";
|
|
113
116
|
return result;
|
|
114
117
|
}
|
|
115
|
-
async function sendActivityInternal({ activity, activityId, activityType, keys, inbox, allowPrivateAddress, headers, specDeterminer, meterProvider, tracerProvider }, span) {
|
|
118
|
+
async function sendActivityInternal({ activity, activityId, activityType, keys, inbox, allowPrivateAddress, headers, specDeterminer, meterProvider, tracerProvider }, span, deps) {
|
|
116
119
|
const logger = getLogger([
|
|
117
120
|
"fedify",
|
|
118
121
|
"federation",
|
|
@@ -121,9 +124,11 @@ async function sendActivityInternal({ activity, activityId, activityType, keys,
|
|
|
121
124
|
const federationMetrics = getFederationMetrics(meterProvider);
|
|
122
125
|
const started = performance.now();
|
|
123
126
|
let deliverySuccess = false;
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
+
const openUnvalidatedHop = deps.openHop ?? (allowPrivateAddress ? openDirectFetch : (url) => openPublicFetch(url));
|
|
128
|
+
async function openHop(url) {
|
|
129
|
+
let session;
|
|
130
|
+
try {
|
|
131
|
+
session = await openUnvalidatedHop(url);
|
|
127
132
|
} catch (error) {
|
|
128
133
|
if (error instanceof UrlError && error.reason === "dns") {
|
|
129
134
|
logger.error("DNS resolution failed for URL: {url}", {
|
|
@@ -140,78 +145,86 @@ async function sendActivityInternal({ activity, activityId, activityType, keys,
|
|
|
140
145
|
});
|
|
141
146
|
throw error;
|
|
142
147
|
}
|
|
148
|
+
return session;
|
|
143
149
|
}
|
|
150
|
+
let initialSession;
|
|
144
151
|
try {
|
|
145
|
-
await
|
|
152
|
+
initialSession = await openHop(inbox.href);
|
|
146
153
|
} catch (error) {
|
|
147
154
|
if (error instanceof FetchError) federationMetrics.recordDelivery(inbox, getDurationMs(started), false, activityType);
|
|
148
155
|
throw error;
|
|
149
156
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
}
|
|
158
|
-
let rsaKey = null;
|
|
159
|
-
for (const key of keys) if (key.privateKey.algorithm.name === "RSASSA-PKCS1-v1_5") {
|
|
160
|
-
rsaKey = key;
|
|
161
|
-
break;
|
|
162
|
-
}
|
|
163
|
-
if (rsaKey == null) logger.warn("No supported key found to sign the request to {inbox}. The request will be sent without a signature. In order to sign the request, at least one RSASSA-PKCS1-v1_5 key must be provided.", {
|
|
164
|
-
inbox: inbox.href,
|
|
165
|
-
keys: keys.map((pair) => ({
|
|
166
|
-
keyId: pair.keyId.href,
|
|
167
|
-
privateKey: pair.privateKey
|
|
168
|
-
}))
|
|
169
|
-
});
|
|
170
|
-
let response;
|
|
157
|
+
let initialPending = true;
|
|
158
|
+
const openDeliveryHop = (url) => {
|
|
159
|
+
if (initialPending) {
|
|
160
|
+
initialPending = false;
|
|
161
|
+
return Promise.resolve(initialSession);
|
|
162
|
+
}
|
|
163
|
+
return openHop(url);
|
|
164
|
+
};
|
|
171
165
|
try {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
166
|
+
headers = new Headers(headers);
|
|
167
|
+
headers.set("Content-Type", "application/activity+json");
|
|
168
|
+
const request = new Request(inbox, {
|
|
169
|
+
method: "POST",
|
|
170
|
+
headers,
|
|
171
|
+
body: JSON.stringify(activity),
|
|
172
|
+
redirect: "manual"
|
|
176
173
|
});
|
|
177
|
-
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
|
|
174
|
+
let rsaKey = null;
|
|
175
|
+
for (const key of keys) if (key.privateKey.algorithm.name === "RSASSA-PKCS1-v1_5") {
|
|
176
|
+
rsaKey = key;
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
if (rsaKey == null) logger.warn("No supported key found to sign the request to {inbox}. The request will be sent without a signature. In order to sign the request, at least one RSASSA-PKCS1-v1_5 key must be provided.", {
|
|
181
180
|
inbox: inbox.href,
|
|
182
|
-
|
|
181
|
+
keys: keys.map((pair) => ({
|
|
182
|
+
keyId: pair.keyId.href,
|
|
183
|
+
privateKey: pair.privateKey
|
|
184
|
+
}))
|
|
183
185
|
});
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
}
|
|
193
|
-
error = "";
|
|
194
|
-
}
|
|
195
|
-
logger.error("Failed to send activity {activityId} to {inbox} ({status} {statusText}):\n{error}", {
|
|
186
|
+
let outcome;
|
|
187
|
+
try {
|
|
188
|
+
outcome = rsaKey == null ? await fetchWithValidatedRedirects(request, openDeliveryHop, (response) => consumeSendActivityResponse(response, inbox)) : await doubleKnockScoped(request, rsaKey, {
|
|
189
|
+
tracerProvider,
|
|
190
|
+
specDeterminer
|
|
191
|
+
}, openDeliveryHop, (response) => consumeSendActivityResponse(response, inbox));
|
|
192
|
+
} catch (error) {
|
|
193
|
+
const failure = error instanceof FetchError || error instanceof UrlError ? error : createFetchError(inbox.href, error);
|
|
194
|
+
logger.error("Failed to send activity {activityId} to {inbox}:\n{error}", {
|
|
196
195
|
activityId,
|
|
197
196
|
inbox: inbox.href,
|
|
198
|
-
|
|
199
|
-
statusText: response.statusText,
|
|
200
|
-
error
|
|
197
|
+
error: failure
|
|
201
198
|
});
|
|
202
|
-
|
|
199
|
+
federationMetrics.recordDelivery(inbox, getDurationMs(started), false, activityType);
|
|
200
|
+
throw failure;
|
|
201
|
+
}
|
|
202
|
+
try {
|
|
203
|
+
if (!outcome.ok) {
|
|
204
|
+
const { status, statusText, error, responseHeaders } = outcome;
|
|
205
|
+
logger.error("Failed to send activity {activityId} to {inbox} ({status} {statusText}):\n{error}", {
|
|
206
|
+
activityId,
|
|
207
|
+
inbox: inbox.href,
|
|
208
|
+
status,
|
|
209
|
+
statusText,
|
|
210
|
+
error
|
|
211
|
+
});
|
|
212
|
+
throw new SendActivityError(inbox, status, `Failed to send activity ${activityId} to ${inbox.href} (${status} ${statusText}):\n${error}`, error, responseHeaders);
|
|
213
|
+
}
|
|
214
|
+
deliverySuccess = true;
|
|
215
|
+
const eventAttributes = {
|
|
216
|
+
"activitypub.inbox.url": inbox.href,
|
|
217
|
+
"activitypub.activity.id": activityId ?? ""
|
|
218
|
+
};
|
|
219
|
+
if (activityType != null) eventAttributes["activitypub.activity.type"] = activityType;
|
|
220
|
+
const actorId = getActivityActorId(activity);
|
|
221
|
+
if (actorId != null) eventAttributes["activitypub.actor.id"] = actorId;
|
|
222
|
+
span.addEvent("activitypub.activity.sent", eventAttributes);
|
|
223
|
+
} finally {
|
|
224
|
+
federationMetrics.recordDelivery(inbox, getDurationMs(started), deliverySuccess, activityType);
|
|
203
225
|
}
|
|
204
|
-
deliverySuccess = true;
|
|
205
|
-
const eventAttributes = {
|
|
206
|
-
"activitypub.inbox.url": inbox.href,
|
|
207
|
-
"activitypub.activity.id": activityId ?? ""
|
|
208
|
-
};
|
|
209
|
-
if (activityType != null) eventAttributes["activitypub.activity.type"] = activityType;
|
|
210
|
-
const actorId = getActivityActorId(activity);
|
|
211
|
-
if (actorId != null) eventAttributes["activitypub.actor.id"] = actorId;
|
|
212
|
-
span.addEvent("activitypub.activity.sent", eventAttributes);
|
|
213
226
|
} finally {
|
|
214
|
-
|
|
227
|
+
if (initialPending) await initialSession.close();
|
|
215
228
|
}
|
|
216
229
|
}
|
|
217
230
|
function createFetchError(url, cause) {
|
|
@@ -219,10 +232,75 @@ function createFetchError(url, cause) {
|
|
|
219
232
|
error.cause = cause;
|
|
220
233
|
return error;
|
|
221
234
|
}
|
|
222
|
-
|
|
235
|
+
/**
|
|
236
|
+
* Starts cancelling the body of a response without waiting for it to settle.
|
|
237
|
+
* The cancellation of a branch of a tee (e.g., a body cloned by a fetch mock)
|
|
238
|
+
* settles only after the other branch is cancelled too, per the Streams
|
|
239
|
+
* standard, so awaiting it could block forever. Failures are only logged.
|
|
240
|
+
*/
|
|
241
|
+
function cancelResponseBody(response, url) {
|
|
242
|
+
response.body?.cancel().catch((error) => {
|
|
243
|
+
getLogger([
|
|
244
|
+
"fedify",
|
|
245
|
+
"federation",
|
|
246
|
+
"outbox"
|
|
247
|
+
]).debug("Failed to cancel the response body from {url}: {error}", {
|
|
248
|
+
url,
|
|
249
|
+
error
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Reads what is needed from the final response of a delivery while its
|
|
255
|
+
* session is open: the body of a successful response is cancelled, and at
|
|
256
|
+
* most 1 KiB of an error response body is read.
|
|
257
|
+
*/
|
|
258
|
+
async function consumeSendActivityResponse(response, inbox) {
|
|
259
|
+
if (response.ok) {
|
|
260
|
+
cancelResponseBody(response, response.url || inbox.href);
|
|
261
|
+
return { ok: true };
|
|
262
|
+
}
|
|
263
|
+
let error;
|
|
264
|
+
try {
|
|
265
|
+
error = await readLimitedResponseBody(response, MAX_ERROR_RESPONSE_BODY_BYTES);
|
|
266
|
+
} catch (_) {
|
|
267
|
+
error = "";
|
|
268
|
+
}
|
|
269
|
+
return {
|
|
270
|
+
ok: false,
|
|
271
|
+
status: response.status,
|
|
272
|
+
statusText: response.statusText,
|
|
273
|
+
error,
|
|
274
|
+
responseHeaders: new Headers(response.headers)
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Sends a request without signing it, following redirects manually like the
|
|
279
|
+
* Fetch standard does. Every hop is opened with `openHop()`, which validates
|
|
280
|
+
* the destination, after the previous hop is closed. The final response is
|
|
281
|
+
* passed to `consume()`, and its session is closed after that.
|
|
282
|
+
* This is exported only for tests; it is not exported from any entry point.
|
|
283
|
+
* @param request The request to send.
|
|
284
|
+
* @param openHop The function to open a session for each hop.
|
|
285
|
+
* @param consume The function to consume the final response.
|
|
286
|
+
* @returns The value returned by `consume`.
|
|
287
|
+
*/
|
|
288
|
+
async function fetchWithValidatedRedirects(request, openHop, consume) {
|
|
289
|
+
const logger = getLogger([
|
|
290
|
+
"fedify",
|
|
291
|
+
"federation",
|
|
292
|
+
"outbox"
|
|
293
|
+
]);
|
|
223
294
|
let body = await request.clone().text();
|
|
224
295
|
for (let redirects = 0;; redirects++) {
|
|
225
|
-
const
|
|
296
|
+
const session = await openHop(request.url);
|
|
297
|
+
let response;
|
|
298
|
+
try {
|
|
299
|
+
response = await session.fetch(request, { redirect: "manual" });
|
|
300
|
+
} catch (error) {
|
|
301
|
+
await closeAfterError(session, logger);
|
|
302
|
+
throw error;
|
|
303
|
+
}
|
|
226
304
|
const location = response.headers.get("Location");
|
|
227
305
|
if (![
|
|
228
306
|
301,
|
|
@@ -230,11 +308,21 @@ async function fetchWithValidatedRedirects(request, validateUrl) {
|
|
|
230
308
|
303,
|
|
231
309
|
307,
|
|
232
310
|
308
|
|
233
|
-
].includes(response.status) || location == null)
|
|
234
|
-
|
|
311
|
+
].includes(response.status) || location == null) try {
|
|
312
|
+
return await consume(response);
|
|
313
|
+
} catch (error) {
|
|
314
|
+
logger.debug("Failed to consume the response from {url}; closing the session: {error}", {
|
|
315
|
+
url: request.url,
|
|
316
|
+
error
|
|
317
|
+
});
|
|
318
|
+
throw error;
|
|
319
|
+
} finally {
|
|
320
|
+
await session.close();
|
|
321
|
+
}
|
|
322
|
+
cancelResponseBody(response, request.url);
|
|
323
|
+
await session.close();
|
|
235
324
|
if (redirects >= 20) throw new TypeError("Too many redirects");
|
|
236
325
|
const url = new URL(location, request.url);
|
|
237
|
-
await validateUrl(url.href);
|
|
238
326
|
const headers = new Headers(request.headers);
|
|
239
327
|
if (url.origin !== new URL(request.url).origin) {
|
|
240
328
|
headers.delete("Authorization");
|
|
@@ -262,6 +350,16 @@ async function fetchWithValidatedRedirects(request, validateUrl) {
|
|
|
262
350
|
});
|
|
263
351
|
}
|
|
264
352
|
}
|
|
353
|
+
async function closeAfterError(session, logger) {
|
|
354
|
+
try {
|
|
355
|
+
await session.close();
|
|
356
|
+
} catch (error) {
|
|
357
|
+
logger.debug("Failed to close the session for {url}: {error}", {
|
|
358
|
+
url: session.url.href,
|
|
359
|
+
error
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
}
|
|
265
363
|
/**
|
|
266
364
|
* An error that is thrown when an activity fails to send to a remote inbox.
|
|
267
365
|
* It contains structured information about the failure, including the HTTP
|
|
@@ -307,4 +405,4 @@ var SendActivityError = class extends Error {
|
|
|
307
405
|
}
|
|
308
406
|
};
|
|
309
407
|
//#endregion
|
|
310
|
-
export { extractInboxes as n,
|
|
408
|
+
export { sendActivity as i, extractInboxes as n, fetchWithValidatedRedirects as r, SendActivityError as t };
|