@fedify/vocab 2.5.0-dev.2513 → 2.5.0-dev.2516

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.
@@ -1,14 +1,14 @@
1
1
  import "temporal-polyfill";
2
2
  globalThis.addEventListener = () => {};
3
3
  import { t as getTypeId } from "./type-BMdjm4Eg.mjs";
4
- import { F as Person, P as Organization, U as Service, a as Application, b as Group } from "./vocab-Dwwwbub3.mjs";
4
+ import { F as Organization, I as Person, W as Service, a as Application, x as Group } from "./vocab-CCAqTuHd.mjs";
5
5
  import { canonicalizePortableUri, formatIri, fromCompatibleEf61Id, isGatewayUrl } from "@fedify/vocab-runtime";
6
6
  import { lookupWebFinger } from "@fedify/webfinger";
7
7
  import { SpanStatusCode, trace } from "@opentelemetry/api";
8
8
  import { domainToASCII, domainToUnicode } from "node:url";
9
9
  //#region deno.json
10
10
  var name = "@fedify/vocab";
11
- var version = "2.5.0-dev.2513+d7ab5950";
11
+ var version = "2.5.0-dev.2516+42d3ed0b";
12
12
  //#endregion
13
13
  //#region src/actor.ts
14
14
  const ACTOR_DISCOVERY_HISTOGRAM_BUCKETS = [
@@ -2,8 +2,8 @@ import "temporal-polyfill";
2
2
  globalThis.addEventListener = () => {};
3
3
  import { n as __exportAll } from "./rolldown-runtime-BWJg4WE8.mjs";
4
4
  import { t as esm_default } from "./esm-BIqRhjGA.mjs";
5
- import { a as normalizeActorHandle, i as isActor, n as getActorHandle, r as getActorTypeName, t as getActorClassByTypeName } from "./actor-DIiC1MSh.mjs";
6
- import { F as Person, P as Organization, U as Service, a as Application, b as Group } from "./vocab-Dwwwbub3.mjs";
5
+ import { a as normalizeActorHandle, i as isActor, n as getActorHandle, r as getActorTypeName, t as getActorClassByTypeName } from "./actor-HAORUnb8.mjs";
6
+ import { F as Organization, I as Person, W as Service, a as Application, x as Group } from "./vocab-CCAqTuHd.mjs";
7
7
  import { createTestMeterProvider, test } from "@fedify/fixture";
8
8
  import { deepStrictEqual, ok, rejects, strictEqual, throws } from "node:assert/strict";
9
9
  //#region ../../node_modules/.pnpm/fast-check@3.23.2/node_modules/fast-check/lib/esm/check/precondition/PreconditionFailure.js
@@ -0,0 +1,292 @@
1
+ import { Temporal } from "temporal-polyfill";
2
+ globalThis.addEventListener = () => {};
3
+ import { A as Note, D as Link, G as Source, H as QuoteRequest, I as Person, U as Reject, f as DataIntegrityProof, h as Endpoints, j as Object$1, t as Accept, u as Create } from "./vocab-CCAqTuHd.mjs";
4
+ import { createTestTracerProvider, mockDocumentLoader, test } from "@fedify/fixture";
5
+ import { deepStrictEqual, notStrictEqual, ok, strictEqual, throws } from "node:assert/strict";
6
+ import { LanguageString } from "@fedify/vocab-runtime";
7
+ import { Buffer } from "node:buffer";
8
+ //#region src/deep-clone.test.ts
9
+ const options = { contextLoader: mockDocumentLoader };
10
+ function personLoader(name, fetched = []) {
11
+ return async (url) => {
12
+ fetched.push(url);
13
+ return {
14
+ contextUrl: null,
15
+ documentUrl: url,
16
+ document: {
17
+ "@context": "https://www.w3.org/ns/activitystreams",
18
+ id: url,
19
+ type: "Person",
20
+ name
21
+ }
22
+ };
23
+ };
24
+ }
25
+ for (const hydrateOriginal of [false, true]) test(`deepClone() isolates embedded quote hydration (${hydrateOriginal})`, async () => {
26
+ const original = await QuoteRequest.fromJsonLd({
27
+ "@context": ["https://www.w3.org/ns/activitystreams", { QuoteRequest: "https://w3id.org/fep/044f#QuoteRequest" }],
28
+ id: "https://a.example/requests/1",
29
+ type: "QuoteRequest",
30
+ instrument: {
31
+ id: "https://a.example/notes/1",
32
+ type: "Note",
33
+ attributedTo: "https://a.example/alice",
34
+ content: "Quoted"
35
+ }
36
+ }, {
37
+ ...options,
38
+ documentLoader: personLoader("Alice")
39
+ });
40
+ const copy = original.deepClone();
41
+ const sourceNote = await original.getInstrument();
42
+ const copyNote = await copy.getInstrument();
43
+ ok(sourceNote instanceof Note && copyNote instanceof Note);
44
+ notStrictEqual(copyNote, sourceNote);
45
+ strictEqual((await (hydrateOriginal ? sourceNote : copyNote).getAttribution())?.name, "Alice");
46
+ for (const Wrapper of [Accept, Reject]) strictEqual((await new Wrapper({ object: hydrateOriginal ? copy : original }).toJsonLd(options)).object.instrument.attributedTo, "https://a.example/alice");
47
+ strictEqual(await original.getInstrument(), sourceNote);
48
+ strictEqual(await copy.getInstrument(), copyNote);
49
+ });
50
+ test("deepClone() copies replacements and preserves graph aliases", async () => {
51
+ const id = new URL("https://example.com/notes/1");
52
+ const child = new Note({
53
+ id,
54
+ url: id,
55
+ content: "Child"
56
+ });
57
+ const source = new Create({
58
+ object: child,
59
+ attachments: [child]
60
+ });
61
+ const copy = source.deepClone({ objects: [child, child] });
62
+ const objects = await Array.fromAsync(copy.getObjects());
63
+ const attachment = (await Array.fromAsync(copy.getAttachments()))[0];
64
+ strictEqual(objects[0], objects[1]);
65
+ strictEqual(objects[0], attachment);
66
+ notStrictEqual(objects[0], child);
67
+ strictEqual(objects[0].id, objects[0].url);
68
+ notStrictEqual(objects[0].id, id);
69
+ objects[0].id.pathname = "/changed";
70
+ strictEqual(id.pathname, "/notes/1");
71
+ strictEqual(await source.getObject(), child);
72
+ const backReference = source.deepClone({ object: source });
73
+ const snapshot = await backReference.getObject();
74
+ ok(snapshot instanceof Create);
75
+ notStrictEqual(snapshot, source);
76
+ notStrictEqual(snapshot, backReference);
77
+ ok(await snapshot.getObject() instanceof Note);
78
+ await backReference.toJsonLd(options);
79
+ });
80
+ test("deepClone() copies non-entity vocabulary objects and standalone roots", () => {
81
+ const endpoint = new URL("https://example.com/inbox");
82
+ const endpoints = new Endpoints({ sharedInbox: endpoint });
83
+ const source = new Source({ content: "Markdown" });
84
+ const copy = new Person({
85
+ endpoints,
86
+ source
87
+ }).deepClone();
88
+ notStrictEqual(copy.endpoints, endpoints);
89
+ notStrictEqual(copy.source, source);
90
+ notStrictEqual(copy.endpoints.sharedInbox, endpoint);
91
+ copy.endpoints.sharedInbox.pathname = "/copied";
92
+ strictEqual(endpoint.pathname, "/inbox");
93
+ const link = new Link({ href: endpoint }).deepClone();
94
+ notStrictEqual(link.href, endpoint);
95
+ strictEqual(link.href.href, endpoint.href);
96
+ });
97
+ test("deepClone() copies byte arrays including Buffer storage", async () => {
98
+ for (const bytes of [new Uint8Array([
99
+ 1,
100
+ 2,
101
+ 3
102
+ ]), Buffer.from([
103
+ 1,
104
+ 2,
105
+ 3
106
+ ])]) {
107
+ const proof = new DataIntegrityProof({ proofValue: bytes });
108
+ const copiedProof = await new Note({ proof }).deepClone().getProof();
109
+ ok(copiedProof instanceof DataIntegrityProof);
110
+ notStrictEqual(copiedProof, proof);
111
+ notStrictEqual(copiedProof.proofValue, bytes);
112
+ copiedProof.proofValue[0] = 9;
113
+ strictEqual(bytes[0], 1);
114
+ bytes[1] = 8;
115
+ strictEqual(copiedProof.proofValue[1], 2);
116
+ }
117
+ });
118
+ test("deepClone() shares immutable scalars and preserves sparse arrays", () => {
119
+ const content = new LanguageString("Hello", "en");
120
+ const published = Temporal.Instant.from("2026-10-27T00:00:00Z");
121
+ const names = new Array(3);
122
+ names[2] = "Kept";
123
+ const source = new Note({
124
+ names,
125
+ content,
126
+ published
127
+ });
128
+ const copy = source.deepClone();
129
+ strictEqual(copy.content, content);
130
+ strictEqual(copy.published, published);
131
+ deepStrictEqual(copy.names, source.names);
132
+ strictEqual(0 in copy.names, false);
133
+ copy.names.push("Copy only");
134
+ strictEqual(source.names.length, 3);
135
+ });
136
+ test("deepClone() retains node defaults and overrides only the root", async () => {
137
+ const fetched = [];
138
+ const [rootTracer, rootSpans] = createTestTracerProvider();
139
+ const [childTracer, childSpans] = createTestTracerProvider();
140
+ const child = new Note({ attribution: new URL("https://example.com/child-actor") }, {
141
+ ...options,
142
+ documentLoader: personLoader("Child", fetched),
143
+ tracerProvider: childTracer
144
+ });
145
+ const source = new Create({
146
+ actor: new URL("https://example.com/root-actor"),
147
+ object: child
148
+ }, {
149
+ ...options,
150
+ documentLoader: personLoader("Root", fetched),
151
+ tracerProvider: rootTracer
152
+ });
153
+ const copy = source.deepClone({}, { documentLoader: personLoader("Override") });
154
+ strictEqual((await copy.getActor())?.name, "Override");
155
+ const copiedChild = await copy.getObject();
156
+ ok(copiedChild instanceof Note);
157
+ strictEqual((await copiedChild.getAttribution())?.name, "Child");
158
+ strictEqual((await source.getActor())?.name, "Root");
159
+ deepStrictEqual(fetched, ["https://example.com/child-actor", "https://example.com/root-actor"]);
160
+ strictEqual(rootSpans.getSpans("activitypub.lookup_object").length, 2);
161
+ strictEqual(childSpans.getSpans("activitypub.lookup_object").length, 1);
162
+ });
163
+ test("deepClone() preserves origin checks and isolates hydrated trust", async () => {
164
+ let fetches = 0;
165
+ const original = await Create.fromJsonLd({
166
+ "@context": "https://www.w3.org/ns/activitystreams",
167
+ id: "https://a.example/create",
168
+ type: "Create",
169
+ object: {
170
+ id: "https://b.example/note",
171
+ type: "Note",
172
+ content: "Embedded"
173
+ }
174
+ }, {
175
+ ...options,
176
+ documentLoader: async (url) => {
177
+ fetches++;
178
+ return {
179
+ contextUrl: null,
180
+ documentUrl: url,
181
+ document: {
182
+ "@context": "https://www.w3.org/ns/activitystreams",
183
+ id: url,
184
+ type: "Note",
185
+ content: "Fetched"
186
+ }
187
+ };
188
+ }
189
+ });
190
+ strictEqual((await original.deepClone().getObject())?.content, "Fetched");
191
+ strictEqual(fetches, 1);
192
+ strictEqual((await original.getObject({ crossOrigin: "trust" }))?.content, "Embedded");
193
+ strictEqual((await original.getObject())?.content, "Fetched");
194
+ strictEqual(fetches, 2);
195
+ });
196
+ test("deepClone() keeps base URLs and discards cached JSON-LD", async () => {
197
+ const source = await Note.fromJsonLd({
198
+ "@context": ["https://www.w3.org/ns/activitystreams", { extension: "https://example.com/extension" }],
199
+ type: "Note",
200
+ id: "./note",
201
+ attributedTo: "./alice",
202
+ extension: "received only"
203
+ }, {
204
+ ...options,
205
+ baseUrl: new URL("https://example.com/posts/"),
206
+ documentLoader: personLoader("Alice")
207
+ });
208
+ const copy = source.deepClone({ content: "Copy" });
209
+ strictEqual(copy.id.href, "https://example.com/posts/note");
210
+ strictEqual((await copy.getAttribution())?.id?.href, "https://example.com/posts/alice");
211
+ const json = await copy.toJsonLd(options);
212
+ strictEqual(json.content, "Copy");
213
+ strictEqual(json.extension, void 0);
214
+ strictEqual((await source.toJsonLd()).extension, "received only");
215
+ });
216
+ test("deepClone() validates replacements through clone() only", () => {
217
+ const source = new Note({ content: "Source" });
218
+ for (const values of [
219
+ { id: 42 },
220
+ {
221
+ name: "one",
222
+ names: ["two"]
223
+ },
224
+ { names: [42] }
225
+ ]) throws(() => source.deepClone(values), TypeError);
226
+ function values(counter) {
227
+ return Object.create({ get content() {
228
+ counter.reads++;
229
+ return "Inherited";
230
+ } });
231
+ }
232
+ const shallowReads = { reads: 0 };
233
+ const deepReads = { reads: 0 };
234
+ strictEqual(source.clone(values(shallowReads)).content, "Inherited");
235
+ strictEqual(source.deepClone(values(deepReads)).content, "Inherited");
236
+ strictEqual(deepReads.reads, shallowReads.reads);
237
+ });
238
+ test("deepClone() preserves user subclasses and handles deep graphs", async () => {
239
+ class CustomNote extends Note {}
240
+ const child = new CustomNote({ content: "Child" });
241
+ const copiedChild = await new Create({ object: child }).deepClone().getObject();
242
+ ok(copiedChild instanceof CustomNote);
243
+ notStrictEqual(copiedChild, child);
244
+ let source = new Note({ content: "End" });
245
+ for (let i = 0; i < 3e3; i++) source = new Note({ replyTarget: source });
246
+ let copy = source.deepClone();
247
+ for (let i = 0; i < 3e3; i++) {
248
+ const next = await copy.getReplyTarget();
249
+ ok(next instanceof Note);
250
+ copy = next;
251
+ }
252
+ strictEqual(copy.content, "End");
253
+ });
254
+ test("deepClone() rejects broken subclass clone results", () => {
255
+ class ReturnsSelf extends Note {
256
+ clone() {
257
+ return this;
258
+ }
259
+ }
260
+ const source = new ReturnsSelf({ id: new URL("https://example.com/note") });
261
+ const id = source.id;
262
+ throws(() => source.deepClone(), /fresh, compatible/);
263
+ strictEqual(source.id, id);
264
+ class Incompatible extends Note {
265
+ clone() {
266
+ return new Object$1({});
267
+ }
268
+ }
269
+ throws(() => new Incompatible({}).deepClone(), /fresh, compatible/);
270
+ class ReusesCopy extends Note {
271
+ static copy;
272
+ clone() {
273
+ return ReusesCopy.copy ??= super.clone();
274
+ }
275
+ }
276
+ const first = new ReusesCopy({ content: "First" });
277
+ const second = new ReusesCopy({ content: "Second" });
278
+ throws(() => new Create({ objects: [first, second] }).deepClone(), /fresh, compatible/);
279
+ strictEqual(first.content, "First");
280
+ strictEqual(second.content, "Second");
281
+ class Throws extends Note {
282
+ clone() {
283
+ throw new Error("Copy failed");
284
+ }
285
+ }
286
+ const child = new Throws({ content: "Unchanged" });
287
+ const parent = new Create({ object: child });
288
+ throws(() => parent.deepClone(), /Copy failed/);
289
+ strictEqual(child.content, "Unchanged");
290
+ });
291
+ //#endregion
292
+ export {};
@@ -1,12 +1,12 @@
1
1
  import "temporal-polyfill";
2
2
  globalThis.addEventListener = () => {};
3
3
  import { t as esm_default } from "./esm-BIqRhjGA.mjs";
4
- import { F as Person, M as OrderedCollection, S as Image, c as CollectionPage, k as Note, s as Collection, u as Create } from "./vocab-Dwwwbub3.mjs";
5
- import { r as traverseCollection, t as lookupObject } from "./lookup-B0Rs8ySI.mjs";
4
+ import { A as Note, C as Image, I as Person, N as OrderedCollection, c as CollectionPage, s as Collection, u as Create } from "./vocab-CCAqTuHd.mjs";
5
+ import { r as traverseCollection, t as lookupObject } from "./lookup-B9VbSKaj.mjs";
6
6
  import { t as assertInstanceOf } from "./utils-Df2odC27.mjs";
7
7
  import { createTestTracerProvider, mockDocumentLoader, test } from "@fedify/fixture";
8
8
  import { deepStrictEqual, ok, rejects } from "node:assert/strict";
9
- import { FetchError, getDocumentLoader, parseIri, withGatewayHints } from "@fedify/vocab-runtime";
9
+ import { FetchError, formatIri, getDocumentLoader, parseIri, withGatewayHints } from "@fedify/vocab-runtime";
10
10
  //#region src/gateway.test.ts
11
11
  const did = "did:key:z6Mkabc";
12
12
  const objectId = `ap+ef61://${did}/objects/1`;
@@ -724,6 +724,73 @@ test("getFirst() passes the referrer chain and collection context", async () =>
724
724
  deepStrictEqual(referrer?.referrer?.referrer?.acceptance, "verified");
725
725
  ok(referrer?.referrer?.referrer?.referrer?.object === create);
726
726
  });
