@fedify/vocab-runtime 2.1.25 → 2.1.27
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 +2 -2
- package/dist/mod.cjs +97 -4
- package/dist/mod.d.cts +30 -2
- package/dist/mod.d.ts +30 -2
- package/dist/mod.js +97 -5
- package/dist/tests/{body-DBqFojnW.mjs → body-pQw7TnzP.mjs} +1 -1
- package/dist/tests/{body-D-gC5vdl.cjs → body-tMF7v1Wt.cjs} +1 -1
- package/dist/tests/body.test.cjs +1 -1
- package/dist/tests/body.test.mjs +1 -1
- package/dist/tests/decimal.test.cjs +3 -2
- package/dist/tests/decimal.test.mjs +3 -2
- package/dist/tests/{docloader-Beoc8qTH.mjs → docloader-B7owxMYS.mjs} +49 -3
- package/dist/tests/{docloader-fn4ICzFS.cjs → docloader-DOROiNle.cjs} +49 -3
- package/dist/tests/docloader.test.cjs +167 -42
- package/dist/tests/docloader.test.mjs +157 -33
- package/dist/tests/{langstr-DDLc4833.mjs → langstr-ABdAOKlF.mjs} +5 -2
- package/dist/tests/{langstr-BOQHfJDr.cjs → langstr-BsqFJupv.cjs} +5 -2
- package/dist/tests/langstr.test.cjs +8 -1
- package/dist/tests/langstr.test.mjs +9 -2
- package/dist/tests/langtag-DgySESmk.cjs +50 -0
- package/dist/tests/langtag-LDBqlxHv.mjs +45 -0
- package/dist/tests/langtag.test.cjs +46 -0
- package/dist/tests/langtag.test.d.cts +1 -0
- package/dist/tests/langtag.test.d.mts +1 -0
- package/dist/tests/langtag.test.mjs +46 -0
- package/dist/tests/multibase/multibase.test.cjs +7 -7
- package/dist/tests/multibase/multibase.test.mjs +5 -5
- package/dist/tests/{request-DxeGyJVh.mjs → request-BBg4llPR.mjs} +1 -1
- package/dist/tests/{request-DrO5xzev.cjs → request-D0CNu0d0.cjs} +1 -1
- package/dist/tests/request.test.cjs +1 -1
- package/dist/tests/request.test.mjs +1 -1
- package/package.json +6 -3
- package/scripts/test-bun.mjs +18 -0
- package/src/contexts/fep-22cd.json +14 -0
- package/src/contexts/fep-6757.json +12 -0
- package/src/contexts/joinmastodon.json +1 -1
- package/src/contexts.ts +16 -0
- package/src/docloader.test.ts +221 -66
- package/src/docloader.ts +2 -0
- package/src/langstr.test.ts +18 -1
- package/src/langstr.ts +6 -2
- package/src/langtag.test.ts +53 -0
- package/src/langtag.ts +76 -0
- package/src/mod.ts +1 -0
- package/src/multibase/multibase.test.ts +5 -5
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require("./chunk-Do9eywBl.cjs");
|
|
2
|
-
const require_request = require("./request-
|
|
3
|
-
const require_body = require("./body-
|
|
2
|
+
const require_request = require("./request-D0CNu0d0.cjs");
|
|
3
|
+
const require_body = require("./body-tMF7v1Wt.cjs");
|
|
4
4
|
const require_link = require("./link-qDTmjPw_.cjs");
|
|
5
5
|
const require_url = require("./url-vZTgkIZg.cjs");
|
|
6
6
|
let _logtape_logtape = require("@logtape/logtape");
|
|
@@ -554,6 +554,36 @@ var did_v1_default = { "@context": {
|
|
|
554
554
|
}
|
|
555
555
|
} };
|
|
556
556
|
//#endregion
|
|
557
|
+
//#region src/contexts/fep-22cd.json
|
|
558
|
+
var fep_22cd_default = { "@context": {
|
|
559
|
+
"fep-22cd": "https://w3id.org/fep/22cd#",
|
|
560
|
+
"schema": "https://schema.org/",
|
|
561
|
+
"xsd": "http://www.w3.org/2001/XMLSchema#",
|
|
562
|
+
"translations": {
|
|
563
|
+
"@id": "fep-22cd:translations",
|
|
564
|
+
"@container": "@set"
|
|
565
|
+
},
|
|
566
|
+
"Translation": "fep-22cd:Translation",
|
|
567
|
+
"sourceUpdated": {
|
|
568
|
+
"@id": "fep-22cd:sourceUpdated",
|
|
569
|
+
"@type": "xsd:dateTime"
|
|
570
|
+
},
|
|
571
|
+
"translator": {
|
|
572
|
+
"@id": "schema:translator",
|
|
573
|
+
"@type": "@id",
|
|
574
|
+
"@container": "@set"
|
|
575
|
+
},
|
|
576
|
+
"inLanguage": "schema:inLanguage",
|
|
577
|
+
"translationOfWork": {
|
|
578
|
+
"@id": "schema:translationOfWork",
|
|
579
|
+
"@type": "@id"
|
|
580
|
+
},
|
|
581
|
+
"isBasedOn": {
|
|
582
|
+
"@id": "schema:isBasedOn",
|
|
583
|
+
"@type": "@id"
|
|
584
|
+
}
|
|
585
|
+
} };
|
|
586
|
+
//#endregion
|
|
557
587
|
//#region src/contexts/fep-5711.json
|
|
558
588
|
var fep_5711_default = { "@context": {
|
|
559
589
|
"likesOf": {
|
|
@@ -590,6 +620,18 @@ var fep_5711_default = { "@context": {
|
|
|
590
620
|
}
|
|
591
621
|
} };
|
|
592
622
|
//#endregion
|
|
623
|
+
//#region src/contexts/fep-6757.json
|
|
624
|
+
var fep_6757_default = { "@context": {
|
|
625
|
+
"license": {
|
|
626
|
+
"@id": "http://purl.org/dc/terms/license",
|
|
627
|
+
"@type": "@id"
|
|
628
|
+
},
|
|
629
|
+
"preferredLicense": {
|
|
630
|
+
"@id": "https://w3id.org/fep/6757#preferredLicense",
|
|
631
|
+
"@type": "@id"
|
|
632
|
+
}
|
|
633
|
+
} };
|
|
634
|
+
//#endregion
|
|
593
635
|
//#region src/contexts/fep-7aa9.json
|
|
594
636
|
var fep_7aa9_default = { "@context": {
|
|
595
637
|
"FeaturedCollection": "https://w3id.org/fep/7aa9#FeaturedCollection",
|
|
@@ -916,7 +958,7 @@ var joinmastodon_default = { "@context": {
|
|
|
916
958
|
"suspended": "toot:suspended",
|
|
917
959
|
"attributionDomains": {
|
|
918
960
|
"@id": "toot:attributionDomains",
|
|
919
|
-
"@
|
|
961
|
+
"@container": "@set"
|
|
920
962
|
}
|
|
921
963
|
} };
|
|
922
964
|
//#endregion
|
|
@@ -4532,6 +4574,8 @@ const preloadedContexts = {
|
|
|
4532
4574
|
"https://www.w3.org/ns/cid/v1": cid_v1_default,
|
|
4533
4575
|
"https://w3id.org/fep/ef61": fep_ef61_default,
|
|
4534
4576
|
"https://w3id.org/fep/7aa9": fep_7aa9_default,
|
|
4577
|
+
"https://w3id.org/fep/6757": fep_6757_default,
|
|
4578
|
+
"https://w3id.org/fep/22cd": fep_22cd_default,
|
|
4535
4579
|
"https://join-lemmy.org/context.json": join_lemmy_default,
|
|
4536
4580
|
"http://joinmastodon.org/ns": joinmastodon_default,
|
|
4537
4581
|
"https://purl.archive.org/miscellany": miscellany_default
|
|
@@ -4648,6 +4692,8 @@ async function getRemoteDocument(url, response, fetch) {
|
|
|
4648
4692
|
* - <https://w3id.org/security/multikey/v1>
|
|
4649
4693
|
* - <https://w3id.org/fep/ef61>
|
|
4650
4694
|
* - <https://w3id.org/fep/7aa9>
|
|
4695
|
+
* - <https://w3id.org/fep/6757>
|
|
4696
|
+
* - <https://w3id.org/fep/22cd>
|
|
4651
4697
|
* - <https://purl.archive.org/socialweb/webfinger>
|
|
4652
4698
|
* - <http://schema.org/>
|
|
4653
4699
|
* @param options Options for the document loader.
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
const require_chunk = require("./chunk-Do9eywBl.cjs");
|
|
2
|
-
const require_request = require("./request-
|
|
3
|
-
const require_docloader = require("./docloader-
|
|
2
|
+
const require_request = require("./request-D0CNu0d0.cjs");
|
|
3
|
+
const require_docloader = require("./docloader-DOROiNle.cjs");
|
|
4
4
|
const require_url = require("./url-vZTgkIZg.cjs");
|
|
5
|
-
let node_test = require("node:test");
|
|
6
5
|
let node_zlib = require("node:zlib");
|
|
7
6
|
let _logtape_logtape = require("@logtape/logtape");
|
|
8
7
|
let node_assert = require("node:assert");
|
|
9
8
|
let node_dns_promises = require("node:dns/promises");
|
|
10
9
|
node_dns_promises = require_chunk.__toESM(node_dns_promises);
|
|
10
|
+
let _fedify_fixture = require("@fedify/fixture");
|
|
11
11
|
let node_http = require("node:http");
|
|
12
|
+
let jsonld_dist_jsonld_esm_js = require("jsonld/dist/jsonld.esm.js");
|
|
13
|
+
jsonld_dist_jsonld_esm_js = require_chunk.__toESM(jsonld_dist_jsonld_esm_js);
|
|
12
14
|
//#region ../../node_modules/.pnpm/glob-to-regexp@0.4.1/node_modules/glob-to-regexp/index.js
|
|
13
15
|
var require_glob_to_regexp = /* @__PURE__ */ require_chunk.__commonJSMin(((exports, module) => {
|
|
14
16
|
module.exports = function(glob, opts) {
|
|
@@ -1210,8 +1212,11 @@ var esm_default = new class FetchMock {
|
|
|
1210
1212
|
}
|
|
1211
1213
|
}({ ...defaultFetchMockConfig });
|
|
1212
1214
|
//#endregion
|
|
1215
|
+
//#region src/jsonld.ts
|
|
1216
|
+
var jsonld_default = jsonld_dist_jsonld_esm_js.default;
|
|
1217
|
+
//#endregion
|
|
1213
1218
|
//#region src/docloader.test.ts
|
|
1214
|
-
(0,
|
|
1219
|
+
(0, _fedify_fixture.test)("new FetchError()", () => {
|
|
1215
1220
|
const e = new require_request.FetchError("https://example.com/", "An error message.");
|
|
1216
1221
|
(0, node_assert.deepStrictEqual)(e.name, "FetchError");
|
|
1217
1222
|
(0, node_assert.deepStrictEqual)(e.url, new URL("https://example.com/"));
|
|
@@ -1224,7 +1229,7 @@ var esm_default = new class FetchMock {
|
|
|
1224
1229
|
(0, node_assert.ok)(e2.response != null);
|
|
1225
1230
|
(0, node_assert.deepStrictEqual)(e2.response.status, 410);
|
|
1226
1231
|
});
|
|
1227
|
-
(0,
|
|
1232
|
+
(0, _fedify_fixture.test)("getDocumentLoader()", async (t) => {
|
|
1228
1233
|
const fetchDocumentLoader = require_docloader.getDocumentLoader();
|
|
1229
1234
|
esm_default.spyGlobal();
|
|
1230
1235
|
esm_default.get("https://example.com/object", { body: {
|
|
@@ -1233,7 +1238,7 @@ var esm_default = new class FetchMock {
|
|
|
1233
1238
|
name: "Fetched object",
|
|
1234
1239
|
type: "Object"
|
|
1235
1240
|
} });
|
|
1236
|
-
await t.
|
|
1241
|
+
await t.step("ok", async () => {
|
|
1237
1242
|
(0, node_assert.deepStrictEqual)(await fetchDocumentLoader("https://example.com/object"), {
|
|
1238
1243
|
contextUrl: null,
|
|
1239
1244
|
documentUrl: "https://example.com/object",
|
|
@@ -1276,7 +1281,7 @@ var esm_default = new class FetchMock {
|
|
|
1276
1281
|
Link: "<https://example.com/object>; rel=\"alternate\"; type=\"application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"\""
|
|
1277
1282
|
}
|
|
1278
1283
|
});
|
|
1279
|
-
await t.
|
|
1284
|
+
await t.step("Link header", async () => {
|
|
1280
1285
|
(0, node_assert.deepStrictEqual)(await fetchDocumentLoader("https://example.com/link-ctx"), {
|
|
1281
1286
|
contextUrl: "https://www.w3.org/ns/activitystreams",
|
|
1282
1287
|
documentUrl: "https://example.com/link-ctx",
|
|
@@ -1297,7 +1302,7 @@ var esm_default = new class FetchMock {
|
|
|
1297
1302
|
}
|
|
1298
1303
|
});
|
|
1299
1304
|
});
|
|
1300
|
-
await t.
|
|
1305
|
+
await t.step("Link header relative url", async () => {
|
|
1301
1306
|
(0, node_assert.deepStrictEqual)(await fetchDocumentLoader("https://example.com/link-ctx"), {
|
|
1302
1307
|
contextUrl: "https://www.w3.org/ns/activitystreams",
|
|
1303
1308
|
documentUrl: "https://example.com/link-ctx",
|
|
@@ -1318,7 +1323,7 @@ var esm_default = new class FetchMock {
|
|
|
1318
1323
|
}
|
|
1319
1324
|
});
|
|
1320
1325
|
});
|
|
1321
|
-
await t.
|
|
1326
|
+
await t.step("wrong Link header syntax", async () => {
|
|
1322
1327
|
(0, node_assert.deepStrictEqual)(await fetchDocumentLoader("https://example.com/obj-w-wrong-link"), {
|
|
1323
1328
|
contextUrl: null,
|
|
1324
1329
|
documentUrl: "https://example.com/obj-w-wrong-link",
|
|
@@ -1342,7 +1347,7 @@ var esm_default = new class FetchMock {
|
|
|
1342
1347
|
</html>`,
|
|
1343
1348
|
headers: { "Content-Type": "text/html; charset=utf-8" }
|
|
1344
1349
|
});
|
|
1345
|
-
await t.
|
|
1350
|
+
await t.step("HTML <link>", async () => {
|
|
1346
1351
|
(0, node_assert.deepStrictEqual)(await fetchDocumentLoader("https://example.com/html-link"), {
|
|
1347
1352
|
contextUrl: null,
|
|
1348
1353
|
documentUrl: "https://example.com/object",
|
|
@@ -1366,7 +1371,7 @@ var esm_default = new class FetchMock {
|
|
|
1366
1371
|
</html>`,
|
|
1367
1372
|
headers: { "Content-Type": "application/xhtml+xml; charset=utf-8" }
|
|
1368
1373
|
});
|
|
1369
|
-
await t.
|
|
1374
|
+
await t.step("XHTML <link>", async () => {
|
|
1370
1375
|
(0, node_assert.deepStrictEqual)(await fetchDocumentLoader("https://example.com/xhtml-link"), {
|
|
1371
1376
|
contextUrl: null,
|
|
1372
1377
|
documentUrl: "https://example.com/object",
|
|
@@ -1392,7 +1397,7 @@ var esm_default = new class FetchMock {
|
|
|
1392
1397
|
</html>`,
|
|
1393
1398
|
headers: { "Content-Type": "text/html; charset=utf-8" }
|
|
1394
1399
|
});
|
|
1395
|
-
await t.
|
|
1400
|
+
await t.step("HTML <a>", async () => {
|
|
1396
1401
|
(0, node_assert.deepStrictEqual)(await fetchDocumentLoader("https://example.com/html-a"), {
|
|
1397
1402
|
contextUrl: null,
|
|
1398
1403
|
documentUrl: "https://example.com/object",
|
|
@@ -1413,7 +1418,7 @@ var esm_default = new class FetchMock {
|
|
|
1413
1418
|
},
|
|
1414
1419
|
headers: { "Content-Type": "text/html; charset=utf-8" }
|
|
1415
1420
|
});
|
|
1416
|
-
await t.
|
|
1421
|
+
await t.step("Wrong Content-Type", async () => {
|
|
1417
1422
|
(0, node_assert.deepStrictEqual)(await fetchDocumentLoader("https://example.com/wrong-content-type"), {
|
|
1418
1423
|
contextUrl: null,
|
|
1419
1424
|
documentUrl: "https://example.com/wrong-content-type",
|
|
@@ -1426,18 +1431,33 @@ var esm_default = new class FetchMock {
|
|
|
1426
1431
|
});
|
|
1427
1432
|
});
|
|
1428
1433
|
esm_default.get("https://example.com/404", { status: 404 });
|
|
1429
|
-
await t.
|
|
1434
|
+
await t.step("not ok", async () => {
|
|
1430
1435
|
await (0, node_assert.rejects)(() => fetchDocumentLoader("https://example.com/404"), require_request.FetchError, "HTTP 404: https://example.com/404");
|
|
1431
1436
|
});
|
|
1432
|
-
await t.
|
|
1437
|
+
await t.step("preloaded contexts", async () => {
|
|
1433
1438
|
for (const [url, document] of Object.entries(require_docloader.preloadedContexts)) (0, node_assert.deepStrictEqual)(await fetchDocumentLoader(url), {
|
|
1434
1439
|
contextUrl: null,
|
|
1435
1440
|
documentUrl: url,
|
|
1436
1441
|
document
|
|
1437
1442
|
});
|
|
1438
1443
|
});
|
|
1444
|
+
await t.step("preloaded Mastodon attribution domains", async () => {
|
|
1445
|
+
const context = ["https://www.w3.org/ns/activitystreams", "http://joinmastodon.org/ns"];
|
|
1446
|
+
const expanded = await jsonld_default.expand({
|
|
1447
|
+
"@context": context,
|
|
1448
|
+
id: "https://social.example/users/alice",
|
|
1449
|
+
type: "Person",
|
|
1450
|
+
attributionDomains: ["blog.example"]
|
|
1451
|
+
}, { documentLoader: fetchDocumentLoader });
|
|
1452
|
+
(0, node_assert.deepStrictEqual)(expanded, [{
|
|
1453
|
+
"@id": "https://social.example/users/alice",
|
|
1454
|
+
"@type": ["https://www.w3.org/ns/activitystreams#Person"],
|
|
1455
|
+
"http://joinmastodon.org/ns#attributionDomains": [{ "@value": "blog.example" }]
|
|
1456
|
+
}]);
|
|
1457
|
+
(0, node_assert.deepStrictEqual)((await jsonld_default.compact(expanded, context, { documentLoader: fetchDocumentLoader })).attributionDomains, ["blog.example"]);
|
|
1458
|
+
});
|
|
1439
1459
|
esm_default.get("https://www.w3.org/ns/cid/v1", { status: 503 });
|
|
1440
|
-
await t.
|
|
1460
|
+
await t.step("preloaded CID v1 context", async () => {
|
|
1441
1461
|
const url = "https://www.w3.org/ns/cid/v1";
|
|
1442
1462
|
(0, node_assert.deepStrictEqual)(await fetchDocumentLoader(url), {
|
|
1443
1463
|
contextUrl: null,
|
|
@@ -1445,7 +1465,7 @@ var esm_default = new class FetchMock {
|
|
|
1445
1465
|
document: require_docloader.cid_v1_default
|
|
1446
1466
|
});
|
|
1447
1467
|
});
|
|
1448
|
-
await t.
|
|
1468
|
+
await t.step("preloaded FEP-ef61 context", async () => {
|
|
1449
1469
|
const url = "https://w3id.org/fep/ef61";
|
|
1450
1470
|
(0, node_assert.ok)(url in require_docloader.preloadedContexts);
|
|
1451
1471
|
(0, node_assert.deepStrictEqual)(await fetchDocumentLoader(url), {
|
|
@@ -1462,7 +1482,7 @@ var esm_default = new class FetchMock {
|
|
|
1462
1482
|
});
|
|
1463
1483
|
});
|
|
1464
1484
|
esm_default.get("https://w3id.org/fep/7aa9", { status: 502 });
|
|
1465
|
-
await t.
|
|
1485
|
+
await t.step("preloaded FEP-7aa9 context", async () => {
|
|
1466
1486
|
const url = "https://w3id.org/fep/7aa9";
|
|
1467
1487
|
(0, node_assert.deepStrictEqual)(await fetchDocumentLoader(url), {
|
|
1468
1488
|
contextUrl: null,
|
|
@@ -1492,7 +1512,115 @@ var esm_default = new class FetchMock {
|
|
|
1492
1512
|
});
|
|
1493
1513
|
(0, node_assert.deepStrictEqual)(esm_default.callHistory.calls(url).length, 0);
|
|
1494
1514
|
});
|
|
1495
|
-
|
|
1515
|
+
esm_default.get("https://w3id.org/fep/6757", { status: 502 });
|
|
1516
|
+
await t.step("preloaded FEP-6757 context", async () => {
|
|
1517
|
+
const url = "https://w3id.org/fep/6757";
|
|
1518
|
+
(0, node_assert.deepStrictEqual)(await fetchDocumentLoader(url), {
|
|
1519
|
+
contextUrl: null,
|
|
1520
|
+
documentUrl: url,
|
|
1521
|
+
document: { "@context": {
|
|
1522
|
+
license: {
|
|
1523
|
+
"@id": "http://purl.org/dc/terms/license",
|
|
1524
|
+
"@type": "@id"
|
|
1525
|
+
},
|
|
1526
|
+
preferredLicense: {
|
|
1527
|
+
"@id": "https://w3id.org/fep/6757#preferredLicense",
|
|
1528
|
+
"@type": "@id"
|
|
1529
|
+
}
|
|
1530
|
+
} }
|
|
1531
|
+
});
|
|
1532
|
+
(0, node_assert.deepStrictEqual)(await jsonld_default.expand({
|
|
1533
|
+
"@context": ["https://www.w3.org/ns/activitystreams", url],
|
|
1534
|
+
type: "Person",
|
|
1535
|
+
license: "https://creativecommons.org/licenses/by/4.0/",
|
|
1536
|
+
preferredLicense: "https://creativecommons.org/licenses/by-nc/4.0/"
|
|
1537
|
+
}, { documentLoader: fetchDocumentLoader }), [{
|
|
1538
|
+
"@type": ["https://www.w3.org/ns/activitystreams#Person"],
|
|
1539
|
+
"http://purl.org/dc/terms/license": [{ "@id": "https://creativecommons.org/licenses/by/4.0/" }],
|
|
1540
|
+
"https://w3id.org/fep/6757#preferredLicense": [{ "@id": "https://creativecommons.org/licenses/by-nc/4.0/" }]
|
|
1541
|
+
}]);
|
|
1542
|
+
(0, node_assert.deepStrictEqual)(esm_default.callHistory.calls(url).length, 0);
|
|
1543
|
+
});
|
|
1544
|
+
esm_default.get("https://w3id.org/fep/22cd", { status: 502 });
|
|
1545
|
+
await t.step("preloaded FEP-22cd context", async () => {
|
|
1546
|
+
const url = "https://w3id.org/fep/22cd";
|
|
1547
|
+
const articleId = "https://example.com/articles/1";
|
|
1548
|
+
const translatorId = "https://example.com/users/alice";
|
|
1549
|
+
const revisionId = "https://example.com/articles/1/revisions/1";
|
|
1550
|
+
(0, node_assert.deepStrictEqual)(await fetchDocumentLoader(url), {
|
|
1551
|
+
contextUrl: null,
|
|
1552
|
+
documentUrl: url,
|
|
1553
|
+
document: { "@context": {
|
|
1554
|
+
"fep-22cd": "https://w3id.org/fep/22cd#",
|
|
1555
|
+
schema: "https://schema.org/",
|
|
1556
|
+
xsd: "http://www.w3.org/2001/XMLSchema#",
|
|
1557
|
+
translations: {
|
|
1558
|
+
"@id": "fep-22cd:translations",
|
|
1559
|
+
"@container": "@set"
|
|
1560
|
+
},
|
|
1561
|
+
Translation: "fep-22cd:Translation",
|
|
1562
|
+
sourceUpdated: {
|
|
1563
|
+
"@id": "fep-22cd:sourceUpdated",
|
|
1564
|
+
"@type": "xsd:dateTime"
|
|
1565
|
+
},
|
|
1566
|
+
translator: {
|
|
1567
|
+
"@id": "schema:translator",
|
|
1568
|
+
"@type": "@id",
|
|
1569
|
+
"@container": "@set"
|
|
1570
|
+
},
|
|
1571
|
+
inLanguage: "schema:inLanguage",
|
|
1572
|
+
translationOfWork: {
|
|
1573
|
+
"@id": "schema:translationOfWork",
|
|
1574
|
+
"@type": "@id"
|
|
1575
|
+
},
|
|
1576
|
+
isBasedOn: {
|
|
1577
|
+
"@id": "schema:isBasedOn",
|
|
1578
|
+
"@type": "@id"
|
|
1579
|
+
}
|
|
1580
|
+
} }
|
|
1581
|
+
});
|
|
1582
|
+
(0, node_assert.deepStrictEqual)(await jsonld_default.expand({
|
|
1583
|
+
"@context": ["https://www.w3.org/ns/activitystreams", url],
|
|
1584
|
+
id: articleId,
|
|
1585
|
+
type: "Article",
|
|
1586
|
+
contentMap: {
|
|
1587
|
+
en: "Original",
|
|
1588
|
+
ko: "Translation"
|
|
1589
|
+
},
|
|
1590
|
+
translations: [{
|
|
1591
|
+
type: "Translation",
|
|
1592
|
+
inLanguage: "ko",
|
|
1593
|
+
translator: [translatorId],
|
|
1594
|
+
translationOfWork: articleId,
|
|
1595
|
+
sourceUpdated: "2026-09-01T00:00:00Z",
|
|
1596
|
+
isBasedOn: revisionId
|
|
1597
|
+
}]
|
|
1598
|
+
}, { documentLoader: fetchDocumentLoader }), [{
|
|
1599
|
+
"@id": articleId,
|
|
1600
|
+
"@type": ["https://www.w3.org/ns/activitystreams#Article"],
|
|
1601
|
+
"https://www.w3.org/ns/activitystreams#content": [{
|
|
1602
|
+
"@language": "en",
|
|
1603
|
+
"@value": "Original"
|
|
1604
|
+
}, {
|
|
1605
|
+
"@language": "ko",
|
|
1606
|
+
"@value": "Translation"
|
|
1607
|
+
}],
|
|
1608
|
+
"https://w3id.org/fep/22cd#translations": [{
|
|
1609
|
+
"@type": ["https://w3id.org/fep/22cd#Translation"],
|
|
1610
|
+
"https://schema.org/inLanguage": [{ "@value": "ko" }],
|
|
1611
|
+
"https://schema.org/translator": [{ "@id": translatorId }],
|
|
1612
|
+
"https://schema.org/translationOfWork": [{ "@id": articleId }],
|
|
1613
|
+
"https://w3id.org/fep/22cd#sourceUpdated": [{
|
|
1614
|
+
"@type": "http://www.w3.org/2001/XMLSchema#dateTime",
|
|
1615
|
+
"@value": "2026-09-01T00:00:00Z"
|
|
1616
|
+
}],
|
|
1617
|
+
"https://schema.org/isBasedOn": [{ "@id": revisionId }]
|
|
1618
|
+
}]
|
|
1619
|
+
}]);
|
|
1620
|
+
(0, node_assert.deepStrictEqual)(esm_default.callHistory.calls(url).length, 0);
|
|
1621
|
+
(0, node_assert.deepStrictEqual)(esm_default.callHistory.calls("https://www.w3.org/ns/activitystreams").length, 0);
|
|
1622
|
+
});
|
|
1623
|
+
await t.step("deny non-HTTP/HTTPS", async () => {
|
|
1496
1624
|
await (0, node_assert.rejects)(() => fetchDocumentLoader("ftp://localhost"), require_url.UrlError);
|
|
1497
1625
|
});
|
|
1498
1626
|
esm_default.get("https://example.com/localhost-redirect", {
|
|
@@ -1517,13 +1645,13 @@ var esm_default = new class FetchMock {
|
|
|
1517
1645
|
name: "Fetched object",
|
|
1518
1646
|
type: "Object"
|
|
1519
1647
|
} });
|
|
1520
|
-
await t.
|
|
1648
|
+
await t.step("allowPrivateAddress: false", async () => {
|
|
1521
1649
|
await (0, node_assert.rejects)(() => fetchDocumentLoader("https://localhost/object"), require_url.UrlError);
|
|
1522
1650
|
await (0, node_assert.rejects)(() => fetchDocumentLoader("https://example.com/localhost-redirect"), require_url.UrlError);
|
|
1523
1651
|
await (0, node_assert.rejects)(() => fetchDocumentLoader("https://example.com/localhost-link"), require_url.UrlError);
|
|
1524
1652
|
});
|
|
1525
1653
|
const fetchDocumentLoader2 = require_docloader.getDocumentLoader({ allowPrivateAddress: true });
|
|
1526
|
-
await t.
|
|
1654
|
+
await t.step("allowPrivateAddress: true", async () => {
|
|
1527
1655
|
const expected = {
|
|
1528
1656
|
contextUrl: null,
|
|
1529
1657
|
documentUrl: "https://localhost/object",
|
|
@@ -1546,7 +1674,7 @@ var esm_default = new class FetchMock {
|
|
|
1546
1674
|
headers: { Location: `https://example.com/too-many-redirects/${Number(cl.url.split("/").at(-1)) + 1}` }
|
|
1547
1675
|
};
|
|
1548
1676
|
});
|
|
1549
|
-
await t.
|
|
1677
|
+
await t.step("too many redirects", async () => {
|
|
1550
1678
|
redirectAttempts = 0;
|
|
1551
1679
|
await (0, node_assert.rejects)(() => fetchDocumentLoader("https://example.com/too-many-redirects/0"), require_request.FetchError, "Too many redirections");
|
|
1552
1680
|
(0, node_assert.deepStrictEqual)(redirectAttempts, 21);
|
|
@@ -1566,7 +1694,7 @@ var esm_default = new class FetchMock {
|
|
|
1566
1694
|
headers: { Location: "https://example.com/redirect-loop-a" }
|
|
1567
1695
|
};
|
|
1568
1696
|
});
|
|
1569
|
-
await t.
|
|
1697
|
+
await t.step("redirect loop", async () => {
|
|
1570
1698
|
loopAttempts = 0;
|
|
1571
1699
|
await (0, node_assert.rejects)(() => fetchDocumentLoader("https://example.com/redirect-loop-a"), require_request.FetchError, "Redirect loop detected");
|
|
1572
1700
|
(0, node_assert.deepStrictEqual)(loopAttempts, 2);
|
|
@@ -1579,7 +1707,7 @@ var esm_default = new class FetchMock {
|
|
|
1579
1707
|
headers: { Location: "/redirect-loop-relative" }
|
|
1580
1708
|
};
|
|
1581
1709
|
});
|
|
1582
|
-
await t.
|
|
1710
|
+
await t.step("redirect loop with relative location", async () => {
|
|
1583
1711
|
relativeLoopAttempts = 0;
|
|
1584
1712
|
await (0, node_assert.rejects)(() => fetchDocumentLoader("https://example.com/redirect-loop-relative"), require_request.FetchError, "Redirect loop detected");
|
|
1585
1713
|
(0, node_assert.deepStrictEqual)(relativeLoopAttempts, 1);
|
|
@@ -1589,7 +1717,7 @@ var esm_default = new class FetchMock {
|
|
|
1589
1717
|
body: maliciousPayload,
|
|
1590
1718
|
headers: { "Content-Type": "text/html; charset=utf-8" }
|
|
1591
1719
|
});
|
|
1592
|
-
await t.
|
|
1720
|
+
await t.step("ReDoS resistance (CVE-2025-68475)", async () => {
|
|
1593
1721
|
const start = performance.now();
|
|
1594
1722
|
await (0, node_assert.rejects)(() => fetchDocumentLoader("https://example.com/redos"), SyntaxError);
|
|
1595
1723
|
const elapsed = performance.now() - start;
|
|
@@ -1597,7 +1725,7 @@ var esm_default = new class FetchMock {
|
|
|
1597
1725
|
});
|
|
1598
1726
|
esm_default.hardReset();
|
|
1599
1727
|
});
|
|
1600
|
-
(0,
|
|
1728
|
+
(0, _fedify_fixture.test)("getDocumentLoader() bounds JSON, HTML, and alternate documents", async () => {
|
|
1601
1729
|
const url = "https://example.com/bounded";
|
|
1602
1730
|
esm_default.mockGlobal();
|
|
1603
1731
|
let oversized = true;
|
|
@@ -1627,7 +1755,7 @@ var esm_default = new class FetchMock {
|
|
|
1627
1755
|
esm_default.hardReset();
|
|
1628
1756
|
}
|
|
1629
1757
|
});
|
|
1630
|
-
(0,
|
|
1758
|
+
(0, _fedify_fixture.test)("getDocumentLoader() rejects oversized gzip responses from fetch", async () => {
|
|
1631
1759
|
const document = { name: "a".repeat(16 * 1024 * 1024) };
|
|
1632
1760
|
const compressed = (0, node_zlib.gzipSync)(JSON.stringify(document));
|
|
1633
1761
|
(0, node_assert.ok)(compressed.byteLength < 64 * 1024);
|
|
@@ -1657,7 +1785,7 @@ var esm_default = new class FetchMock {
|
|
|
1657
1785
|
});
|
|
1658
1786
|
}
|
|
1659
1787
|
});
|
|
1660
|
-
(0,
|
|
1788
|
+
(0, _fedify_fixture.test)("getRemoteDocument() bounds JSON by default", async () => {
|
|
1661
1789
|
let canceled = false;
|
|
1662
1790
|
let pulls = 0;
|
|
1663
1791
|
await (0, node_assert.rejects)(require_docloader.getRemoteDocument("https://example.com/document", new Response(new ReadableStream({
|
|
@@ -1674,17 +1802,14 @@ var esm_default = new class FetchMock {
|
|
|
1674
1802
|
(0, node_assert.deepStrictEqual)(canceled, true);
|
|
1675
1803
|
(0, node_assert.deepStrictEqual)(pulls, 257);
|
|
1676
1804
|
});
|
|
1677
|
-
(0,
|
|
1678
|
-
if ("Deno" in globalThis && (await Deno.permissions.query({ name: "net" })).state !== "granted")
|
|
1679
|
-
t.skip("requires the net permission");
|
|
1680
|
-
return;
|
|
1681
|
-
}
|
|
1805
|
+
(0, _fedify_fixture.test)("getDocumentLoader() logs DNS failures as such", async (t) => {
|
|
1806
|
+
if ("Deno" in globalThis && (await Deno.permissions.query({ name: "net" })).state !== "granted") throw new Error("This DNS test requires Deno network permission (--allow-net).");
|
|
1682
1807
|
const loader = require_docloader.getDocumentLoader();
|
|
1683
1808
|
for (const result of [
|
|
1684
1809
|
"throws",
|
|
1685
1810
|
"empty",
|
|
1686
1811
|
"private"
|
|
1687
|
-
]) await t.
|
|
1812
|
+
]) await t.step(result, async () => {
|
|
1688
1813
|
const originalLookup = node_dns_promises.default.lookup;
|
|
1689
1814
|
node_dns_promises.default.lookup = (() => result === "throws" ? Promise.reject(/* @__PURE__ */ new Error("Resolver unavailable")) : Promise.resolve(result === "empty" ? [] : [{
|
|
1690
1815
|
address: "127.0.0.1",
|
|
@@ -1732,14 +1857,14 @@ var esm_default = new class FetchMock {
|
|
|
1732
1857
|
}
|
|
1733
1858
|
});
|
|
1734
1859
|
});
|
|
1735
|
-
(0,
|
|
1860
|
+
(0, _fedify_fixture.test)("getDocumentLoader() bounds alternate document chains", async (t) => {
|
|
1736
1861
|
const base = "https://example.com/alternate-chain/";
|
|
1737
1862
|
const loader = require_docloader.getDocumentLoader({ allowPrivateAddress: true });
|
|
1738
1863
|
for (const mode of [
|
|
1739
1864
|
"header",
|
|
1740
1865
|
"html",
|
|
1741
1866
|
"mixed"
|
|
1742
|
-
]) for (const hops of [20, 21]) await t.
|
|
1867
|
+
]) for (const hops of [20, 21]) await t.step(`${mode}: ${hops} hops`, async () => {
|
|
1743
1868
|
esm_default.mockGlobal();
|
|
1744
1869
|
let requests = 0;
|
|
1745
1870
|
esm_default.get(`begin:${base}`, ({ url }) => {
|
|
@@ -1768,7 +1893,7 @@ var esm_default = new class FetchMock {
|
|
|
1768
1893
|
"alternate-redirect",
|
|
1769
1894
|
"redirect-alternate",
|
|
1770
1895
|
"redirect-intermediate"
|
|
1771
|
-
]) await t.
|
|
1896
|
+
]) await t.step(`${mode}: cycle`, async () => {
|
|
1772
1897
|
esm_default.mockGlobal();
|
|
1773
1898
|
let requests = 0;
|
|
1774
1899
|
esm_default.get(`begin:${base}`, ({ url }) => {
|
|
@@ -1790,7 +1915,7 @@ var esm_default = new class FetchMock {
|
|
|
1790
1915
|
esm_default.hardReset();
|
|
1791
1916
|
}
|
|
1792
1917
|
});
|
|
1793
|
-
await t.
|
|
1918
|
+
await t.step("alternate followed by 20 redirects shares the limit", async () => {
|
|
1794
1919
|
esm_default.mockGlobal();
|
|
1795
1920
|
let requests = 0;
|
|
1796
1921
|
esm_default.get(`begin:${base}`, ({ url }) => {
|
|
@@ -1810,7 +1935,7 @@ var esm_default = new class FetchMock {
|
|
|
1810
1935
|
esm_default.hardReset();
|
|
1811
1936
|
}
|
|
1812
1937
|
});
|
|
1813
|
-
await t.
|
|
1938
|
+
await t.step("relative alternate after redirect and isolated calls", async () => {
|
|
1814
1939
|
esm_default.mockGlobal();
|
|
1815
1940
|
esm_default.get(`${base}start`, Response.redirect(`${base}html`, 302));
|
|
1816
1941
|
esm_default.get(`${base}html`, alternate("./document", true));
|
|
@@ -1834,10 +1959,10 @@ var esm_default = new class FetchMock {
|
|
|
1834
1959
|
} });
|
|
1835
1960
|
}
|
|
1836
1961
|
});
|
|
1837
|
-
(0,
|
|
1962
|
+
(0, _fedify_fixture.test)("getDocumentLoader() preserves cancellation across alternates", async (t) => {
|
|
1838
1963
|
const base = "https://example.com/alternate-abort/";
|
|
1839
1964
|
const loader = require_docloader.getDocumentLoader({ allowPrivateAddress: true });
|
|
1840
|
-
for (const html of [false, true]) await t.
|
|
1965
|
+
for (const html of [false, true]) await t.step(html ? "HTML" : "Link header", async () => {
|
|
1841
1966
|
esm_default.mockGlobal();
|
|
1842
1967
|
const controller = new AbortController();
|
|
1843
1968
|
let requests = 0;
|
|
@@ -1860,7 +1985,7 @@ var esm_default = new class FetchMock {
|
|
|
1860
1985
|
}
|
|
1861
1986
|
});
|
|
1862
1987
|
});
|
|
1863
|
-
(0,
|
|
1988
|
+
(0, _fedify_fixture.test)("getDocumentLoader() rejects cancellation before fetching", async () => {
|
|
1864
1989
|
esm_default.mockGlobal();
|
|
1865
1990
|
let requests = 0;
|
|
1866
1991
|
const url = "https://example.com/pre-aborted-alternate";
|