@fedify/vocab 2.1.1 → 2.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/deno.json +1 -1
- package/dist/mod.cjs +3873 -5608
- package/dist/mod.d.cts +383 -384
- package/dist/mod.d.ts +383 -384
- package/dist/mod.js +1117 -2853
- package/dist-tests/{actor.test.js → actor.test.mjs} +315 -557
- package/dist-tests/{deno-BUQBaFF5.js → deno-DW1_1YTc.mjs} +66 -145
- package/dist-tests/{lookup.test.js → lookup.test.mjs} +29 -48
- package/dist-tests/type-Cf-vxmre.mjs +9 -0
- package/dist-tests/type.test.mjs +16 -0
- package/dist-tests/{utils-BSWXlrig.js → utils-CE8Dk5hm.mjs} +3 -7
- package/dist-tests/{vocab-uMop7StC.js → vocab-7uCD77Gl.mjs} +1118 -2801
- package/dist-tests/{vocab.test.js → vocab.test.mjs} +100 -158
- package/package.json +6 -6
- package/dist-tests/type-CNuABalk.js +0 -13
- package/dist-tests/type.test.js +0 -24
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import { Activity, Announce, Collection, Create, CryptographicKey, Endpoints, Follow, Hashtag, Link, Note, Object as Object$1, OrderedCollectionPage, Person, Place, Question, Source, vocab_exports } from "./vocab-uMop7StC.js";
|
|
6
|
-
import { assertInstanceOf } from "./utils-BSWXlrig.js";
|
|
1
|
+
import { Temporal } from "@js-temporal/polyfill";
|
|
2
|
+
globalThis.addEventListener = () => {};
|
|
3
|
+
import { _ as Place, a as Create, b as Source, c as Follow, d as Link, f as Note, g as Person, i as Collection, m as OrderedCollectionPage, n as Announce, o as CryptographicKey, p as Object$1, s as Endpoints, t as Activity, u as Hashtag, v as Question, x as vocab_exports } from "./vocab-7uCD77Gl.mjs";
|
|
4
|
+
import { t as assertInstanceOf } from "./utils-CE8Dk5hm.mjs";
|
|
7
5
|
import { mockDocumentLoader, test } from "@fedify/fixture";
|
|
8
6
|
import { deepStrictEqual, notDeepStrictEqual, ok, rejects, throws } from "node:assert/strict";
|
|
9
7
|
import { LanguageString, decodeMultibase } from "@fedify/vocab-runtime";
|
|
10
8
|
import { pascalCase } from "es-toolkit";
|
|
11
9
|
import { areAllScalarTypes, loadSchemaFiles } from "@fedify/vocab-tools";
|
|
12
|
-
|
|
13
10
|
//#region src/vocab.test.ts
|
|
14
11
|
test("new Object()", () => {
|
|
15
12
|
const obj = new Object$1({
|
|
@@ -102,8 +99,7 @@ test("Object.fromJsonLd()", async () => {
|
|
|
102
99
|
const note = await create.getObject();
|
|
103
100
|
assertInstanceOf(note, Note);
|
|
104
101
|
deepStrictEqual(note.content, "Content");
|
|
105
|
-
|
|
106
|
-
assertInstanceOf(empty, Object$1);
|
|
102
|
+
assertInstanceOf(await Object$1.fromJsonLd({}), Object$1);
|
|
107
103
|
await rejects(() => Object$1.fromJsonLd(null), TypeError);
|
|
108
104
|
await rejects(() => Object$1.fromJsonLd(void 0), TypeError);
|
|
109
105
|
});
|
|
@@ -250,8 +246,7 @@ test({
|
|
|
250
246
|
assertInstanceOf(object, Object$1);
|
|
251
247
|
deepStrictEqual(object.id, new URL("https://example.com/object"));
|
|
252
248
|
deepStrictEqual(object.name, "Fetched object");
|
|
253
|
-
|
|
254
|
-
deepStrictEqual(jsonLd, {
|
|
249
|
+
deepStrictEqual(await activity.toJsonLd(), {
|
|
255
250
|
"@context": [
|
|
256
251
|
"https://w3id.org/identity/v1",
|
|
257
252
|
"https://www.w3.org/ns/activitystreams",
|
|
@@ -270,9 +265,8 @@ test({
|
|
|
270
265
|
}
|
|
271
266
|
}
|
|
272
267
|
});
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
const activity3 = await Activity.fromJsonLd({
|
|
268
|
+
deepStrictEqual(await new Activity({ object: new URL("https://example.com/not-found") }).getObject({ suppressError: true }), null);
|
|
269
|
+
const object3 = await (await Activity.fromJsonLd({
|
|
276
270
|
"@context": "https://www.w3.org/ns/activitystreams",
|
|
277
271
|
type: "Create",
|
|
278
272
|
object: {
|
|
@@ -280,8 +274,7 @@ test({
|
|
|
280
274
|
type: "Note",
|
|
281
275
|
content: "Hello world"
|
|
282
276
|
}
|
|
283
|
-
});
|
|
284
|
-
const object3 = await activity3.getObject();
|
|
277
|
+
})).getObject();
|
|
285
278
|
assertInstanceOf(object3, Note);
|
|
286
279
|
deepStrictEqual(await object3.toJsonLd(), {
|
|
287
280
|
"@context": "https://www.w3.org/ns/activitystreams",
|
|
@@ -340,8 +333,7 @@ test("Activity.clone()", async () => {
|
|
|
340
333
|
}), TypeError);
|
|
341
334
|
});
|
|
342
335
|
test("Question.voters", async () => {
|
|
343
|
-
const
|
|
344
|
-
const json = await question.toJsonLd({ format: "compact" });
|
|
336
|
+
const json = await new Question({ voters: 123 }).toJsonLd({ format: "compact" });
|
|
345
337
|
ok(typeof json === "object" && json != null);
|
|
346
338
|
ok("votersCount" in json);
|
|
347
339
|
deepStrictEqual(json["votersCount"], 123);
|
|
@@ -381,19 +373,17 @@ test("Person.fromJsonLd()", async () => {
|
|
|
381
373
|
const publicKey = await person.getPublicKey({ documentLoader: mockDocumentLoader });
|
|
382
374
|
assertInstanceOf(publicKey, CryptographicKey);
|
|
383
375
|
deepStrictEqual(publicKey?.ownerId, new URL("https://todon.eu/users/hongminhee"));
|
|
384
|
-
|
|
376
|
+
deepStrictEqual((await Person.fromJsonLd({
|
|
385
377
|
"@context": ["https://www.w3.org/ns/activitystreams", { alsoKnownAs: {
|
|
386
378
|
"@id": "as:alsoKnownAs",
|
|
387
379
|
"@type": "@id"
|
|
388
380
|
} }],
|
|
389
381
|
"type": "Person",
|
|
390
382
|
"alsoKnownAs": "at://did:plc:x7xdowahlhm5xulzqw4ehv6q"
|
|
391
|
-
});
|
|
392
|
-
deepStrictEqual(person2.aliasId, new URL("at://did%3Aplc%3Ax7xdowahlhm5xulzqw4ehv6q"));
|
|
383
|
+
})).aliasId, new URL("at://did%3Aplc%3Ax7xdowahlhm5xulzqw4ehv6q"));
|
|
393
384
|
});
|
|
394
385
|
test("Person.toJsonLd()", async () => {
|
|
395
|
-
|
|
396
|
-
deepStrictEqual(await person.toJsonLd(), {
|
|
386
|
+
deepStrictEqual(await new Person({ aliases: [new URL("https://example.com/alias")] }).toJsonLd(), {
|
|
397
387
|
"@context": [
|
|
398
388
|
"https://www.w3.org/ns/activitystreams",
|
|
399
389
|
"https://w3id.org/security/v1",
|
|
@@ -443,21 +433,18 @@ test("Endpoints.toJsonLd() omits type", async () => {
|
|
|
443
433
|
ok(!("type" in compact), "compact heuristic output should not have 'type'");
|
|
444
434
|
deepStrictEqual(compact["sharedInbox"], "https://example.com/inbox");
|
|
445
435
|
deepStrictEqual(compact["@context"], "https://www.w3.org/ns/activitystreams");
|
|
446
|
-
|
|
436
|
+
ok(!("@type" in (await ep.toJsonLd({
|
|
447
437
|
format: "expand",
|
|
448
438
|
contextLoader: mockDocumentLoader
|
|
449
|
-
});
|
|
450
|
-
ok(!("
|
|
451
|
-
const compactLib = await ep.toJsonLd({
|
|
439
|
+
}))[0]), "expanded output should not have '@type'");
|
|
440
|
+
ok(!("type" in await ep.toJsonLd({
|
|
452
441
|
format: "compact",
|
|
453
442
|
contextLoader: mockDocumentLoader
|
|
454
|
-
});
|
|
455
|
-
|
|
456
|
-
const restored = await Endpoints.fromJsonLd(compact, {
|
|
443
|
+
})), "compact (library) output should not have 'type'");
|
|
444
|
+
deepStrictEqual(await Endpoints.fromJsonLd(compact, {
|
|
457
445
|
documentLoader: mockDocumentLoader,
|
|
458
446
|
contextLoader: mockDocumentLoader
|
|
459
|
-
});
|
|
460
|
-
deepStrictEqual(restored, ep);
|
|
447
|
+
}), ep);
|
|
461
448
|
});
|
|
462
449
|
test("Source.toJsonLd() omits type", async () => {
|
|
463
450
|
const src = new Source({
|
|
@@ -467,16 +454,14 @@ test("Source.toJsonLd() omits type", async () => {
|
|
|
467
454
|
const compact = await src.toJsonLd();
|
|
468
455
|
ok(!("type" in compact), "compact heuristic output should not have 'type'");
|
|
469
456
|
deepStrictEqual(compact["mediaType"], "text/plain");
|
|
470
|
-
|
|
457
|
+
ok(!("@type" in (await src.toJsonLd({
|
|
471
458
|
format: "expand",
|
|
472
459
|
contextLoader: mockDocumentLoader
|
|
473
|
-
});
|
|
474
|
-
|
|
475
|
-
const restored = await Source.fromJsonLd(compact, {
|
|
460
|
+
}))[0]), "expanded output should not have '@type'");
|
|
461
|
+
deepStrictEqual(await Source.fromJsonLd(compact, {
|
|
476
462
|
documentLoader: mockDocumentLoader,
|
|
477
463
|
contextLoader: mockDocumentLoader
|
|
478
|
-
});
|
|
479
|
-
deepStrictEqual(restored, src);
|
|
464
|
+
}), src);
|
|
480
465
|
});
|
|
481
466
|
test("Endpoints.fromJsonLd() accepts input with @type (backward compat)", async () => {
|
|
482
467
|
const ep = await Endpoints.fromJsonLd({
|
|
@@ -530,32 +515,27 @@ test("Endpoints with all properties set omits type", async () => {
|
|
|
530
515
|
format,
|
|
531
516
|
contextLoader: mockDocumentLoader
|
|
532
517
|
});
|
|
533
|
-
|
|
518
|
+
deepStrictEqual(await Endpoints.fromJsonLd(jsonLd, {
|
|
534
519
|
documentLoader: mockDocumentLoader,
|
|
535
520
|
contextLoader: mockDocumentLoader
|
|
536
|
-
});
|
|
537
|
-
deepStrictEqual(restored, ep, `round-trip failed for format=${format ?? "heuristic"}`);
|
|
521
|
+
}), ep, `round-trip failed for format=${format ?? "heuristic"}`);
|
|
538
522
|
}
|
|
539
523
|
});
|
|
540
524
|
test("Empty Endpoints omits type", async () => {
|
|
541
525
|
const ep = new Endpoints({});
|
|
542
|
-
|
|
543
|
-
ok(!("type" in
|
|
544
|
-
const expanded = await ep.toJsonLd({
|
|
526
|
+
ok(!("type" in await ep.toJsonLd()), "empty compact output should not have 'type'");
|
|
527
|
+
ok(!("@type" in ((await ep.toJsonLd({
|
|
545
528
|
format: "expand",
|
|
546
529
|
contextLoader: mockDocumentLoader
|
|
547
|
-
});
|
|
548
|
-
ok(!("@type" in (expanded[0] ?? {})), "empty expanded output should not have '@type'");
|
|
530
|
+
}))[0] ?? {})), "empty expanded output should not have '@type'");
|
|
549
531
|
});
|
|
550
532
|
test("Empty Source omits type", async () => {
|
|
551
533
|
const src = new Source({});
|
|
552
|
-
|
|
553
|
-
ok(!("type" in
|
|
554
|
-
const expanded = await src.toJsonLd({
|
|
534
|
+
ok(!("type" in await src.toJsonLd()), "empty compact output should not have 'type'");
|
|
535
|
+
ok(!("@type" in ((await src.toJsonLd({
|
|
555
536
|
format: "expand",
|
|
556
537
|
contextLoader: mockDocumentLoader
|
|
557
|
-
});
|
|
558
|
-
ok(!("@type" in (expanded[0] ?? {})), "empty expanded output should not have '@type'");
|
|
538
|
+
}))[0] ?? {})), "empty expanded output should not have '@type'");
|
|
559
539
|
});
|
|
560
540
|
test("Person.toJsonLd() embeds Endpoints without type", async () => {
|
|
561
541
|
const person = new Person({
|
|
@@ -580,11 +560,10 @@ test("Person.toJsonLd() embeds Endpoints without type", async () => {
|
|
|
580
560
|
const expandedEndpoints = expanded[0]["https://www.w3.org/ns/activitystreams#endpoints"]?.[0];
|
|
581
561
|
ok(expandedEndpoints != null, "expanded endpoints should be present");
|
|
582
562
|
ok(!("@type" in expandedEndpoints), "expanded embedded endpoints should not have '@type'");
|
|
583
|
-
|
|
563
|
+
deepStrictEqual((await Person.fromJsonLd(expanded, {
|
|
584
564
|
documentLoader: mockDocumentLoader,
|
|
585
565
|
contextLoader: mockDocumentLoader
|
|
586
|
-
});
|
|
587
|
-
deepStrictEqual(restored2.endpoints?.sharedInbox, person.endpoints?.sharedInbox);
|
|
566
|
+
})).endpoints?.sharedInbox, person.endpoints?.sharedInbox);
|
|
588
567
|
const compactLib = await person.toJsonLd({
|
|
589
568
|
format: "compact",
|
|
590
569
|
contextLoader: mockDocumentLoader,
|
|
@@ -593,21 +572,19 @@ test("Person.toJsonLd() embeds Endpoints without type", async () => {
|
|
|
593
572
|
const endpointsLib = compactLib["endpoints"];
|
|
594
573
|
ok(endpointsLib != null, "compact-lib endpoints should be present");
|
|
595
574
|
ok(!("type" in endpointsLib), "compact-lib endpoints should not have 'type'");
|
|
596
|
-
|
|
575
|
+
deepStrictEqual((await Person.fromJsonLd(compactLib, {
|
|
597
576
|
documentLoader: mockDocumentLoader,
|
|
598
577
|
contextLoader: mockDocumentLoader
|
|
599
|
-
});
|
|
600
|
-
deepStrictEqual(restored3.endpoints?.sharedInbox, person.endpoints?.sharedInbox);
|
|
578
|
+
})).endpoints?.sharedInbox, person.endpoints?.sharedInbox);
|
|
601
579
|
});
|
|
602
580
|
test("Object.toJsonLd() embeds Source without type", async () => {
|
|
603
|
-
const
|
|
581
|
+
const compact = await new Object$1({
|
|
604
582
|
id: new URL("https://example.com/object/1"),
|
|
605
583
|
source: new Source({
|
|
606
584
|
content: "Hello, world!",
|
|
607
585
|
mediaType: "text/plain"
|
|
608
586
|
})
|
|
609
|
-
});
|
|
610
|
-
const compact = await obj.toJsonLd();
|
|
587
|
+
}).toJsonLd();
|
|
611
588
|
const source = compact["source"];
|
|
612
589
|
ok(source != null, "source should be present");
|
|
613
590
|
ok(!("type" in source), "embedded source should not have 'type'");
|
|
@@ -658,11 +635,10 @@ test("Source with LanguageString content omits type", async () => {
|
|
|
658
635
|
});
|
|
659
636
|
const compact = await src.toJsonLd();
|
|
660
637
|
ok(!("type" in compact), "source with LanguageString should not have 'type'");
|
|
661
|
-
|
|
638
|
+
deepStrictEqual(await Source.fromJsonLd(compact, {
|
|
662
639
|
documentLoader: mockDocumentLoader,
|
|
663
640
|
contextLoader: mockDocumentLoader
|
|
664
|
-
});
|
|
665
|
-
deepStrictEqual(restored, src);
|
|
641
|
+
}), src);
|
|
666
642
|
});
|
|
667
643
|
test("Cross-format round-trip for Endpoints", async () => {
|
|
668
644
|
const ep = new Endpoints({
|
|
@@ -670,24 +646,21 @@ test("Cross-format round-trip for Endpoints", async () => {
|
|
|
670
646
|
proxyUrl: new URL("https://example.com/proxy")
|
|
671
647
|
});
|
|
672
648
|
const compact1 = await ep.toJsonLd();
|
|
673
|
-
const
|
|
649
|
+
const expanded = await (await Endpoints.fromJsonLd(compact1, {
|
|
674
650
|
documentLoader: mockDocumentLoader,
|
|
675
651
|
contextLoader: mockDocumentLoader
|
|
676
|
-
})
|
|
677
|
-
const expanded = await restored1.toJsonLd({
|
|
652
|
+
})).toJsonLd({
|
|
678
653
|
format: "expand",
|
|
679
654
|
contextLoader: mockDocumentLoader
|
|
680
655
|
});
|
|
681
|
-
const
|
|
656
|
+
const compact2 = await (await Endpoints.fromJsonLd(expanded, {
|
|
682
657
|
documentLoader: mockDocumentLoader,
|
|
683
658
|
contextLoader: mockDocumentLoader
|
|
684
|
-
});
|
|
685
|
-
|
|
686
|
-
const restored3 = await Endpoints.fromJsonLd(compact2, {
|
|
659
|
+
})).toJsonLd({ contextLoader: mockDocumentLoader });
|
|
660
|
+
deepStrictEqual(await Endpoints.fromJsonLd(compact2, {
|
|
687
661
|
documentLoader: mockDocumentLoader,
|
|
688
662
|
contextLoader: mockDocumentLoader
|
|
689
|
-
});
|
|
690
|
-
deepStrictEqual(restored3, ep);
|
|
663
|
+
}), ep);
|
|
691
664
|
});
|
|
692
665
|
test("Collection.fromJsonLd()", async () => {
|
|
693
666
|
const collection = await Collection.fromJsonLd({
|
|
@@ -742,14 +715,11 @@ test("Note.quoteUrl", async () => {
|
|
|
742
715
|
_misskey_quote: "https://example.com/object2",
|
|
743
716
|
quoteUri: "https://example.com/object3"
|
|
744
717
|
};
|
|
745
|
-
|
|
746
|
-
deepStrictEqual(loaded.quoteUrl, new URL("https://example.com/object"));
|
|
718
|
+
deepStrictEqual((await Note.fromJsonLd(jsonLd)).quoteUrl, new URL("https://example.com/object"));
|
|
747
719
|
delete jsonLd.quoteUrl;
|
|
748
|
-
|
|
749
|
-
deepStrictEqual(loaded2.quoteUrl, new URL("https://example.com/object2"));
|
|
720
|
+
deepStrictEqual((await Note.fromJsonLd(jsonLd)).quoteUrl, new URL("https://example.com/object2"));
|
|
750
721
|
delete jsonLd._misskey_quote;
|
|
751
|
-
|
|
752
|
-
deepStrictEqual(loaded3.quoteUrl, new URL("https://example.com/object3"));
|
|
722
|
+
deepStrictEqual((await Note.fromJsonLd(jsonLd)).quoteUrl, new URL("https://example.com/object3"));
|
|
753
723
|
});
|
|
754
724
|
test("Key.publicKey", async () => {
|
|
755
725
|
const jwk = {
|
|
@@ -760,11 +730,10 @@ test("Key.publicKey", async () => {
|
|
|
760
730
|
key_ops: ["verify"],
|
|
761
731
|
ext: true
|
|
762
732
|
};
|
|
763
|
-
const
|
|
733
|
+
const jsonLd = await new CryptographicKey({ publicKey: await crypto.subtle.importKey("jwk", jwk, {
|
|
764
734
|
name: "RSASSA-PKCS1-v1_5",
|
|
765
735
|
hash: "SHA-256"
|
|
766
|
-
}, true, ["verify"]) });
|
|
767
|
-
const jsonLd = await key.toJsonLd({ contextLoader: mockDocumentLoader });
|
|
736
|
+
}, true, ["verify"]) }).toJsonLd({ contextLoader: mockDocumentLoader });
|
|
768
737
|
deepStrictEqual(jsonLd, {
|
|
769
738
|
"@context": "https://w3id.org/security/v1",
|
|
770
739
|
publicKeyPem: "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxsRuvCkgJtflBTl4OVsm\nnt/J1mQfZasfJtN33dcZ3d1lJroxmgmMu69zjGEAwkNbMQaWNLqC4eogkJaeJ4RR\n5MHYXkL9nNilVoTkjX5BVit3puzs7XJ7WQnKQgQMI+ezn24GHsZ/v1JIo77lerX5\nk4HNwTNVt+yaZVQWaOMR3+6FwziQR6kd0VuG9/a9dgAnz2cEoORRC1i4W7IZaB1s\nZnh1WbHbevlGd72HSXll5rocPIHn8gq6xpBgpHwRphlRsgn4KHaJ6brXDIJjrnQh\nIe/YUBOGj/ImSEXhRwlFerKsoAVnZ0Hwbfa46qk44TAt8CyoPMWmpK6pt0ng4pQ2\nuwIDAQAB\n-----END PUBLIC KEY-----\n",
|
|
@@ -825,8 +794,7 @@ test("Place.fromJsonLd()", async () => {
|
|
|
825
794
|
});
|
|
826
795
|
});
|
|
827
796
|
test("Actor.getOutbox()", async () => {
|
|
828
|
-
const
|
|
829
|
-
const outbox = await person.getOutbox({ documentLoader: mockDocumentLoader });
|
|
797
|
+
const outbox = await new Person({ outbox: new URL("https://example.com/orderedcollectionpage") }).getOutbox({ documentLoader: mockDocumentLoader });
|
|
830
798
|
assertInstanceOf(outbox, OrderedCollectionPage);
|
|
831
799
|
deepStrictEqual(outbox.totalItems, 1);
|
|
832
800
|
});
|
|
@@ -839,21 +807,19 @@ test("Link.fromJsonLd()", async () => {
|
|
|
839
807
|
});
|
|
840
808
|
deepStrictEqual(link.rel, "canonical");
|
|
841
809
|
deepStrictEqual(link.href, new URL("at://did%3Aplc%3Aia76kvnndjutgedggx2ibrem/app.bsky.feed.post/3lyxjjs27jkqg"));
|
|
842
|
-
|
|
810
|
+
deepStrictEqual((await Link.fromJsonLd({
|
|
843
811
|
"@context": "https://www.w3.org/ns/activitystreams",
|
|
844
812
|
"type": "Link",
|
|
845
813
|
"href": "at://bnewbold.bsky.team/app.bsky.feed.post/3jwdwj2ctlk26"
|
|
846
|
-
});
|
|
847
|
-
deepStrictEqual(
|
|
848
|
-
const link3 = await Link.fromJsonLd({
|
|
814
|
+
})).href, new URL("at://bnewbold.bsky.team/app.bsky.feed.post/3jwdwj2ctlk26"));
|
|
815
|
+
deepStrictEqual((await Link.fromJsonLd({
|
|
849
816
|
"@context": "https://www.w3.org/ns/activitystreams",
|
|
850
817
|
"type": "Link",
|
|
851
818
|
"href": "at://did:plc:ia76kvnndjutgedggx2ibrem"
|
|
852
|
-
});
|
|
853
|
-
deepStrictEqual(link3.href, new URL("at://did%3Aplc%3Aia76kvnndjutgedggx2ibrem"));
|
|
819
|
+
})).href, new URL("at://did%3Aplc%3Aia76kvnndjutgedggx2ibrem"));
|
|
854
820
|
});
|
|
855
821
|
test("Person.fromJsonLd() with relative URLs", async () => {
|
|
856
|
-
|
|
822
|
+
deepStrictEqual((await (await Person.fromJsonLd({
|
|
857
823
|
"@context": ["https://www.w3.org/ns/activitystreams", "https://w3id.org/security/v1"],
|
|
858
824
|
id: "https://example.com/ap/actors/019382d3-63d7-7cf7-86e8-91e2551c306c",
|
|
859
825
|
type: "Person",
|
|
@@ -862,14 +828,11 @@ test("Person.fromJsonLd() with relative URLs", async () => {
|
|
|
862
828
|
type: "Image",
|
|
863
829
|
url: "/avatars/test-avatar.jpg"
|
|
864
830
|
}
|
|
865
|
-
}
|
|
866
|
-
const person = await Person.fromJsonLd(json, {
|
|
831
|
+
}, {
|
|
867
832
|
documentLoader: mockDocumentLoader,
|
|
868
833
|
contextLoader: mockDocumentLoader
|
|
869
|
-
});
|
|
870
|
-
|
|
871
|
-
deepStrictEqual(icon?.url, new URL("https://example.com/avatars/test-avatar.jpg"));
|
|
872
|
-
const json2 = {
|
|
834
|
+
})).getIcon())?.url, new URL("https://example.com/avatars/test-avatar.jpg"));
|
|
835
|
+
deepStrictEqual((await (await Person.fromJsonLd({
|
|
873
836
|
"@context": ["https://www.w3.org/ns/activitystreams", "https://w3id.org/security/v1"],
|
|
874
837
|
id: "https://example.com/ap/actors/019382d3-63d7-7cf7-86e8-91e2551c306c",
|
|
875
838
|
type: "Person",
|
|
@@ -879,16 +842,13 @@ test("Person.fromJsonLd() with relative URLs", async () => {
|
|
|
879
842
|
type: "Image",
|
|
880
843
|
url: "/avatars/test-avatar.jpg"
|
|
881
844
|
}
|
|
882
|
-
}
|
|
883
|
-
const person2 = await Person.fromJsonLd(json2, {
|
|
845
|
+
}, {
|
|
884
846
|
documentLoader: mockDocumentLoader,
|
|
885
847
|
contextLoader: mockDocumentLoader
|
|
886
|
-
});
|
|
887
|
-
const icon2 = await person2.getIcon();
|
|
888
|
-
deepStrictEqual(icon2?.url, new URL("https://media.example.com/avatars/test-avatar.jpg"));
|
|
848
|
+
})).getIcon())?.url, new URL("https://media.example.com/avatars/test-avatar.jpg"));
|
|
889
849
|
});
|
|
890
850
|
test("Person.fromJsonLd() with relative URLs and baseUrl", async () => {
|
|
891
|
-
|
|
851
|
+
deepStrictEqual((await (await Person.fromJsonLd({
|
|
892
852
|
"@context": ["https://www.w3.org/ns/activitystreams", "https://w3id.org/security/v1"],
|
|
893
853
|
"id": "https://example.com/ap/actors/019382d3-63d7-7cf7-86e8-91e2551c306c",
|
|
894
854
|
"type": "Person",
|
|
@@ -897,14 +857,11 @@ test("Person.fromJsonLd() with relative URLs and baseUrl", async () => {
|
|
|
897
857
|
"type": "Image",
|
|
898
858
|
"url": "/avatars/test-avatar.jpg"
|
|
899
859
|
}
|
|
900
|
-
}
|
|
901
|
-
const personWithBase = await Person.fromJsonLd(json, {
|
|
860
|
+
}, {
|
|
902
861
|
documentLoader: mockDocumentLoader,
|
|
903
862
|
contextLoader: mockDocumentLoader,
|
|
904
863
|
baseUrl: new URL("https://example.com")
|
|
905
|
-
});
|
|
906
|
-
const icon = await personWithBase.getIcon();
|
|
907
|
-
deepStrictEqual(icon?.url, new URL("https://example.com/avatars/test-avatar.jpg"));
|
|
864
|
+
})).getIcon())?.url, new URL("https://example.com/avatars/test-avatar.jpg"));
|
|
908
865
|
});
|
|
909
866
|
test("FEP-fe34: Trust tracking in object construction", async () => {
|
|
910
867
|
const note = new Note({
|
|
@@ -935,8 +892,7 @@ test("FEP-fe34: Trust tracking in object cloning", () => {
|
|
|
935
892
|
id: new URL("https://example.com/new-note"),
|
|
936
893
|
content: "New content"
|
|
937
894
|
});
|
|
938
|
-
|
|
939
|
-
deepStrictEqual(clonedCreate.objectId, new URL("https://example.com/new-note"));
|
|
895
|
+
deepStrictEqual(create.clone({ object: newNote }).objectId, new URL("https://example.com/new-note"));
|
|
940
896
|
});
|
|
941
897
|
test("FEP-fe34: crossOrigin ignore behavior (default)", async () => {
|
|
942
898
|
const crossOriginDocumentLoader = async (url) => {
|
|
@@ -952,13 +908,11 @@ test("FEP-fe34: crossOrigin ignore behavior (default)", async () => {
|
|
|
952
908
|
};
|
|
953
909
|
throw new Error("Document not found");
|
|
954
910
|
};
|
|
955
|
-
|
|
911
|
+
deepStrictEqual(await new Create({
|
|
956
912
|
id: new URL("https://example.com/create"),
|
|
957
913
|
actor: new URL("https://example.com/actor"),
|
|
958
914
|
object: new URL("https://different-origin.com/note")
|
|
959
|
-
});
|
|
960
|
-
const result = await create.getObject({ documentLoader: crossOriginDocumentLoader });
|
|
961
|
-
deepStrictEqual(result, null);
|
|
915
|
+
}).getObject({ documentLoader: crossOriginDocumentLoader }), null);
|
|
962
916
|
});
|
|
963
917
|
test("FEP-fe34: crossOrigin throw behavior", async () => {
|
|
964
918
|
const crossOriginDocumentLoader = async (url) => {
|
|
@@ -998,12 +952,11 @@ test("FEP-fe34: crossOrigin trust behavior", async () => {
|
|
|
998
952
|
};
|
|
999
953
|
throw new Error("Document not found");
|
|
1000
954
|
};
|
|
1001
|
-
const
|
|
955
|
+
const result = await new Create({
|
|
1002
956
|
id: new URL("https://example.com/create"),
|
|
1003
957
|
actor: new URL("https://example.com/actor"),
|
|
1004
958
|
object: new URL("https://different-origin.com/note")
|
|
1005
|
-
})
|
|
1006
|
-
const result = await create.getObject({
|
|
959
|
+
}).getObject({
|
|
1007
960
|
documentLoader: crossOriginDocumentLoader,
|
|
1008
961
|
crossOrigin: "trust"
|
|
1009
962
|
});
|
|
@@ -1025,12 +978,11 @@ test("FEP-fe34: Same origin objects are trusted", async () => {
|
|
|
1025
978
|
};
|
|
1026
979
|
throw new Error("Document not found");
|
|
1027
980
|
};
|
|
1028
|
-
const
|
|
981
|
+
const result = await new Create({
|
|
1029
982
|
id: new URL("https://example.com/create"),
|
|
1030
983
|
actor: new URL("https://example.com/actor"),
|
|
1031
984
|
object: new URL("https://example.com/note")
|
|
1032
|
-
});
|
|
1033
|
-
const result = await create.getObject({ documentLoader: sameOriginDocumentLoader });
|
|
985
|
+
}).getObject({ documentLoader: sameOriginDocumentLoader });
|
|
1034
986
|
assertInstanceOf(result, Note);
|
|
1035
987
|
deepStrictEqual(result?.id, new URL("https://example.com/note"));
|
|
1036
988
|
deepStrictEqual(result?.content, "This is a legitimate note");
|
|
@@ -1073,16 +1025,14 @@ test("FEP-fe34: Embedded cross-origin objects from JSON-LD are ignored by defaul
|
|
|
1073
1025
|
deepStrictEqual(result?.content, "Legitimate note from origin");
|
|
1074
1026
|
});
|
|
1075
1027
|
test("FEP-fe34: Constructor vs JSON-LD parsing trust difference", async () => {
|
|
1076
|
-
|
|
1028
|
+
deepStrictEqual((await new Create({
|
|
1077
1029
|
id: new URL("https://example.com/create"),
|
|
1078
1030
|
actor: new URL("https://example.com/actor"),
|
|
1079
1031
|
object: new Note({
|
|
1080
1032
|
id: new URL("https://different-origin.com/note"),
|
|
1081
1033
|
content: "Constructor embedded note"
|
|
1082
1034
|
})
|
|
1083
|
-
});
|
|
1084
|
-
const constructorResult = await constructorCreate.getObject();
|
|
1085
|
-
deepStrictEqual(constructorResult?.content, "Constructor embedded note");
|
|
1035
|
+
}).getObject())?.content, "Constructor embedded note");
|
|
1086
1036
|
const jsonLdCreate = await Create.fromJsonLd({
|
|
1087
1037
|
"@context": "https://www.w3.org/ns/activitystreams",
|
|
1088
1038
|
"@type": "Create",
|
|
@@ -1107,8 +1057,7 @@ test("FEP-fe34: Constructor vs JSON-LD parsing trust difference", async () => {
|
|
|
1107
1057
|
};
|
|
1108
1058
|
throw new Error("Document not found");
|
|
1109
1059
|
};
|
|
1110
|
-
|
|
1111
|
-
deepStrictEqual(jsonLdResult?.content, "Fetched from origin");
|
|
1060
|
+
deepStrictEqual((await jsonLdCreate.getObject({ documentLoader }))?.content, "Fetched from origin");
|
|
1112
1061
|
});
|
|
1113
1062
|
test("FEP-fe34: Array properties respect cross-origin policy", async () => {
|
|
1114
1063
|
const crossOriginDocumentLoader = async (url) => {
|
|
@@ -1237,9 +1186,9 @@ test("FEP-fe34: Embedded objects in arrays from JSON-LD respect cross-origin pol
|
|
|
1237
1186
|
assertInstanceOf(items[1], Note);
|
|
1238
1187
|
deepStrictEqual(items[1].content, "Legitimate note from actual origin");
|
|
1239
1188
|
});
|
|
1240
|
-
function getAllProperties(type, types
|
|
1189
|
+
function getAllProperties(type, types) {
|
|
1241
1190
|
const props = type.properties;
|
|
1242
|
-
if (type.extends != null) props.push(...getAllProperties(types
|
|
1191
|
+
if (type.extends != null) props.push(...getAllProperties(types[type.extends], types));
|
|
1243
1192
|
return props;
|
|
1244
1193
|
}
|
|
1245
1194
|
const ed25519PublicKey = new CryptographicKey({
|
|
@@ -1354,8 +1303,7 @@ const sampleValues = {
|
|
|
1354
1303
|
};
|
|
1355
1304
|
const types = navigator?.userAgent === "Cloudflare-Workers" ? {} : await loadSchemaFiles(import.meta.dirname);
|
|
1356
1305
|
for (const typeUri in types) {
|
|
1357
|
-
const
|
|
1358
|
-
const cls = vocab_exports[type.name];
|
|
1306
|
+
const cls = vocab_exports[types[typeUri].name];
|
|
1359
1307
|
sampleValues[typeUri] = new cls({
|
|
1360
1308
|
"@id": "https://example.com/",
|
|
1361
1309
|
"@type": typeUri
|
|
@@ -1384,17 +1332,17 @@ for (const typeUri in types) {
|
|
|
1384
1332
|
}
|
|
1385
1333
|
}
|
|
1386
1334
|
const empty = new cls({});
|
|
1387
|
-
for (const property
|
|
1388
|
-
if (property
|
|
1389
|
-
if (!property
|
|
1335
|
+
for (const property of allProperties) if (areAllScalarTypes(property.range, types)) {
|
|
1336
|
+
if (property.functional || property.singularAccessor) deepStrictEqual(empty[property.singularName], null);
|
|
1337
|
+
if (!property.functional) deepStrictEqual(empty[property.pluralName], []);
|
|
1390
1338
|
} else {
|
|
1391
|
-
if (property
|
|
1392
|
-
deepStrictEqual(await empty[`get${pascalCase(property
|
|
1393
|
-
deepStrictEqual(empty[`${property
|
|
1339
|
+
if (property.functional || property.singularAccessor) {
|
|
1340
|
+
deepStrictEqual(await empty[`get${pascalCase(property.singularName)}`].call(empty, { documentLoader: mockDocumentLoader }), null);
|
|
1341
|
+
deepStrictEqual(empty[`${property.singularName}Id`], null);
|
|
1394
1342
|
}
|
|
1395
|
-
if (!property
|
|
1396
|
-
deepStrictEqual(await Array.fromAsync(empty[`get${pascalCase(property
|
|
1397
|
-
deepStrictEqual(empty[`${property
|
|
1343
|
+
if (!property.functional) {
|
|
1344
|
+
deepStrictEqual(await Array.fromAsync(empty[`get${pascalCase(property.pluralName)}`].call(empty, { documentLoader: mockDocumentLoader })), []);
|
|
1345
|
+
deepStrictEqual(empty[`${property.singularName}Ids`], []);
|
|
1398
1346
|
}
|
|
1399
1347
|
}
|
|
1400
1348
|
}
|
|
@@ -1445,8 +1393,7 @@ for (const typeUri in types) {
|
|
|
1445
1393
|
};
|
|
1446
1394
|
if (property.functional || property.singularAccessor) test(`${type.name}.get${pascalCase(property.singularName)}() [auto]`, async () => {
|
|
1447
1395
|
const instance = new cls({ [property.singularName]: new URL("https://example.com/test") });
|
|
1448
|
-
|
|
1449
|
-
deepStrictEqual(value, sampleValues[property.range[0]]);
|
|
1396
|
+
deepStrictEqual(await instance[`get${pascalCase(property.singularName)}`].call(instance, { documentLoader: docLoader }), sampleValues[property.range[0]]);
|
|
1450
1397
|
if (property.untyped) return;
|
|
1451
1398
|
const wrongRef = new cls({ [property.singularName]: new URL("https://example.com/wrong-type") });
|
|
1452
1399
|
await rejects(() => wrongRef[`get${pascalCase(property.singularName)}`].call(wrongRef, { documentLoader: mockDocumentLoader }), TypeError);
|
|
@@ -1474,13 +1421,11 @@ for (const typeUri in types) {
|
|
|
1474
1421
|
"@id": "https://example.com/",
|
|
1475
1422
|
"@type": typeUri
|
|
1476
1423
|
});
|
|
1477
|
-
if (type.typeless) {
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
ok(!("type" in compactJsonLd), `${type.name} is typeless; compact output should not have 'type'`);
|
|
1483
|
-
} else deepStrictEqual(await instance.toJsonLd({
|
|
1424
|
+
if (type.typeless) ok(!("type" in await instance.toJsonLd({
|
|
1425
|
+
format: "compact",
|
|
1426
|
+
contextLoader: mockDocumentLoader
|
|
1427
|
+
})), `${type.name} is typeless; compact output should not have 'type'`);
|
|
1428
|
+
else deepStrictEqual(await instance.toJsonLd({
|
|
1484
1429
|
format: "compact",
|
|
1485
1430
|
contextLoader: mockDocumentLoader
|
|
1486
1431
|
}), {
|
|
@@ -1516,31 +1461,28 @@ for (const typeUri in types) {
|
|
|
1516
1461
|
});
|
|
1517
1462
|
deepStrictEqual(jsonLd2["@context"], "https://www.w3.org/ns/activitystreams");
|
|
1518
1463
|
deepStrictEqual(jsonLd2.id, "https://example.com/");
|
|
1519
|
-
|
|
1464
|
+
deepStrictEqual(await cls.fromJsonLd(jsonLd2, {
|
|
1520
1465
|
documentLoader: mockDocumentLoader,
|
|
1521
1466
|
contextLoader: mockDocumentLoader
|
|
1522
|
-
});
|
|
1523
|
-
deepStrictEqual(restored2, instance);
|
|
1467
|
+
}), instance);
|
|
1524
1468
|
const expanded = await instance.toJsonLd({
|
|
1525
1469
|
contextLoader: mockDocumentLoader,
|
|
1526
1470
|
format: "expand"
|
|
1527
1471
|
});
|
|
1528
|
-
|
|
1472
|
+
deepStrictEqual(await cls.fromJsonLd(expanded, {
|
|
1529
1473
|
documentLoader: mockDocumentLoader,
|
|
1530
1474
|
contextLoader: mockDocumentLoader
|
|
1531
|
-
});
|
|
1532
|
-
deepStrictEqual(restored3, instance);
|
|
1475
|
+
}), instance);
|
|
1533
1476
|
const instance2 = new cls({
|
|
1534
1477
|
id: new URL("https://example.com/"),
|
|
1535
1478
|
...initValues,
|
|
1536
1479
|
...globalThis.Object.fromEntries(allProperties.filter((p) => !areAllScalarTypes(p.range, types)).map((p) => p.functional ? [p.singularName, new URL("https://example.com/test")] : [p.pluralName, [new URL("https://example.com/test")]]))
|
|
1537
1480
|
});
|
|
1538
1481
|
const jsonLd3 = await instance2.toJsonLd({ contextLoader: mockDocumentLoader });
|
|
1539
|
-
|
|
1482
|
+
deepStrictEqual(await cls.fromJsonLd(jsonLd3, {
|
|
1540
1483
|
documentLoader: mockDocumentLoader,
|
|
1541
1484
|
contextLoader: mockDocumentLoader
|
|
1542
|
-
});
|
|
1543
|
-
deepStrictEqual(restored4, instance2);
|
|
1485
|
+
}), instance2);
|
|
1544
1486
|
rejects(() => instance.toJsonLd({ context: "https://www.w3.org/ns/activitystreams" }), TypeError);
|
|
1545
1487
|
rejects(() => instance.toJsonLd({
|
|
1546
1488
|
format: "expand",
|
|
@@ -1567,5 +1509,5 @@ for (const typeUri in types) {
|
|
|
1567
1509
|
deepStrictEqual(cls.typeId, new URL(type.uri));
|
|
1568
1510
|
});
|
|
1569
1511
|
}
|
|
1570
|
-
|
|
1571
|
-
|
|
1512
|
+
//#endregion
|
|
1513
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fedify/vocab",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.3",
|
|
4
4
|
"homepage": "https://fedify.dev/",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -46,16 +46,16 @@
|
|
|
46
46
|
"es-toolkit": "1.43.0",
|
|
47
47
|
"jsonld": "^9.0.0",
|
|
48
48
|
"pkijs": "^3.3.3",
|
|
49
|
-
"@fedify/
|
|
50
|
-
"@fedify/
|
|
51
|
-
"@fedify/vocab-runtime": "2.1.
|
|
49
|
+
"@fedify/vocab-tools": "2.1.3",
|
|
50
|
+
"@fedify/webfinger": "2.1.3",
|
|
51
|
+
"@fedify/vocab-runtime": "2.1.3"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@types/node": "^22.17.0",
|
|
55
55
|
"fast-check": "^3.22.0",
|
|
56
56
|
"fetch-mock": "^12.5.4",
|
|
57
|
-
"tsdown": "^0.
|
|
58
|
-
"typescript": "^5.9.
|
|
57
|
+
"tsdown": "^0.21.6",
|
|
58
|
+
"typescript": "^5.9.2",
|
|
59
59
|
"@fedify/fixture": "2.0.0"
|
|
60
60
|
},
|
|
61
61
|
"keywords": [
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import { Temporal } from "@js-temporal/polyfill";
|
|
3
|
-
globalThis.addEventListener = () => {};
|
|
4
|
-
|
|
5
|
-
//#region src/type.ts
|
|
6
|
-
function getTypeId(object) {
|
|
7
|
-
if (object == null) return object;
|
|
8
|
-
const cls = object.constructor;
|
|
9
|
-
return cls.typeId;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
//#endregion
|
|
13
|
-
export { getTypeId };
|