@fedify/vocab-runtime 2.5.0-dev.2513 → 2.5.0-dev.2532

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 +21 -0
  3. package/dist/internal/portable-dereference.d.cts +9 -1
  4. package/dist/internal/portable-dereference.d.ts +9 -1
  5. package/dist/internal/portable-dereference.js +21 -1
  6. package/dist/mod.cjs +1 -1
  7. package/dist/mod.js +1 -1
  8. package/dist/tests/{body-B-lP0k3j.cjs → body-Clt-mj2L.cjs} +1 -1
  9. package/dist/tests/{body-D880mING.mjs → body-CsaMjyeJ.mjs} +1 -1
  10. package/dist/tests/body.test.cjs +1 -1
  11. package/dist/tests/body.test.mjs +1 -1
  12. package/dist/tests/decimal.test.cjs +3 -3
  13. package/dist/tests/decimal.test.mjs +3 -3
  14. package/dist/tests/{docloader-BI-HRShZ.cjs → docloader-CjpwSHqE.cjs} +2 -2
  15. package/dist/tests/{docloader-rHrF5QRp.mjs → docloader-CrqLwb1f.mjs} +2 -2
  16. package/dist/tests/docloader.test.cjs +2 -2
  17. package/dist/tests/docloader.test.mjs +2 -2
  18. package/dist/tests/internal/portable-dereference.test.cjs +31 -1
  19. package/dist/tests/internal/portable-dereference.test.mjs +31 -1
  20. package/dist/tests/{portable-dereference-BUoDzMxk.cjs → portable-dereference-Cpe93KjP.cjs} +56 -0
  21. package/dist/tests/{portable-dereference-Du2k3ngE.mjs → portable-dereference-DapCH3Fb.mjs} +39 -1
  22. package/dist/tests/{portable-media-DVWGq_Yb.mjs → portable-media-BVpm5WsN.mjs} +2 -2
  23. package/dist/tests/{portable-media-CJ7mnaX-.cjs → portable-media-BfJu9npe.cjs} +2 -2
  24. package/dist/tests/portable-media.test.cjs +1 -1
  25. package/dist/tests/portable-media.test.mjs +1 -1
  26. package/dist/tests/portable-workers.test.cjs +1 -1
  27. package/dist/tests/portable-workers.test.mjs +1 -1
  28. package/dist/tests/{request-Cq5Bltfa.mjs → request-B5RuHslS.mjs} +1 -1
  29. package/dist/tests/{request-CnfHGsWV.cjs → request-D2ZmJUZw.cjs} +1 -1
  30. package/dist/tests/request.test.cjs +1 -1
  31. package/dist/tests/request.test.mjs +1 -1
  32. package/package.json +1 -1
  33. package/src/internal/portable-dereference.test.ts +34 -0
  34. package/src/internal/portable-dereference.ts +21 -0
package/deno.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fedify/vocab-runtime",
3
- "version": "2.5.0-dev.2513+d7ab5950",
3
+ "version": "2.5.0-dev.2532+a971acb5",
4
4
  "license": "MIT",
5
5
  "exports": {
6
6
  ".": "./src/mod.ts",
@@ -126,6 +126,26 @@ function copyPortableProvenance(from, to) {
126
126
  });
127
127
  }
128
128
  /**
129
+ * Reconnects an existing historical referrer to its independent graph copy.
130
+ * Does not create provenance or add verification or collection-context evidence.
131
+ * An unresolved referrer remains external history. Like the other provenance
132
+ * helpers, this is for generated vocabulary code, not a public trust API.
133
+ * @internal
134
+ */
135
+ function retargetPortableReferrer(copy, resolve) {
136
+ const provenance = provenances.get(copy);
137
+ if (provenance?.referrer == null) return;
138
+ const object = resolve(provenance.referrer.object);
139
+ if (object == null) return;
140
+ provenances.set(copy, {
141
+ ...provenance,
142
+ referrer: {
143
+ ...provenance.referrer,
144
+ object
145
+ }
146
+ });
147
+ }
148
+ /**
129
149
  * Recognizes an FEP-ef61 compatible identifier to dereference as a portable
130
150
  * object.
131
151
  *
@@ -783,4 +803,5 @@ exports.mustDereferencePortableObject = mustDereferencePortableObject;
783
803
  exports.parseCompatibleEf61Reference = parseCompatibleEf61Reference;
784
804
  exports.recordPortableReferrer = recordPortableReferrer;
785
805
  exports.rejectMalformedCompatibleReference = rejectMalformedCompatibleReference;
806
+ exports.retargetPortableReferrer = retargetPortableReferrer;
786
807
  exports.warnUnverifiableEmbeddedObject = warnUnverifiableEmbeddedObject;
@@ -77,6 +77,14 @@ declare function recordPortableReferrer(parent: object, child: unknown, property
77
77
  */
78
78
  declare function copyPortableProvenance(from: object, to: object): void;
