@fedify/vocab 2.2.0-dev.731 → 2.2.0-dev.768

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 (49) hide show
  1. package/deno.json +1 -1
  2. package/dist/mod.cjs +3371 -472
  3. package/dist/mod.d.cts +618 -6
  4. package/dist/mod.d.ts +618 -6
  5. package/dist/mod.js +3368 -473
  6. package/dist-tests/actor.test.mjs +2 -2
  7. package/dist-tests/announce.yaml +8 -0
  8. package/dist-tests/article.yaml +28 -0
  9. package/dist-tests/chatmessage.yaml +28 -0
  10. package/dist-tests/collection.yaml +8 -0
  11. package/dist-tests/collectionpage.yaml +8 -0
  12. package/dist-tests/create.yaml +8 -0
  13. package/dist-tests/delete.yaml +8 -0
  14. package/dist-tests/{deno-D3oW1uY5.mjs → deno-BK-iAbfe.mjs} +2 -2
  15. package/dist-tests/interactionpolicy.yaml +16 -2
  16. package/dist-tests/lookup.test.mjs +2 -2
  17. package/dist-tests/note.yaml +28 -0
  18. package/dist-tests/object.yaml +3 -3
  19. package/dist-tests/orderedcollection.yaml +8 -0
  20. package/dist-tests/orderedcollectionpage.yaml +8 -0
  21. package/dist-tests/question.yaml +28 -0
  22. package/dist-tests/quoteauthorization.yaml +39 -0
  23. package/dist-tests/quoterequest.yaml +47 -0
  24. package/dist-tests/tombstone.yaml +10 -0
  25. package/dist-tests/type.test.mjs +10 -1
  26. package/dist-tests/update.yaml +8 -0
  27. package/dist-tests/{vocab-CGZuHaxe.mjs → vocab-DKp-OcRQ.mjs} +3372 -473
  28. package/dist-tests/vocab.test.mjs +356 -42
  29. package/package.json +4 -4
  30. package/src/__snapshots__/vocab.test.ts.snap +327 -15
  31. package/src/announce.yaml +8 -0
  32. package/src/article.yaml +28 -0
  33. package/src/chatmessage.yaml +28 -0
  34. package/src/collection.yaml +8 -0
  35. package/src/collectionpage.yaml +8 -0
  36. package/src/create.yaml +8 -0
  37. package/src/delete.yaml +8 -0
  38. package/src/interactionpolicy.yaml +16 -2
  39. package/src/note.yaml +28 -0
  40. package/src/object.yaml +3 -3
  41. package/src/orderedcollection.yaml +8 -0
  42. package/src/orderedcollectionpage.yaml +8 -0
  43. package/src/question.yaml +28 -0
  44. package/src/quoteauthorization.yaml +39 -0
  45. package/src/quoterequest.yaml +47 -0
  46. package/src/tombstone.yaml +10 -0
  47. package/src/type.test.ts +17 -1
  48. package/src/update.yaml +8 -0
  49. package/src/vocab.test.ts +498 -40
package/src/vocab.test.ts CHANGED
@@ -4,6 +4,7 @@ import {
4
4
  LanguageString,
5
5
  parseDecimal,
6
6
  } from "@fedify/vocab-runtime";
