@fedify/vocab 2.2.14-dev.2082 → 2.2.14
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 +1826 -181
- package/dist/mod.js +1826 -181
- package/dist-tests/actor.test.mjs +2 -2
- package/dist-tests/{deno-RUnTBRj7.mjs → deno-Bm7tiCIb.mjs} +2 -2
- package/dist-tests/lookup.test.mjs +7 -7
- package/dist-tests/type.test.mjs +1 -1
- package/dist-tests/{vocab-BPaC52Gq.mjs → vocab-B7Fuv7Kz.mjs} +1825 -180
- package/dist-tests/vocab.test.mjs +144 -1
- package/package.json +4 -4
- package/src/lookup.test.ts +6 -5
- package/src/vocab.test.ts +197 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Temporal } from "@js-temporal/polyfill";
|
|
2
2
|
globalThis.addEventListener = () => {};
|
|
3
|
-
import { A as vocab_exports, C as QuoteAuthorization, D as Tombstone, E as Source, S as Question, _ as OrderedCollectionPage, a as Create, b as Place, c as Endpoints, d as Hashtag, f as InteractionPolicy, g as Object$1, h as Note, i as Collection, l as Follow, m as Link, n as Announce, o as CryptographicKey, p as InteractionRule, s as Delete, t as Activity, w as QuoteRequest, x as PropertyValue, y as Person } from "./vocab-
|
|
3
|
+
import { A as vocab_exports, C as QuoteAuthorization, D as Tombstone, E as Source, S as Question, _ as OrderedCollectionPage, a as Create, b as Place, c as Endpoints, d as Hashtag, f as InteractionPolicy, g as Object$1, h as Note, i as Collection, l as Follow, m as Link, n as Announce, o as CryptographicKey, p as InteractionRule, s as Delete, t as Activity, w as QuoteRequest, x as PropertyValue, y as Person } from "./vocab-B7Fuv7Kz.mjs";
|
|
4
4
|
import { t as assertInstanceOf } from "./utils-CE8Dk5hm.mjs";
|
|
5
5
|
import { mockDocumentLoader, test } from "@fedify/fixture";
|
|
6
6
|
import { deepStrictEqual, notDeepStrictEqual, ok, rejects, throws } from "node:assert/strict";
|
|
@@ -412,6 +412,72 @@ test({
|
|
|
412
412
|
deepStrictEqual(objects2[0].name, "Second object");
|
|
413
413
|
}
|
|
414
414
|
});
|
|
415
|
+
function embeddedPropertyDocument(property) {
|
|
416
|
+
const context = "https://www.w3.org/ns/activitystreams";
|
|
417
|
+
return {
|
|
418
|
+
"@context": [context, { CustomImage: `${context}#Image` }],
|
|
419
|
+
type: property === "attachment" ? "Note" : "Create",
|
|
420
|
+
[property]: [
|
|
421
|
+
{
|
|
422
|
+
"@context": [context, { "@vocab": "https://example.com/" }],
|
|
423
|
+
type: "CustomImage",
|
|
424
|
+
name: "Malformed when reparsed"
|
|
425
|
+
},
|
|
426
|
+
{
|
|
427
|
+
"@context": context,
|
|
428
|
+
type: "Image",
|
|
429
|
+
name: "Cached image"
|
|
430
|
+
},
|
|
431
|
+
{
|
|
432
|
+
type: "Image",
|
|
433
|
+
name: "Decoded image"
|
|
434
|
+
}
|
|
435
|
+
]
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
for (const suppressError of [
|
|
439
|
+
void 0,
|
|
440
|
+
false,
|
|
441
|
+
true
|
|
442
|
+
]) {
|
|
443
|
+
test(`Note.getAttachments() cached parse failure (suppressError: ${suppressError})`, async () => {
|
|
444
|
+
const jsonLd = embeddedPropertyDocument("attachment");
|
|
445
|
+
const note = await Note.fromJsonLd(jsonLd);
|
|
446
|
+
if (suppressError) {
|
|
447
|
+
for (let i = 0; i < 2; i++) deepStrictEqual((await Array.fromAsync(note.getAttachments({ suppressError }))).map((attachment) => attachment.name), ["Cached image", "Decoded image"]);
|
|
448
|
+
await rejects(() => Array.fromAsync(note.getAttachments()), TypeError);
|
|
449
|
+
} else await rejects(() => Array.fromAsync(note.getAttachments({ suppressError })), TypeError);
|
|
450
|
+
deepStrictEqual(await note.toJsonLd(), jsonLd);
|
|
451
|
+
});
|
|
452
|
+
test(`Activity.getObject() cached parse failure (suppressError: ${suppressError})`, async () => {
|
|
453
|
+
const jsonLd = embeddedPropertyDocument("object");
|
|
454
|
+
const activity = await Activity.fromJsonLd(jsonLd);
|
|
455
|
+
if (suppressError) {
|
|
456
|
+
deepStrictEqual(await activity.getObject({ suppressError }), null);
|
|
457
|
+
deepStrictEqual(await activity.getObject({ suppressError }), null);
|
|
458
|
+
await rejects(() => activity.getObject(), TypeError);
|
|
459
|
+
} else await rejects(() => activity.getObject({ suppressError }), TypeError);
|
|
460
|
+
deepStrictEqual(await activity.toJsonLd(), jsonLd);
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
test("Note.getAttachments() suppresses cached context loader failures", async () => {
|
|
464
|
+
const note = await Note.fromJsonLd(embeddedPropertyDocument("attachment"));
|
|
465
|
+
const contextLoader = () => Promise.reject(/* @__PURE__ */ new Error("Context loader failed"));
|
|
466
|
+
await rejects(() => Array.fromAsync(note.getAttachments({ contextLoader })), (error) => error instanceof Error && !(error instanceof TypeError));
|
|
467
|
+
deepStrictEqual((await Array.fromAsync(note.getAttachments({
|
|
468
|
+
contextLoader,
|
|
469
|
+
suppressError: true
|
|
470
|
+
}))).map((attachment) => attachment.name), ["Decoded image"]);
|
|
471
|
+
});
|
|
472
|
+
test("Activity.getObject() suppresses cached context loader failures", async () => {
|
|
473
|
+
const activity = await Activity.fromJsonLd(embeddedPropertyDocument("object"));
|
|
474
|
+
const contextLoader = () => Promise.reject(/* @__PURE__ */ new Error("Context loader failed"));
|
|
475
|
+
await rejects(() => activity.getObject({ contextLoader }), (error) => error instanceof Error && !(error instanceof TypeError));
|
|
476
|
+
deepStrictEqual(await activity.getObject({
|
|
477
|
+
contextLoader,
|
|
478
|
+
suppressError: true
|
|
479
|
+
}), null);
|
|
480
|
+
});
|
|
415
481
|
test("Activity.clone()", async () => {
|
|
416
482
|
const activity = new Activity({
|
|
417
483
|
actor: new Person({ name: "John Doe" }),
|
|
@@ -1080,6 +1146,83 @@ test("Delete.toJsonLd() compacts embedded QuoteRequest", async () => {
|
|
|
1080
1146
|
type: "Delete"
|
|
1081
1147
|
});
|
|
1082
1148
|
});
|
|
1149
|
+
test("Note.quoteUrl (IRI-typed alias terms)", async () => {
|
|
1150
|
+
const jsonLd = {
|
|
1151
|
+
"@context": ["https://www.w3.org/ns/activitystreams", {
|
|
1152
|
+
fedibird: "http://fedibird.com/ns#",
|
|
1153
|
+
misskey: "https://misskey-hub.net/ns#",
|
|
1154
|
+
_misskey_quote: {
|
|
1155
|
+
"@id": "misskey:_misskey_quote",
|
|
1156
|
+
"@type": "@id"
|
|
1157
|
+
},
|
|
1158
|
+
quoteUri: {
|
|
1159
|
+
"@id": "fedibird:quoteUri",
|
|
1160
|
+
"@type": "@id"
|
|
1161
|
+
}
|
|
1162
|
+
}],
|
|
1163
|
+
id: "https://example.com/notes/1",
|
|
1164
|
+
type: "Note",
|
|
1165
|
+
_misskey_quote: "https://example.com/notes/quoted",
|
|
1166
|
+
quoteUri: "https://example.com/notes/quoted2"
|
|
1167
|
+
};
|
|
1168
|
+
deepStrictEqual((await Note.fromJsonLd(jsonLd)).quoteUrl, new URL("https://example.com/notes/quoted"));
|
|
1169
|
+
delete jsonLd._misskey_quote;
|
|
1170
|
+
deepStrictEqual((await Note.fromJsonLd(jsonLd)).quoteUrl, new URL("https://example.com/notes/quoted2"));
|
|
1171
|
+
});
|
|
1172
|
+
test("Note.quoteUrl (IRI-typed primary term)", async () => {
|
|
1173
|
+
const context = ["https://www.w3.org/ns/activitystreams", {
|
|
1174
|
+
misskey: "https://misskey-hub.net/ns#",
|
|
1175
|
+
quoteUrl: {
|
|
1176
|
+
"@id": "as:quoteUrl",
|
|
1177
|
+
"@type": "@id"
|
|
1178
|
+
},
|
|
1179
|
+
_misskey_quote: "misskey:_misskey_quote"
|
|
1180
|
+
}];
|
|
1181
|
+
deepStrictEqual((await Note.fromJsonLd({
|
|
1182
|
+
"@context": context,
|
|
1183
|
+
type: "Note",
|
|
1184
|
+
quoteUrl: "https://example.com/object"
|
|
1185
|
+
})).quoteUrl, new URL("https://example.com/object"));
|
|
1186
|
+
deepStrictEqual((await Note.fromJsonLd({
|
|
1187
|
+
"@context": context,
|
|
1188
|
+
type: "Note",
|
|
1189
|
+
quoteUrl: "https://example.com/object",
|
|
1190
|
+
_misskey_quote: "https://example.com/object2"
|
|
1191
|
+
})).quoteUrl, new URL("https://example.com/object"));
|
|
1192
|
+
});
|
|
1193
|
+
test("Note.quoteUrl (unparsable IRI-valued terms)", async () => {
|
|
1194
|
+
const context = ["https://www.w3.org/ns/activitystreams", {
|
|
1195
|
+
misskey: "https://misskey-hub.net/ns#",
|
|
1196
|
+
_misskey_quote: {
|
|
1197
|
+
"@id": "misskey:_misskey_quote",
|
|
1198
|
+
"@type": "@id"
|
|
1199
|
+
}
|
|
1200
|
+
}];
|
|
1201
|
+
for (const quote of [
|
|
1202
|
+
{
|
|
1203
|
+
type: "Note",
|
|
1204
|
+
content: "An inlined quote without an id"
|
|
1205
|
+
},
|
|
1206
|
+
"_:b0",
|
|
1207
|
+
"",
|
|
1208
|
+
"notes/relative"
|
|
1209
|
+
]) {
|
|
1210
|
+
const loaded = await Note.fromJsonLd({
|
|
1211
|
+
"@context": context,
|
|
1212
|
+
id: "https://example.com/notes/1",
|
|
1213
|
+
type: "Note",
|
|
1214
|
+
content: "Hello",
|
|
1215
|
+
_misskey_quote: quote
|
|
1216
|
+
});
|
|
1217
|
+
deepStrictEqual(loaded.quoteUrl, null, JSON.stringify(quote));
|
|
1218
|
+
deepStrictEqual(loaded.content, "Hello");
|
|
1219
|
+
}
|
|
1220
|
+
deepStrictEqual((await Note.fromJsonLd({
|
|
1221
|
+
"@context": context,
|
|
1222
|
+
type: "Note",
|
|
1223
|
+
_misskey_quote: "at://did:plc:abc/app.bsky.feed.post/xyz"
|
|
1224
|
+
})).quoteUrl, new URL("at://" + encodeURIComponent("did:plc:abc/app.bsky.feed.post/xyz")));
|
|
1225
|
+
});
|
|
1083
1226
|
test("Key.publicKey", async () => {
|
|
1084
1227
|
const jwk = {
|
|
1085
1228
|
kty: "RSA",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fedify/vocab",
|
|
3
|
-
"version": "2.2.14
|
|
3
|
+
"version": "2.2.14",
|
|
4
4
|
"homepage": "https://fedify.dev/",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -46,9 +46,9 @@
|
|
|
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-
|
|
49
|
+
"@fedify/vocab-tools": "2.2.14",
|
|
50
|
+
"@fedify/webfinger": "2.2.14",
|
|
51
|
+
"@fedify/vocab-runtime": "2.2.14"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@types/node": "^22.17.0",
|
package/src/lookup.test.ts
CHANGED
|
@@ -79,7 +79,8 @@ test("lookupObject()", {
|
|
|
79
79
|
);
|
|
80
80
|
});
|
|
81
81
|
|
|
82
|
-
|
|
82
|
+
// Workers load fixtures through fetch(), so keep the spy fallback between steps.
|
|
83
|
+
fetchMock.removeRoutes({ includeFallback: false });
|
|
83
84
|
fetchMock.get("begin:https://example.com/.well-known/webfinger", {
|
|
84
85
|
subject: "acct:janedoe@example.com",
|
|
85
86
|
links: [
|
|
@@ -99,7 +100,7 @@ test("lookupObject()", {
|
|
|
99
100
|
);
|
|
100
101
|
});
|
|
101
102
|
|
|
102
|
-
fetchMock.removeRoutes();
|
|
103
|
+
fetchMock.removeRoutes({ includeFallback: false });
|
|
103
104
|
fetchMock.get(
|
|
104
105
|
"begin:https://example.com/.well-known/webfinger",
|
|
105
106
|
() =>
|
|
@@ -130,7 +131,7 @@ test("lookupObject()", {
|
|
|
130
131
|
deepStrictEqual(await promise, null);
|
|
131
132
|
});
|
|
132
133
|
|
|
133
|
-
fetchMock.removeRoutes();
|
|
134
|
+
fetchMock.removeRoutes({ includeFallback: false });
|
|
134
135
|
fetchMock.get(
|
|
135
136
|
"begin:https://example.com/.well-known/webfinger",
|
|
136
137
|
{
|
|
@@ -155,7 +156,7 @@ test("lookupObject()", {
|
|
|
155
156
|
deepStrictEqual(person.id, new URL("https://example.com/person"));
|
|
156
157
|
});
|
|
157
158
|
|
|
158
|
-
fetchMock.removeRoutes();
|
|
159
|
+
fetchMock.removeRoutes({ includeFallback: false });
|
|
159
160
|
fetchMock.get(
|
|
160
161
|
"begin:https://example.com/.well-known/webfinger",
|
|
161
162
|
() =>
|
|
@@ -186,7 +187,7 @@ test("lookupObject()", {
|
|
|
186
187
|
deepStrictEqual(result, null);
|
|
187
188
|
});
|
|
188
189
|
|
|
189
|
-
fetchMock.removeRoutes();
|
|
190
|
+
fetchMock.removeRoutes({ includeFallback: false });
|
|
190
191
|
fetchMock.get(
|
|
191
192
|
"https://example.com/slow-object",
|
|
192
193
|
() =>
|
package/src/vocab.test.ts
CHANGED
|
@@ -613,6 +613,104 @@ test({
|
|
|
613
613
|
},
|
|
614
614
|
});
|
|
615
615
|
|
|
616
|
+
// The alias is inherited during initial expansion, but is unavailable when
|
|
617
|
+
// an embedded value is reparsed standalone from the cached JSON-LD.
|
|
618
|
+
function embeddedPropertyDocument(property: "attachment" | "object") {
|
|
619
|
+
const context = "https://www.w3.org/ns/activitystreams";
|
|
620
|
+
return {
|
|
621
|
+
"@context": [context, { CustomImage: `${context}#Image` }],
|
|
622
|
+
type: property === "attachment" ? "Note" : "Create",
|
|
623
|
+
[property]: [
|
|
624
|
+
{
|
|
625
|
+
"@context": [context, { "@vocab": "https://example.com/" }],
|
|
626
|
+
type: "CustomImage",
|
|
627
|
+
name: "Malformed when reparsed",
|
|
628
|
+
},
|
|
629
|
+
{ "@context": context, type: "Image", name: "Cached image" },
|
|
630
|
+
{ type: "Image", name: "Decoded image" },
|
|
631
|
+
],
|
|
632
|
+
};
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
for (const suppressError of [undefined, false, true]) {
|
|
636
|
+
test(
|
|
637
|
+
`Note.getAttachments() cached parse failure (suppressError: ${suppressError})`,
|
|
638
|
+
async () => {
|
|
639
|
+
const jsonLd = embeddedPropertyDocument("attachment");
|
|
640
|
+
const note = await Note.fromJsonLd(jsonLd);
|
|
641
|
+
if (suppressError) {
|
|
642
|
+
for (let i = 0; i < 2; i++) {
|
|
643
|
+
const attachments: (Object | Link | PropertyValue)[] = await Array
|
|
644
|
+
.fromAsync(
|
|
645
|
+
note.getAttachments({ suppressError }),
|
|
646
|
+
);
|
|
647
|
+
deepStrictEqual(
|
|
648
|
+
attachments.map((attachment) => attachment.name),
|
|
649
|
+
["Cached image", "Decoded image"],
|
|
650
|
+
);
|
|
651
|
+
}
|
|
652
|
+
// Suppression must not remove or replace the cached malformed value.
|
|
653
|
+
await rejects(() => Array.fromAsync(note.getAttachments()), TypeError);
|
|
654
|
+
} else {
|
|
655
|
+
await rejects(
|
|
656
|
+
() => Array.fromAsync(note.getAttachments({ suppressError })),
|
|
657
|
+
TypeError,
|
|
658
|
+
);
|
|
659
|
+
}
|
|
660
|
+
deepStrictEqual(await note.toJsonLd(), jsonLd);
|
|
661
|
+
},
|
|
662
|
+
);
|
|
663
|
+
|
|
664
|
+
test(
|
|
665
|
+
`Activity.getObject() cached parse failure (suppressError: ${suppressError})`,
|
|
666
|
+
async () => {
|
|
667
|
+
const jsonLd = embeddedPropertyDocument("object");
|
|
668
|
+
const activity = await Activity.fromJsonLd(jsonLd);
|
|
669
|
+
if (suppressError) {
|
|
670
|
+
deepStrictEqual(await activity.getObject({ suppressError }), null);
|
|
671
|
+
deepStrictEqual(await activity.getObject({ suppressError }), null);
|
|
672
|
+
await rejects(() => activity.getObject(), TypeError);
|
|
673
|
+
} else {
|
|
674
|
+
await rejects(() => activity.getObject({ suppressError }), TypeError);
|
|
675
|
+
}
|
|
676
|
+
deepStrictEqual(await activity.toJsonLd(), jsonLd);
|
|
677
|
+
},
|
|
678
|
+
);
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
test("Note.getAttachments() suppresses cached context loader failures", async () => {
|
|
682
|
+
const note = await Note.fromJsonLd(embeddedPropertyDocument("attachment"));
|
|
683
|
+
const contextLoader = () =>
|
|
684
|
+
Promise.reject(new Error("Context loader failed"));
|
|
685
|
+
await rejects(
|
|
686
|
+
() => Array.fromAsync(note.getAttachments({ contextLoader })),
|
|
687
|
+
(error: unknown) => error instanceof Error && !(error instanceof TypeError),
|
|
688
|
+
);
|
|
689
|
+
// Both cached values need the failing loader; the decoded value remains usable.
|
|
690
|
+
const attachments: (Object | Link | PropertyValue)[] = await Array.fromAsync(
|
|
691
|
+
note.getAttachments({ contextLoader, suppressError: true }),
|
|
692
|
+
);
|
|
693
|
+
deepStrictEqual(attachments.map((attachment) => attachment.name), [
|
|
694
|
+
"Decoded image",
|
|
695
|
+
]);
|
|
696
|
+
});
|
|
697
|
+
|
|
698
|
+
test("Activity.getObject() suppresses cached context loader failures", async () => {
|
|
699
|
+
const activity = await Activity.fromJsonLd(
|
|
700
|
+
embeddedPropertyDocument("object"),
|
|
701
|
+
);
|
|
702
|
+
const contextLoader = () =>
|
|
703
|
+
Promise.reject(new Error("Context loader failed"));
|
|
704
|
+
await rejects(
|
|
705
|
+
() => activity.getObject({ contextLoader }),
|
|
706
|
+
(error: unknown) => error instanceof Error && !(error instanceof TypeError),
|
|
707
|
+
);
|
|
708
|
+
deepStrictEqual(
|
|
709
|
+
await activity.getObject({ contextLoader, suppressError: true }),
|
|
710
|
+
null,
|
|
711
|
+
);
|
|
712
|
+
});
|
|
713
|
+
|
|
616
714
|
test("Activity.clone()", async () => {
|
|
617
715
|
const activity = new Activity({
|
|
618
716
|
actor: new Person({
|
|
@@ -1658,6 +1756,105 @@ test("Delete.toJsonLd() compacts embedded QuoteRequest", async () => {
|
|
|
1658
1756
|
);
|
|
1659
1757
|
});
|
|
1660
1758
|
|
|
1759
|
+
test("Note.quoteUrl (IRI-typed alias terms)", async () => {
|
|
1760
|
+
const jsonLd: Record<string, unknown> = {
|
|
1761
|
+
"@context": [
|
|
1762
|
+
"https://www.w3.org/ns/activitystreams",
|
|
1763
|
+
{
|
|
1764
|
+
fedibird: "http://fedibird.com/ns#",
|
|
1765
|
+
misskey: "https://misskey-hub.net/ns#",
|
|
1766
|
+
_misskey_quote: {
|
|
1767
|
+
"@id": "misskey:_misskey_quote",
|
|
1768
|
+
"@type": "@id",
|
|
1769
|
+
},
|
|
1770
|
+
quoteUri: {
|
|
1771
|
+
"@id": "fedibird:quoteUri",
|
|
1772
|
+
"@type": "@id",
|
|
1773
|
+
},
|
|
1774
|
+
},
|
|
1775
|
+
],
|
|
1776
|
+
id: "https://example.com/notes/1",
|
|
1777
|
+
type: "Note",
|
|
1778
|
+
_misskey_quote: "https://example.com/notes/quoted",
|
|
1779
|
+
quoteUri: "https://example.com/notes/quoted2",
|
|
1780
|
+
};
|
|
1781
|
+
|
|
1782
|
+
const loaded = await Note.fromJsonLd(jsonLd);
|
|
1783
|
+
deepStrictEqual(loaded.quoteUrl, new URL("https://example.com/notes/quoted"));
|
|
1784
|
+
|
|
1785
|
+
delete jsonLd._misskey_quote;
|
|
1786
|
+
const loaded2 = await Note.fromJsonLd(jsonLd);
|
|
1787
|
+
deepStrictEqual(
|
|
1788
|
+
loaded2.quoteUrl,
|
|
1789
|
+
new URL("https://example.com/notes/quoted2"),
|
|
1790
|
+
);
|
|
1791
|
+
});
|
|
1792
|
+
|
|
1793
|
+
test("Note.quoteUrl (IRI-typed primary term)", async () => {
|
|
1794
|
+
const context = [
|
|
1795
|
+
"https://www.w3.org/ns/activitystreams",
|
|
1796
|
+
{
|
|
1797
|
+
misskey: "https://misskey-hub.net/ns#",
|
|
1798
|
+
quoteUrl: { "@id": "as:quoteUrl", "@type": "@id" },
|
|
1799
|
+
_misskey_quote: "misskey:_misskey_quote",
|
|
1800
|
+
},
|
|
1801
|
+
];
|
|
1802
|
+
|
|
1803
|
+
const loaded = await Note.fromJsonLd({
|
|
1804
|
+
"@context": context,
|
|
1805
|
+
type: "Note",
|
|
1806
|
+
quoteUrl: "https://example.com/object",
|
|
1807
|
+
});
|
|
1808
|
+
deepStrictEqual(loaded.quoteUrl, new URL("https://example.com/object"));
|
|
1809
|
+
|
|
1810
|
+
// An IRI-valued quoteUrl still takes precedence over a plain-string alias:
|
|
1811
|
+
const loaded2 = await Note.fromJsonLd({
|
|
1812
|
+
"@context": context,
|
|
1813
|
+
type: "Note",
|
|
1814
|
+
quoteUrl: "https://example.com/object",
|
|
1815
|
+
_misskey_quote: "https://example.com/object2",
|
|
1816
|
+
});
|
|
1817
|
+
deepStrictEqual(loaded2.quoteUrl, new URL("https://example.com/object"));
|
|
1818
|
+
});
|
|
1819
|
+
|
|
1820
|
+
test("Note.quoteUrl (unparsable IRI-valued terms)", async () => {
|
|
1821
|
+
const context = [
|
|
1822
|
+
"https://www.w3.org/ns/activitystreams",
|
|
1823
|
+
{
|
|
1824
|
+
misskey: "https://misskey-hub.net/ns#",
|
|
1825
|
+
_misskey_quote: { "@id": "misskey:_misskey_quote", "@type": "@id" },
|
|
1826
|
+
},
|
|
1827
|
+
];
|
|
1828
|
+
for (
|
|
1829
|
+
const quote of [
|
|
1830
|
+
{ type: "Note", content: "An inlined quote without an id" },
|
|
1831
|
+
"_:b0",
|
|
1832
|
+
"",
|
|
1833
|
+
"notes/relative",
|
|
1834
|
+
]
|
|
1835
|
+
) {
|
|
1836
|
+
const loaded = await Note.fromJsonLd({
|
|
1837
|
+
"@context": context,
|
|
1838
|
+
id: "https://example.com/notes/1",
|
|
1839
|
+
type: "Note",
|
|
1840
|
+
content: "Hello",
|
|
1841
|
+
_misskey_quote: quote,
|
|
1842
|
+
});
|
|
1843
|
+
deepStrictEqual(loaded.quoteUrl, null, JSON.stringify(quote));
|
|
1844
|
+
deepStrictEqual(loaded.content, "Hello");
|
|
1845
|
+
}
|
|
1846
|
+
|
|
1847
|
+
const atUri = await Note.fromJsonLd({
|
|
1848
|
+
"@context": context,
|
|
1849
|
+
type: "Note",
|
|
1850
|
+
_misskey_quote: "at://did:plc:abc/app.bsky.feed.post/xyz",
|
|
1851
|
+
});
|
|
1852
|
+
deepStrictEqual(
|
|
1853
|
+
atUri.quoteUrl,
|
|
1854
|
+
new URL("at://" + encodeURIComponent("did:plc:abc/app.bsky.feed.post/xyz")),
|
|
1855
|
+
);
|
|
1856
|
+
});
|
|
1857
|
+
|
|
1661
1858
|
test("Key.publicKey", async () => {
|
|
1662
1859
|
const jwk = {
|
|
1663
1860
|
kty: "RSA",
|