79
79
  /**
80
+ * Reconnects an existing historical referrer to its independent graph copy.
81
+ * Does not create provenance or add verification or collection-context evidence.
82
+ * An unresolved referrer remains external history. Like the other provenance
83
+ * helpers, this is for generated vocabulary code, not a public trust API.
84
+ * @internal
85
+ */
86
+ declare function retargetPortableReferrer(copy: object, resolve: (original: object) => object | undefined): void;
87
+ /**
80
88
  * Recognizes an FEP-ef61 compatible identifier to dereference as a portable
81
89
  * object.
82
90
  *
@@ -406,4 +414,4 @@ declare function dereferencePortableIri<T extends {
406
414
  id: URL | null;
407
415
  }>(url: URL, options: DereferencePortableIriOptions<T>): Promise<T | null>;
408
416
  //#endregion
409
- export { DereferenceCandidate, DereferenceFailure, DereferenceObserver, DereferencePortableIriOptions, PortableObjectRejectedError, PortableReferrerLink, PortableResponseClaim, acceptCandidate, copyPortableProvenance, createSnapshotContextLoader, dereferencePortableIri, getPortableGatewayCandidates, getPortableResponseClaim, getReferrerGateways, isCompatibleEf61Iri, isInPortableChain, isPortableIri, isPortableMode, isUnsecuredPortableObject, isUnverifiedPortableClaim, markUnverifiedPortableClaim, mustDereferencePortableObject, parseCompatibleEf61Reference, recordPortableReferrer, rejectMalformedCompatibleReference, warnUnverifiableEmbeddedObject };
417
+ export { DereferenceCandidate, DereferenceFailure, DereferenceObserver, DereferencePortableIriOptions, PortableObjectRejectedError, PortableReferrerLink, PortableResponseClaim, acceptCandidate, copyPortableProvenance, createSnapshotContextLoader, dereferencePortableIri, getPortableGatewayCandidates, getPortableResponseClaim, getReferrerGateways, isCompatibleEf61Iri, isInPortableChain, isPortableIri, isPortableMode, isUnsecuredPortableObject, isUnverifiedPortableClaim, markUnverifiedPortableClaim, mustDereferencePortableObject, parseCompatibleEf61Reference, recordPortableReferrer, rejectMalformedCompatibleReference, retargetPortableReferrer, warnUnverifiableEmbeddedObject };
@@ -77,6 +77,14 @@ declare function recordPortableReferrer(parent: object, child: unknown, property
77
77
  */
78
78
  declare function copyPortableProvenance(from: object, to: object): void;