727
+ test("deepClone() preserves historical ancestry independently of replacements", async () => {
728
+ const context = Object.freeze({});
729
+ const documentLoader = createLoader({
730
+ [gatewayUrl("https://gw.example", "/actor/outbox")]: portableCollection("/actor/outbox", {
731
+ attributedTo: `ap://${did}/actor`,
732
+ first: {
733
+ id: `ap://${did}/actor/outbox?page=1`,
734
+ type: "OrderedCollectionPage",
735
+ partOf: `ap://${did}/other/outbox`,
736
+ next: `ap://${did}/actor/outbox?page=2`
737
+ }
738
+ }),
739
+ [gatewayUrl("https://gw.example", "/actor/outbox?page=2")]: {
740
+ "@context": "https://www.w3.org/ns/activitystreams",
741
+ id: `ap://${did}/actor/outbox?page=2`,
742
+ type: "OrderedCollectionPage"
743
+ },
744
+ [gatewayUrl("https://gw.example", "/actor")]: {
745
+ "@context": "https://www.w3.org/ns/activitystreams",
746
+ id: `ap://${did}/actor`,
747
+ type: "Person",
748
+ name: "Fetched actor"
749
+ }
750
+ });
751
+ const verifier = createRecordingVerifier(() => ({
752
+ verified: true,
753
+ collectionContext: context
754
+ }));
755
+ const options = {
756
+ documentLoader,
757
+ contextLoader: mockDocumentLoader,
758
+ gateways: ["https://gw.example"],
759
+ verifyPortableObject: verifier
760
+ };
761
+ const actor = await Person.fromJsonLd({
762
+ "@context": "https://www.w3.org/ns/activitystreams",
763
+ id: `ap://${did}/actor`,
764
+ type: "Person",
765
+ outbox: `ap://${did}/actor/outbox`
766
+ }, { contextLoader: mockDocumentLoader });
767
+ const outbox = await actor.getOutbox(options);
768
+ assertInstanceOf(outbox, OrderedCollection);
769
+ const first = await outbox.getFirst(options);
770
+ assertInstanceOf(first, CollectionPage);
771
+ const copy = outbox.deepClone({
772
+ id: parseIri(`ap://${did}/other/outbox`),
773
+ attribution: parseIri(`ap://${did}/different-actor`)
774
+ });
775
+ const copiedFirst = await copy.getFirst(options);
776
+ assertInstanceOf(copiedFirst, CollectionPage);
777
+ ok(copiedFirst !== first);
778
+ await copiedFirst.getNext(options);
779
+ const referrer = verifier.calls.at(-1).options.referrer;
780
+ ok(referrer?.object === copiedFirst);
781
+ const history = referrer.referrer;
782
+ ok(history?.object instanceof OrderedCollection);
783
+ ok(history.object !== copy && history.object !== outbox);
784
+ deepStrictEqual(history.id, outbox.id);
785
+ deepStrictEqual(history.acceptance, void 0);
786
+ deepStrictEqual(history.collectionContext, void 0);
787
+ deepStrictEqual(history.object.attributionId, outbox.attributionId);
788
+ deepStrictEqual(copiedFirst.partOfId, first.partOfId);
789
+ ok(copiedFirst.partOfId.href !== history.id.href);
790
+ ok(history.referrer?.object === actor);
791
+ await history.object.getAttribution(options);
792
+ deepStrictEqual((await outbox.toJsonLd()).attributedTo, formatIri(outbox.attributionId));
793
+ });
727
794
  test("accessors do not trust objects embedded in unsecured collections", async () => {
728
795
  const itemPath = "/objects/1";
729
796
  const options = {
@@ -763,7 +830,7 @@ test("accessors do not trust objects embedded in unsecured collections", async (
763
830
  }))).length, 1);
