@fedify/vocab-runtime 2.4.0-dev.2056 → 2.4.0-dev.2065

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.
Files changed (34) hide show
  1. package/deno.json +1 -1
  2. package/dist/internal/portable-dereference.cjs +355 -8
  3. package/dist/internal/portable-dereference.d.cts +238 -6
  4. package/dist/internal/portable-dereference.d.ts +238 -6
  5. package/dist/internal/portable-dereference.js +343 -10
  6. package/dist/mod.cjs +1 -1
  7. package/dist/mod.d.cts +2 -2
  8. package/dist/mod.d.ts +2 -2
  9. package/dist/mod.js +1 -1
  10. package/dist/portable-DH3947GK.d.ts +160 -0
  11. package/dist/portable-comBI05Y.d.cts +160 -0
  12. package/dist/tests/{body-wkL-XGhe.mjs → body-CNO0jMV8.mjs} +1 -1
  13. package/dist/tests/{body-h9zUR79f.cjs → body-DXHOazEl.cjs} +1 -1
  14. package/dist/tests/body.test.cjs +1 -1
  15. package/dist/tests/body.test.mjs +1 -1
  16. package/dist/tests/decimal.test.cjs +1 -1
  17. package/dist/tests/decimal.test.mjs +1 -1
  18. package/dist/tests/{docloader-CBLgaVPd.cjs → docloader-4Txefi7y.cjs} +2 -2
  19. package/dist/tests/{docloader-DMGssPEX.mjs → docloader-C-nWtUWo.mjs} +2 -2
  20. package/dist/tests/docloader.test.cjs +2 -2
  21. package/dist/tests/docloader.test.mjs +2 -2
  22. package/dist/tests/internal/portable-dereference.test.cjs +87 -0
  23. package/dist/tests/internal/portable-dereference.test.mjs +87 -0
  24. package/dist/tests/{request-ClFs0ePp.cjs → request-BOLanqAd.cjs} +1 -1
  25. package/dist/tests/{request-Ytm0xyZH.mjs → request-dpFdQKXr.mjs} +1 -1
  26. package/dist/tests/request.test.cjs +1 -1
  27. package/dist/tests/request.test.mjs +1 -1
  28. package/package.json +1 -1
  29. package/src/internal/portable-dereference.test.ts +32 -0
  30. package/src/internal/portable-dereference.ts +521 -12
  31. package/src/mod.ts +2 -0
  32. package/src/portable.ts +136 -8
  33. package/dist/portable-CduElToy.d.ts +0 -52
  34. package/dist/portable-DxF2Ut-Z.d.cts +0 -52
@@ -1,6 +1,6 @@
1
1
 
2
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";
3
+ import { a as formatIri, c as haveSameFe34Origin, g as toCompatibleEf61Id, m as parseIri, o as fromCompatibleEf61Id, r as canonicalizePortableUri } from "../url-CEhi4hb4.js";
4
4
  import jsonld_default from "../jsonld.js";
5
5
  import { getLogger } from "@logtape/logtape";
6
6
  import { SpanStatusCode } from "@opentelemetry/api";
@@ -24,6 +24,301 @@ const BASELINE_CONTEXT_URLS = /* @__PURE__ */ new Set([
24
24
  "https://w3id.org/security/data-integrity/v1"
25
25
  ]);