79
79
  /**
80
+ * Reconnects an existing historical referrer to its independent graph copy.
81
+ * Does not create provenance or add verification or collection-context evidence.
82
+ * An unresolved referrer remains external history. Like the other provenance
83
+ * helpers, this is for generated vocabulary code, not a public trust API.
84
+ * @internal
85
+ */
86
+ declare function retargetPortableReferrer(copy: object, resolve: (original: object) => object | undefined): void;
87
+ /**
80
88
  * Recognizes an FEP-ef61 compatible identifier to dereference as a portable
81
89
  * object.
82
90
  *
@@ -406,4 +414,4 @@ declare function dereferencePortableIri<T extends {
406
414
  id: URL | null;
407
415
  }>(url: URL, options: DereferencePortableIriOptions<T>): Promise<T | null>;
408
416
  //#endregion
409
- export { DereferenceCandidate, DereferenceFailure, DereferenceObserver, DereferencePortableIriOptions, PortableObjectRejectedError, PortableReferrerLink, PortableResponseClaim, acceptCandidate, copyPortableProvenance, createSnapshotContextLoader, dereferencePortableIri, getPortableGatewayCandidates, getPortableResponseClaim, getReferrerGateways, isCompatibleEf61Iri, isInPortableChain, isPortableIri, isPortableMode, isUnsecuredPortableObject, isUnverifiedPortableClaim, markUnverifiedPortableClaim, mustDereferencePortableObject, parseCompatibleEf61Reference, recordPortableReferrer, rejectMalformedCompatibleReference, warnUnverifiableEmbeddedObject };
417
+ export { DereferenceCandidate, DereferenceFailure, DereferenceObserver, DereferencePortableIriOptions, PortableObjectRejectedError, PortableReferrerLink, PortableResponseClaim, acceptCandidate, copyPortableProvenance, createSnapshotContextLoader, dereferencePortableIri, getPortableGatewayCandidates, getPortableResponseClaim, getReferrerGateways, isCompatibleEf61Iri, isInPortableChain, isPortableIri, isPortableMode, isUnsecuredPortableObject, isUnverifiedPortableClaim, markUnverifiedPortableClaim, mustDereferencePortableObject, parseCompatibleEf61Reference, recordPortableReferrer, rejectMalformedCompatibleReference, retargetPortableReferrer, warnUnverifiableEmbeddedObject };
@@ -125,6 +125,26 @@ function copyPortableProvenance(from, to) {
125
125
  });
126
126
  }
127
127
  /**
128
+ * Reconnects an existing historical referrer to its independent graph copy.
129
+ * Does not create provenance or add verification or collection-context evidence.
130
+ * An unresolved referrer remains external history. Like the other provenance
131
+ * helpers, this is for generated vocabulary code, not a public trust API.
132
+ * @internal
133
+ */
134
+ function retargetPortableReferrer(copy, resolve) {
135
+ const provenance = provenances.get(copy);
136
+ if (provenance?.referrer == null) return;
137
+ const object = resolve(provenance.referrer.object);
138
+ if (object == null) return;
139
+ provenances.set(copy, {
140
+ ...provenance,
141
+ referrer: {
142
+ ...provenance.referrer,
143
+ object
144
+ }
145
+ });
146
+ }
147
+ /**
128
148
  * Recognizes an FEP-ef61 compatible identifier to dereference as a portable
129
149
  * object.
130
150
  *
@@ -763,4 +783,4 @@ async function checkPortableObjectId(document, expectedId, contextLoader) {
763
783
  if (actualId !== expectedId) throw new PortableObjectRejection("its @id ({objectId}) does not match the requested portable ID", { objectId: id });
764
784
  }
765
785
  //#endregion
766
- export { PortableObjectRejectedError, acceptCandidate, copyPortableProvenance, createSnapshotContextLoader, dereferencePortableIri, getPortableGatewayCandidates, getPortableResponseClaim, getReferrerGateways, isCompatibleEf61Iri, isInPortableChain, isPortableIri, isPortableMode, isUnsecuredPortableObject, isUnverifiedPortableClaim, markUnverifiedPortableClaim, mustDereferencePortableObject, parseCompatibleEf61Reference, recordPortableReferrer, rejectMalformedCompatibleReference, warnUnverifiableEmbeddedObject };
786
+ export { PortableObjectRejectedError, acceptCandidate, copyPortableProvenance, createSnapshotContextLoader, dereferencePortableIri, getPortableGatewayCandidates, getPortableResponseClaim, getReferrerGateways, isCompatibleEf61Iri, isInPortableChain, isPortableIri, isPortableMode, isUnsecuredPortableObject, isUnverifiedPortableClaim, markUnverifiedPortableClaim, mustDereferencePortableObject, parseCompatibleEf61Reference, recordPortableReferrer, rejectMalformedCompatibleReference, retargetPortableReferrer, warnUnverifiableEmbeddedObject };
package/dist/mod.cjs CHANGED
@@ -17,7 +17,7 @@ let _multiformats_base_x = require("@multiformats/base-x");
17
17
  _multiformats_base_x = require_rolldown_runtime.__toESM(_multiformats_base_x, 1);
18
18
  //#region deno.json
19
19
  var name = "@fedify/vocab-runtime";
20
- var version = "2.5.0-dev.2513+d7ab5950";
20
+ var version = "2.5.0-dev.2532+a971acb5";
21
21
  //#endregion
22
22
  //#region src/request.ts
23
23
  /**
package/dist/mod.js CHANGED
@@ -13,7 +13,7 @@ import { PublicKeyInfo } from "pkijs";
13
13
  import baseX from "@multiformats/base-x";
14
14
  //#region deno.json
15
15
  var name = "@fedify/vocab-runtime";
16
- var version = "2.5.0-dev.2513+d7ab5950";
16
+ var version = "2.5.0-dev.2532+a971acb5";
17
17
  //#endregion
18
18
  //#region src/request.ts
19
19
  /**
@@ -1,4 +1,4 @@
1
- const require_request = require("./request-CnfHGsWV.cjs");
1
+ const require_request = require("./request-D2ZmJUZw.cjs");
2
2
  let _logtape_logtape = require("@logtape/logtape");
3
3
  //#region src/body.ts
4
4
  /** Decoded JSON body limit: 16 MiB. @internal */
@@ -1,4 +1,4 @@
1
- import { t as FetchError } from "./request-Cq5Bltfa.mjs";
1
+ import { t as FetchError } from "./request-B5RuHslS.mjs";
2
2
  import { getLogger } from "@logtape/logtape";
3
3
  //#region src/body.ts
4
4
  /** Decoded JSON body limit: 16 MiB. @internal */
@@ -1,4 +1,4 @@
1
- const require_body = require("./body-B-lP0k3j.cjs");
1
+ const require_body = require("./body-Clt-mj2L.cjs");
2
2
  let node_assert_strict = require("node:assert/strict");
3
3
  let node_test = require("node:test");
4
4
  let node_zlib = require("node:zlib");
@@ -1,4 +1,4 @@
1
- import { i as readBoundedText, t as BodyTooLargeError } from "./body-D880mING.mjs";
1
+ import { i as readBoundedText, t as BodyTooLargeError } from "./body-CsaMjyeJ.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,12 +1,12 @@
1
- require("./request-CnfHGsWV.cjs");
1
+ require("./request-D2ZmJUZw.cjs");
2
2
  require("./url-Bdj-rTcC.cjs");
3
- require("./docloader-BI-HRShZ.cjs");
3
+ require("./docloader-CjpwSHqE.cjs");
4
4
  require("./key-C-AYkdJJ.cjs");
5
5
  require("./multibase-B5Mea7Ip.cjs");
6
6
  require("./digest-3FeH2Y-Q.cjs");
7
7
  require("./langtag-DASCPgl3.cjs");
8
8
  require("./langstr-h89Kjekh.cjs");