7
+ import { configure, type LogRecord, reset } from "@logtape/logtape";
7
8
  import {
8
9
  areAllScalarTypes,
9
10
  loadSchemaFiles,
@@ -27,9 +28,12 @@ import {
27
28
  Create,
28
29
  CryptographicKey,
29
30
  type DataIntegrityProof,
31
+ Delete,
30
32
  Endpoints,
31
33
  Follow,
32
34
  Hashtag,
35
+ InteractionPolicy,
36
+ InteractionRule,
33
37
  Link,
34
38
  Note,
35
39
  Object,
@@ -37,9 +41,91 @@ import {
37
41
  Person,
38
42
  Place,
39
43
  Question,
44
+ QuoteAuthorization,
45
+ QuoteRequest,
40
46
  Source,
47
+ Tombstone,
41
48
  } from "./vocab.ts";
42
49
 
50
+ const NOTE_QUOTE_CONTEXT = [
51
+ "https://www.w3.org/ns/activitystreams",
52
+ "https://w3id.org/security/data-integrity/v1",
53
+ "https://gotosocial.org/ns",
54
+ {
55
+ Emoji: "toot:Emoji",
56
+ Hashtag: "as:Hashtag",
57
+ _misskey_quote: "misskey:_misskey_quote",
58
+ QuoteAuthorization: "https://w3id.org/fep/044f#QuoteAuthorization",
59
+ fedibird: "http://fedibird.com/ns#",
60
+ misskey: "https://misskey-hub.net/ns#",
61
+ quote: {
62
+ "@id": "https://w3id.org/fep/044f#quote",
63
+ "@type": "@id",
64
+ },
65
+ quoteAuthorization: {
66
+ "@id": "https://w3id.org/fep/044f#quoteAuthorization",
67
+ "@type": "@id",
68
+ },
69
+ quoteUri: "fedibird:quoteUri",
70
+ quoteUrl: "as:quoteUrl",
71
+ sensitive: "as:sensitive",
72
+ toot: "http://joinmastodon.org/ns#",
73
+ emojiReactions: {
74
+ "@id": "fedibird:emojiReactions",
75
+ "@type": "@id",
76
+ },
77
+ },
78
+ ] as const;
79
+
80
+ const QUOTE_REQUEST_CONTEXT = [
81
+ "https://w3id.org/identity/v1",
82
+ "https://www.w3.org/ns/activitystreams",
83
+ "https://w3id.org/security/data-integrity/v1",
84
+ "https://gotosocial.org/ns",
85
+ {
86
+ ...NOTE_QUOTE_CONTEXT[3],
87
+ ChatMessage: "http://litepub.social/ns#ChatMessage",
88
+ QuoteRequest: "https://w3id.org/fep/044f#QuoteRequest",
89
+ votersCount: {
90
+ "@id": "toot:votersCount",
91
+ "@type": "http://www.w3.org/2001/XMLSchema#nonNegativeInteger",
92
+ },
93
+ },
94
+ ] as const;
95
+
96
+ const DELETE_QUOTE_REQUEST_CONTEXT = [
97
+ "https://w3id.org/identity/v1",
98
+ "https://www.w3.org/ns/activitystreams",
99
+ "https://w3id.org/security/data-integrity/v1",
100
+ "https://gotosocial.org/ns",
101
+ {
102
+ ChatMessage: "http://litepub.social/ns#ChatMessage",
103
+ Emoji: "toot:Emoji",
104
+ Hashtag: "as:Hashtag",
105
+ QuoteAuthorization: "https://w3id.org/fep/044f#QuoteAuthorization",
106
+ QuoteRequest: "https://w3id.org/fep/044f#QuoteRequest",
107
+ _misskey_quote: "misskey:_misskey_quote",
108
+ fedibird: "http://fedibird.com/ns#",
109
+ misskey: "https://misskey-hub.net/ns#",
110
+ quote: {
111
+ "@id": "https://w3id.org/fep/044f#quote",
112
+ "@type": "@id",
113
+ },
114
+ quoteAuthorization: {
115
+ "@id": "https://w3id.org/fep/044f#quoteAuthorization",
116
+ "@type": "@id",
117
+ },
118
+ quoteUri: "fedibird:quoteUri",
119
+ quoteUrl: "as:quoteUrl",
120
+ sensitive: "as:sensitive",
121
+ toot: "http://joinmastodon.org/ns#",
122
+ votersCount: {
123
+ "@id": "toot:votersCount",
124
+ "@type": "http://www.w3.org/2001/XMLSchema#nonNegativeInteger",
125
+ },
126
+ },
127
+ ] as const;
128
+
43
129
  test("new Object()", () => {
44
130
  const obj = new Object({
45
131
  name: "Test",
@@ -246,26 +332,7 @@ test("Note.toJsonLd()", async () => {
246
332
  ],
247
333
  });
248
334
  deepStrictEqual(await note.toJsonLd({ contextLoader: mockDocumentLoader }), {
249
- "@context": [
250
- "https://www.w3.org/ns/activitystreams",
251
- "https://w3id.org/security/data-integrity/v1",
252
- "https://gotosocial.org/ns",
253
- {
254
- Emoji: "toot:Emoji",
255
- Hashtag: "as:Hashtag",
256
- _misskey_quote: "misskey:_misskey_quote",
257
- fedibird: "http://fedibird.com/ns#",
258
- misskey: "https://misskey-hub.net/ns#",
259
- quoteUri: "fedibird:quoteUri",
260
- quoteUrl: "as:quoteUrl",
261
- sensitive: "as:sensitive",
262
- toot: "http://joinmastodon.org/ns#",
263
- emojiReactions: {
264
- "@id": "fedibird:emojiReactions",
265
- "@type": "@id",
266
- },
267
- },
268
- ],
335
+ "@context": NOTE_QUOTE_CONTEXT,
269
336
  tag: {
270
337
  "@context": [
271
338
  "https://www.w3.org/ns/activitystreams",
@@ -665,6 +732,133 @@ test("Person.toJsonLd()", async () => {
665
732
  });
666
733
  });
667
734
 
735
+ test("Tombstone.toJsonLd() serializes formerType", async () => {
736
+ const deleted = Temporal.Instant.from("2024-01-15T00:00:00Z");
737
+ const tombstone = new Tombstone({
738
+ id: new URL("https://example.com/users/alice"),
739
+ formerType: Person,
740
+ deleted,
741
+ });
742
+
743
+ deepStrictEqual(
744
+ await tombstone.toJsonLd({ contextLoader: mockDocumentLoader }),
745
+ {
746
+ "@context": [
747
+ "https://www.w3.org/ns/activitystreams",
748
+ "https://w3id.org/security/data-integrity/v1",
749
+ "https://gotosocial.org/ns",
750
+ ],
751
+ id: "https://example.com/users/alice",
752
+ type: "Tombstone",
753
+ formerType: "as:Person",
754
+ deleted: "2024-01-15T00:00:00Z",
755
+ },
756
+ );
757
+
758
+ const expanded = await tombstone.toJsonLd({
759
+ format: "expand",
760
+ contextLoader: mockDocumentLoader,
761
+ }) as Record<string, unknown>[];
762
+ deepStrictEqual(expanded, [{
763
+ "@id": "https://example.com/users/alice",
764
+ "@type": ["https://www.w3.org/ns/activitystreams#Tombstone"],
765
+ "https://www.w3.org/ns/activitystreams#formerType": [{
766
+ "@id": "https://www.w3.org/ns/activitystreams#Person",
767
+ }],
768
+ "https://www.w3.org/ns/activitystreams#deleted": [{
769
+ "@type": "http://www.w3.org/2001/XMLSchema#dateTime",
770
+ "@value": "2024-01-15T00:00:00Z",
771
+ }],
772
+ }]);
773
+ });
774
+
775
+ test("Tombstone.fromJsonLd() restores formerType", async () => {
776
+ const tombstone = await Tombstone.fromJsonLd({
777
+ "@context": [
778
+ "https://www.w3.org/ns/activitystreams",
779
+ "https://w3id.org/security/data-integrity/v1",
780
+ "https://gotosocial.org/ns",
781
+ ],
782
+ id: "https://example.com/users/alice",
783
+ type: "Tombstone",
784
+ formerType: "as:Person",
785
+ deleted: "2024-01-15T00:00:00Z",
786
+ }, {
787
+ contextLoader: mockDocumentLoader,
788
+ });
789
+
790
+ deepStrictEqual(tombstone.formerType, Person);
791
+ deepStrictEqual(tombstone.formerTypes, [Person]);
792
+ deepStrictEqual(
793
+ tombstone.deleted,
794
+ Temporal.Instant.from("2024-01-15T00:00:00Z"),
795
+ );
796
+ });
797
+
798
+ test("Tombstone.fromJsonLd() ignores unknown formerType values", async () => {
799
+ const records: LogRecord[] = [];
800
+ await reset();
801
+ try {
802
+ await configure({
803
+ sinks: {
804
+ buffer(record: LogRecord): void {
805
+ records.push(record);
806
+ },
807
+ },
808
+ filters: {},
809
+ loggers: [{ category: [], sinks: ["buffer"] }],
810
+ });
811
+
812
+ const tombstone = await Tombstone.fromJsonLd({
813
+ "@id": "https://example.com/users/alice",
814
+ "@type": ["https://www.w3.org/ns/activitystreams#Tombstone"],
815
+ "https://www.w3.org/ns/activitystreams#formerType": [{
816
+ "@id": "https://example.com/ns#Widget",
817
+ }],
818
+ "https://www.w3.org/ns/activitystreams#deleted": [{
819
+ "@type": "http://www.w3.org/2001/XMLSchema#dateTime",
820
+ "@value": "2024-01-15T00:00:00Z",
821
+ }],
822
+ });
823
+
824
+ deepStrictEqual(tombstone.formerTypes, []);
825
+ deepStrictEqual(
826
+ tombstone.deleted,
827
+ Temporal.Instant.from("2024-01-15T00:00:00Z"),
828
+ );
829
+ deepStrictEqual(
830
+ records.some((record) =>
831
+ record.rawMessage ===
832
+ "Ignoring unknown vocabulary entity type reference: {typeId}" &&
833
+ record.properties.typeId === "https://example.com/ns#Widget"
834
+ ),
835
+ true,
836
+ );
837
+ } finally {
838
+ await reset();
839
+ }
840
+ });
841
+
842
+ test("Tombstone.fromJsonLd() ignores malformed formerType values", async () => {
843
+ const tombstone = await Tombstone.fromJsonLd({
844
+ "@id": "https://example.com/users/alice",
845
+ "@type": ["https://www.w3.org/ns/activitystreams#Tombstone"],
846
+ "https://www.w3.org/ns/activitystreams#formerType": [{
847
+ "@value": "Widget",
848
+ }],
849
+ "https://www.w3.org/ns/activitystreams#deleted": [{
850
+ "@type": "http://www.w3.org/2001/XMLSchema#dateTime",
851
+ "@value": "2024-01-15T00:00:00Z",
852
+ }],
853
+ });
854
+
855
+ deepStrictEqual(tombstone.formerTypes, []);
856
+ deepStrictEqual(
857
+ tombstone.deleted,
858
+ Temporal.Instant.from("2024-01-15T00:00:00Z"),
859
+ );
860
+ });
861
+
668
862
  test("Endpoints.toJsonLd() omits type", async () => {
669
863
  const ep = new Endpoints({
670
864
  sharedInbox: new URL("https://example.com/inbox"),
@@ -1072,26 +1266,7 @@ test("Note.quoteUrl", async () => {
1072
1266
  quoteUrl: new URL("https://example.com/object"),
1073
1267
  });
1074
1268
  const expected = {
1075
- "@context": [
1076
- "https://www.w3.org/ns/activitystreams",
1077
- "https://w3id.org/security/data-integrity/v1",
1078
- "https://gotosocial.org/ns",
1079
- {
1080
- Emoji: "toot:Emoji",
1081
- Hashtag: "as:Hashtag",
1082
- _misskey_quote: "misskey:_misskey_quote",
1083
- fedibird: "http://fedibird.com/ns#",
1084
- misskey: "https://misskey-hub.net/ns#",
1085
- quoteUri: "fedibird:quoteUri",
1086
- quoteUrl: "as:quoteUrl",
1087
- sensitive: "as:sensitive",
1088
- toot: "http://joinmastodon.org/ns#",
1089
- emojiReactions: {
1090
- "@id": "fedibird:emojiReactions",
1091
- "@type": "@id",
1092
- },
1093
- },
1094
- ],
1269
+ "@context": NOTE_QUOTE_CONTEXT,
1095
1270
  _misskey_quote: "https://example.com/object",
1096
1271
  quoteUri: "https://example.com/object",
1097
1272
  quoteUrl: "https://example.com/object",
@@ -1128,6 +1303,288 @@ test("Note.quoteUrl", async () => {
1128
1303
  deepStrictEqual(loaded3.quoteUrl, new URL("https://example.com/object3"));
1129
1304
  });
1130
1305
 
1306
+ test("Note.quote", async () => {
1307
+ const note = new Note({
1308
+ quote: new URL("https://example.com/object"),
1309
+ });
1310
+ const expected = {
1311
+ "@context": NOTE_QUOTE_CONTEXT,
1312
+ quote: "https://example.com/object",
1313
+ type: "Note",
1314
+ };
1315
+ deepStrictEqual(await note.toJsonLd(), expected);
1316
+ deepStrictEqual(await note.toJsonLd({ format: "compact" }), expected);
1317
+
1318
+ const loaded = await Note.fromJsonLd({
1319
+ "@context": [
1320
+ "https://www.w3.org/ns/activitystreams",
1321
+ {
1322
+ quote: {
1323
+ "@id": "https://w3id.org/fep/044f#quote",
1324
+ "@type": "@id",
1325
+ },
1326
+ },
1327
+ ],
1328
+ type: "Note",
1329
+ quote: "https://example.com/object",
1330
+ });
1331
+ deepStrictEqual(loaded.quoteId, new URL("https://example.com/object"));
1332
+ });
1333
+
1334
+ test("Note.quoteAuthorization", async () => {
1335
+ const note = new Note({
1336
+ quoteAuthorization: new URL("https://example.com/authorizations/1"),
1337
+ });
1338
+ const expected = {
1339
+ "@context": NOTE_QUOTE_CONTEXT,
1340
+ quoteAuthorization: "https://example.com/authorizations/1",
1341
+ type: "Note",
1342
+ };
1343
+ deepStrictEqual(await note.toJsonLd(), expected);
1344
+ deepStrictEqual(await note.toJsonLd({ format: "compact" }), expected);
1345
+
1346
+ const loaded = await Note.fromJsonLd({
1347
+ "@context": [
1348
+ "https://www.w3.org/ns/activitystreams",
1349
+ {
1350
+ QuoteAuthorization: "https://w3id.org/fep/044f#QuoteAuthorization",
1351
+ quoteAuthorization: {
1352
+ "@id": "https://w3id.org/fep/044f#quoteAuthorization",
1353
+ "@type": "@id",
1354
+ },
1355
+ },
1356
+ ],
1357
+ type: "Note",
1358
+ quoteAuthorization: "https://example.com/authorizations/1",
1359
+ });
1360
+ deepStrictEqual(
1361
+ loaded.quoteAuthorizationId,
1362
+ new URL("https://example.com/authorizations/1"),
1363
+ );
1364
+
1365
+ const loadedFromGoToSocialContext = await Note.fromJsonLd({
1366
+ "@context": [
1367
+ "https://www.w3.org/ns/activitystreams",
1368
+ "https://gotosocial.org/ns",
1369
+ ],
1370
+ type: "Note",
1371
+ quoteAuthorization: "https://example.com/authorizations/2",
1372
+ }, {
1373
+ documentLoader: mockDocumentLoader,
1374
+ contextLoader: mockDocumentLoader,
1375
+ });
1376
+ deepStrictEqual(
1377
+ loadedFromGoToSocialContext.quoteAuthorizationId,
1378
+ new URL("https://example.com/authorizations/2"),
1379
+ );
1380
+ });
1381
+
1382
+ test("InteractionPolicy.canQuote", async () => {
1383
+ const note = new Note({
1384
+ interactionPolicy: new InteractionPolicy({
1385
+ canQuote: new InteractionRule({
1386
+ automaticApproval: new URL(
1387
+ "https://www.w3.org/ns/activitystreams#Public",
1388
+ ),
1389
+ }),
1390
+ }),
1391
+ });
1392
+ const expected = {
1393
+ "@context": NOTE_QUOTE_CONTEXT,
1394
+ interactionPolicy: {
1395
+ canQuote: {
1396
+ automaticApproval: "as:Public",
1397
+ },
1398
+ },
1399
+ type: "Note",
1400
+ };
1401
+ deepStrictEqual(
1402
+ await note.toJsonLd({ contextLoader: mockDocumentLoader }),
1403
+ expected,
1404
+ );
1405
+
1406
+ const loaded = await Note.fromJsonLd(expected, {
1407
+ documentLoader: mockDocumentLoader,
1408
+ contextLoader: mockDocumentLoader,
1409
+ });
1410
+ deepStrictEqual(
1411
+ await loaded.toJsonLd({ contextLoader: mockDocumentLoader }),
1412
+ expected,
1413
+ );
1414
+ });
1415
+
1416
+ test("QuoteAuthorization.fromJsonLd()", async () => {
1417
+ const jsonLd = {
1418
+ "@context": [
1419
+ "https://www.w3.org/ns/activitystreams",
1420
+ "https://w3id.org/security/data-integrity/v1",
1421
+ "https://gotosocial.org/ns",
1422
+ {
1423
+ QuoteAuthorization: "https://w3id.org/fep/044f#QuoteAuthorization",
1424
+ },
1425
+ ],
1426
+ type: "QuoteAuthorization",
1427
+ id: "https://example.com/users/alice/stamps/1",
1428
+ attributedTo: "https://example.com/users/alice",
1429
+ interactingObject: "https://example.com/users/bob/statuses/1",
1430
+ interactionTarget: "https://example.com/users/alice/statuses/1",
1431
+ };
1432
+ const authorization = await QuoteAuthorization.fromJsonLd(jsonLd, {
1433
+ documentLoader: mockDocumentLoader,
1434
+ contextLoader: mockDocumentLoader,
1435
+ });
1436
+ assertInstanceOf(authorization, QuoteAuthorization);
1437
+ deepStrictEqual(
1438
+ await authorization.toJsonLd({ contextLoader: mockDocumentLoader }),
1439
+ jsonLd,
1440
+ );
1441
+
1442
+ const loadedFromGoToSocialContext = await QuoteAuthorization.fromJsonLd({
1443
+ "@context": [
1444
+ "https://www.w3.org/ns/activitystreams",
1445
+ "https://gotosocial.org/ns",
1446
+ ],
1447
+ type: "QuoteAuthorization",
1448
+ id: "https://example.com/users/alice/stamps/2",
1449
+ attributedTo: "https://example.com/users/alice",
1450
+ interactingObject: "https://example.com/users/bob/statuses/2",
1451
+ interactionTarget: "https://example.com/users/alice/statuses/2",
1452
+ }, {
1453
+ documentLoader: mockDocumentLoader,
1454
+ contextLoader: mockDocumentLoader,
1455
+ });
1456
+ assertInstanceOf(loadedFromGoToSocialContext, QuoteAuthorization);
1457
+ deepStrictEqual(
1458
+ loadedFromGoToSocialContext.id,
1459
+ new URL("https://example.com/users/alice/stamps/2"),
1460
+ );
1461
+ });
1462
+
1463
+ test("QuoteRequest.toJsonLd()", async () => {
1464
+ const request = new QuoteRequest({
1465
+ object: new URL("https://example.com/users/alice/statuses/1"),
1466
+ instrument: new Note({
1467
+ id: new URL("https://example.com/users/bob/statuses/1"),
1468
+ content: "I am quoting alice's post",
1469
+ quote: new URL("https://example.com/users/alice/statuses/1"),
1470
+ }),
1471
+ });
1472
+ const expected = {
1473
+ "@context": QUOTE_REQUEST_CONTEXT,
1474
+ type: "QuoteRequest",
1475
+ object: "https://example.com/users/alice/statuses/1",
1476
+ instrument: {
1477
+ type: "Note",
1478
+ id: "https://example.com/users/bob/statuses/1",
1479
+ content: "I am quoting alice's post",
1480
+ quote: "https://example.com/users/alice/statuses/1",
1481
+ },
1482
+ };
1483
+ deepStrictEqual(
1484
+ await request.toJsonLd({ contextLoader: mockDocumentLoader }),
1485
+ expected,
1486
+ );
1487
+
1488
+ const loaded = await QuoteRequest.fromJsonLd(expected, {
1489
+ documentLoader: mockDocumentLoader,
1490
+ contextLoader: mockDocumentLoader,
1491
+ });
1492
+ assertInstanceOf(loaded, QuoteRequest);
1493
+ deepStrictEqual(
1494
+ await loaded.toJsonLd({ contextLoader: mockDocumentLoader }),
1495
+ expected,
1496
+ );
1497
+
1498
+ const loadedFromGoToSocialContext = await QuoteRequest.fromJsonLd({
1499
+ "@context": [
1500
+ "https://www.w3.org/ns/activitystreams",
1501
+ "https://gotosocial.org/ns",
1502
+ ],
1503
+ type: "QuoteRequest",
1504
+ object: "https://example.com/users/alice/statuses/3",
1505
+ }, {
1506
+ documentLoader: mockDocumentLoader,
1507
+ contextLoader: mockDocumentLoader,
1508
+ });
1509
+ assertInstanceOf(loadedFromGoToSocialContext, QuoteRequest);
1510
+ deepStrictEqual(
1511
+ loadedFromGoToSocialContext.objectId,
1512
+ new URL("https://example.com/users/alice/statuses/3"),
1513
+ );
1514
+ });
1515
+
1516
+ test("Collection.toJsonLd() compacts embedded QuoteRequest", async () => {
1517
+ const collection = new Collection({
1518
+ items: [
1519
+ new QuoteRequest({
1520
+ object: new URL("https://example.com/users/alice/statuses/1"),
1521
+ }),
1522
+ ],
1523
+ });
1524
+ deepStrictEqual(
1525
+ await collection.toJsonLd({ contextLoader: mockDocumentLoader }),
1526
+ {
1527
+ "@context": [
1528
+ "https://www.w3.org/ns/activitystreams",
1529
+ "https://w3id.org/security/data-integrity/v1",
1530
+ "https://gotosocial.org/ns",
1531
+ {
1532
+ ChatMessage: "http://litepub.social/ns#ChatMessage",
1533
+ Emoji: "toot:Emoji",
1534
+ Hashtag: "as:Hashtag",
1535
+ QuoteAuthorization: "https://w3id.org/fep/044f#QuoteAuthorization",
1536
+ QuoteRequest: "https://w3id.org/fep/044f#QuoteRequest",
1537
+ _misskey_quote: "misskey:_misskey_quote",
1538
+ fedibird: "http://fedibird.com/ns#",
1539
+ misskey: "https://misskey-hub.net/ns#",
1540
+ quote: {
1541
+ "@id": "https://w3id.org/fep/044f#quote",
1542
+ "@type": "@id",
1543
+ },
1544
+ quoteAuthorization: {
1545
+ "@id": "https://w3id.org/fep/044f#quoteAuthorization",
1546
+ "@type": "@id",
1547
+ },
1548
+ quoteUri: "fedibird:quoteUri",
1549
+ quoteUrl: "as:quoteUrl",
1550
+ sensitive: "as:sensitive",
1551
+ toot: "http://joinmastodon.org/ns#",
1552
+ votersCount: "toot:votersCount",
1553
+ emojiReactions: {
1554
+ "@id": "fedibird:emojiReactions",
1555
+ "@type": "@id",
1556
+ },
1557
+ },
1558
+ ],
1559
+ items: {
1560
+ "@context": QUOTE_REQUEST_CONTEXT,
1561
+ object: "https://example.com/users/alice/statuses/1",
1562
+ type: "QuoteRequest",
1563
+ },
1564
+ type: "Collection",
1565
+ },
1566
+ );
1567
+ });
1568
+
1569
+ test("Delete.toJsonLd() compacts embedded QuoteRequest", async () => {
1570
+ const activity = new Delete({
1571
+ object: new QuoteRequest({
1572
+ object: new URL("https://example.com/users/alice/statuses/1"),
1573
+ }),
1574
+ });
1575
+ deepStrictEqual(
1576
+ await activity.toJsonLd({ contextLoader: mockDocumentLoader }),
1577
+ {
1578
+ "@context": DELETE_QUOTE_REQUEST_CONTEXT,
1579
+ object: {
1580
+ object: "https://example.com/users/alice/statuses/1",
1581
+ type: "QuoteRequest",
1582
+ },
1583
+ type: "Delete",
1584
+ },
1585
+ );
1586
+ });
1587
+
1131
1588
  test("Key.publicKey", async () => {
1132
1589
  const jwk = {
1133
1590
  kty: "RSA",
@@ -1948,6 +2405,7 @@ const sampleValues: Record<string, any> = {
1948
2405
  "fedify:multibaseKey": ed25519PublicKey.publicKey,
1949
2406
  "fedify:proofPurpose": "assertionMethod",
1950
2407
  "fedify:units": "m",
2408
+ "fedify:vocabEntityType": Person,
1951
2409
  };
1952
2410
 
1953
2411
  const types: Record<string, TypeSchema> =