26
26
  /**
27
+ * The maximum number of links in a referrer chain passed to a
28
+ * {@link PortableObjectVerifier}. Longer chains are cut off and marked as
29
+ * truncated.
30
+ */
31
+ const MAX_REFERRER_CHAIN_LENGTH = 32;
32
+ const provenances = /* @__PURE__ */ new WeakMap();
33
+ function getObjectId(object) {
34
+ if (object == null || typeof object !== "object" || !("id" in object)) return null;
35
+ const id = object.id;
36
+ return id instanceof URL ? id : null;
37
+ }
38
+ /**
39
+ * Checks whether a vocabulary object is part of a chain of portable objects,
40
+ * i.e., whether it has a portable ID or was obtained from a portable object.
41
+ *
42
+ * @internal Technically exported for generated vocabulary classes, but not
43
+ * part of the public API contract. This is not considered public API for
44
+ * Semantic Versioning decisions.
45
+ */
46
+ function isInPortableChain(object) {
47
+ if (provenances.has(object)) return true;
48
+ const id = getObjectId(object);
49
+ return id != null && isPortableIri(id);
50
+ }
51
+ /**
52
+ * Checks whether a vocabulary object was accepted without an integrity
53
+ * proof, e.g., as an unsecured portable collection served by a trusted
54
+ * gateway. Objects embedded in such an object must not be trusted because
55
+ * of their origin.
56
+ *
57
+ * @internal Technically exported for generated vocabulary classes, but not
58
+ * part of the public API contract. This is not considered public API for
59
+ * Semantic Versioning decisions.
60
+ */
61
+ function isUnsecuredPortableObject(object) {
62
+ return provenances.get(object)?.acceptance === "unsecured";
63
+ }
64
+ /**
65
+ * Checks whether a URL is an FEP-ef61 compatible identifier, i.e., an HTTP(S)
66
+ * URL under a gateway's `/.well-known/apgateway/` path that stands for
67
+ * a portable object. Malformed compatible identifiers count as compatible
68
+ * identifiers too.
69
+ *
70
+ * @internal Technically exported for generated vocabulary classes, but not
71
+ * part of the public API contract. This is not considered public API for
72
+ * Semantic Versioning decisions.
73
+ */
74
+ function isCompatibleEf61Iri(url) {
75
+ try {
76
+ return fromCompatibleEf61Id(url) != null;
77
+ } catch (error) {
78
+ if (error instanceof TypeError) return true;
79
+ throw error;
80
+ }
81
+ }
82
+ /**
83
+ * Records that a vocabulary object returned by a property accessor was
84
+ * obtained through the given property of a portable object, so that later
85
+ * dereferences from it can tell where it came from. Nothing is recorded if
86
+ * the parent is not in a portable chain, or if the child already has its
87
+ * provenance.
88
+ *
89
+ * @internal Technically exported for generated vocabulary classes, but not
90
+ * part of the public API contract. This is not considered public API for
91
+ * Semantic Versioning decisions.
92
+ */
93
+ function recordPortableReferrer(parent, child, property) {
94
+ if (child == null || typeof child !== "object") return;
95
+ if (provenances.has(child) || !isInPortableChain(parent)) return;
96
+ provenances.set(child, { referrer: {
97
+ object: parent,
98
+ property
99
+ } });
100
+ }
101
+ /**
102
+ * Copies the provenance of a vocabulary object to its clone. The clone
103
+ * keeps where the original came from and the restriction on unsecured
104
+ * objects, but not a positive verification status nor a collection context,
105
+ * since the clone may have different property values.
106
+ *
107
+ * @internal Technically exported for generated vocabulary classes, but not
108
+ * part of the public API contract. This is not considered public API for
109
+ * Semantic Versioning decisions.
110
+ */
111
+ function copyPortableProvenance(from, to) {
112
+ const provenance = provenances.get(from);
113
+ if (provenance == null) return;
114
+ provenances.set(to, {
115
+ referrer: provenance.referrer,
116
+ ...provenance.acceptance === "unsecured" ? { acceptance: "unsecured" } : {}
117
+ });
118
+ }
119
+ /**
120
+ * Recognizes an FEP-ef61 compatible identifier to dereference as a portable
121
+ * object.
122
+ *
123
+ * @returns `undefined` if the URL is not a compatible identifier; `null` if
124
+ * it is a malformed compatible identifier; otherwise, the portable
125
+ * ID it stands for and the gateway it names.
126
+ * @internal Technically exported for generated vocabulary classes, but not
127
+ * part of the public API contract. This is not considered public API for
128
+ * Semantic Versioning decisions.
129
+ */
130
+ function parseCompatibleEf61Reference(url) {
131
+ if (typeof url === "string") {
132
+ if (!URL.canParse(url)) return void 0;
133
+ url = new URL(url);
134
+ }
135
+ try {
136
+ const id = fromCompatibleEf61Id(url);
137
+ if (id == null) return void 0;
138
+ return {
139
+ id,
140
+ gateway: new URL(url.origin)
141
+ };
142
+ } catch (error) {
143
+ if (error instanceof TypeError) {
144
+ logger.debug("Invalid FEP-ef61 compatible identifier {url}: {error}", {
145
+ url: url.href,
146
+ error
147
+ });
148
+ return null;
149
+ }
150
+ throw error;
151
+ }
152
+ }
153
+ /**
154
+ * Checks whether a property accessor call on a vocabulary object applies the
155
+ * FEP-ef61 portable object policy, i.e., whether the `verifyPortableObject`
156
+ * option is given or the object is part of a chain of portable objects.
157
+ * In this mode, compatible identifiers are dereferenced as portable objects,
158
+ * and fetched documents that turn out to stand for portable objects are
159
+ * verified as such.
160
+ *
161
+ * @internal Technically exported for generated vocabulary classes, but not
162
+ * part of the public API contract. This is not considered public API for
163
+ * Semantic Versioning decisions.
164
+ */
165
+ function isPortableMode(object, options) {
166
+ return options.verifyPortableObject != null || isInPortableChain(object);
167
+ }
168
+ /**
169
+ * Checks whether an object embedded in a property of a vocabulary object has
170
+ * to be dereferenced by its `@id` and verified as a portable object rather
171
+ * than trusted as embedded, even with `crossOrigin: "trust"`. This is the
172
+ * case in {@link isPortableMode | portable mode} if its `@id` is an FEP-ef61
173
+ * compatible identifier, or a portable IRI whose DID differs from the
174
+ * owner's portable ID.
175
+ *
176
+ * @param parent The object whose property embeds the object.
177
+ * @param ownerId The ID of the object that vouches for embedded objects, or
178
+ * `null` if embedded objects are not trusted by their owner.
179
+ * @param id The `@id` of the embedded object.
180
+ * @param options The options of the accessor.
181
+ * @internal Technically exported for generated vocabulary classes, but not
182
+ * part of the public API contract. This is not considered public API for
183
+ * Semantic Versioning decisions.
184
+ */
185
+ function mustDereferencePortableObject(parent, ownerId, id, options) {
186
+ if (!isPortableMode(parent, options)) return false;
187
+ if (isCompatibleEf61Iri(id)) return true;
188
+ if (!isPortableIri(id)) return false;
189
+ return ownerId == null || !isPortableIri(ownerId) || !haveSameFe34Origin(ownerId, id);
190
+ }
191
+ const PORTABLE_IRI_PATTERN = /^ap(?:\+ef61)?:/i;
192
+ /**
193
+ * Finds out whether a document fetched as an ordinary HTTP(S) document
194
+ * claims to be a portable object: its final URL is a portable IRI or an
195
+ * FEP-ef61 compatible identifier, or else its `@id` is. The final URL takes
196
+ * precedence, so a document whose `@id` claims another object fails the
197
+ * identity check against the final URL.
198
+ *
199
+ * @param documentUrl The final URL of the document.
200
+ * @param objectId The `@id` of the parsed document.
201
+ * @returns `undefined` if the document does not claim to be a portable
202
+ * object; `null` if the claim is malformed; otherwise, the claim.
203
+ * @internal Technically exported for generated vocabulary classes, but not
204
+ * part of the public API contract. This is not considered public API for
205
+ * Semantic Versioning decisions.
206
+ */
207
+ function getPortableResponseClaim(documentUrl, objectId) {
208
+ if (PORTABLE_IRI_PATTERN.test(documentUrl)) {
209
+ let id;
210
+ try {
211
+ id = parseIri(documentUrl);
212
+ if (canonicalizePortableUri(documentUrl) !== canonicalizePortableUri(formatIri(id))) return null;
213
+ } catch (error) {
214
+ if (error instanceof TypeError) return null;
215
+ throw error;
216
+ }
217
+ return {
218
+ id,
219
+ inferredGateways: getPortableGatewayCandidates(id)
220
+ };
221
+ }
222
+ for (const url of [documentUrl, objectId]) {
223
+ if (url == null) continue;
224
+ const compatible = parseCompatibleEf61Reference(url);
225
+ if (compatible === null) return null;
226
+ if (compatible != null) return {
227
+ id: compatible.id,
228
+ inferredGateways: [compatible.gateway]
229
+ };
230
+ if (url instanceof URL && isPortableIri(url)) return {
231
+ id: url,
232
+ inferredGateways: getPortableGatewayCandidates(url)
233
+ };
234
+ }
235
+ }
236
+ const unverifiedPortableClaims = /* @__PURE__ */ new WeakSet();
237
+ /**
238
+ * Records that an object fetched as an ordinary HTTP(S) object stands for
239
+ * a portable object if its reference, its final URL, or its `@id` is
240
+ * a portable IRI or an FEP-ef61 compatible identifier. Accessors do not
241
+ * cache such objects in their parents, so that a later call with the
242
+ * `verifyPortableObject` option dereferences and verifies them.
243
+ *
244
+ * @internal Technically exported for generated vocabulary classes, but not
245
+ * part of the public API contract. This is not considered public API for
246
+ * Semantic Versioning decisions.
247
+ */
248
+ function markUnverifiedPortableClaim(object, reference, documentUrl) {
249
+ const objectId = getObjectId(object);
250
+ if (isPortableIri(reference) || isCompatibleEf61Iri(reference) || PORTABLE_IRI_PATTERN.test(documentUrl) || isCompatibleEf61Iri(documentUrl) || objectId != null && (isPortableIri(objectId) || isCompatibleEf61Iri(objectId))) unverifiedPortableClaims.add(object);
251
+ }
252
+ /**
253
+ * Checks whether an object was fetched as an ordinary HTTP(S) object although
254
+ * it stands for a portable object. See {@link markUnverifiedPortableClaim}.
255
+ *
256
+ * @internal Technically exported for generated vocabulary classes, but not
257
+ * part of the public API contract. This is not considered public API for
258
+ * Semantic Versioning decisions.
259
+ */
260
+ function isUnverifiedPortableClaim(object) {
261
+ return unverifiedPortableClaims.has(object);
262
+ }
263
+ /**
264
+ * Rejects a malformed FEP-ef61 compatible identifier found in a reference,
265
+ * the final URL of a fetched document, or its `@id`, when it would be
266
+ * dereferenced as a portable object. It is rejected without a request (or
267
+ * without returning the fetched document), since it cannot be verified as
268
+ * a portable object, and fetching it as an ordinary HTTP(S) object would
269
+ * skip the portable object policy.
270
+ *
271
+ * @param url The rejected URL, for the log message.
272
+ * @param options The options of the accessor.
273
+ * @returns Always `null`.
274
+ * @throws {Error} If `crossOrigin` is `"throw"` and `suppressError` is not
275
+ * set.
276
+ * @internal Technically exported for generated vocabulary classes, but not
277
+ * part of the public API contract. This is not considered public API for
278
+ * Semantic Versioning decisions.
279
+ */
280
+ function rejectMalformedCompatibleReference(url, options) {
281
+ const message = "Refusing to dereference {url}, because it is a malformed FEP-ef61 compatible identifier, which cannot be verified as a portable object.";
282
+ if (options.crossOrigin === "throw" && !options.suppressError) throw new PortableObjectRejectedError(message.replace("{url}", url));
283
+ logger.warn(message, { url });
284
+ return null;
285
+ }
286
+ /**
287
+ * Logs that an embedded object without `@id` in an object accepted without
288
+ * an integrity proof is dropped, because it cannot be dereferenced and
289
+ * verified on its own.
290
+ *
291
+ * @internal Technically exported for generated vocabulary classes, but not
292
+ * part of the public API contract. This is not considered public API for
293
+ * Semantic Versioning decisions.
294
+ */
295
+ function warnUnverifiableEmbeddedObject(parent, property) {
296
+ logger.warn("Dropping an embedded object without @id in the {property} property of {parentId}, because the parent was accepted without an integrity proof and the embedded object cannot be verified on its own.", {
297
+ property,
298
+ parentId: getObjectId(parent)?.href ?? null
299
+ });
300
+ }
301
+ function buildReferrerChain(link, depth = 0) {
302
+ if (link == null) return void 0;
303
+ const provenance = provenances.get(link.object);
304
+ const base = {
305
+ object: link.object,
306
+ id: getObjectId(link.object),
307
+ property: link.property,
308
+ ...provenance?.acceptance == null ? {} : { acceptance: provenance.acceptance },
309
+ ...provenance?.collectionContext === void 0 ? {} : { collectionContext: provenance.collectionContext }
310
+ };
311
+ if (provenance?.referrer == null) return base;
312
+ if (depth + 1 >= MAX_REFERRER_CHAIN_LENGTH) return {
313
+ ...base,
314
+ truncated: true
315
+ };
316
+ return {
317
+ ...base,
318
+ referrer: buildReferrerChain(provenance.referrer, depth + 1)
319
+ };
320
+ }
321
+ /**
27
322
  * Checks whether a URL is an FEP-ef61 portable ActivityPub IRI.
28
323
  *
29
324
  * @internal Technically exported for generated vocabulary classes, but not
@@ -92,12 +387,18 @@ function parseGatewayOrigin(gateway) {
92
387
  * The parsed object keeps the loader for its own later dereferences, so
93
388
  * `release()` turns it into a plain pass-through to the underlying loader
94
389
  * once the operation is over.
390
+ *
391
+ * @internal Technically exported for generated vocabulary classes, but not
392
+ * part of the public API contract. This is not considered public API for
393
+ * Semantic Versioning decisions.
95
394
  */