9
- require("./portable-media-CJ7mnaX-.cjs");
9
+ require("./portable-media-BfJu9npe.cjs");
10
10
  let node_test = require("node:test");
11
11
  let node_assert = require("node:assert");
12
12
  //#region src/decimal.ts
@@ -1,12 +1,12 @@
1
- import "./request-Cq5Bltfa.mjs";
1
+ import "./request-B5RuHslS.mjs";
2
2
  import "./url-COj5Q8mb.mjs";
3
- import "./docloader-rHrF5QRp.mjs";
3
+ import "./docloader-CrqLwb1f.mjs";
4
4
  import "./key-C2Db_TAJ.mjs";
5
5
  import "./multibase-BPnF_L4e.mjs";
6
6
  import "./digest-COC7xDiQ.mjs";
7
7
  import "./langtag-CD3zHKPN.mjs";
8
8
  import "./langstr-Dw8IBDZl.mjs";
9
- import "./portable-media-DVWGq_Yb.mjs";
9
+ import "./portable-media-BVpm5WsN.mjs";
10
10
  import { test } from "node:test";
11
11
  import { deepStrictEqual, throws } from "node:assert";
12
12
  //#region src/decimal.ts
@@ -1,6 +1,6 @@
1
- const require_request = require("./request-CnfHGsWV.cjs");
1
+ const require_request = require("./request-D2ZmJUZw.cjs");
2
2
  const require_url = require("./url-Bdj-rTcC.cjs");
3
- const require_body = require("./body-B-lP0k3j.cjs");
3
+ const require_body = require("./body-Clt-mj2L.cjs");
4
4
  const require_contexts = require("./contexts-C9Lj11SC.cjs");
5
5
  const require_link = require("./link-DlKm8bEr.cjs");
6
6
  const require_public_fetch = require("./public-fetch-BGj5pzUD.cjs");
@@ -1,6 +1,6 @@
1
- import { a as logRequest, n as createActivityPubRequest, o as name, s as version, t as FetchError } from "./request-Cq5Bltfa.mjs";
1
+ import { a as logRequest, n as createActivityPubRequest, o as name, s as version, t as FetchError } from "./request-B5RuHslS.mjs";
2
2
  import { n as UrlError } from "./url-COj5Q8mb.mjs";
3
- import { i as readBoundedText, n as MAX_BODY_SIZE, r as readBoundedBytes, t as BodyTooLargeError } from "./body-D880mING.mjs";
3
+ import { i as readBoundedText, n as MAX_BODY_SIZE, r as readBoundedBytes, t as BodyTooLargeError } from "./body-CsaMjyeJ.mjs";
4
4
  import { t as preloadedContexts } from "./contexts-duRA_dDC.mjs";
5
5
  import { t as HttpHeaderLink } from "./link-Cevmc87v.mjs";
6
6
  import { n as openDirectFetch, r as openPublicFetch } from "./public-fetch-Cxo3Yzdf.mjs";
@@ -1,8 +1,8 @@
1
- const require_request = require("./request-CnfHGsWV.cjs");
1
+ const require_request = require("./request-D2ZmJUZw.cjs");
2
2
  const require_url = require("./url-Bdj-rTcC.cjs");
3
3
  const require_contexts = require("./contexts-C9Lj11SC.cjs");
4
4
  const require_public_fetch = require("./public-fetch-BGj5pzUD.cjs");
5
- const require_docloader = require("./docloader-BI-HRShZ.cjs");
5
+ const require_docloader = require("./docloader-CjpwSHqE.cjs");
6
6
  const require_esm = require("./esm-Q2tdh5f3.cjs");
7
7
  const require_jsonld = require("./jsonld-CmDhHNTx.cjs");
8
8
  let node_zlib = require("node:zlib");
@@ -1,9 +1,9 @@
1
1
  import { t as esm_default } from "./esm-Ds-eHTfY.mjs";
2
- import { t as FetchError } from "./request-Cq5Bltfa.mjs";
2
+ import { t as FetchError } from "./request-B5RuHslS.mjs";
3
3
  import { n as UrlError } from "./url-COj5Q8mb.mjs";
4
4
  import { n as cid_v1_default, t as preloadedContexts } from "./contexts-duRA_dDC.mjs";
5
5
  import { t as createPublicFetch } from "./public-fetch-Cxo3Yzdf.mjs";
6
- import { a as withDocumentLoaderTimeout, i as resolveDocumentLoaderTimeout, n as getDocumentLoader, r as getRemoteDocument, t as createDocumentLoader } from "./docloader-rHrF5QRp.mjs";
6
+ import { a as withDocumentLoaderTimeout, i as resolveDocumentLoaderTimeout, n as getDocumentLoader, r as getRemoteDocument, t as createDocumentLoader } from "./docloader-CrqLwb1f.mjs";
7
7
  import { t as jsonld_default } from "./jsonld-DweIJ07b.mjs";
8
8
  import { gzipSync } from "node:zlib";
9
9
  import { configure, reset } from "@logtape/logtape";
@@ -1,10 +1,40 @@
1
1
  const require_url = require("../url-Bdj-rTcC.cjs");
2
2
  const require_jsonld_cache = require("../jsonld-cache-DKIWKxEX.cjs");
