@fedify/vocab-runtime 2.4.0-dev.1567 → 2.4.0-dev.1570

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 (48) hide show
  1. package/deno.json +1 -2
  2. package/dist/mod.cjs +190 -178
  3. package/dist/mod.d.cts +190 -59
  4. package/dist/mod.d.ts +190 -59
  5. package/dist/mod.js +184 -165
  6. package/dist/tests/decimal.test.cjs +3 -3
  7. package/dist/tests/decimal.test.mjs +3 -3
  8. package/dist/tests/{docloader-D61oV0K1.mjs → docloader-C76ldE5C.mjs} +10 -97
  9. package/dist/tests/{docloader-BcaQHb0Q.cjs → docloader-mvgIWKI7.cjs} +9 -102
  10. package/dist/tests/docloader.test.cjs +6 -58
  11. package/dist/tests/docloader.test.mjs +6 -58
  12. package/dist/tests/{key-CDGDH_vC.mjs → key-CrrK9mYh.mjs} +1 -69
  13. package/dist/tests/{key-_wXwomh_.cjs → key-pMmqUKuo.cjs} +0 -86
  14. package/dist/tests/key.test.cjs +1 -48
  15. package/dist/tests/key.test.mjs +1 -48
  16. package/dist/tests/{request-Cn0vP7Hj.mjs → request-BEXkv1ul.mjs} +1 -1
  17. package/dist/tests/{request-DnNWah97.cjs → request-SworbvLc.cjs} +1 -1
  18. package/dist/tests/request.test.cjs +1 -1
  19. package/dist/tests/request.test.mjs +1 -1
  20. package/dist/tests/{url-2XwVbUS_.cjs → url-C20FhC7p.cjs} +0 -108
  21. package/dist/tests/{url-YWJbnRlf.mjs → url-m9Qzxy-Y.mjs} +1 -85
  22. package/dist/tests/url.test.cjs +1 -104
  23. package/dist/tests/url.test.mjs +2 -105
  24. package/package.json +1 -11
  25. package/src/contexts.ts +0 -2
  26. package/src/docloader.test.ts +6 -102
  27. package/src/docloader.ts +8 -76
  28. package/src/key.test.ts +0 -86
  29. package/src/key.ts +0 -125
  30. package/src/mod.ts +0 -8
  31. package/src/url.test.ts +1 -252
  32. package/src/url.ts +0 -141
  33. package/tsdown.config.ts +1 -6
  34. package/dist/docloader-DnUMWHaJ.d.cts +0 -202
  35. package/dist/docloader-xRGn1azD.d.ts +0 -202
  36. package/dist/internal/jsonld-cache.cjs +0 -279
  37. package/dist/internal/jsonld-cache.d.cts +0 -48
  38. package/dist/internal/jsonld-cache.d.ts +0 -48
  39. package/dist/internal/jsonld-cache.js +0 -275
  40. package/dist/tests/jsonld-cache.test.cjs +0 -652
  41. package/dist/tests/jsonld-cache.test.d.cts +0 -1
  42. package/dist/tests/jsonld-cache.test.d.mts +0 -1
  43. package/dist/tests/jsonld-cache.test.mjs +0 -651
  44. package/dist/url-BAdyyqAa.cjs +0 -315
  45. package/dist/url-BuxPHxK2.js +0 -261
  46. package/src/contexts/fep-7aa9.json +0 -24
  47. package/src/internal/jsonld-cache.ts +0 -538
  48. package/src/jsonld-cache.test.ts +0 -554
@@ -1,7 +1,7 @@
1
1
  require("./chunk-C2EiDwsr.cjs");
2
- const require_request = require("./request-DnNWah97.cjs");
2
+ const require_request = require("./request-SworbvLc.cjs");
3
3
  const require_link = require("./link-FguCydMA.cjs");
4
- const require_url = require("./url-2XwVbUS_.cjs");
4
+ const require_url = require("./url-C20FhC7p.cjs");
5
5
  let _logtape_logtape = require("@logtape/logtape");
6
6
  let _opentelemetry_api = require("@opentelemetry/api");
7
7
  //#endregion
@@ -4278,28 +4278,6 @@ const preloadedContexts = {
4278
4278
  "@type": "@id"
4279
4279
  }
4280
4280
  } },