96
395
  function createSnapshotContextLoader(contextLoader) {
396
+ for (let wrapped = snapshotLoaders.get(contextLoader); wrapped?.released; wrapped = snapshotLoaders.get(contextLoader)) contextLoader = wrapped.base;
97
397
  const cache = /* @__PURE__ */ new Map();
98
398
  let released = false;
99
399
  const release = () => {
100
400
  released = true;
401
+ state.released = true;
101
402
  cache.clear();
102
403
  };
103
404
  const loader = async (url, options) => {
@@ -119,11 +420,17 @@ function createSnapshotContextLoader(contextLoader) {
119
420
  }
120
421
  return structuredClone(await promise);
121
422
  };
423
+ const state = {
424
+ base: contextLoader,
425
+ released: false
426
+ };
427
+ snapshotLoaders.set(loader, state);
122
428
  return {
123
429
  loader,
124
430
  release
125
431
  };
126
432
  }
433
+ const snapshotLoaders = /* @__PURE__ */ new WeakMap();
127
434
  /**
128
435
  * The error thrown by {@link dereferencePortableIri} under
129
436
  * `crossOrigin: "throw"` when gateways returned objects but none of them
@@ -150,9 +457,10 @@ var PortableObjectRejection = class {
150
457
  *
151
458
  * Gateways are tried one by one until one of them returns a single-node
152
459
  * 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.
460
+ * which passes `verifyPortableObject`. When there is no gateway to try, the
461
+ * document loader is asked for the portable IRI itself, and its result is
462
+ * validated the same way. If the `response` option is given, only that
463
+ * document is validated, and nothing is fetched.
156
464
  *
157
465
  * @returns The parsed object, or `null` if no valid object was retrieved and
158
466
  * `suppressError` is set or the failure was a rejected object
@@ -168,7 +476,10 @@ async function dereferencePortableIri(url, options) {
168
476
  url = parseIri(url);
169
477
  const lookupUrl = formatIri(url);
170
478
  const { span } = options;
171
- const gateways = getPortableGatewayCandidates(url, options.gateways);
479
+ const explicitGateways = options.gateways == null ? void 0 : getPortableGatewayCandidates(url, options.gateways);
480
+ const inferredGateways = options.inferredGateways ?? (explicitGateways == null ? getPortableGatewayCandidates(url) : []);
481
+ const gateways = [...inferredGateways];
482
+ for (const gateway of explicitGateways ?? []) if (!gateways.some((g) => g.href === gateway.href)) gateways.push(gateway);
172
483
  const fail = (error) => {
173
484
  span?.setStatus({
174
485
  code: SpanStatusCode.ERROR,
@@ -189,7 +500,12 @@ async function dereferencePortableIri(url, options) {
189
500
  let expectedId;
190
501
  try {
191
502
  expectedId = canonicalizePortableUri(lookupUrl);
192
- for (const gateway of gateways) requestUrls.push({
503
+ if (options.response != null) requestUrls.push({
504
+ url: options.response.documentUrl,
505
+ gateway: null,
506
+ response: options.response
507
+ });
508
+ else for (const gateway of gateways) requestUrls.push({
193
509
  url: toCompatibleEf61Id(url, gateway).href,
194
510
  gateway
195
511
  });
@@ -204,12 +520,14 @@ async function dereferencePortableIri(url, options) {
204
520
  const contextLoader = snapshot.loader;
205
521
  const attempts = [];
206
522
  const { signal } = options;
523
+ const gatewayHints = explicitGateways == null && inferredGateways.length > 0 ? inferredGateways : void 0;
524
+ const referrer = buildReferrerChain(options.referrer);
207
525
  try {
208
- for (const { url: requestUrl, gateway } of requestUrls) {
526
+ for (const { url: requestUrl, gateway, response } of requestUrls) {
209
527
  signal?.throwIfAborted();
210
528
  let remoteDocument;
211
529
  try {
212
- remoteDocument = await options.documentLoader(requestUrl, signal == null ? void 0 : { signal });
530
+ remoteDocument = response ?? await options.documentLoader(requestUrl, signal == null ? void 0 : { signal });
213
531
  } catch (error) {
214
532
  signal?.throwIfAborted();
215
533
  logger.debug("Failed to fetch {url} from {requestUrl}: {error}", {
@@ -226,12 +544,22 @@ async function dereferencePortableIri(url, options) {
226
544
  const { document } = remoteDocument;
227
545
  try {
228
546
  await checkPortableObjectId(document, expectedId, contextLoader);
547
+ let documentUrl;
548
+ try {
549
+ documentUrl = parseIri(remoteDocument.documentUrl);
550
+ } catch {
551
+ documentUrl = void 0;
552
+ }
229
553
  let result;
230
554
  try {
231
555
  result = await verify(document, {
232
556
  documentLoader: options.documentLoader,
233
557
  contextLoader,
234
- tracerProvider: options.tracerProvider
558
+ tracerProvider: options.tracerProvider,
559
+ ...documentUrl == null ? {} : { documentUrl },
560
+ ...explicitGateways == null ? {} : { gateways: explicitGateways },
561
+ ...gatewayHints == null ? {} : { gatewayHints },
562
+ ...referrer == null ? {} : { referrer }
235
563
  });
236
564
  } catch (error) {
237
565
  throw new PortableObjectRejection("the proof verifier failed: {error}", { error });
@@ -242,6 +570,11 @@ async function dereferencePortableIri(url, options) {
242
570
  baseUrl: url
243
571
  });
244
572
  signal?.throwIfAborted();
573
+ if (object != null && typeof object === "object") provenances.set(object, {
574
+ acceptance: result.unsecured === true ? "unsecured" : "verified",
575
+ ...result.collectionContext === void 0 ? {} : { collectionContext: result.collectionContext },
576
+ ...options.referrer == null ? {} : { referrer: options.referrer }
577
+ });
245
578
  if (gateway != null) span?.setAttribute("activitypub.gateway", gateway.href);
246
579
  return object;
247
580
  } catch (error) {
@@ -308,4 +641,4 @@ async function checkPortableObjectId(document, expectedId, contextLoader) {
308
641
  if (actualId !== expectedId) throw new PortableObjectRejection("its @id ({objectId}) does not match the requested portable ID", { objectId: id });
309
642
  }
310
643
  //#endregion
311
- export { PortableObjectRejectedError, dereferencePortableIri, getPortableGatewayCandidates, isPortableIri };
644
+ export { PortableObjectRejectedError, copyPortableProvenance, createSnapshotContextLoader, dereferencePortableIri, getPortableGatewayCandidates, getPortableResponseClaim, isCompatibleEf61Iri, isInPortableChain, isPortableIri, isPortableMode, isUnsecuredPortableObject, isUnverifiedPortableClaim, markUnverifiedPortableClaim, mustDereferencePortableObject, parseCompatibleEf61Reference, recordPortableReferrer, rejectMalformedCompatibleReference, warnUnverifiableEmbeddedObject };
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.2056+e6394f3b";
19
+ var version = "2.4.0-dev.2065+b09fdd33";
20
20
  //#endregion
21
21
  //#region src/request.ts
22
22
  /**
package/dist/mod.d.cts CHANGED
@@ -1,6 +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
+ import { i as PortableObjectVerifierOptions, n as PortableObjectVerification, r as PortableObjectVerifier, t as PortableObjectReferrer } from "./portable-comBI05Y.cjs";
4
4
  import { TracerProvider } from "@opentelemetry/api";
5
5
 
6
6
  //#region src/contexts.d.ts
@@ -547,4 +547,4 @@ declare function isValidPublicIPv4Address(address: string): boolean;
547
547
  declare function isValidPublicIPv6Address(address: string): boolean;
548
548
  declare function expandIPv6Address(address: string): string;
549
549
  //#endregion
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 };
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 PortableObjectReferrer, type PortableObjectVerification, 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,6 +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
+ import { i as PortableObjectVerifierOptions, n as PortableObjectVerification, r as PortableObjectVerifier, t as PortableObjectReferrer } from "./portable-DH3947GK.js";
4
4
  import { TracerProvider } from "@opentelemetry/api";
5
5
  //#region src/contexts.d.ts
6
6
  declare const preloadedContexts: Record<string, unknown>;
@@ -546,4 +546,4 @@ declare function isValidPublicIPv4Address(address: string): boolean;
546
546
  declare function isValidPublicIPv6Address(address: string): boolean;
547
547
  declare function expandIPv6Address(address: string): string;
548
548
  //#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 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 };
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 PortableObjectReferrer, type PortableObjectVerification, 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.2056+e6394f3b";
15
+ var version = "2.4.0-dev.2065+b09fdd33";
16
16
  //#endregion
17
17
  //#region src/request.ts
18
18
  /**
@@ -0,0 +1,160 @@
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
+ * The URL the document was finally retrieved from, i.e., the `documentUrl`
28
+ * of the document loader's result, which may differ from the requested URL
29
+ * after redirects. Trust decisions such as the [FEP-ef61] gateway trust
30
+ * policy for unsecured collections depend on it, so custom document loaders
31
+ * must report it truthfully.
32
+ *
33
+ * [FEP-ef61]: https://w3id.org/fep/ef61
34
+ * @since 2.4.0
35
+ */
36
+ readonly documentUrl?: URL;
37
+ /**
38
+ * The gateways that the caller explicitly passed to the accessor through
39
+ * its `gateways` option, in order. It is `undefined` if the caller did not
40
+ * pass the option, and can be empty.
41
+ * @since 2.4.0
42
+ */
43
+ readonly gateways?: readonly URL[];
44
+ /**
45
+ * The gateways inferred from the reference, in order, when the caller did
46
+ * not pass the `gateways` option: the `@gateway` location hints of
47
+ * a portable IRI, the gateway named by an FEP-ef61 compatible identifier,
48
+ * or the WebFinger server of a portable actor. They only tell where the
49
+ * document and related objects might be retrieved, and must not be
50
+ * trusted to act for the portable object's DID.
51
+ * @since 2.4.0
52
+ */
53
+ readonly gatewayHints?: readonly URL[];
54
+ /**
55
+ * The object whose property referred to the document, if the document was
56
+ * dereferenced through a property accessor.
57
+ * @since 2.4.0
58
+ */
59
+ readonly referrer?: PortableObjectReferrer;
60
+ }
61
+ /**
62
+ * An object whose property referred to a portable object being verified.
63
+ * Referrers form a chain: {@link PortableObjectReferrer.referrer} is the
64
+ * object through which this referrer itself was obtained, and so on.
65
+ * @since 2.4.0
66
+ */
67
+ interface PortableObjectReferrer {
68
+ /**
69
+ * The referring vocabulary object.
70
+ */
71
+ readonly object: unknown;
72
+ /**
73
+ * The `@id` of the referring object, if any.
74
+ */
75
+ readonly id: URL | null;
76
+ /**
77
+ * The expanded URI of the property through which the referring object
78
+ * referred to the next object in the chain, e.g.,
79
+ * `https://www.w3.org/ns/activitystreams#outbox`.
80
+ */
81
+ readonly property: string;
82
+ /**
83
+ * How the referring object itself was accepted by a
84
+ * {@link PortableObjectVerifier} when it was dereferenced through gateways:
85
+ *
86
+ * - `"verified"`: accepted as verified, e.g., with a valid integrity proof.
87
+ * - `"unsecured"`: accepted without an integrity proof, e.g., as an
88
+ * unsecured collection served by a trusted gateway.
89
+ *
90
+ * It is `undefined` if the referring object was not dereferenced through
91
+ * gateways, e.g., if it was embedded in another object or constructed by
92
+ * the application.
93
+ */
94
+ readonly acceptance?: "verified" | "unsecured";
95
+ /**
96
+ * The opaque collection context that a {@link PortableObjectVerifier}
97
+ * attached to the referring object when it accepted it. See
98
+ * {@link PortableObjectVerification}.
99
+ */
100
+ readonly collectionContext?: unknown;
101
+ /**
102
+ * The referrer of the referring object, if any.
103
+ */
104
+ readonly referrer?: PortableObjectReferrer;
105
+ /**
106
+ * Whether the chain was cut off here because it was too long. If `true`,
107
+ * the referring object may have a referrer which is not included.
108
+ */
109
+ readonly truncated?: boolean;
110
+ }
111
+ /**
112
+ * The result of a {@link PortableObjectVerifier}.
113
+ * @since 2.4.0
114
+ */
115
+ type PortableObjectVerification = {
116
+ /** Whether the document is accepted. */readonly verified: false;
117
+ } | {
118
+ /** Whether the document is accepted. */readonly verified: true;
119
+ /**
120
+ * Whether the document was accepted without an integrity proof, e.g., as
121
+ * an unsecured [FEP-ef61] collection served by a gateway that its owner
122
+ * lists. Objects embedded in such a document are not trusted because of
123
+ * their origin; property accessors dereference and verify them one by
124
+ * one instead.
125
+ *
126
+ * [FEP-ef61]: https://w3id.org/fep/ef61
127
+ */
128
+ readonly unsecured?: boolean;
129
+ /**
130
+ * An opaque value that the verifier wants to receive again as
131
+ * {@link PortableObjectReferrer.collectionContext} when objects referred
132
+ * to by this document, such as collection pages, are verified.
133
+ */
134
+ readonly collectionContext?: unknown;
135
+ };
136
+ /**
137
+ * A function that applies the [FEP-ef61] trust policy to a portable object
138
+ * fetched through a gateway.
139
+ *
140
+ * It receives the fetched JSON-LD document as is, and resolves to an object
141
+ * whose `verified` property tells whether the document is acceptable, e.g.,
142
+ * whether it carries a valid [FEP-8b32] Object Integrity Proof made by the
143
+ * DID in its portable ID. `verifyPortableObject()` and
144
+ * `verifyPortableObjectProof()` from `@fedify/fedify` satisfy this type, so
145
+ * they can be passed as the `verifyPortableObject` option of generated
146
+ * vocabulary accessors such as `Activity.getObject()`.
147
+ *
148
+ * [FEP-ef61]: https://w3id.org/fep/ef61
149
+ * [FEP-8b32]: https://w3id.org/fep/8b32
150
+ *
151
+ * @param document The fetched JSON-LD document.
152
+ * @param options Loaders, tracing options, and where the document came from.
153
+ * @returns An object whose `verified` property is `true` if and only if the
154
+ * document satisfies the policy. Other properties, such as
155
+ * a failure reason, are logged when verification fails.
156
+ * @since 2.4.0
157
+ */
158
+ type PortableObjectVerifier = (document: unknown, options: PortableObjectVerifierOptions) => Promise<PortableObjectVerification>;
159
+ //#endregion
160
+ export { PortableObjectVerifierOptions as i, PortableObjectVerification as n, PortableObjectVerifier as r, PortableObjectReferrer as t };