3
- const require_portable_dereference = require("../portable-dereference-BUoDzMxk.cjs");
3
+ const require_portable_dereference = require("../portable-dereference-Cpe93KjP.cjs");
4
4
  let node_assert_strict = require("node:assert/strict");
5
5
  let node_test = require("node:test");
6
6
  //#region src/internal/portable-dereference.test.ts
7
7
  const hrefs = (urls) => urls.map((url) => url.href);
8
+ (0, node_test.test)("retargetPortableReferrer() only reconnects existing provenance", () => {
9
+ const id = require_url.parseIri("ap://did:key:z6Mkabc/actor");
10
+ const parent = {
11
+ id,
12
+ gateways: [new URL("https://original.example")]
13
+ };
14
+ const copiedParent = {
15
+ id,
16
+ gateways: [new URL("https://copy.example")]
17
+ };
18
+ const source = {};
19
+ const copy = {};
20
+ let calls = 0;
21
+ require_portable_dereference.retargetPortableReferrer(copy, () => {
22
+ calls++;
23
+ return copiedParent;
24
+ });
25
+ (0, node_assert_strict.deepStrictEqual)(calls, 0);
26
+ (0, node_assert_strict.ok)(!require_portable_dereference.isInPortableChain(copy));
27
+ require_portable_dereference.recordPortableReferrer(parent, source, "https://example.com/property");
28
+ require_portable_dereference.copyPortableProvenance(source, copy);
29
+ require_portable_dereference.retargetPortableReferrer(copy, () => void 0);
30
+ (0, node_assert_strict.deepStrictEqual)(hrefs(require_portable_dereference.getReferrerGateways(copy, id)), ["https://original.example/"]);
31
+ require_portable_dereference.retargetPortableReferrer(copy, (original) => {
32
+ (0, node_assert_strict.ok)(original === parent);
33
+ return copiedParent;
34
+ });
35
+ (0, node_assert_strict.deepStrictEqual)(hrefs(require_portable_dereference.getReferrerGateways(copy, id)), ["https://copy.example/"]);
36
+ (0, node_assert_strict.deepStrictEqual)(hrefs(require_portable_dereference.getReferrerGateways(source, id)), ["https://original.example/"]);
37
+ });
8
38
  (0, node_test.test)("isPortableIri()", () => {
9
39
  (0, node_assert_strict.ok)(require_portable_dereference.isPortableIri(require_url.parseIri("ap://did:key:z6Mkabc/actor")));
10
40
  (0, node_assert_strict.ok)(require_portable_dereference.isPortableIri(require_url.parseIri("ap+ef61://did:key:z6Mkabc/actor")));
@@ -1,10 +1,40 @@
1
1
  import { E as withGatewayHints, b as parseIri } from "../url-COj5Q8mb.mjs";
2
2
  import { n as createScopedContextLoader } from "../jsonld-cache-KH40z9_7.mjs";
3
- import { a as recordPortableReferrer, i as isPortableIri, n as getPortableGatewayCandidates, r as getReferrerGateways, t as createSnapshotContextLoader } from "../portable-dereference-Du2k3ngE.mjs";
3
+ import { a as isInPortableChain, c as retargetPortableReferrer, i as getReferrerGateways, n as createSnapshotContextLoader, o as isPortableIri, r as getPortableGatewayCandidates, s as recordPortableReferrer, t as copyPortableProvenance } from "../portable-dereference-DapCH3Fb.mjs";
4
4
  import { deepStrictEqual, ok, throws } from "node:assert/strict";
5
5
  import { test } from "node:test";
6
6
  //#region src/internal/portable-dereference.test.ts
7
7
  const hrefs = (urls) => urls.map((url) => url.href);
8
+ test("retargetPortableReferrer() only reconnects existing provenance", () => {
9
+ const id = parseIri("ap://did:key:z6Mkabc/actor");
10
+ const parent = {
11
+ id,
12
+ gateways: [new URL("https://original.example")]
13
+ };
14
+ const copiedParent = {
15
+ id,
16
+ gateways: [new URL("https://copy.example")]
17
+ };
18
+ const source = {};
19
+ const copy = {};
20
+ let calls = 0;
21
+ retargetPortableReferrer(copy, () => {
22
+ calls++;
23
+ return copiedParent;
24
+ });
25
+ deepStrictEqual(calls, 0);
26
+ ok(!isInPortableChain(copy));
27
+ recordPortableReferrer(parent, source, "https://example.com/property");
28
+ copyPortableProvenance(source, copy);
29
+ retargetPortableReferrer(copy, () => void 0);
30
+ deepStrictEqual(hrefs(getReferrerGateways(copy, id)), ["https://original.example/"]);
31
+ retargetPortableReferrer(copy, (original) => {
32
+ ok(original === parent);
33
+ return copiedParent;
34
+ });
35
+ deepStrictEqual(hrefs(getReferrerGateways(copy, id)), ["https://copy.example/"]);
36
+ deepStrictEqual(hrefs(getReferrerGateways(source, id)), ["https://original.example/"]);
37
+ });
8
38
  test("isPortableIri()", () => {
9
39
  ok(isPortableIri(parseIri("ap://did:key:z6Mkabc/actor")));
10
40
  ok(isPortableIri(parseIri("ap+ef61://did:key:z6Mkabc/actor")));
@@ -87,6 +87,44 @@ function recordPortableReferrer(parent, child, property) {
87
87
  } });
88
88
  }
89
89
  /**
90
+ * Copies the provenance of a vocabulary object to its clone. The clone
91
+ * keeps where the original came from and the restriction on unsecured
92
+ * objects, but not a positive verification status nor a collection context,
93
+ * since the clone may have different property values.
94
+ *
95
+ * @internal Technically exported for generated vocabulary classes, but not
96
+ * part of the public API contract. This is not considered public API for
97
+ * Semantic Versioning decisions.
98
+ */
99
+ function copyPortableProvenance(from, to) {
100
+ const provenance = provenances.get(from);
101
+ if (provenance == null) return;
102
+ provenances.set(to, {
103
+ referrer: provenance.referrer,
104
+ ...provenance.acceptance === "unsecured" ? { acceptance: "unsecured" } : {}
105
+ });
106
+ }
107
+ /**
108
+ * Reconnects an existing historical referrer to its independent graph copy.
109
+ * Does not create provenance or add verification or collection-context evidence.
110
+ * An unresolved referrer remains external history. Like the other provenance
111
+ * helpers, this is for generated vocabulary code, not a public trust API.
112
+ * @internal
113
+ */
114
+ function retargetPortableReferrer(copy, resolve) {
115
+ const provenance = provenances.get(copy);
116
+ if (provenance?.referrer == null) return;
117
+ const object = resolve(provenance.referrer.object);
118
+ if (object == null) return;
119
+ provenances.set(copy, {
120
+ ...provenance,
121
+ referrer: {
122
+ ...provenance.referrer,
123
+ object
124
+ }
125
+ });
126
+ }
127
+ /**
90
128
  * Checks whether a URL is an FEP-ef61 portable ActivityPub IRI.
91
129
  *
92
130
  * @internal Technically exported for generated vocabulary classes, but not
@@ -247,6 +285,12 @@ function createSnapshotContextLoader(contextLoader, suppressError) {
247
285
  };
248
286
  }
249
287
  //#endregion
288
+ Object.defineProperty(exports, "copyPortableProvenance", {
289
+ enumerable: true,
290
+ get: function() {
291
+ return copyPortableProvenance;
292
+ }
293
+ });
250
294
  Object.defineProperty(exports, "createSnapshotContextLoader", {
251
295
  enumerable: true,
252
296
  get: function() {
@@ -265,6 +309,12 @@ Object.defineProperty(exports, "getReferrerGateways", {
265
309
  return getReferrerGateways;
266
310
  }
267
311
  });
312
+ Object.defineProperty(exports, "isInPortableChain", {
313
+ enumerable: true,
314
+ get: function() {
315
+ return isInPortableChain;
316
+ }
317
+ });
268
318
  Object.defineProperty(exports, "isPortableIri", {
269
319
  enumerable: true,
270
320
  get: function() {
@@ -277,3 +327,9 @@ Object.defineProperty(exports, "recordPortableReferrer", {
277
327
  return recordPortableReferrer;
278
328
  }
279
329
  });
330
+ Object.defineProperty(exports, "retargetPortableReferrer", {
331
+ enumerable: true,
332
+ get: function() {
333
+ return retargetPortableReferrer;
334
+ }
335
+ });
@@ -87,6 +87,44 @@ function recordPortableReferrer(parent, child, property) {
87
87
  } });
88
88
  }
89
89
  /**
90
+ * Copies the provenance of a vocabulary object to its clone. The clone
91
+ * keeps where the original came from and the restriction on unsecured
92
+ * objects, but not a positive verification status nor a collection context,
93
+ * since the clone may have different property values.
94
+ *
95
+ * @internal Technically exported for generated vocabulary classes, but not
96
+ * part of the public API contract. This is not considered public API for
97
+ * Semantic Versioning decisions.
98
+ */
99
+ function copyPortableProvenance(from, to) {
100
+ const provenance = provenances.get(from);
101
+ if (provenance == null) return;
102
+ provenances.set(to, {
103
+ referrer: provenance.referrer,
104
+ ...provenance.acceptance === "unsecured" ? { acceptance: "unsecured" } : {}
105
+ });
106
+ }
107
+ /**
108
+ * Reconnects an existing historical referrer to its independent graph copy.
109
+ * Does not create provenance or add verification or collection-context evidence.
110
+ * An unresolved referrer remains external history. Like the other provenance
111
+ * helpers, this is for generated vocabulary code, not a public trust API.
112
+ * @internal
113
+ */
114
+ function retargetPortableReferrer(copy, resolve) {
115
+ const provenance = provenances.get(copy);
116
+ if (provenance?.referrer == null) return;
117
+ const object = resolve(provenance.referrer.object);
118
+ if (object == null) return;
119
+ provenances.set(copy, {
120
+ ...provenance,
121
+ referrer: {
122
+ ...provenance.referrer,
123
+ object
124
+ }
125
+ });
126
+ }
127
+ /**
90
128
  * Checks whether a URL is an FEP-ef61 portable ActivityPub IRI.
91
129
  *
92
130
  * @internal Technically exported for generated vocabulary classes, but not
@@ -247,4 +285,4 @@ function createSnapshotContextLoader(contextLoader, suppressError) {
247
285
  };
248
286
  }
249
287
  //#endregion
250
- export { recordPortableReferrer as a, isPortableIri as i, getPortableGatewayCandidates as n, getReferrerGateways as r, createSnapshotContextLoader as t };
288
+ export { isInPortableChain as a, retargetPortableReferrer as c, getReferrerGateways as i, createSnapshotContextLoader as n, isPortableIri as o, getPortableGatewayCandidates as r, recordPortableReferrer as s, copyPortableProvenance as t };
@@ -1,6 +1,6 @@
1
- import { r as getUserAgent } from "./request-Cq5Bltfa.mjs";
1
+ import { r as getUserAgent } from "./request-B5RuHslS.mjs";
2
2
  import { T as validatePublicUrl, y as parseGatewayUrl } from "./url-COj5Q8mb.mjs";
3
- import { r as readBoundedBytes } from "./body-D880mING.mjs";
3
+ import { r as readBoundedBytes } from "./body-CsaMjyeJ.mjs";
4
4
  import { a as verifyDigestMultibase, i as parseHashlink, r as parseDigestMultibase } from "./digest-COC7xDiQ.mjs";
5
5
  //#region src/portable-media.ts
6
6
  function resolveTimeout(value, fallback) {
@@ -1,6 +1,6 @@
1
- const require_request = require("./request-CnfHGsWV.cjs");
1
+ const require_request = require("./request-D2ZmJUZw.cjs");
2
2
  const require_url = require("./url-Bdj-rTcC.cjs");
3
- const require_body = require("./body-B-lP0k3j.cjs");
3
+ const require_body = require("./body-Clt-mj2L.cjs");
4
4
  const require_digest = require("./digest-3FeH2Y-Q.cjs");
5
5
  //#region src/portable-media.ts
6
6
  function resolveTimeout(value, fallback) {
@@ -1,5 +1,5 @@
1
1
  const require_digest = require("./digest-3FeH2Y-Q.cjs");
2
- const require_portable_media = require("./portable-media-CJ7mnaX-.cjs");
2
+ const require_portable_media = require("./portable-media-BfJu9npe.cjs");
3
3
  let node_assert_strict = require("node:assert/strict");
4
4
  let node_test = require("node:test");
5
5
  let node_http = require("node:http");
@@ -1,5 +1,5 @@
1
1
  import { n as createHashlink, t as computeDigestMultibase } from "./digest-COC7xDiQ.mjs";
2
- import { t as fetchPortableMedia } from "./portable-media-DVWGq_Yb.mjs";
2
+ import { t as fetchPortableMedia } from "./portable-media-BVpm5WsN.mjs";
3
3
  import { deepStrictEqual, equal, rejects } from "node:assert/strict";
4
4
  import { test } from "node:test";
5
5
  import { createServer } from "node:http";
@@ -2,7 +2,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_url = require("./url-Bdj-rTcC.cjs");
3
3
  const require_key = require("./key-C-AYkdJJ.cjs");
4
4
  const require_digest = require("./digest-3FeH2Y-Q.cjs");
5
- const require_portable_dereference = require("./portable-dereference-BUoDzMxk.cjs");
5
+ const require_portable_dereference = require("./portable-dereference-Cpe93KjP.cjs");
6
6
  let node_assert_strict = require("node:assert/strict");
7
7
  let _fedify_fixture = require("@fedify/fixture");
8
8
  //#region src/portable-workers.test.ts
@@ -1,7 +1,7 @@
1
1
  import { C as toCompatibleEf61Id, a as canonicalizePortableUri, b as parseIri, c as fromCompatibleEf61Id, s as formatIri } from "./url-COj5Q8mb.mjs";
2
2
  import { i as importDidKey, t as exportDidKey } from "./key-C2Db_TAJ.mjs";
3
3
  import { n as createHashlink, o as verifyHashlink, t as computeDigestMultibase } from "./digest-COC7xDiQ.mjs";
4
- import { n as getPortableGatewayCandidates } from "./portable-dereference-Du2k3ngE.mjs";
4
+ import { r as getPortableGatewayCandidates } from "./portable-dereference-DapCH3Fb.mjs";
5
5
  import { deepStrictEqual, equal } from "node:assert/strict";
6
6
  import { test, testDefinitions } from "@fedify/fixture";
7
7
  //#region src/portable-workers.test.ts
@@ -2,7 +2,7 @@ import { n as UrlError } from "./url-COj5Q8mb.mjs";
2
2
  import process from "node:process";
3
3
  //#region deno.json
4
4
  var name = "@fedify/vocab-runtime";
5
- var version = "2.5.0-dev.2513+d7ab5950";
5
+ var version = "2.5.0-dev.2532+a971acb5";
6
6
  //#endregion
7
7
  //#region src/request.ts
8
8
  /**
@@ -4,7 +4,7 @@ let node_process = require("node:process");
4
4
  node_process = require_rolldown_runtime.__toESM(node_process, 1);
5
5
  //#region deno.json
6
6
  var name = "@fedify/vocab-runtime";
7
- var version = "2.5.0-dev.2513+d7ab5950";
7
+ var version = "2.5.0-dev.2532+a971acb5";
8
8
  //#endregion
9
9
  //#region src/request.ts
10
10
  /**
@@ -1,5 +1,5 @@
1
1
  const require_rolldown_runtime = require("./rolldown-runtime-emK7D4bc.cjs");
2
- const require_request = require("./request-CnfHGsWV.cjs");
2
+ const require_request = require("./request-D2ZmJUZw.cjs");
3
3
  const require_url = require("./url-Bdj-rTcC.cjs");
4
4
  let node_test = require("node:test");
5
5
  let node_process = require("node:process");
@@ -1,4 +1,4 @@
1
- import { i as isTransientFetchError, n as createActivityPubRequest, r as getUserAgent, s as version, t as FetchError } from "./request-Cq5Bltfa.mjs";
1
+ import { i as isTransientFetchError, n as createActivityPubRequest, r as getUserAgent, s as version, t as FetchError } from "./request-B5RuHslS.mjs";
2
2
  import { n as UrlError } from "./url-COj5Q8mb.mjs";
3
3
  import { test } from "node:test";
4
4
  import process from "node:process";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fedify/vocab-runtime",
3
- "version": "2.5.0-dev.2513+d7ab5950",
3
+ "version": "2.5.0-dev.2532+a971acb5",
4
4
  "homepage": "https://fedify.dev/",
5
5
  "repository": {
6
6
  "type": "git",
@@ -4,15 +4,49 @@ import type { DocumentLoader } from "../docloader.ts";
4
4
  import { parseIri, withGatewayHints } from "../url.ts";
5
5
  import { createScopedContextLoader } from "./jsonld-cache.ts";
6
6
  import {
7
+ copyPortableProvenance,
7
8
  createSnapshotContextLoader,
8
9
  getPortableGatewayCandidates,
9
10
  getReferrerGateways,
11
+ isInPortableChain,
10
12
  isPortableIri,
11
13
  recordPortableReferrer,
14
+ retargetPortableReferrer,
12
15
  } from "./portable-dereference.ts";
13
16
 
14
17
  const hrefs = (urls: URL[]) => urls.map((url) => url.href);
15
18
 
19
+ test("retargetPortableReferrer() only reconnects existing provenance", () => {
20
+ const id = parseIri("ap://did:key:z6Mkabc/actor");
21
+ const parent = { id, gateways: [new URL("https://original.example")] };
22
+ const copiedParent = { id, gateways: [new URL("https://copy.example")] };
23
+ const source = {};
24
+ const copy = {};
25
+ let calls = 0;
26
+ retargetPortableReferrer(copy, () => {
27
+ calls++;
28
+ return copiedParent;
29
+ });
30
+ deepStrictEqual(calls, 0);
31
+ ok(!isInPortableChain(copy));
32
+ recordPortableReferrer(parent, source, "https://example.com/property");
33
+ copyPortableProvenance(source, copy);
34
+ retargetPortableReferrer(copy, () => undefined);
35
+ deepStrictEqual(hrefs(getReferrerGateways(copy, id)!), [
36
+ "https://original.example/",
37
+ ]);
38
+ retargetPortableReferrer(copy, (original) => {
39
+ ok(original === parent);
40
+ return copiedParent;
41
+ });
42
+ deepStrictEqual(hrefs(getReferrerGateways(copy, id)!), [
43
+ "https://copy.example/",
44
+ ]);
45
+ deepStrictEqual(hrefs(getReferrerGateways(source, id)!), [
46
+ "https://original.example/",
47
+ ]);
48
+ });
49
+
16
50
  test("isPortableIri()", () => {
17
51
  ok(isPortableIri(parseIri("ap://did:key:z6Mkabc/actor")));
18
52
  ok(isPortableIri(parseIri("ap+ef61://did:key:z6Mkabc/actor")));
@@ -198,6 +198,27 @@ export function copyPortableProvenance(from: object, to: object): void {
198
198
  });
199
199
  }
200
200
 
201
+ /**
202
+ * Reconnects an existing historical referrer to its independent graph copy.
203
+ * Does not create provenance or add verification or collection-context evidence.
204
+ * An unresolved referrer remains external history. Like the other provenance
205
+ * helpers, this is for generated vocabulary code, not a public trust API.
206
+ * @internal
207
+ */
208
+ export function retargetPortableReferrer(
209
+ copy: object,
210
+ resolve: (original: object) => object | undefined,
211
+ ): void {
212
+ const provenance = provenances.get(copy);
213
+ if (provenance?.referrer == null) return;
214
+ const object = resolve(provenance.referrer.object);
215
+ if (object == null) return;
216
+ provenances.set(copy, {
217
+ ...provenance,
218
+ referrer: { ...provenance.referrer, object },
219
+ });
220
+ }
221
+
201
222
  /**
202
223
  * Recognizes an FEP-ef61 compatible identifier to dereference as a portable
203
224
  * object.