764
831
  const outbox3 = await (await createPerson()).getOutbox(options);
765
832
  assertInstanceOf(outbox3, Collection);
766
- deepStrictEqual(await Array.fromAsync(outbox3.clone().getItems({
833
+ for (const copy of [outbox3.clone(), outbox3.deepClone()]) deepStrictEqual(await Array.fromAsync(copy.getItems({
767
834
  ...options,
768
835
  documentLoader: createLoader({}),
769
836
  suppressError: true
@@ -1,7 +1,7 @@
1
1
  import "temporal-polyfill";
2
2
  globalThis.addEventListener = () => {};
3
- import { E as Link, F as Person, J as Video, P as Organization, S as Image, U as Service, a as Application, b as Group, k as Note, s as Collection, u as Create, z as Question } from "./vocab-Dwwwbub3.mjs";
4
- import "./src-DblV5ccz.mjs";
3
+ import { A as Note, B as Question, C as Image, D as Link, F as Organization, I as Person, W as Service, Y as Video, a as Application, s as Collection, u as Create, x as Group } from "./vocab-CCAqTuHd.mjs";
4
+ import "./src-sHf6TARh.mjs";
5
5
  import { test } from "@fedify/fixture";
6
6
  import { deepStrictEqual, ok } from "node:assert/strict";
7
7
  import { getDocumentLoader, preloadedContexts } from "@fedify/vocab-runtime";
@@ -1,8 +1,8 @@
1
1
  import { Temporal } from "temporal-polyfill";
2
2
  globalThis.addEventListener = () => {};
3
- import { i as isActor, o as name, s as version } from "./actor-DIiC1MSh.mjs";
3
+ import { i as isActor, o as name, s as version } from "./actor-HAORUnb8.mjs";
4
4
  import { t as getTypeId } from "./type-BMdjm4Eg.mjs";
5
- import { A as Object$1 } from "./vocab-Dwwwbub3.mjs";
5
+ import { j as Object$1 } from "./vocab-CCAqTuHd.mjs";
6
6
  import { canonicalizePortableUri, formatIri, getDocumentLoader, haveSameFe34Origin, haveSameIriOrigin, parseIri } from "@fedify/vocab-runtime";
7
7
  import { lookupWebFinger } from "@fedify/webfinger";
8
8
  import { SpanStatusCode, trace } from "@opentelemetry/api";
@@ -1,8 +1,8 @@
1
1
  import "temporal-polyfill";
2
2
  globalThis.addEventListener = () => {};
3
3
  import { t as esm_default } from "./esm-BIqRhjGA.mjs";
4
- import { A as Object$1, F as Person, k as Note, s as Collection } from "./vocab-Dwwwbub3.mjs";
5
- import { n as lookupObserver, r as traverseCollection, t as lookupObject } from "./lookup-B0Rs8ySI.mjs";
4
+ import { A as Note, I as Person, j as Object$1, s as Collection } from "./vocab-CCAqTuHd.mjs";
5
+ import { n as lookupObserver, r as traverseCollection, t as lookupObject } from "./lookup-B9VbSKaj.mjs";
6
6
  import { t as assertInstanceOf } from "./utils-Df2odC27.mjs";
7
7
  import { createTestMeterProvider, createTestTracerProvider, mockDocumentLoader, test } from "@fedify/fixture";
8
8
  import { deepStrictEqual, equal, ok, rejects } from "node:assert/strict";
@@ -1,9 +1,9 @@
1
1
  import "temporal-polyfill";
2
2
  globalThis.addEventListener = () => {};
3
3
  import { t as esm_default } from "./esm-BIqRhjGA.mjs";
4
- import { n as getActorHandle } from "./actor-DIiC1MSh.mjs";
5
- import { F as Person } from "./vocab-Dwwwbub3.mjs";
6
- import { t as lookupObject } from "./lookup-B0Rs8ySI.mjs";
4
+ import { n as getActorHandle } from "./actor-HAORUnb8.mjs";
5
+ import { I as Person } from "./vocab-CCAqTuHd.mjs";
6
+ import { t as lookupObject } from "./lookup-B9VbSKaj.mjs";
7
7
  import { t as assertInstanceOf } from "./utils-Df2odC27.mjs";
8
8
  import { mockDocumentLoader, test } from "@fedify/fixture";
9
9
  import { deepStrictEqual, equal, rejects } from "node:assert/strict";
@@ -1,6 +1,6 @@
1
1
  import "temporal-polyfill";
2
2
  globalThis.addEventListener = () => {};
3
- import { M as OrderedCollection, Z as vocab_exports, i as Announce, k as Note, u as Create, z as Question } from "./vocab-Dwwwbub3.mjs";
3
+ import { A as Note, B as Question, N as OrderedCollection, Q as vocab_exports, i as Announce, u as Create } from "./vocab-CCAqTuHd.mjs";
4
4
  import { mockDocumentLoader, test } from "@fedify/fixture";
5
5
  import { deepStrictEqual, ok } from "node:assert/strict";
6
6
  import { isMarkerSafeContext, retainSignedRepresentation } from "@fedify/vocab-runtime/internal/signed-representation";
@@ -135,6 +135,20 @@ test("a clone does not inherit a retained signed representation", async () => {
135
135
  deepStrictEqual(embedded["@context"], void 0);
136
136
  deepStrictEqual(embedded.content, "Changed");
137
137
  });
138
+ test("deepClone() drops retained signed representations at every level", async () => {
139
+ const note = retainedNote();
140
+ const original = new Create({ object: note });
141
+ retainSignedRepresentation(original, {
142
+ "@context": "https://www.w3.org/ns/activitystreams",
143
+ type: "Create",
144
+ content: "Retained root only"
145
+ });
146
+ const json = await new Create({ object: original.deepClone() }).toJsonLd(options);
147
+ deepStrictEqual(json.object.content, void 0);
148
+ deepStrictEqual(json.object.object.content, "Hello");
149
+ deepStrictEqual(json.object.object.proof, void 0);
150
+ deepStrictEqual((await new Create({ object: note }).toJsonLd(options)).object, securedNote);
151
+ });
138
152
  test("every generated default context keeps placeholders recoverable", async () => {
139
153
  const classes = Object.values(vocab_exports).filter((value) => typeof value === "function" && value.typeId instanceof URL);
140
154
  ok(classes.length > 0);