4281
- "https://w3id.org/fep/7aa9": { "@context": {
4282
- "FeaturedCollection": "https://w3id.org/fep/7aa9#FeaturedCollection",
4283
- "FeaturedItem": "https://w3id.org/fep/7aa9#FeaturedItem",
4284
- "FeatureRequest": "https://w3id.org/fep/7aa9#FeatureRequest",
4285
- "FeatureAuthorization": "https://w3id.org/fep/7aa9#FeatureAuthorization",
4286
- "topic": {
4287
- "@id": "https://w3id.org/fep/7aa9#topic",
4288
- "@type": "@id"
4289
- },
4290
- "featuredObject": {
4291
- "@id": "https://w3id.org/fep/7aa9#featuredObject",
4292
- "@type": "@id"
4293
- },
4294
- "canFeature": {
4295
- "@id": "https://w3id.org/fep/7aa9#canFeature",
4296
- "@type": "@id"
4297
- },
4298
- "featureAuthorization": {
4299
- "@id": "https://w3id.org/fep/7aa9#featureAuthorization",
4300
- "@type": "@id"
4301
- }
4302
- } },
4303
4281
  "https://join-lemmy.org/context.json": { "@context": ["https://w3id.org/security/v1", {
4304
4282
  "as": "https://www.w3.org/ns/activitystreams#",
4305
4283
  "lemmy": "https://join-lemmy.org/ns#",
@@ -4363,66 +4341,6 @@ const logger = (0, _logtape_logtape.getLogger)([
4363
4341
  "docloader"
4364
4342
  ]);
4365
4343
  const DEFAULT_MAX_REDIRECTION = 20;
4366
- const MAX_HTML_SIZE = 1024 * 1024;
4367
- function createResponseMetadata(response) {
4368
- return new Response(null, {
4369
- headers: response.headers,
4370
- status: response.status,
4371
- statusText: response.statusText
4372
- });
4373
- }
4374
- async function cancelResponseBody(response) {
4375
- if (response.body != null) await response.body.cancel();
4376
- }
4377
- async function readBoundedText(response, maxBytes) {
4378
- const contentLength = response.headers.get("Content-Length");
4379
- if (contentLength != null) {
4380
- const size = Number(contentLength);
4381
- if (size > maxBytes) {
4382
- await cancelResponseBody(response);
4383
- return {
4384
- text: "",
4385
- size,
4386
- tooLarge: true
4387
- };
4388
- }
4389
- }
4390
- if (response.body == null) return {
4391
- text: "",
4392
- size: 0,
4393
- tooLarge: false
4394
- };
4395
- const reader = response.body.getReader();
4396
- const decoder = new TextDecoder();
4397
- let text = "";
4398
- let size = 0;
4399
- try {
4400
- while (true) {
4401
- const result = await reader.read();
4402
- if (result.done) break;
4403
- const chunkSize = result.value.byteLength;
4404
- if (size + chunkSize > maxBytes) {
4405
- size += chunkSize;
4406
- await reader.cancel();
4407
- return {
4408
- text: "",
4409
- size,
4410
- tooLarge: true
4411
- };
4412
- }
4413
- size += chunkSize;
4414
- text += decoder.decode(result.value, { stream: true });
4415
- }
4416
- text += decoder.decode();
4417
- return {
4418
- text,
4419
- size,
4420
- tooLarge: false
4421
- };
4422
- } finally {
4423
- reader.releaseLock();
4424
- }
4425
- }
4426
4344
  /**
4427
4345
  * Gets a {@link RemoteDocument} from the given response.
4428
4346
  * @param url The URL of the document to load.
@@ -4477,19 +4395,19 @@ async function getRemoteDocument(url, response, fetch) {
4477
4395
  }
4478
4396
  let document;
4479
4397
  if (!jsonLd && (contentType === "text/html" || contentType?.startsWith("text/html;") || contentType === "application/xhtml+xml" || contentType?.startsWith("application/xhtml+xml;"))) {
4480
- const errorResponse = createResponseMetadata(response);
4481
- const html = await readBoundedText(response, MAX_HTML_SIZE);
4482
- if (html.tooLarge) {
4398
+ const MAX_HTML_SIZE = 1024 * 1024;
4399
+ const html = await response.text();
4400
+ if (html.length > MAX_HTML_SIZE) {
4483
4401
  logger.warn("HTML response too large, skipping alternate link discovery: {url}", {
4484
4402
  url: documentUrl,
4485
- size: html.size
4403
+ size: html.length
4486
4404
  });
4487
- throw new require_request.FetchError(documentUrl, `HTML document is too large to scan for an ActivityPub alternate link (Content-Type: ${contentType})`, errorResponse);
4405
+ document = JSON.parse(html);
4488
4406
  } else {
4489
4407
  const tagPattern = /<(a|link)\s+([^>]*?)\s*\/?>/gi;
4490
4408
  const attrPattern = /([a-z][a-z:_-]*)=(?:"([^"]*)"|'([^']*)'|([^\s>]+))/gi;
4491
4409
  let tagMatch;
4492
- while ((tagMatch = tagPattern.exec(html.text)) !== null) {
4410
+ while ((tagMatch = tagPattern.exec(html)) !== null) {
4493
4411
  const tagContent = tagMatch[2];
4494
4412
  let attrMatch;
4495
4413
  const attribs = {};
@@ -4506,12 +4424,7 @@ async function getRemoteDocument(url, response, fetch) {
4506
4424
  return await fetch(new URL(attribs.href, docUrl).href);
4507
4425
  }
4508
4426
  }
4509
- try {
4510
- document = JSON.parse(html.text);
4511
- } catch (error) {
4512
- if (!(error instanceof SyntaxError)) throw error;
4513
- throw new require_request.FetchError(documentUrl, `HTML document has no ActivityPub alternate link (Content-Type: ${contentType})`, errorResponse);
4514
- }
4427
+ document = JSON.parse(html);
4515
4428
  }
4516
4429
  } else document = await response.json();
4517
4430
  logger.debug("Fetched document: {status} {url} {headers}", {
@@ -4622,12 +4535,6 @@ Object.defineProperty(exports, "getDocumentLoader", {
4622
4535
  return getDocumentLoader;
4623
4536
  }
4624
4537
  });
4625
- Object.defineProperty(exports, "getRemoteDocument", {
4626
- enumerable: true,
4627
- get: function() {
4628
- return getRemoteDocument;
4629
- }
4630
- });
4631
4538
  Object.defineProperty(exports, "preloadedContexts", {
4632
4539
  enumerable: true,
4633
4540
  get: function() {
@@ -1,7 +1,7 @@
1
1
  const require_chunk = require("./chunk-C2EiDwsr.cjs");
2
- const require_docloader = require("./docloader-BcaQHb0Q.cjs");
3
- const require_request = require("./request-DnNWah97.cjs");
4
- const require_url = require("./url-2XwVbUS_.cjs");
2
+ const require_docloader = require("./docloader-mvgIWKI7.cjs");
3
+ const require_request = require("./request-SworbvLc.cjs");
4
+ const require_url = require("./url-C20FhC7p.cjs");
5
5
  let node_assert = require("node:assert");
6
6
  let node_test = require("node:test");
7
7
  //#region ../../node_modules/.pnpm/glob-to-regexp@0.4.1/node_modules/glob-to-regexp/index.js
@@ -1267,7 +1267,7 @@ var esm_default = new class FetchMock {
1267
1267
  type: "Object"
1268
1268
  },
1269
1269
  headers: {
1270
- "Content-Type": "application/activity+json",
1270
+ "Content-Type": "text/html; charset=utf-8",
1271
1271
  Link: "<https://example.com/object>; rel=\"alternate\"; type=\"application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"\""
1272
1272
  }
1273
1273
  });
@@ -1399,27 +1399,6 @@ var esm_default = new class FetchMock {
1399
1399
  }
1400
1400
  });
1401
1401
  });
1402
- esm_default.get("https://example.com/html-no-alternate", {
1403
- body: `<!DOCTYPE html>
1404
- <html>
1405
- <head>
1406
- <title>Not an ActivityPub document</title>
1407
- </head>
1408
- <body>Not found</body>
1409
- </html>`,
1410
- headers: { "Content-Type": "text/html; charset=utf-8" }
1411
- });
1412
- await t.test("HTML without ActivityPub alternate link", async () => {
1413
- await (0, node_assert.rejects)(() => fetchDocumentLoader("https://example.com/html-no-alternate"), (error) => {
1414
- (0, node_assert.ok)(error instanceof require_request.FetchError);
1415
- (0, node_assert.ok)(error.message.includes("HTML document has no ActivityPub alternate link"));
1416
- (0, node_assert.ok)(error.message.includes("Content-Type: text/html; charset=utf-8"));
1417
- (0, node_assert.deepStrictEqual)(error.url, new URL("https://example.com/html-no-alternate"));
1418
- (0, node_assert.ok)(error.response != null);
1419
- (0, node_assert.deepStrictEqual)(error.response.headers.get("Content-Type"), "text/html; charset=utf-8");
1420
- return true;
1421
- });
1422
- });
1423
1402
  esm_default.get("https://example.com/wrong-content-type", {
1424
1403
  body: {
1425
1404
  "@context": "https://www.w3.org/ns/activitystreams",
@@ -1429,7 +1408,7 @@ var esm_default = new class FetchMock {
1429
1408
  },
1430
1409
  headers: { "Content-Type": "text/html; charset=utf-8" }
1431
1410
  });
1432
- await t.test("wrong Content-Type with JSON body", async () => {
1411
+ await t.test("Wrong Content-Type", async () => {
1433
1412
  (0, node_assert.deepStrictEqual)(await fetchDocumentLoader("https://example.com/wrong-content-type"), {
1434
1413
  contextUrl: null,
1435
1414
  documentUrl: "https://example.com/wrong-content-type",
@@ -1441,37 +1420,6 @@ var esm_default = new class FetchMock {
1441
1420
  }
1442
1421
  });
1443
1422
  });
1444
- esm_default.get("https://example.com/large-html", {
1445
- body: "<!DOCTYPE html>",
1446
- headers: {
1447
- "Content-Length": String(1048577),
1448
- "Content-Type": "text/html; charset=utf-8"
1449
- }
1450
- });
1451
- await t.test("HTML Content-Length over limit", async () => {
1452
- await (0, node_assert.rejects)(() => fetchDocumentLoader("https://example.com/large-html"), (error) => {
1453
- (0, node_assert.ok)(error instanceof require_request.FetchError);
1454
- (0, node_assert.ok)(error.message.includes("HTML document is too large to scan for an ActivityPub alternate link"));
1455
- (0, node_assert.ok)(error.response != null);
1456
- (0, node_assert.deepStrictEqual)(error.response.status, 200);
1457
- (0, node_assert.deepStrictEqual)(error.response.headers.get("Content-Type"), "text/html; charset=utf-8");
1458
- return true;
1459
- });
1460
- });
1461
- await t.test("HTML Content-Length over limit cancels body", async () => {
1462
- let canceled = false;
1463
- const response = new Response("<!DOCTYPE html>", { headers: {
1464
- "Content-Length": String(1048577),
1465
- "Content-Type": "text/html; charset=utf-8"
1466
- } });
1467
- Object.defineProperty(response, "body", { value: { cancel: () => {
1468
- canceled = true;
1469
- } } });
1470
- await (0, node_assert.rejects)(() => require_docloader.getRemoteDocument("https://example.com/large-html-cancel", response, () => {
1471
- throw new Error("unexpected alternate fetch");
1472
- }), require_request.FetchError);
1473
- (0, node_assert.deepStrictEqual)(canceled, true);
1474
- });
1475
1423
  esm_default.get("https://example.com/404", { status: 404 });
1476
1424
  await t.test("not ok", async () => {
1477
1425
  await (0, node_assert.rejects)(() => fetchDocumentLoader("https://example.com/404"), require_request.FetchError, "HTTP 404: https://example.com/404");
@@ -1588,7 +1536,7 @@ var esm_default = new class FetchMock {
1588
1536
  });
1589
1537
  await t.test("ReDoS resistance (CVE-2025-68475)", async () => {
1590
1538
  const start = performance.now();
1591
- await (0, node_assert.rejects)(() => fetchDocumentLoader("https://example.com/redos"), require_request.FetchError);
1539
+ await (0, node_assert.rejects)(() => fetchDocumentLoader("https://example.com/redos"), SyntaxError);
1592
1540
  const elapsed = performance.now() - start;
1593
1541
  (0, node_assert.ok)(elapsed < 1e3, `Potential ReDoS vulnerability detected: ${elapsed}ms (expected < 1000ms)`);
1594
1542
  });
@@ -1,6 +1,6 @@
1
- import { n as getRemoteDocument, r as preloadedContexts, t as getDocumentLoader } from "./docloader-D61oV0K1.mjs";
2
- import { t as FetchError } from "./request-Cn0vP7Hj.mjs";
3
- import { t as UrlError } from "./url-YWJbnRlf.mjs";
1
+ import { n as preloadedContexts, t as getDocumentLoader } from "./docloader-C76ldE5C.mjs";
2
+ import { t as FetchError } from "./request-BEXkv1ul.mjs";
3
+ import { t as UrlError } from "./url-m9Qzxy-Y.mjs";
4
4
  import { deepStrictEqual, ok, rejects } from "node:assert";
5
5
  import { test } from "node:test";
6
6
  //#region \0rolldown/runtime.js
@@ -1286,7 +1286,7 @@ test("getDocumentLoader()", async (t) => {
1286
1286
  type: "Object"
1287
1287
  },
1288
1288
  headers: {
1289
- "Content-Type": "application/activity+json",
1289
+ "Content-Type": "text/html; charset=utf-8",
1290
1290
  Link: "<https://example.com/object>; rel=\"alternate\"; type=\"application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"\""
1291
1291
  }
1292
1292
  });
@@ -1418,27 +1418,6 @@ test("getDocumentLoader()", async (t) => {
1418
1418
  }
1419
1419
  });
1420
1420
  });
1421
- esm_default.get("https://example.com/html-no-alternate", {
1422
- body: `<!DOCTYPE html>
1423
- <html>
1424
- <head>
1425
- <title>Not an ActivityPub document</title>
1426
- </head>
1427
- <body>Not found</body>
1428
- </html>`,
1429
- headers: { "Content-Type": "text/html; charset=utf-8" }
1430
- });
1431
- await t.test("HTML without ActivityPub alternate link", async () => {
1432
- await rejects(() => fetchDocumentLoader("https://example.com/html-no-alternate"), (error) => {
1433
- ok(error instanceof FetchError);
1434
- ok(error.message.includes("HTML document has no ActivityPub alternate link"));
1435
- ok(error.message.includes("Content-Type: text/html; charset=utf-8"));
1436
- deepStrictEqual(error.url, new URL("https://example.com/html-no-alternate"));
1437
- ok(error.response != null);
1438
- deepStrictEqual(error.response.headers.get("Content-Type"), "text/html; charset=utf-8");
1439
- return true;
1440
- });
1441
- });
1442
1421
  esm_default.get("https://example.com/wrong-content-type", {
1443
1422
  body: {
1444
1423
  "@context": "https://www.w3.org/ns/activitystreams",
@@ -1448,7 +1427,7 @@ test("getDocumentLoader()", async (t) => {
1448
1427
  },
1449
1428
  headers: { "Content-Type": "text/html; charset=utf-8" }
1450
1429
  });
1451
- await t.test("wrong Content-Type with JSON body", async () => {
1430
+ await t.test("Wrong Content-Type", async () => {
1452
1431
  deepStrictEqual(await fetchDocumentLoader("https://example.com/wrong-content-type"), {
1453
1432
  contextUrl: null,
1454
1433
  documentUrl: "https://example.com/wrong-content-type",
@@ -1460,37 +1439,6 @@ test("getDocumentLoader()", async (t) => {
1460
1439
  }
1461
1440
  });
1462
1441
  });
1463
- esm_default.get("https://example.com/large-html", {
1464
- body: "<!DOCTYPE html>",
1465
- headers: {
1466
- "Content-Length": String(1048577),
1467
- "Content-Type": "text/html; charset=utf-8"
1468
- }
1469
- });
1470
- await t.test("HTML Content-Length over limit", async () => {
1471
- await rejects(() => fetchDocumentLoader("https://example.com/large-html"), (error) => {
1472
- ok(error instanceof FetchError);
1473
- ok(error.message.includes("HTML document is too large to scan for an ActivityPub alternate link"));
1474
- ok(error.response != null);
1475
- deepStrictEqual(error.response.status, 200);
1476
- deepStrictEqual(error.response.headers.get("Content-Type"), "text/html; charset=utf-8");
1477
- return true;
1478
- });
1479
- });
1480
- await t.test("HTML Content-Length over limit cancels body", async () => {
1481
- let canceled = false;
1482
- const response = new Response("<!DOCTYPE html>", { headers: {
1483
- "Content-Length": String(1048577),
1484
- "Content-Type": "text/html; charset=utf-8"
1485
- } });
1486
- Object.defineProperty(response, "body", { value: { cancel: () => {
1487
- canceled = true;
1488
- } } });
1489
- await rejects(() => getRemoteDocument("https://example.com/large-html-cancel", response, () => {
1490
- throw new Error("unexpected alternate fetch");
1491
- }), FetchError);
1492
- deepStrictEqual(canceled, true);
1493
- });
1494
1442
  esm_default.get("https://example.com/404", { status: 404 });
1495
1443
  await t.test("not ok", async () => {
1496
1444
  await rejects(() => fetchDocumentLoader("https://example.com/404"), FetchError, "HTTP 404: https://example.com/404");
@@ -1607,7 +1555,7 @@ test("getDocumentLoader()", async (t) => {
1607
1555
  });
1608
1556
  await t.test("ReDoS resistance (CVE-2025-68475)", async () => {
1609
1557
  const start = performance.now();
1610
- await rejects(() => fetchDocumentLoader("https://example.com/redos"), FetchError);
1558
+ await rejects(() => fetchDocumentLoader("https://example.com/redos"), SyntaxError);
1611
1559
  const elapsed = performance.now() - start;
1612
1560
  ok(elapsed < 1e3, `Potential ReDoS vulnerability detected: ${elapsed}ms (expected < 1000ms)`);
1613
1561
  });
@@ -45,11 +45,6 @@ const algorithms = {
45
45
  },
46
46
  "1.3.101.112": "Ed25519"
47
47
  };
48
- const DID_KEY_PREFIX = "did:key:";
49
- const ED25519_PUBLIC_KEY_MULTICODEC = 237;
50
- const ED25519_PUBLIC_KEY_LENGTH = 32;
51
- const DID_KEY_PATTERN = /^did:key:([^/?#]+)$/;
52
- const DID_KEY_VERIFICATION_METHOD_PATTERN = /^did:key:([^/?#]+)#([^/?#]+)$/;
53
48
  /**
54
49
  * Imports a PEM-SPKI formatted public key.
55
50
  * @param pem The PEM-SPKI formatted public key.
@@ -111,69 +106,6 @@ const PKCS1_HEADER = /^\s*-----BEGIN\s+RSA\s+PUBLIC\s+KEY-----\s*\n/;
111
106
  function importPem(pem) {
112
107
  return PKCS1_HEADER.test(pem) ? importPkcs1(pem) : importSpki(pem);
113
108
  }
114
- function decodeEd25519DidKeyMultibase(multibaseKey) {
115
- if (!multibaseKey.startsWith("z")) throw new TypeError("did:key must use base58-btc Multibase encoding.");
116
- let decoded;
117
- try {
118
- decoded = decodeMultibase(multibaseKey);
119
- } catch (error) {
120
- throw new TypeError("Invalid did:key Multibase encoding.", { cause: error });
121
- }
122
- const { code } = getMulticodecPrefix(decoded);
123
- if (code !== ED25519_PUBLIC_KEY_MULTICODEC) throw new TypeError("Unsupported did:key type: 0x" + code.toString(16));
124
- const content = removeMulticodecPrefix(decoded);
125
- if (content.length !== ED25519_PUBLIC_KEY_LENGTH) throw new TypeError("Invalid Ed25519 did:key length.");
126
- return content;
127
- }
128
- /**
129
- * Imports an Ed25519 `did:key` DID.
130
- *
131
- * @param did The `did:key` DID.
132
- * @returns The imported Ed25519 public key.
133
- * @throws {TypeError} If the DID is malformed or uses an unsupported key type.
134
- * @since 2.4.0
135
- */
136
- async function importDidKey(did) {
137
- const match = (did instanceof URL ? did.href : did).match(DID_KEY_PATTERN);
138
- if (match == null) throw new TypeError("Invalid did:key DID.");
139
- const content = decodeEd25519DidKeyMultibase(match[1]);
140
- return await crypto.subtle.importKey("raw", content.slice(), "Ed25519", true, ["verify"]);
141
- }
142
- /**
143
- * Exports an Ed25519 public key as a `did:key` DID.
144
- *
145
- * @param key The Ed25519 public key.
146
- * @returns The `did:key` DID.
147
- * @throws {TypeError} If the key is invalid or unsupported.
148
- * @since 2.4.0
149
- */
150
- async function exportDidKey(key) {
151
- if (key.algorithm.name !== "Ed25519") throw new TypeError("Unsupported key type: " + JSON.stringify(key.algorithm));
152
- return DID_KEY_PREFIX + await exportMultibaseKey(key);
153
- }
154
- /**
155
- * Parses an Ed25519 `did:key` verification method DID URL.
156
- *
157
- * @param didUrl The `did:key` DID URL.
158
- * @returns The parsed verification method.
159
- * @throws {TypeError} If the DID URL is malformed, unsupported, or its
160
- * fragment does not identify the same key as the DID.
161
- * @since 2.4.0
162
- */
163
- async function parseDidKeyVerificationMethod(didUrl) {
164
- const didUrlString = didUrl instanceof URL ? didUrl.href : didUrl;
165
- const match = didUrlString.match(DID_KEY_VERIFICATION_METHOD_PATTERN);
166
- if (match == null) throw new TypeError("Invalid did:key verification method.");
167
- const [, publicKeyMultibase, fragment] = match;
168
- if (publicKeyMultibase !== fragment) throw new TypeError("Invalid did:key verification method fragment.");
169
- const publicKey = await importDidKey(DID_KEY_PREFIX + publicKeyMultibase);
170
- return {
171
- id: new URL(didUrlString),
172
- controller: new URL(DID_KEY_PREFIX + publicKeyMultibase),
173
- publicKeyMultibase,
174
- publicKey
175
- };
176
- }
177
109
  /**
178
110
  * Imports a [Multibase]-encoded public key.
179
111
  *
@@ -237,4 +169,4 @@ async function exportMultibaseKey(key) {
237
169
  return new TextDecoder().decode(encoded);
238
170
  }
239
171
  //#endregion
240
- export { importMultibaseKey as a, importSpki as c, importJwk as d, importDidKey as i, parseDidKeyVerificationMethod as l, exportMultibaseKey as n, importPem as o, exportSpki as r, importPkcs1 as s, exportDidKey as t, exportJwk as u };
172
+ export { importPkcs1 as a, importJwk as c, importPem as i, exportSpki as n, importSpki as o, importMultibaseKey as r, exportJwk as s, exportMultibaseKey as t };
@@ -46,11 +46,6 @@ const algorithms = {
46
46
  },
47
47
  "1.3.101.112": "Ed25519"
48
48
  };
49
- const DID_KEY_PREFIX = "did:key:";
50
- const ED25519_PUBLIC_KEY_MULTICODEC = 237;
51
- const ED25519_PUBLIC_KEY_LENGTH = 32;
52
- const DID_KEY_PATTERN = /^did:key:([^/?#]+)$/;
53
- const DID_KEY_VERIFICATION_METHOD_PATTERN = /^did:key:([^/?#]+)#([^/?#]+)$/;
54
49
  /**
55
50
  * Imports a PEM-SPKI formatted public key.
56
51
  * @param pem The PEM-SPKI formatted public key.
@@ -112,69 +107,6 @@ const PKCS1_HEADER = /^\s*-----BEGIN\s+RSA\s+PUBLIC\s+KEY-----\s*\n/;
112
107
  function importPem(pem) {
113
108
  return PKCS1_HEADER.test(pem) ? importPkcs1(pem) : importSpki(pem);
114
109
  }
115
- function decodeEd25519DidKeyMultibase(multibaseKey) {
116
- if (!multibaseKey.startsWith("z")) throw new TypeError("did:key must use base58-btc Multibase encoding.");
117
- let decoded;
118
- try {
119
- decoded = require_multibase.decodeMultibase(multibaseKey);
120
- } catch (error) {
121
- throw new TypeError("Invalid did:key Multibase encoding.", { cause: error });
122
- }
123
- const { code } = require_multicodec.getMulticodecPrefix(decoded);
124
- if (code !== ED25519_PUBLIC_KEY_MULTICODEC) throw new TypeError("Unsupported did:key type: 0x" + code.toString(16));
125
- const content = require_multicodec.removeMulticodecPrefix(decoded);
126
- if (content.length !== ED25519_PUBLIC_KEY_LENGTH) throw new TypeError("Invalid Ed25519 did:key length.");
127
- return content;
128
- }
129
- /**
130
- * Imports an Ed25519 `did:key` DID.
131
- *
132
- * @param did The `did:key` DID.
133
- * @returns The imported Ed25519 public key.
134
- * @throws {TypeError} If the DID is malformed or uses an unsupported key type.
135
- * @since 2.4.0
136
- */
137
- async function importDidKey(did) {
138
- const match = (did instanceof URL ? did.href : did).match(DID_KEY_PATTERN);
139
- if (match == null) throw new TypeError("Invalid did:key DID.");
140
- const content = decodeEd25519DidKeyMultibase(match[1]);
141
- return await crypto.subtle.importKey("raw", content.slice(), "Ed25519", true, ["verify"]);
142
- }
143
- /**
144
- * Exports an Ed25519 public key as a `did:key` DID.
145
- *
146
- * @param key The Ed25519 public key.
147
- * @returns The `did:key` DID.
148
- * @throws {TypeError} If the key is invalid or unsupported.
149
- * @since 2.4.0
150
- */
151
- async function exportDidKey(key) {
152
- if (key.algorithm.name !== "Ed25519") throw new TypeError("Unsupported key type: " + JSON.stringify(key.algorithm));
153
- return DID_KEY_PREFIX + await exportMultibaseKey(key);
154
- }
155
- /**
156
- * Parses an Ed25519 `did:key` verification method DID URL.
157
- *
158
- * @param didUrl The `did:key` DID URL.
159
- * @returns The parsed verification method.
160
- * @throws {TypeError} If the DID URL is malformed, unsupported, or its
161
- * fragment does not identify the same key as the DID.
162
- * @since 2.4.0
163
- */
164
- async function parseDidKeyVerificationMethod(didUrl) {
165
- const didUrlString = didUrl instanceof URL ? didUrl.href : didUrl;
166
- const match = didUrlString.match(DID_KEY_VERIFICATION_METHOD_PATTERN);
167
- if (match == null) throw new TypeError("Invalid did:key verification method.");
168
- const [, publicKeyMultibase, fragment] = match;
169
- if (publicKeyMultibase !== fragment) throw new TypeError("Invalid did:key verification method fragment.");
170
- const publicKey = await importDidKey(DID_KEY_PREFIX + publicKeyMultibase);
171
- return {
172
- id: new URL(didUrlString),
173
- controller: new URL(DID_KEY_PREFIX + publicKeyMultibase),
174
- publicKeyMultibase,
175
- publicKey
176
- };
177
- }
178
110
  /**
179
111
  * Imports a [Multibase]-encoded public key.
180
112
  *
@@ -238,12 +170,6 @@ async function exportMultibaseKey(key) {
238
170
  return new TextDecoder().decode(encoded);
239
171
  }
240
172
  //#endregion
241
- Object.defineProperty(exports, "exportDidKey", {
242
- enumerable: true,
243
- get: function() {
244
- return exportDidKey;
245
- }
246
- });
247
173
  Object.defineProperty(exports, "exportJwk", {
248
174
  enumerable: true,
249
175
  get: function() {
@@ -262,12 +188,6 @@ Object.defineProperty(exports, "exportSpki", {
262
188
  return exportSpki;
263
189
  }
264
190
  });
265
- Object.defineProperty(exports, "importDidKey", {
266
- enumerable: true,
267
- get: function() {
268
- return importDidKey;
269
- }
270
- });
271
191
  Object.defineProperty(exports, "importJwk", {
272
192
  enumerable: true,
273
193
  get: function() {
@@ -298,9 +218,3 @@ Object.defineProperty(exports, "importSpki", {
298
218
  return importSpki;
299
219
  }
300
220
  });
301
- Object.defineProperty(exports, "parseDidKeyVerificationMethod", {
302
- enumerable: true,
303
- get: function() {
304
- return parseDidKeyVerificationMethod;
305
- }
306
- });
@@ -1,6 +1,5 @@
1
1
  require("./chunk-C2EiDwsr.cjs");
2
- const require_multicodec = require("./multicodec-CxGVGa91.cjs");
3
- const require_key = require("./key-_wXwomh_.cjs");
2
+ const require_key = require("./key-pMmqUKuo.cjs");
4
3
  const require_multibase = require("./multibase-Bz_UUDtL.cjs");
5
4
  let node_assert = require("node:assert");
6
5
  let node_test = require("node:test");
@@ -72,50 +71,4 @@ const ed25519Multibase = "z6MksHj1MJnidCtDiyYW9ugNFftoX9fLK4bornTxmMZ6X7vq";
72
71
  x: "Lm_M42cB3HkUiODQsXRcweM6TByfzEHGO9ND274JcOY"
73
72
  }, "public")), "z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK");
74
73
  });
75
- (0, node_test.test)("exportDidKey() and importDidKey()", async () => {
76
- const did = await require_key.exportDidKey(await require_key.importJwk(ed25519Jwk, "public"));
77
- (0, node_assert.deepStrictEqual)(did, `did:key:${ed25519Multibase}`);
78
- (0, node_assert.deepStrictEqual)(await require_key.exportJwk(await require_key.importDidKey(did)), ed25519Jwk);
79
- (0, node_assert.deepStrictEqual)(await require_key.exportJwk(await require_key.importDidKey(new URL(did))), ed25519Jwk);
80
- const rsaKey = await require_key.importJwk(rsaJwk, "public");
81
- await (0, node_assert.rejects)(() => require_key.exportDidKey(rsaKey), TypeError);
82
- await (0, node_assert.rejects)(() => require_key.importDidKey(`did:key:${rsaMultibase}`), /* @__PURE__ */ new TypeError("Unsupported did:key type: 0x1205"));
83
- });
84
- (0, node_test.test)("parseDidKeyVerificationMethod()", async () => {
85
- const verificationMethod = `did:key:${ed25519Multibase}#${ed25519Multibase}`;
86
- const parsed = await require_key.parseDidKeyVerificationMethod(verificationMethod);
87
- (0, node_assert.deepStrictEqual)(parsed.id, new URL(verificationMethod));
88
- (0, node_assert.deepStrictEqual)(parsed.controller, new URL(`did:key:${ed25519Multibase}`));
89
- (0, node_assert.deepStrictEqual)(parsed.publicKeyMultibase, ed25519Multibase);
90
- (0, node_assert.deepStrictEqual)(await require_key.exportJwk(parsed.publicKey), ed25519Jwk);
91
- });
92
- (0, node_test.test)("did:key helpers reject malformed values", async () => {
93
- const ed25519Key = await require_key.importJwk(ed25519Jwk, "public");
94
- const raw = new Uint8Array(await crypto.subtle.exportKey("raw", ed25519Key));
95
- const shortEd25519 = new TextDecoder().decode(require_multibase.encodeMultibase("base58btc", require_multicodec.addMulticodecPrefix(237, raw.slice(0, 31))));
96
- const base64UrlEd25519 = new TextDecoder().decode(require_multibase.encodeMultibase("base64url", require_multicodec.addMulticodecPrefix(237, raw)));
97
- const malformedMulticodec = new TextDecoder().decode(require_multibase.encodeMultibase("base58btc", Uint8Array.from([128])));
98
- for (const value of [
99
- "did:web:example.com",
100
- "did:key:",
101
- `did:key:${ed25519Multibase}/path`,
102
- `did:key:${ed25519Multibase}?query`,
103
- `did:key:${ed25519Multibase}#${ed25519Multibase}`,
104
- "did:key:z0",
105
- `did:key:${base64UrlEd25519}`,
106
- `did:key:${shortEd25519}`,
107
- `did:key:${malformedMulticodec}`
108
- ]) await (0, node_assert.rejects)(() => require_key.importDidKey(value), TypeError);
109
- for (const value of [
110
- `did:key:${ed25519Multibase}`,
111
- `did:key:${ed25519Multibase}#`,
112
- `did:key:${ed25519Multibase}#z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK`,
113
- `did:key:${ed25519Multibase}#${base64UrlEd25519}`,
114
- "did:key:z0#z0",
115
- `did:key:${rsaMultibase}#${rsaMultibase}`,
116
- `did:key:${shortEd25519}#${shortEd25519}`,
117
- `did:key:${malformedMulticodec}#${malformedMulticodec}`,
118
- "https://example.com/key"
119
- ]) await (0, node_assert.rejects)(() => require_key.parseDidKeyVerificationMethod(value), TypeError);
120
- });
121
74
  //#endregion