@fedify/vocab-runtime 2.4.0-dev.2035 → 2.4.0-dev.2054
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/deno.json +2 -1
- package/dist/internal/portable-dereference.cjs +315 -0
- package/dist/internal/portable-dereference.d.cts +87 -0
- package/dist/internal/portable-dereference.d.ts +87 -0
- package/dist/internal/portable-dereference.js +311 -0
- package/dist/mod.cjs +8 -2
- package/dist/mod.d.cts +2 -1
- package/dist/mod.d.ts +2 -1
- package/dist/mod.js +8 -2
- package/dist/portable-CduElToy.d.ts +52 -0
- package/dist/portable-DxF2Ut-Z.d.cts +52 -0
- package/dist/tests/{body-DRpkDnEg.cjs → body-B-qUpCl3.cjs} +1 -1
- package/dist/tests/{body-BEIDQFV6.mjs → body-hdMfBU1p.mjs} +1 -1
- package/dist/tests/body.test.cjs +1 -1
- package/dist/tests/body.test.mjs +1 -1
- package/dist/tests/decimal.test.cjs +1 -1
- package/dist/tests/decimal.test.mjs +1 -1
- package/dist/tests/{docloader-M8t8o-GD.cjs → docloader-BLHl6D4V.cjs} +2 -2
- package/dist/tests/{docloader-DHux1ztB.mjs → docloader-C_fQRm09.mjs} +2 -2
- package/dist/tests/docloader.test.cjs +2 -2
- package/dist/tests/docloader.test.mjs +2 -2
- package/dist/tests/internal/portable-dereference.test.cjs +123 -0
- package/dist/tests/internal/portable-dereference.test.d.cts +1 -0
- package/dist/tests/internal/portable-dereference.test.d.mts +1 -0
- package/dist/tests/internal/portable-dereference.test.mjs +124 -0
- package/dist/tests/jsonld-CmDhHNTx.cjs +12 -0
- package/dist/tests/jsonld-DweIJ07b.mjs +5 -0
- package/dist/tests/jsonld-cache.test.cjs +17 -22
- package/dist/tests/jsonld-cache.test.mjs +1 -4
- package/dist/tests/{request-eP_YLVjb.mjs → request-Bbg1-1C3.mjs} +8 -2
- package/dist/tests/{request-BbczASfn.cjs → request-CcifKcqU.cjs} +8 -2
- package/dist/tests/request.test.cjs +4 -1
- package/dist/tests/request.test.mjs +4 -1
- package/package.json +11 -1
- package/src/internal/portable-dereference.test.ts +74 -0
- package/src/internal/portable-dereference.ts +426 -0
- package/src/mod.ts +4 -0
- package/src/portable.ts +52 -0
- package/src/request.test.ts +10 -1
- package/src/request.ts +9 -1
- package/tsdown.config.ts +1 -0
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
|
|
2
|
+
import { t as preloadedContexts } from "../contexts-DoZUIW7y.js";
|
|
3
|
+
import { a as formatIri, g as toCompatibleEf61Id, m as parseIri, r as canonicalizePortableUri } from "../url-CEhi4hb4.js";
|
|
4
|
+
import jsonld_default from "../jsonld.js";
|
|
5
|
+
import { getLogger } from "@logtape/logtape";
|
|
6
|
+
import { SpanStatusCode } from "@opentelemetry/api";
|
|
7
|
+
//#region src/internal/portable-dereference.ts
|
|
8
|
+
const logger = getLogger([
|
|
9
|
+
"fedify",
|
|
10
|
+
"vocab",
|
|
11
|
+
"gateway"
|
|
12
|
+
]);
|
|
13
|
+
/**
|
|
14
|
+
* The maximum number of `@gateway` location hints to try for one reference.
|
|
15
|
+
* Hints come from possibly untrusted documents, so they are bounded to keep
|
|
16
|
+
* a single accessor call from fanning out to many servers.
|
|
17
|
+
*/
|
|
18
|
+
const MAX_GATEWAY_HINTS = 5;
|
|
19
|
+
const LOCATION_HINT_PARAMETER = "@gateway";
|
|
20
|
+
const BASELINE_CONTEXT_URLS = /* @__PURE__ */ new Set([
|
|
21
|
+
"https://w3id.org/identity/v1",
|
|
22
|
+
"https://www.w3.org/ns/activitystreams",
|
|
23
|
+
"https://w3id.org/security/v1",
|
|
24
|
+
"https://w3id.org/security/data-integrity/v1"
|
|
25
|
+
]);
|
|
26
|
+
/**
|
|
27
|
+
* Checks whether a URL is an FEP-ef61 portable ActivityPub IRI.
|
|
28
|
+
*
|
|
29
|
+
* @internal Technically exported for generated vocabulary classes, but not
|
|
30
|
+
* part of the public API contract. This is not considered public API for
|
|
31
|
+
* Semantic Versioning decisions.
|
|
32
|
+
*/
|
|
33
|
+
function isPortableIri(url) {
|
|
34
|
+
return url.protocol === "ap+ef61:" || url.protocol === "ap:";
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Picks the ordered list of FEP-ef61 gateways to fetch a portable IRI from.
|
|
38
|
+
*
|
|
39
|
+
* If `gateways` is given, it is used as is (even when empty), and `@gateway`
|
|
40
|
+
* location hints in the IRI are ignored. Otherwise, up to
|
|
41
|
+
* {@link MAX_GATEWAY_HINTS} valid `@gateway` hints are used. Duplicate
|
|
42
|
+
* gateways are dropped in both cases.
|
|
43
|
+
*
|
|
44
|
+
* @throws {TypeError} If an explicit gateway is not an HTTP(S) origin.
|
|
45
|
+
* @internal
|
|
46
|
+
*/
|
|
47
|
+
function getPortableGatewayCandidates(url, gateways) {
|
|
48
|
+
const candidates = [];
|
|
49
|
+
const seen = /* @__PURE__ */ new Set();
|
|
50
|
+
const add = (gateway) => {
|
|
51
|
+
if (seen.has(gateway.href)) return;
|
|
52
|
+
seen.add(gateway.href);
|
|
53
|
+
candidates.push(gateway);
|
|
54
|
+
};
|
|
55
|
+
if (gateways != null) {
|
|
56
|
+
for (const gateway of gateways) {
|
|
57
|
+
const parsed = parseGatewayOrigin(gateway);
|
|
58
|
+
if (parsed == null) throw new TypeError("FEP-ef61 gateways must be HTTP(S) origins with no credentials, path, query, or fragment: " + String(gateway));
|
|
59
|
+
add(parsed);
|
|
60
|
+
}
|
|
61
|
+
return candidates;
|
|
62
|
+
}
|
|
63
|
+
for (const hint of new URLSearchParams(url.search).getAll(LOCATION_HINT_PARAMETER)) {
|
|
64
|
+
if (candidates.length >= MAX_GATEWAY_HINTS) break;
|
|
65
|
+
const parsed = parseGatewayOrigin(hint);
|
|
66
|
+
if (parsed == null) {
|
|
67
|
+
logger.debug("Ignoring an invalid FEP-ef61 gateway hint {hint} in {url}.", {
|
|
68
|
+
hint,
|
|
69
|
+
url: formatIri(url)
|
|
70
|
+
});
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
add(parsed);
|
|
74
|
+
}
|
|
75
|
+
return candidates;
|
|
76
|
+
}
|
|
77
|
+
function parseGatewayOrigin(gateway) {
|
|
78
|
+
let url;
|
|
79
|
+
if (gateway instanceof URL) url = new URL(gateway.href);
|
|
80
|
+
else if (typeof gateway === "string" && URL.canParse(gateway)) url = new URL(gateway);
|
|
81
|
+
else return null;
|
|
82
|
+
if (url.protocol !== "http:" && url.protocol !== "https:" || url.href !== `${url.origin}/`) return null;
|
|
83
|
+
return url;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Creates a context loader that returns the same context documents for the
|
|
87
|
+
* whole dereference operation, so that the identity check, the proof
|
|
88
|
+
* verifier, and the parser interpret the fetched document identically even
|
|
89
|
+
* if the underlying loader is nondeterministic. Failed loads are not
|
|
90
|
+
* remembered, so a transient failure does not affect the next gateway.
|
|
91
|
+
*
|
|
92
|
+
* The parsed object keeps the loader for its own later dereferences, so
|
|
93
|
+
* `release()` turns it into a plain pass-through to the underlying loader
|
|
94
|
+
* once the operation is over.
|
|
95
|
+
*/
|
|
96
|
+
function createSnapshotContextLoader(contextLoader) {
|
|
97
|
+
const cache = /* @__PURE__ */ new Map();
|
|
98
|
+
let released = false;
|
|
99
|
+
const release = () => {
|
|
100
|
+
released = true;
|
|
101
|
+
cache.clear();
|
|
102
|
+
};
|
|
103
|
+
const loader = async (url, options) => {
|
|
104
|
+
if (released) return await contextLoader(url, options);
|
|
105
|
+
const key = URL.canParse(url) ? new URL(url).href : url;
|
|
106
|
+
if (BASELINE_CONTEXT_URLS.has(key)) return {
|
|
107
|
+
contextUrl: null,
|
|
108
|
+
document: structuredClone(preloadedContexts[key]),
|
|
109
|
+
documentUrl: key
|
|
110
|
+
};
|
|
111
|
+
let promise = cache.get(key);
|
|
112
|
+
if (promise == null) {
|
|
113
|
+
const loading = contextLoader(url, options).then((document) => structuredClone(document));
|
|
114
|
+
promise = loading;
|
|
115
|
+
cache.set(key, loading);
|
|
116
|
+
loading.catch(() => {
|
|
117
|
+
if (cache.get(key) === loading) cache.delete(key);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
return structuredClone(await promise);
|
|
121
|
+
};
|
|
122
|
+
return {
|
|
123
|
+
loader,
|
|
124
|
+
release
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* The error thrown by {@link dereferencePortableIri} under
|
|
129
|
+
* `crossOrigin: "throw"` when gateways returned objects but none of them
|
|
130
|
+
* satisfied the identity and proof checks.
|
|
131
|
+
*
|
|
132
|
+
* @internal Not part of the public API contract.
|
|
133
|
+
*/
|
|
134
|
+
var PortableObjectRejectedError = class extends Error {
|
|
135
|
+
constructor(message) {
|
|
136
|
+
super(message);
|
|
137
|
+
this.name = "PortableObjectRejectedError";
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
var PortableObjectRejection = class {
|
|
141
|
+
message;
|
|
142
|
+
values;
|
|
143
|
+
constructor(message, values = {}) {
|
|
144
|
+
this.message = message;
|
|
145
|
+
this.values = values;
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
/**
|
|
149
|
+
* Dereferences an FEP-ef61 portable IRI through its gateways.
|
|
150
|
+
*
|
|
151
|
+
* Gateways are tried one by one until one of them returns a single-node
|
|
152
|
+
* document whose `@id`, if any, canonically matches the requested IRI and
|
|
153
|
+
* which passes `verifyPortableObject`. When there is no gateway to try, the document
|
|
154
|
+
* loader is asked for the portable IRI itself, and its result is validated
|
|
155
|
+
* the same way.
|
|
156
|
+
*
|
|
157
|
+
* @returns The parsed object, or `null` if no valid object was retrieved and
|
|
158
|
+
* `suppressError` is set or the failure was a rejected object
|
|
159
|
+
* (unless `crossOrigin` is `"throw"`).
|
|
160
|
+
* @throws {TypeError} If `gateways` has an invalid entry (always), if no
|
|
161
|
+
* verifier is given, or if the IRI cannot be turned into
|
|
162
|
+
* a gateway URL (unless `suppressError` is set).
|
|
163
|
+
* @internal Technically exported for generated vocabulary classes, but not
|
|
164
|
+
* part of the public API contract. This is not considered public API for
|
|
165
|
+
* Semantic Versioning decisions.
|
|
166
|
+
*/
|
|
167
|
+
async function dereferencePortableIri(url, options) {
|
|
168
|
+
url = parseIri(url);
|
|
169
|
+
const lookupUrl = formatIri(url);
|
|
170
|
+
const { span } = options;
|
|
171
|
+
const gateways = getPortableGatewayCandidates(url, options.gateways);
|
|
172
|
+
const fail = (error) => {
|
|
173
|
+
span?.setStatus({
|
|
174
|
+
code: SpanStatusCode.ERROR,
|
|
175
|
+
message: String(error)
|
|
176
|
+
});
|
|
177
|
+
if (options.suppressError) {
|
|
178
|
+
logger.error("Failed to dereference {url}: {error}", {
|
|
179
|
+
url: lookupUrl,
|
|
180
|
+
error
|
|
181
|
+
});
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
throw error;
|
|
185
|
+
};
|
|
186
|
+
const verify = options.verifyPortableObject;
|
|
187
|
+
if (verify == null) return fail(/* @__PURE__ */ new TypeError("Dereferencing the portable object " + lookupUrl + " requires the verifyPortableObject option, e.g., verifyPortableObjectProof() from @fedify/fedify."));
|
|
188
|
+
const requestUrls = [];
|
|
189
|
+
let expectedId;
|
|
190
|
+
try {
|
|
191
|
+
expectedId = canonicalizePortableUri(lookupUrl);
|
|
192
|
+
for (const gateway of gateways) requestUrls.push({
|
|
193
|
+
url: toCompatibleEf61Id(url, gateway).href,
|
|
194
|
+
gateway
|
|
195
|
+
});
|
|
196
|
+
} catch (error) {
|
|
197
|
+
return fail(error);
|
|
198
|
+
}
|
|
199
|
+
if (requestUrls.length < 1) requestUrls.push({
|
|
200
|
+
url: lookupUrl,
|
|
201
|
+
gateway: null
|
|
202
|
+
});
|
|
203
|
+
const snapshot = createSnapshotContextLoader(options.contextLoader);
|
|
204
|
+
const contextLoader = snapshot.loader;
|
|
205
|
+
const attempts = [];
|
|
206
|
+
const { signal } = options;
|
|
207
|
+
try {
|
|
208
|
+
for (const { url: requestUrl, gateway } of requestUrls) {
|
|
209
|
+
signal?.throwIfAborted();
|
|
210
|
+
let remoteDocument;
|
|
211
|
+
try {
|
|
212
|
+
remoteDocument = await options.documentLoader(requestUrl, signal == null ? void 0 : { signal });
|
|
213
|
+
} catch (error) {
|
|
214
|
+
signal?.throwIfAborted();
|
|
215
|
+
logger.debug("Failed to fetch {url} from {requestUrl}: {error}", {
|
|
216
|
+
url: lookupUrl,
|
|
217
|
+
requestUrl,
|
|
218
|
+
error
|
|
219
|
+
});
|
|
220
|
+
attempts.push({
|
|
221
|
+
type: "error",
|
|
222
|
+
error
|
|
223
|
+
});
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
const { document } = remoteDocument;
|
|
227
|
+
try {
|
|
228
|
+
await checkPortableObjectId(document, expectedId, contextLoader);
|
|
229
|
+
let result;
|
|
230
|
+
try {
|
|
231
|
+
result = await verify(document, {
|
|
232
|
+
documentLoader: options.documentLoader,
|
|
233
|
+
contextLoader,
|
|
234
|
+
tracerProvider: options.tracerProvider
|
|
235
|
+
});
|
|
236
|
+
} catch (error) {
|
|
237
|
+
throw new PortableObjectRejection("the proof verifier failed: {error}", { error });
|
|
238
|
+
}
|
|
239
|
+
if (!result.verified) throw new PortableObjectRejection("it does not satisfy the FEP-ef61 proof policy: {result}", { result });
|
|
240
|
+
const object = await options.parse(document, {
|
|
241
|
+
contextLoader,
|
|
242
|
+
baseUrl: url
|
|
243
|
+
});
|
|
244
|
+
signal?.throwIfAborted();
|
|
245
|
+
if (gateway != null) span?.setAttribute("activitypub.gateway", gateway.href);
|
|
246
|
+
return object;
|
|
247
|
+
} catch (error) {
|
|
248
|
+
signal?.throwIfAborted();
|
|
249
|
+
if (error instanceof PortableObjectRejection) {
|
|
250
|
+
logger.warn("Rejected the portable object {url} served from {requestUrl}, because " + error.message, {
|
|
251
|
+
...error.values,
|
|
252
|
+
url: lookupUrl,
|
|
253
|
+
requestUrl
|
|
254
|
+
});
|
|
255
|
+
attempts.push({
|
|
256
|
+
type: "rejected",
|
|
257
|
+
source: requestUrl
|
|
258
|
+
});
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
logger.debug("Failed to parse {url} from {requestUrl}: {error}", {
|
|
262
|
+
url: lookupUrl,
|
|
263
|
+
requestUrl,
|
|
264
|
+
error
|
|
265
|
+
});
|
|
266
|
+
attempts.push({
|
|
267
|
+
type: "error",
|
|
268
|
+
error
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
} finally {
|
|
273
|
+
snapshot.release();
|
|
274
|
+
}
|
|
275
|
+
const rejected = attempts.filter((a) => a.type === "rejected");
|
|
276
|
+
if (rejected.length > 0) {
|
|
277
|
+
const message = "No gateway returned a valid portable object for " + lookupUrl + "; refusing to return the object. Objects retrieved from: " + rejected.map((a) => a.source).join(", ") + ".";
|
|
278
|
+
if (options.suppressError || options.crossOrigin !== "throw") {
|
|
279
|
+
span?.setStatus({
|
|
280
|
+
code: SpanStatusCode.ERROR,
|
|
281
|
+
message
|
|
282
|
+
});
|
|
283
|
+
logger.warn(message);
|
|
284
|
+
return null;
|
|
285
|
+
}
|
|
286
|
+
throw new PortableObjectRejectedError(message);
|
|
287
|
+
}
|
|
288
|
+
const errors = attempts.flatMap((a) => a.type === "error" ? [a.error] : []);
|
|
289
|
+
return fail(errors.length === 1 ? errors[0] : new AggregateError(errors, "Failed to dereference " + lookupUrl + " through any of its gateways: " + requestUrls.map((r) => r.url).join(", ")));
|
|
290
|
+
}
|
|
291
|
+
async function checkPortableObjectId(document, expectedId, contextLoader) {
|
|
292
|
+
if (document == null || typeof document !== "object" || Array.isArray(document)) throw new PortableObjectRejection("it is not a single JSON object");
|
|
293
|
+
const expanded = await jsonld_default.expand(document, {
|
|
294
|
+
documentLoader: contextLoader,
|
|
295
|
+
keepFreeFloatingNodes: true
|
|
296
|
+
});
|
|
297
|
+
if (expanded.length !== 1) throw new PortableObjectRejection("it does not have exactly one top-level node");
|
|
298
|
+
const id = expanded[0]["@id"];
|
|
299
|
+
if (id == null) return;
|
|
300
|
+
if (typeof id !== "string") throw new PortableObjectRejection("it has an invalid @id");
|
|
301
|
+
let actualId;
|
|
302
|
+
try {
|
|
303
|
+
actualId = canonicalizePortableUri(id);
|
|
304
|
+
} catch (error) {
|
|
305
|
+
if (!(error instanceof TypeError)) throw error;
|
|
306
|
+
actualId = null;
|
|
307
|
+
}
|
|
308
|
+
if (actualId !== expectedId) throw new PortableObjectRejection("its @id ({objectId}) does not match the requested portable ID", { objectId: id });
|
|
309
|
+
}
|
|
310
|
+
//#endregion
|
|
311
|
+
export { PortableObjectRejectedError, dereferencePortableIri, getPortableGatewayCandidates, isPortableIri };
|
package/dist/mod.cjs
CHANGED
|
@@ -16,7 +16,7 @@ let _multiformats_base_x = require("@multiformats/base-x");
|
|
|
16
16
|
_multiformats_base_x = require_rolldown_runtime.__toESM(_multiformats_base_x, 1);
|
|
17
17
|
//#region deno.json
|
|
18
18
|
var name = "@fedify/vocab-runtime";
|
|
19
|
-
var version = "2.4.0-dev.
|
|
19
|
+
var version = "2.4.0-dev.2054+1756e190";
|
|
20
20
|
//#endregion
|
|
21
21
|
//#region src/request.ts
|
|
22
22
|
/**
|
|
@@ -46,6 +46,12 @@ var FetchError = class extends Error {
|
|
|
46
46
|
}
|
|
47
47
|
};
|
|
48
48
|
/**
|
|
49
|
+
* The `Accept` header value for fetching ActivityPub objects. ActivityPub
|
|
50
|
+
* and FEP-ef61 gateways require the ActivityStreams profile on the JSON-LD
|
|
51
|
+
* media type.
|
|
52
|
+
*/
|
|
53
|
+
const ACTIVITYPUB_ACCEPT = "application/activity+json, application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"";
|
|
54
|
+
/**
|
|
49
55
|
* Creates a request for the given URL.
|
|
50
56
|
* @param url The URL to create the request for.
|
|
51
57
|
* @param options The options for the request.
|
|
@@ -55,7 +61,7 @@ var FetchError = class extends Error {
|
|
|
55
61
|
function createActivityPubRequest(url, options = {}) {
|
|
56
62
|
return new Request(url, {
|
|
57
63
|
headers: {
|
|
58
|
-
Accept:
|
|
64
|
+
Accept: ACTIVITYPUB_ACCEPT,
|
|
59
65
|
"User-Agent": typeof options.userAgent === "string" ? options.userAgent : getUserAgent(options.userAgent)
|
|
60
66
|
},
|
|
61
67
|
redirect: "manual"
|
package/dist/mod.d.cts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
2
|
import { a as DocumentLoaderOptions, c as getDocumentLoader, d as FetchError, f as GetUserAgentOptions, h as logRequest, i as DocumentLoaderFactoryOptions, l as getRemoteDocument, m as getUserAgent, n as DocumentLoader, o as GetDocumentLoaderOptions, p as createActivityPubRequest, r as DocumentLoaderFactory, s as RemoteDocument, t as AuthenticatedDocumentLoaderFactory, u as CreateRequestOptions } from "./docloader-Dr8wEkif.cjs";
|
|
3
|
+
import { n as PortableObjectVerifierOptions, t as PortableObjectVerifier } from "./portable-DxF2Ut-Z.cjs";
|
|
3
4
|
import { TracerProvider } from "@opentelemetry/api";
|
|
4
5
|
|
|
5
6
|
//#region src/contexts.d.ts
|
|
@@ -546,4 +547,4 @@ declare function isValidPublicIPv4Address(address: string): boolean;
|
|
|
546
547
|
declare function isValidPublicIPv6Address(address: string): boolean;
|
|
547
548
|
declare function expandIPv6Address(address: string): string;
|
|
548
549
|
//#endregion
|
|
549
|
-
export { type AuthenticatedDocumentLoaderFactory, type CreateRequestOptions, type Decimal, type DidKeyVerificationMethod, type DocumentLoader, type DocumentLoaderFactory, type DocumentLoaderFactoryOptions, type DocumentLoaderOptions, FetchError, type GetDocumentLoaderOptions, type GetUserAgentOptions, type Json, LanguageString, type ParsedDigestMultibase, type ParsedHashlink, type PropertyPreprocessor, type PropertyPreprocessorContext, type RemoteDocument, UrlError, arePortableUrisEqual, canParseDecimal, canonicalizePortableUri, computeDigestMultibase, createActivityPubRequest, createHashlink, decodeMultibase, encodeMultibase, encodingFromBaseData, expandIPv6Address, exportDidKey, exportMultibaseKey, exportSpki, formatIri, fromCompatibleEf61Id, getDocumentLoader, getFe34Origin, getRemoteDocument, getUserAgent, haveSameFe34Origin, haveSameIriOrigin, importDidKey, importMultibaseKey, importPem, importPkcs1, importSpki, isDecimal, isGatewayUrl, isValidPublicIPv4Address, isValidPublicIPv6Address, logRequest, parseDecimal, parseDidKeyVerificationMethod, parseDigestMultibase, parseGatewayUrl, parseHashlink, parseIri, parseJsonLdId, preloadedContexts, toCompatibleEf61Id, validatePublicUrl, verifyDigestMultibase, verifyHashlink };
|
|
550
|
+
export { type AuthenticatedDocumentLoaderFactory, type CreateRequestOptions, type Decimal, type DidKeyVerificationMethod, type DocumentLoader, type DocumentLoaderFactory, type DocumentLoaderFactoryOptions, type DocumentLoaderOptions, FetchError, type GetDocumentLoaderOptions, type GetUserAgentOptions, type Json, LanguageString, type ParsedDigestMultibase, type ParsedHashlink, type PortableObjectVerifier, type PortableObjectVerifierOptions, type PropertyPreprocessor, type PropertyPreprocessorContext, type RemoteDocument, UrlError, arePortableUrisEqual, canParseDecimal, canonicalizePortableUri, computeDigestMultibase, createActivityPubRequest, createHashlink, decodeMultibase, encodeMultibase, encodingFromBaseData, expandIPv6Address, exportDidKey, exportMultibaseKey, exportSpki, formatIri, fromCompatibleEf61Id, getDocumentLoader, getFe34Origin, getRemoteDocument, getUserAgent, haveSameFe34Origin, haveSameIriOrigin, importDidKey, importMultibaseKey, importPem, importPkcs1, importSpki, isDecimal, isGatewayUrl, isValidPublicIPv4Address, isValidPublicIPv6Address, logRequest, parseDecimal, parseDidKeyVerificationMethod, parseDigestMultibase, parseGatewayUrl, parseHashlink, parseIri, parseJsonLdId, preloadedContexts, toCompatibleEf61Id, validatePublicUrl, verifyDigestMultibase, verifyHashlink };
|
package/dist/mod.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/// <reference lib="esnext.temporal" />
|
|
2
2
|
import { a as DocumentLoaderOptions, c as getDocumentLoader, d as FetchError, f as GetUserAgentOptions, h as logRequest, i as DocumentLoaderFactoryOptions, l as getRemoteDocument, m as getUserAgent, n as DocumentLoader, o as GetDocumentLoaderOptions, p as createActivityPubRequest, r as DocumentLoaderFactory, s as RemoteDocument, t as AuthenticatedDocumentLoaderFactory, u as CreateRequestOptions } from "./docloader-Dr8wEkif.js";
|
|
3
|
+
import { n as PortableObjectVerifierOptions, t as PortableObjectVerifier } from "./portable-CduElToy.js";
|
|
3
4
|
import { TracerProvider } from "@opentelemetry/api";
|
|
4
5
|
//#region src/contexts.d.ts
|
|
5
6
|
declare const preloadedContexts: Record<string, unknown>;
|
|
@@ -545,4 +546,4 @@ declare function isValidPublicIPv4Address(address: string): boolean;
|
|
|
545
546
|
declare function isValidPublicIPv6Address(address: string): boolean;
|
|
546
547
|
declare function expandIPv6Address(address: string): string;
|
|
547
548
|
//#endregion
|
|
548
|
-
export { type AuthenticatedDocumentLoaderFactory, type CreateRequestOptions, type Decimal, type DidKeyVerificationMethod, type DocumentLoader, type DocumentLoaderFactory, type DocumentLoaderFactoryOptions, type DocumentLoaderOptions, FetchError, type GetDocumentLoaderOptions, type GetUserAgentOptions, type Json, LanguageString, type ParsedDigestMultibase, type ParsedHashlink, type PropertyPreprocessor, type PropertyPreprocessorContext, type RemoteDocument, UrlError, arePortableUrisEqual, canParseDecimal, canonicalizePortableUri, computeDigestMultibase, createActivityPubRequest, createHashlink, decodeMultibase, encodeMultibase, encodingFromBaseData, expandIPv6Address, exportDidKey, exportMultibaseKey, exportSpki, formatIri, fromCompatibleEf61Id, getDocumentLoader, getFe34Origin, getRemoteDocument, getUserAgent, haveSameFe34Origin, haveSameIriOrigin, importDidKey, importMultibaseKey, importPem, importPkcs1, importSpki, isDecimal, isGatewayUrl, isValidPublicIPv4Address, isValidPublicIPv6Address, logRequest, parseDecimal, parseDidKeyVerificationMethod, parseDigestMultibase, parseGatewayUrl, parseHashlink, parseIri, parseJsonLdId, preloadedContexts, toCompatibleEf61Id, validatePublicUrl, verifyDigestMultibase, verifyHashlink };
|
|
549
|
+
export { type AuthenticatedDocumentLoaderFactory, type CreateRequestOptions, type Decimal, type DidKeyVerificationMethod, type DocumentLoader, type DocumentLoaderFactory, type DocumentLoaderFactoryOptions, type DocumentLoaderOptions, FetchError, type GetDocumentLoaderOptions, type GetUserAgentOptions, type Json, LanguageString, type ParsedDigestMultibase, type ParsedHashlink, type PortableObjectVerifier, type PortableObjectVerifierOptions, type PropertyPreprocessor, type PropertyPreprocessorContext, type RemoteDocument, UrlError, arePortableUrisEqual, canParseDecimal, canonicalizePortableUri, computeDigestMultibase, createActivityPubRequest, createHashlink, decodeMultibase, encodeMultibase, encodingFromBaseData, expandIPv6Address, exportDidKey, exportMultibaseKey, exportSpki, formatIri, fromCompatibleEf61Id, getDocumentLoader, getFe34Origin, getRemoteDocument, getUserAgent, haveSameFe34Origin, haveSameIriOrigin, importDidKey, importMultibaseKey, importPem, importPkcs1, importSpki, isDecimal, isGatewayUrl, isValidPublicIPv4Address, isValidPublicIPv6Address, logRequest, parseDecimal, parseDidKeyVerificationMethod, parseDigestMultibase, parseGatewayUrl, parseHashlink, parseIri, parseJsonLdId, preloadedContexts, toCompatibleEf61Id, validatePublicUrl, verifyDigestMultibase, verifyHashlink };
|
package/dist/mod.js
CHANGED
|
@@ -12,7 +12,7 @@ import { PublicKeyInfo } from "pkijs";
|
|
|
12
12
|
import baseX from "@multiformats/base-x";
|
|
13
13
|
//#region deno.json
|
|
14
14
|
var name = "@fedify/vocab-runtime";
|
|
15
|
-
var version = "2.4.0-dev.
|
|
15
|
+
var version = "2.4.0-dev.2054+1756e190";
|
|
16
16
|
//#endregion
|
|
17
17
|
//#region src/request.ts
|
|
18
18
|
/**
|
|
@@ -42,6 +42,12 @@ var FetchError = class extends Error {
|
|
|
42
42
|
}
|
|
43
43
|
};
|
|
44
44
|
/**
|
|
45
|
+
* The `Accept` header value for fetching ActivityPub objects. ActivityPub
|
|
46
|
+
* and FEP-ef61 gateways require the ActivityStreams profile on the JSON-LD
|
|
47
|
+
* media type.
|
|
48
|
+
*/
|
|
49
|
+
const ACTIVITYPUB_ACCEPT = "application/activity+json, application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"";
|
|
50
|
+
/**
|
|
45
51
|
* Creates a request for the given URL.
|
|
46
52
|
* @param url The URL to create the request for.
|
|
47
53
|
* @param options The options for the request.
|
|
@@ -51,7 +57,7 @@ var FetchError = class extends Error {
|
|
|
51
57
|
function createActivityPubRequest(url, options = {}) {
|
|
52
58
|
return new Request(url, {
|
|
53
59
|
headers: {
|
|
54
|
-
Accept:
|
|
60
|
+
Accept: ACTIVITYPUB_ACCEPT,
|
|
55
61
|
"User-Agent": typeof options.userAgent === "string" ? options.userAgent : getUserAgent(options.userAgent)
|
|
56
62
|
},
|
|
57
63
|
redirect: "manual"
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/// <reference lib="esnext.temporal" />
|
|
2
|
+
import { n as DocumentLoader } from "./docloader-Dr8wEkif.js";
|
|
3
|
+
import { TracerProvider } from "@opentelemetry/api";
|
|
4
|
+
|
|
5
|
+
//#region src/portable.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Options passed to a {@link PortableObjectVerifier}.
|
|
8
|
+
* @since 2.4.0
|
|
9
|
+
*/
|
|
10
|
+
interface PortableObjectVerifierOptions {
|
|
11
|
+
/**
|
|
12
|
+
* The document loader for fetching remote documents, such as verification
|
|
13
|
+
* methods that are not `did:key` URLs.
|
|
14
|
+
*/
|
|
15
|
+
readonly documentLoader?: DocumentLoader;
|
|
16
|
+
/**
|
|
17
|
+
* The document loader for fetching remote JSON-LD contexts. During
|
|
18
|
+
* gateway dereferencing, this loader returns the same context documents
|
|
19
|
+
* that the vocabulary parser sees.
|
|
20
|
+
*/
|
|
21
|
+
readonly contextLoader?: DocumentLoader;
|
|
22
|
+
/**
|
|
23
|
+
* The OpenTelemetry tracer provider.
|
|
24
|
+
*/
|
|
25
|
+
readonly tracerProvider?: TracerProvider;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* A function that applies the [FEP-ef61] proof policy to a portable object
|
|
29
|
+
* fetched through a gateway.
|
|
30
|
+
*
|
|
31
|
+
* It receives the fetched JSON-LD document as is, and resolves to an object
|
|
32
|
+
* whose `verified` property tells whether the document carries a valid
|
|
33
|
+
* [FEP-8b32] Object Integrity Proof made by the DID in its portable ID.
|
|
34
|
+
* `verifyPortableObjectProof()` from `@fedify/fedify` satisfies this type, so
|
|
35
|
+
* it can be passed as the `verifyPortableObject` option of generated
|
|
36
|
+
* vocabulary accessors such as `Activity.getObject()`.
|
|
37
|
+
*
|
|
38
|
+
* [FEP-ef61]: https://w3id.org/fep/ef61
|
|
39
|
+
* [FEP-8b32]: https://w3id.org/fep/8b32
|
|
40
|
+
*
|
|
41
|
+
* @param document The fetched JSON-LD document.
|
|
42
|
+
* @param options Loaders and tracing options for verification.
|
|
43
|
+
* @returns An object whose `verified` property is `true` if and only if the
|
|
44
|
+
* document satisfies the proof policy. Other properties, such as
|
|
45
|
+
* a failure reason, are logged when verification fails.
|
|
46
|
+
* @since 2.4.0
|
|
47
|
+
*/
|
|
48
|
+
type PortableObjectVerifier = (document: unknown, options: PortableObjectVerifierOptions) => Promise<{
|
|
49
|
+
readonly verified: boolean;
|
|
50
|
+
}>;
|
|
51
|
+
//#endregion
|
|
52
|
+
export { PortableObjectVerifierOptions as n, PortableObjectVerifier as t };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/// <reference lib="esnext.temporal" />
|
|
2
|
+
import { n as DocumentLoader } from "./docloader-Dr8wEkif.cjs";
|
|
3
|
+
import { TracerProvider } from "@opentelemetry/api";
|
|
4
|
+
|
|
5
|
+
//#region src/portable.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Options passed to a {@link PortableObjectVerifier}.
|
|
8
|
+
* @since 2.4.0
|
|
9
|
+
*/
|
|
10
|
+
interface PortableObjectVerifierOptions {
|
|
11
|
+
/**
|
|
12
|
+
* The document loader for fetching remote documents, such as verification
|
|
13
|
+
* methods that are not `did:key` URLs.
|
|
14
|
+
*/
|
|
15
|
+
readonly documentLoader?: DocumentLoader;
|
|
16
|
+
/**
|
|
17
|
+
* The document loader for fetching remote JSON-LD contexts. During
|
|
18
|
+
* gateway dereferencing, this loader returns the same context documents
|
|
19
|
+
* that the vocabulary parser sees.
|
|
20
|
+
*/
|
|
21
|
+
readonly contextLoader?: DocumentLoader;
|
|
22
|
+
/**
|
|
23
|
+
* The OpenTelemetry tracer provider.
|
|
24
|
+
*/
|
|
25
|
+
readonly tracerProvider?: TracerProvider;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* A function that applies the [FEP-ef61] proof policy to a portable object
|
|
29
|
+
* fetched through a gateway.
|
|
30
|
+
*
|
|
31
|
+
* It receives the fetched JSON-LD document as is, and resolves to an object
|
|
32
|
+
* whose `verified` property tells whether the document carries a valid
|
|
33
|
+
* [FEP-8b32] Object Integrity Proof made by the DID in its portable ID.
|
|
34
|
+
* `verifyPortableObjectProof()` from `@fedify/fedify` satisfies this type, so
|
|
35
|
+
* it can be passed as the `verifyPortableObject` option of generated
|
|
36
|
+
* vocabulary accessors such as `Activity.getObject()`.
|
|
37
|
+
*
|
|
38
|
+
* [FEP-ef61]: https://w3id.org/fep/ef61
|
|
39
|
+
* [FEP-8b32]: https://w3id.org/fep/8b32
|
|
40
|
+
*
|
|
41
|
+
* @param document The fetched JSON-LD document.
|
|
42
|
+
* @param options Loaders and tracing options for verification.
|
|
43
|
+
* @returns An object whose `verified` property is `true` if and only if the
|
|
44
|
+
* document satisfies the proof policy. Other properties, such as
|
|
45
|
+
* a failure reason, are logged when verification fails.
|
|
46
|
+
* @since 2.4.0
|
|
47
|
+
*/
|
|
48
|
+
type PortableObjectVerifier = (document: unknown, options: PortableObjectVerifierOptions) => Promise<{
|
|
49
|
+
readonly verified: boolean;
|
|
50
|
+
}>;
|
|
51
|
+
//#endregion
|
|
52
|
+
export { PortableObjectVerifierOptions as n, PortableObjectVerifier as t };
|
package/dist/tests/body.test.cjs
CHANGED
package/dist/tests/body.test.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as readBoundedText, t as BodyTooLargeError } from "./body-
|
|
1
|
+
import { r as readBoundedText, t as BodyTooLargeError } from "./body-hdMfBU1p.mjs";
|
|
2
2
|
import { deepStrictEqual, ok, rejects } from "node:assert/strict";
|
|
3
3
|
import { test } from "node:test";
|
|
4
4
|
import { gunzipSync, gzipSync } from "node:zlib";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const require_request = require("./request-
|
|
2
|
-
const require_body = require("./body-
|
|
1
|
+
const require_request = require("./request-CcifKcqU.cjs");
|
|
2
|
+
const require_body = require("./body-B-qUpCl3.cjs");
|
|
3
3
|
const require_contexts = require("./contexts-Ch3v2Cgu.cjs");
|
|
4
4
|
const require_link = require("./link-DlKm8bEr.cjs");
|
|
5
5
|
const require_url = require("./url-BqlldzT8.cjs");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as name, i as logRequest, n as createActivityPubRequest, o as version, t as FetchError } from "./request-
|
|
2
|
-
import { n as MAX_BODY_SIZE, r as readBoundedText, t as BodyTooLargeError } from "./body-
|
|
1
|
+
import { a as name, i as logRequest, n as createActivityPubRequest, o as version, t as FetchError } from "./request-Bbg1-1C3.mjs";
|
|
2
|
+
import { n as MAX_BODY_SIZE, r as readBoundedText, t as BodyTooLargeError } from "./body-hdMfBU1p.mjs";
|
|
3
3
|
import { t as preloadedContexts } from "./contexts-BBX_qhBL.mjs";
|
|
4
4
|
import { t as HttpHeaderLink } from "./link-Cevmc87v.mjs";
|
|
5
5
|
import { t as UrlError, v as validatePublicUrl } from "./url-DgJM9WJn.mjs";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
const require_rolldown_runtime = require("./rolldown-runtime-emK7D4bc.cjs");
|
|
2
|
-
const require_request = require("./request-
|
|
2
|
+
const require_request = require("./request-CcifKcqU.cjs");
|
|
3
3
|
const require_contexts = require("./contexts-Ch3v2Cgu.cjs");
|
|
4
4
|
const require_url = require("./url-BqlldzT8.cjs");
|
|
5
|
-
const require_docloader = require("./docloader-
|
|
5
|
+
const require_docloader = require("./docloader-BLHl6D4V.cjs");
|
|
6
6
|
let node_test = require("node:test");
|
|
7
7
|
let node_zlib = require("node:zlib");
|
|
8
8
|
let node_assert = require("node:assert");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { t as FetchError } from "./request-
|
|
1
|
+
import { t as FetchError } from "./request-Bbg1-1C3.mjs";
|
|
2
2
|
import { n as cid_v1_default, t as preloadedContexts } from "./contexts-BBX_qhBL.mjs";
|
|
3
3
|
import { t as UrlError } from "./url-DgJM9WJn.mjs";
|
|
4
|
-
import { n as getRemoteDocument, t as getDocumentLoader } from "./docloader-
|
|
4
|
+
import { n as getRemoteDocument, t as getDocumentLoader } from "./docloader-C_fQRm09.mjs";
|
|
5
5
|
import { test } from "node:test";
|
|
6
6
|
import { gzipSync } from "node:zlib";
|
|
7
7
|
import { deepStrictEqual, ok, rejects } from "node:assert";
|