@fedify/vocab-runtime 2.1.0-dev.565 → 2.1.0-dev.599

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 (71) hide show
  1. package/deno.json +4 -3
  2. package/dist/chunk-CUT6urMc.cjs +30 -0
  3. package/dist/jsonld.cjs +8 -0
  4. package/dist/jsonld.d.cts +6 -0
  5. package/dist/jsonld.d.ts +6 -0
  6. package/dist/jsonld.js +7 -0
  7. package/dist/mod.cjs +4485 -4329
  8. package/dist/mod.d.cts +95 -4
  9. package/dist/mod.d.ts +95 -4
  10. package/dist/mod.js +4474 -4299
  11. package/dist/tests/decimal.test.cjs +154 -0
  12. package/dist/tests/decimal.test.d.cts +1 -0
  13. package/dist/tests/decimal.test.d.ts +1 -0
  14. package/dist/tests/decimal.test.js +153 -0
  15. package/dist/tests/docloader-B7jXFZpf.cjs +4562 -0
  16. package/dist/tests/docloader-DMCOWvVB.js +4550 -0
  17. package/dist/tests/docloader.test.cjs +7 -4491
  18. package/dist/tests/docloader.test.js +4 -4488
  19. package/dist/tests/internal/multicodec.test.cjs +77 -0
  20. package/dist/tests/internal/multicodec.test.d.cts +1 -0
  21. package/dist/tests/internal/multicodec.test.d.ts +1 -0
  22. package/dist/tests/internal/multicodec.test.js +76 -0
  23. package/dist/tests/key-ByCmSI2y.js +183 -0
  24. package/dist/tests/key-CCPn6TEY.cjs +231 -0
  25. package/dist/tests/key.test.cjs +36 -212
  26. package/dist/tests/key.test.js +9 -185
  27. package/dist/tests/langstr-BsVE3s9u.js +30 -0
  28. package/dist/tests/langstr-EPh86hXK.cjs +36 -0
  29. package/dist/tests/langstr.test.cjs +5 -33
  30. package/dist/tests/langstr.test.js +1 -29
  31. package/dist/tests/link.test.cjs +1 -1
  32. package/dist/tests/link.test.js +1 -1
  33. package/dist/tests/multibase/multibase.test.cjs +1 -1
  34. package/dist/tests/multibase/multibase.test.js +1 -1
  35. package/dist/tests/multicodec--6hQ74zI.cjs +59 -0
  36. package/dist/tests/multicodec-Dq3IiOV4.js +41 -0
  37. package/dist/tests/{request-3ywvRFy1.js → request-BQtyeAfw.js} +6 -3
  38. package/dist/tests/{request-Dhnqve0g.cjs → request-CW9KOmQu.cjs} +6 -3
  39. package/dist/tests/request.test.cjs +1 -1
  40. package/dist/tests/request.test.js +1 -1
  41. package/dist/tests/url.test.cjs +1 -1
  42. package/dist/tests/url.test.js +1 -1
  43. package/package.json +12 -2
  44. package/src/contexts/activitystreams.json +379 -0
  45. package/src/contexts/did-v1.json +57 -0
  46. package/src/contexts/fep-5711.json +36 -0
  47. package/src/contexts/gotosocial.json +86 -0
  48. package/src/contexts/identity-v1.json +152 -0
  49. package/src/contexts/joinmastodon.json +28 -0
  50. package/src/contexts/schemaorg.json +8845 -0
  51. package/src/contexts/security-data-integrity-v1.json +78 -0
  52. package/src/contexts/security-data-integrity-v2.json +81 -0
  53. package/src/contexts/security-multikey-v1.json +35 -0
  54. package/src/contexts/security-v1.json +74 -0
  55. package/src/contexts/webfinger.json +10 -0
  56. package/src/contexts.ts +33 -4392
  57. package/src/decimal.test.ts +90 -0
  58. package/src/decimal.ts +112 -0
  59. package/src/internal/multicodec.test.ts +68 -0
  60. package/src/internal/multicodec.ts +53 -0
  61. package/src/jsonld.ts +4 -0
  62. package/src/key.test.ts +22 -1
  63. package/src/key.ts +9 -8
  64. package/src/mod.ts +6 -0
  65. package/tsdown.config.ts +1 -1
  66. /package/dist/tests/{link-Ck2yj4dH.js → link-C3q2TC2G.js} +0 -0
  67. /package/dist/tests/{link-CdFPEo9O.cjs → link-DYNFAdNu.cjs} +0 -0
  68. /package/dist/tests/{multibase-DStmqni9.js → multibase-B4g8pz6F.js} +0 -0
  69. /package/dist/tests/{multibase-BFbBiaPE.cjs → multibase-o_ovPHYJ.cjs} +0 -0
  70. /package/dist/tests/{url-fW_DHbih.js → url-CWEP9Zs9.js} +0 -0
  71. /package/dist/tests/{url-C5Vs9nYh.cjs → url-DIjOdK8Q.cjs} +0 -0
@@ -1,191 +1,10 @@
1
1
  const require_chunk = require('./chunk-DWy1uDak.cjs');
2
- const require_multibase = require('./multibase-BFbBiaPE.cjs');
2
+ require('./multicodec--6hQ74zI.cjs');
3
+ const require_key = require('./key-CCPn6TEY.cjs');
4
+ const require_multibase = require('./multibase-o_ovPHYJ.cjs');
3
5
  const node_assert = require_chunk.__toESM(require("node:assert"));
4
6
  const node_test = require_chunk.__toESM(require("node:test"));
5
- const asn1js = require_chunk.__toESM(require("asn1js"));
6
- const byte_encodings_base64 = require_chunk.__toESM(require("byte-encodings/base64"));
7
- const byte_encodings_base64url = require_chunk.__toESM(require("byte-encodings/base64url"));
8
- const byte_encodings_hex = require_chunk.__toESM(require("byte-encodings/hex"));
9
- const multicodec = require_chunk.__toESM(require("multicodec"));
10
- const node_crypto = require_chunk.__toESM(require("node:crypto"));
11
- const pkijs = require_chunk.__toESM(require("pkijs"));
12
7
 
13
- //#region src/jwk.ts
14
- function validateCryptoKey(key, type) {
15
- if (type != null && key.type !== type) throw new TypeError(`The key is not a ${type} key.`);
16
- if (!key.extractable) throw new TypeError("The key is not extractable.");
17
- if (key.algorithm.name !== "RSASSA-PKCS1-v1_5" && key.algorithm.name !== "Ed25519") throw new TypeError("Currently only RSASSA-PKCS1-v1_5 and Ed25519 keys are supported. More algorithms will be added in the future!");
18
- if (key.algorithm.name === "RSASSA-PKCS1-v1_5") {
19
- const algorithm = key.algorithm;
20
- if (algorithm.hash.name !== "SHA-256") throw new TypeError("For compatibility with the existing Fediverse software (e.g., Mastodon), hash algorithm for RSASSA-PKCS1-v1_5 keys must be SHA-256.");
21
- }
22
- }
23
- async function exportJwk(key) {
24
- validateCryptoKey(key);
25
- const jwk = await crypto.subtle.exportKey("jwk", key);
26
- if (jwk.crv === "Ed25519") jwk.alg = "Ed25519";
27
- return jwk;
28
- }
29
- async function importJwk(jwk, type) {
30
- let key;
31
- if (jwk.kty === "RSA" && jwk.alg === "RS256") key = await crypto.subtle.importKey("jwk", jwk, {
32
- name: "RSASSA-PKCS1-v1_5",
33
- hash: "SHA-256"
34
- }, true, type === "public" ? ["verify"] : ["sign"]);
35
- else if (jwk.kty === "OKP" && jwk.crv === "Ed25519") {
36
- if (navigator?.userAgent === "Cloudflare-Workers") {
37
- jwk = { ...jwk };
38
- delete jwk.alg;
39
- }
40
- key = await crypto.subtle.importKey("jwk", jwk, "Ed25519", true, type === "public" ? ["verify"] : ["sign"]);
41
- } else throw new TypeError("Unsupported JWK format.");
42
- validateCryptoKey(key, type);
43
- return key;
44
- }
45
-
46
- //#endregion
47
- //#region src/key.ts
48
- const algorithms = {
49
- "1.2.840.113549.1.1.1": {
50
- name: "RSASSA-PKCS1-v1_5",
51
- hash: "SHA-256"
52
- },
53
- "1.3.101.112": "Ed25519"
54
- };
55
- /**
56
- * Imports a PEM-SPKI formatted public key.
57
- * @param pem The PEM-SPKI formatted public key.
58
- * @returns The imported public key.
59
- * @throws {TypeError} If the key is invalid or unsupported.
60
- * @since 0.5.0
61
- */
62
- async function importSpki(pem) {
63
- pem = pem.replace(/(?:-----(?:BEGIN|END) PUBLIC KEY-----|\s)/g, "");
64
- let spki;
65
- try {
66
- spki = (0, byte_encodings_base64.decodeBase64)(pem);
67
- } catch (_) {
68
- throw new TypeError("Invalid PEM-SPKI format.");
69
- }
70
- const pki = pkijs.PublicKeyInfo.fromBER(spki);
71
- const oid = pki.algorithm.algorithmId;
72
- const algorithm = algorithms[oid];
73
- if (algorithm == null) throw new TypeError("Unsupported algorithm: " + oid);
74
- return await crypto.subtle.importKey("spki", spki, algorithm, true, ["verify"]);
75
- }
76
- /**
77
- * Exports a public key in PEM-SPKI format.
78
- * @param key The public key to export.
79
- * @returns The exported public key in PEM-SPKI format.
80
- * @throws {TypeError} If the key is invalid or unsupported.
81
- * @since 0.5.0
82
- */
83
- async function exportSpki(key) {
84
- validateCryptoKey(key);
85
- const spki = await crypto.subtle.exportKey("spki", key);
86
- let pem = (0, byte_encodings_base64.encodeBase64)(spki);
87
- pem = (pem.match(/.{1,64}/g) || []).join("\n");
88
- return `-----BEGIN PUBLIC KEY-----\n${pem}\n-----END PUBLIC KEY-----\n`;
89
- }
90
- /**
91
- * Imports a PEM-PKCS#1 formatted public key.
92
- * @param pem The PEM-PKCS#1 formatted public key.
93
- * @returns The imported public key.
94
- * @throws {TypeError} If the key is invalid or unsupported.
95
- * @since 1.5.0
96
- */
97
- function importPkcs1(pem) {
98
- const key = (0, node_crypto.createPublicKey)({
99
- key: pem,
100
- format: "pem",
101
- type: "pkcs1"
102
- });
103
- const spki = key.export({
104
- type: "spki",
105
- format: "pem"
106
- });
107
- return importSpki(spki);
108
- }
109
- const PKCS1_HEADER = /^\s*-----BEGIN\s+RSA\s+PUBLIC\s+KEY-----\s*\n/;
110
- /**
111
- * Imports a PEM formatted public key (SPKI or PKCS#1).
112
- * @param pem The PEM formatted public key to import (SPKI or PKCS#1).
113
- * @returns The imported public key.
114
- * @throws {TypeError} If the key is invalid or unsupported.
115
- * @since 1.5.0
116
- */
117
- function importPem(pem) {
118
- return PKCS1_HEADER.test(pem) ? importPkcs1(pem) : importSpki(pem);
119
- }
120
- /**
121
- * Imports a [Multibase]-encoded public key.
122
- *
123
- * [Multibase]: https://www.w3.org/TR/vc-data-integrity/#multibase-0
124
- * @param key The Multibase-encoded public key.
125
- * @returns The imported public key.
126
- * @throws {TypeError} If the key is invalid or unsupported.
127
- * @since 0.10.0
128
- */
129
- async function importMultibaseKey(key) {
130
- const decoded = require_multibase.decodeMultibase(key);
131
- const code = (0, multicodec.getCodeFromData)(decoded);
132
- const content = (0, multicodec.rmPrefix)(decoded);
133
- if (code === 4613) {
134
- const keyObject = (0, node_crypto.createPublicKey)({
135
- key: content,
136
- format: "der",
137
- type: "pkcs1"
138
- });
139
- const exported = keyObject.export({
140
- type: "spki",
141
- format: "der"
142
- });
143
- const spki = exported instanceof Uint8Array ? exported : new Uint8Array(exported);
144
- return await crypto.subtle.importKey("spki", new Uint8Array(spki), {
145
- name: "RSASSA-PKCS1-v1_5",
146
- hash: "SHA-256"
147
- }, true, ["verify"]);
148
- } else if (code === 237) return await crypto.subtle.importKey("raw", content.slice(), "Ed25519", true, ["verify"]);
149
- else throw new TypeError("Unsupported key type: 0x" + code.toString(16));
150
- }
151
- /**
152
- * Exports a public key in [Multibase] format.
153
- *
154
- * [Multibase]: https://www.w3.org/TR/vc-data-integrity/#multibase-0
155
- * @param key The public key to export.
156
- * @returns The exported public key in Multibase format.
157
- * @throws {TypeError} If the key is invalid or unsupported.
158
- * @since 0.10.0
159
- */
160
- async function exportMultibaseKey(key) {
161
- let content;
162
- let code;
163
- if (key.algorithm.name === "Ed25519") {
164
- content = await crypto.subtle.exportKey("raw", key);
165
- code = 237;
166
- } else if (key.algorithm.name === "RSASSA-PKCS1-v1_5" && key.algorithm.hash.name === "SHA-256") {
167
- const jwk = await crypto.subtle.exportKey("jwk", key);
168
- const decodedN = (0, byte_encodings_base64url.decodeBase64Url)(jwk.n);
169
- const n = new Uint8Array(decodedN.length + 1);
170
- n.set(decodedN, 1);
171
- const sequence = new asn1js.Sequence({ value: [new asn1js.Integer({
172
- isHexOnly: true,
173
- valueHex: n
174
- }), new asn1js.Integer({
175
- isHexOnly: true,
176
- valueHex: (0, byte_encodings_base64url.decodeBase64Url)(jwk.e)
177
- })] });
178
- content = sequence.toBER(false);
179
- code = 4613;
180
- } else throw new TypeError("Unsupported key type: " + JSON.stringify(key.algorithm));
181
- const codeHex = code.toString(16);
182
- const codeBytes = (0, byte_encodings_hex.decodeHex)(codeHex.length % 2 < 1 ? codeHex : "0" + codeHex);
183
- const prefixed = (0, multicodec.addPrefix)(codeBytes, new Uint8Array(content));
184
- const encoded = require_multibase.encodeMultibase("base58btc", prefixed);
185
- return new TextDecoder().decode(encoded);
186
- }
187
-
188
- //#endregion
189
8
  //#region src/key.test.ts
190
9
  const rsaSpki = "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxsRuvCkgJtflBTl4OVsm\nnt/J1mQfZasfJtN33dcZ3d1lJroxmgmMu69zjGEAwkNbMQaWNLqC4eogkJaeJ4RR\n5MHYXkL9nNilVoTkjX5BVit3puzs7XJ7WQnKQgQMI+ezn24GHsZ/v1JIo77lerX5\nk4HNwTNVt+yaZVQWaOMR3+6FwziQR6kd0VuG9/a9dgAnz2cEoORRC1i4W7IZaB1s\nZnh1WbHbevlGd72HSXll5rocPIHn8gq6xpBgpHwRphlRsgn4KHaJ6brXDIJjrnQh\nIe/YUBOGj/ImSEXhRwlFerKsoAVnZ0Hwbfa46qk44TAt8CyoPMWmpK6pt0ng4pQ2\nuwIDAQAB\n-----END PUBLIC KEY-----\n";
191
10
  const rsaPkcs1 = "-----BEGIN RSA PUBLIC KEY-----\nMIIBCgKCAQEAxsRuvCkgJtflBTl4OVsmnt/J1mQfZasfJtN33dcZ3d1lJroxmgmM\nu69zjGEAwkNbMQaWNLqC4eogkJaeJ4RR5MHYXkL9nNilVoTkjX5BVit3puzs7XJ7\nWQnKQgQMI+ezn24GHsZ/v1JIo77lerX5k4HNwTNVt+yaZVQWaOMR3+6FwziQR6kd\n0VuG9/a9dgAnz2cEoORRC1i4W7IZaB1sZnh1WbHbevlGd72HSXll5rocPIHn8gq6\nxpBgpHwRphlRsgn4KHaJ6brXDIJjrnQhIe/YUBOGj/ImSEXhRwlFerKsoAVnZ0Hw\nbfa46qk44TAt8CyoPMWmpK6pt0ng4pQ2uwIDAQAB\n-----END RSA PUBLIC KEY-----\n";
@@ -209,45 +28,50 @@ const ed25519Jwk = {
209
28
  };
210
29
  const ed25519Multibase = "z6MksHj1MJnidCtDiyYW9ugNFftoX9fLK4bornTxmMZ6X7vq";
211
30
  (0, node_test.test)("importSpki()", async () => {
212
- const rsaKey = await importSpki(rsaSpki);
213
- (0, node_assert.deepStrictEqual)(await exportJwk(rsaKey), rsaJwk);
214
- const ed25519Key = await importSpki(ed25519Pem);
215
- (0, node_assert.deepStrictEqual)(await exportJwk(ed25519Key), ed25519Jwk);
31
+ const rsaKey = await require_key.importSpki(rsaSpki);
32
+ (0, node_assert.deepStrictEqual)(await require_key.exportJwk(rsaKey), rsaJwk);
33
+ const ed25519Key = await require_key.importSpki(ed25519Pem);
34
+ (0, node_assert.deepStrictEqual)(await require_key.exportJwk(ed25519Key), ed25519Jwk);
216
35
  });
217
36
  (0, node_test.test)("exportSpki()", async () => {
218
- const rsaKey = await importJwk(rsaJwk, "public");
219
- const rsaSpki$1 = await exportSpki(rsaKey);
37
+ const rsaKey = await require_key.importJwk(rsaJwk, "public");
38
+ const rsaSpki$1 = await require_key.exportSpki(rsaKey);
220
39
  (0, node_assert.deepStrictEqual)(rsaSpki$1, rsaSpki$1);
221
- const ed25519Key = await importJwk(ed25519Jwk, "public");
222
- const ed25519Spki = await exportSpki(ed25519Key);
40
+ const ed25519Key = await require_key.importJwk(ed25519Jwk, "public");
41
+ const ed25519Spki = await require_key.exportSpki(ed25519Key);
223
42
  (0, node_assert.deepStrictEqual)(ed25519Spki, ed25519Pem);
224
43
  });
225
44
  (0, node_test.test)("importPkcs1()", async () => {
226
- const rsaKey = await importPkcs1(rsaPkcs1);
227
- (0, node_assert.deepStrictEqual)(await exportJwk(rsaKey), rsaJwk);
45
+ const rsaKey = await require_key.importPkcs1(rsaPkcs1);
46
+ (0, node_assert.deepStrictEqual)(await require_key.exportJwk(rsaKey), rsaJwk);
228
47
  });
229
48
  (0, node_test.test)("importPem()", async () => {
230
- const rsaPkcs1Key = await importPem(rsaPkcs1);
231
- (0, node_assert.deepStrictEqual)(await exportJwk(rsaPkcs1Key), rsaJwk);
232
- const rsaSpkiKey = await importPem(rsaSpki);
233
- (0, node_assert.deepStrictEqual)(await exportJwk(rsaSpkiKey), rsaJwk);
234
- const ed25519Key = await importPem(ed25519Pem);
235
- (0, node_assert.deepStrictEqual)(await exportJwk(ed25519Key), ed25519Jwk);
49
+ const rsaPkcs1Key = await require_key.importPem(rsaPkcs1);
50
+ (0, node_assert.deepStrictEqual)(await require_key.exportJwk(rsaPkcs1Key), rsaJwk);
51
+ const rsaSpkiKey = await require_key.importPem(rsaSpki);
52
+ (0, node_assert.deepStrictEqual)(await require_key.exportJwk(rsaSpkiKey), rsaJwk);
53
+ const ed25519Key = await require_key.importPem(ed25519Pem);
54
+ (0, node_assert.deepStrictEqual)(await require_key.exportJwk(ed25519Key), ed25519Jwk);
236
55
  });
237
56
  (0, node_test.test)("importMultibase()", async () => {
238
- const rsaKey = await importMultibaseKey(rsaMultibase);
239
- (0, node_assert.deepStrictEqual)(await exportJwk(rsaKey), rsaJwk);
240
- const ed25519Key = await importMultibaseKey(ed25519Multibase);
241
- (0, node_assert.deepStrictEqual)(await exportJwk(ed25519Key), ed25519Jwk);
57
+ const rsaKey = await require_key.importMultibaseKey(rsaMultibase);
58
+ (0, node_assert.deepStrictEqual)(await require_key.exportJwk(rsaKey), rsaJwk);
59
+ const ed25519Key = await require_key.importMultibaseKey(ed25519Multibase);
60
+ (0, node_assert.deepStrictEqual)(await require_key.exportJwk(ed25519Key), ed25519Jwk);
61
+ });
62
+ (0, node_test.test)("importMultibase() rejects malformed multicodec prefixes", async () => {
63
+ const decoder = new TextDecoder();
64
+ await (0, node_assert.rejects)(() => require_key.importMultibaseKey(decoder.decode(require_multibase.encodeMultibase("base58btc", new Uint8Array([])))), /* @__PURE__ */ new TypeError("Invalid multicodec prefix."));
65
+ await (0, node_assert.rejects)(() => require_key.importMultibaseKey(decoder.decode(require_multibase.encodeMultibase("base58btc", Uint8Array.from([128])))), /* @__PURE__ */ new TypeError("Invalid multicodec prefix."));
242
66
  });
243
67
  (0, node_test.test)("exportMultibaseKey()", async () => {
244
- const rsaKey = await importJwk(rsaJwk, "public");
245
- const rsaMb = await exportMultibaseKey(rsaKey);
68
+ const rsaKey = await require_key.importJwk(rsaJwk, "public");
69
+ const rsaMb = await require_key.exportMultibaseKey(rsaKey);
246
70
  (0, node_assert.deepStrictEqual)(rsaMb, rsaMultibase);
247
- const ed25519Key = await importJwk(ed25519Jwk, "public");
248
- const ed25519Mb = await exportMultibaseKey(ed25519Key);
71
+ const ed25519Key = await require_key.importJwk(ed25519Jwk, "public");
72
+ const ed25519Mb = await require_key.exportMultibaseKey(ed25519Key);
249
73
  (0, node_assert.deepStrictEqual)(ed25519Mb, ed25519Multibase);
250
- const rsaKey2 = await importJwk({
74
+ const rsaKey2 = await require_key.importJwk({
251
75
  alg: "RS256",
252
76
  ext: true,
253
77
  key_ops: ["verify"],
@@ -255,9 +79,9 @@ const ed25519Multibase = "z6MksHj1MJnidCtDiyYW9ugNFftoX9fLK4bornTxmMZ6X7vq";
255
79
  kty: "RSA",
256
80
  n: "sbX82NTV6IylxCh7MfV4hlyvaniCajuP97GyOqSvTmoEdBOflFvZ06kR_9D6ctt45Fk6hskfnag2GG69NALVH2o4RCR6tQiLRpKcMRtDYE_thEmfBvDzm_VVkOIYfxu-Ipuo9J_S5XDNDjczx2v-3oDh5-CIHkU46hvFeCvpUS-L8TJSbgX0kjVk_m4eIb9wh63rtmD6Uz_KBtCo5mmR4TEtcLZKYdqMp3wCjN-TlgHiz_4oVXWbHUefCEe8rFnX1iQnpDHU49_SaXQoud1jCaexFn25n-Aa8f8bc5Vm-5SeRwidHa6ErvEhTvf1dz6GoNPp2iRvm-wJ1gxwWJEYPQ"
257
81
  }, "public");
258
- const rsaMb2 = await exportMultibaseKey(rsaKey2);
82
+ const rsaMb2 = await require_key.exportMultibaseKey(rsaKey2);
259
83
  (0, node_assert.deepStrictEqual)(rsaMb2, "z4MXj1wBzi9jUstyPMS4jQqB6KdJaiatPkAtVtGc6bQEQEEsKTic4G7Rou3iBf9vPmT5dbkm9qsZsuVNjq8HCuW1w24nhBFGkRE4cd2Uf2tfrB3N7h4mnyPp1BF3ZttHTYv3DLUPi1zMdkULiow3M1GfXkoC6DoxDUm1jmN6GBj22SjVsr6dxezRVQc7aj9TxE7JLbMH1wh5X3kA58H3DFW8rnYMakFGbca5CB2Jf6CnGQZmL7o5uJAdTwXfy2iiiyPxXEGerMhHwhjTA1mKYobyk2CpeEcmvynADfNZ5MBvcCS7m3XkFCMNUYBS9NQ3fze6vMSUPsNa6GVYmKx2x6JrdEjCk3qRMMmyjnjCMfR4pXbRMZa3i");
260
- const ed25519Key2 = await importJwk({
84
+ const ed25519Key2 = await require_key.importJwk({
261
85
  alg: "Ed25519",
262
86
  crv: "Ed25519",
263
87
  ext: true,
@@ -265,7 +89,7 @@ const ed25519Multibase = "z6MksHj1MJnidCtDiyYW9ugNFftoX9fLK4bornTxmMZ6X7vq";
265
89
  kty: "OKP",
266
90
  x: "Lm_M42cB3HkUiODQsXRcweM6TByfzEHGO9ND274JcOY"
267
91
  }, "public");
268
- const ed25519Mb2 = await exportMultibaseKey(ed25519Key2);
92
+ const ed25519Mb2 = await require_key.exportMultibaseKey(ed25519Key2);
269
93
  (0, node_assert.deepStrictEqual)(ed25519Mb2, "z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK");
270
94
  });
271
95
 
@@ -1,190 +1,9 @@
1
- import { decodeMultibase, encodeMultibase } from "./multibase-DStmqni9.js";
2
- import { deepStrictEqual } from "node:assert";
1
+ import "./multicodec-Dq3IiOV4.js";
2
+ import { exportJwk, exportMultibaseKey, exportSpki, importJwk, importMultibaseKey, importPem, importPkcs1, importSpki } from "./key-ByCmSI2y.js";
3
+ import { encodeMultibase } from "./multibase-B4g8pz6F.js";
4
+ import { deepStrictEqual, rejects } from "node:assert";
3
5
  import { test } from "node:test";
4
- import { Integer, Sequence } from "asn1js";
5
- import { decodeBase64, encodeBase64 } from "byte-encodings/base64";
6
- import { decodeBase64Url } from "byte-encodings/base64url";
7
- import { decodeHex } from "byte-encodings/hex";
8
- import { addPrefix, getCodeFromData, rmPrefix } from "multicodec";
9
- import { createPublicKey } from "node:crypto";
10
- import { PublicKeyInfo } from "pkijs";
11
6
 
12
- //#region src/jwk.ts
13
- function validateCryptoKey(key, type) {
14
- if (type != null && key.type !== type) throw new TypeError(`The key is not a ${type} key.`);
15
- if (!key.extractable) throw new TypeError("The key is not extractable.");
16
- if (key.algorithm.name !== "RSASSA-PKCS1-v1_5" && key.algorithm.name !== "Ed25519") throw new TypeError("Currently only RSASSA-PKCS1-v1_5 and Ed25519 keys are supported. More algorithms will be added in the future!");
17
- if (key.algorithm.name === "RSASSA-PKCS1-v1_5") {
18
- const algorithm = key.algorithm;
19
- if (algorithm.hash.name !== "SHA-256") throw new TypeError("For compatibility with the existing Fediverse software (e.g., Mastodon), hash algorithm for RSASSA-PKCS1-v1_5 keys must be SHA-256.");
20
- }
21
- }
22
- async function exportJwk(key) {
23
- validateCryptoKey(key);
24
- const jwk = await crypto.subtle.exportKey("jwk", key);
25
- if (jwk.crv === "Ed25519") jwk.alg = "Ed25519";
26
- return jwk;
27
- }
28
- async function importJwk(jwk, type) {
29
- let key;
30
- if (jwk.kty === "RSA" && jwk.alg === "RS256") key = await crypto.subtle.importKey("jwk", jwk, {
31
- name: "RSASSA-PKCS1-v1_5",
32
- hash: "SHA-256"
33
- }, true, type === "public" ? ["verify"] : ["sign"]);
34
- else if (jwk.kty === "OKP" && jwk.crv === "Ed25519") {
35
- if (navigator?.userAgent === "Cloudflare-Workers") {
36
- jwk = { ...jwk };
37
- delete jwk.alg;
38
- }
39
- key = await crypto.subtle.importKey("jwk", jwk, "Ed25519", true, type === "public" ? ["verify"] : ["sign"]);
40
- } else throw new TypeError("Unsupported JWK format.");
41
- validateCryptoKey(key, type);
42
- return key;
43
- }
44
-
45
- //#endregion
46
- //#region src/key.ts
47
- const algorithms = {
48
- "1.2.840.113549.1.1.1": {
49
- name: "RSASSA-PKCS1-v1_5",
50
- hash: "SHA-256"
51
- },
52
- "1.3.101.112": "Ed25519"
53
- };
54
- /**
55
- * Imports a PEM-SPKI formatted public key.
56
- * @param pem The PEM-SPKI formatted public key.
57
- * @returns The imported public key.
58
- * @throws {TypeError} If the key is invalid or unsupported.
59
- * @since 0.5.0
60
- */
61
- async function importSpki(pem) {
62
- pem = pem.replace(/(?:-----(?:BEGIN|END) PUBLIC KEY-----|\s)/g, "");
63
- let spki;
64
- try {
65
- spki = decodeBase64(pem);
66
- } catch (_) {
67
- throw new TypeError("Invalid PEM-SPKI format.");
68
- }
69
- const pki = PublicKeyInfo.fromBER(spki);
70
- const oid = pki.algorithm.algorithmId;
71
- const algorithm = algorithms[oid];
72
- if (algorithm == null) throw new TypeError("Unsupported algorithm: " + oid);
73
- return await crypto.subtle.importKey("spki", spki, algorithm, true, ["verify"]);
74
- }
75
- /**
76
- * Exports a public key in PEM-SPKI format.
77
- * @param key The public key to export.
78
- * @returns The exported public key in PEM-SPKI format.
79
- * @throws {TypeError} If the key is invalid or unsupported.
80
- * @since 0.5.0
81
- */
82
- async function exportSpki(key) {
83
- validateCryptoKey(key);
84
- const spki = await crypto.subtle.exportKey("spki", key);
85
- let pem = encodeBase64(spki);
86
- pem = (pem.match(/.{1,64}/g) || []).join("\n");
87
- return `-----BEGIN PUBLIC KEY-----\n${pem}\n-----END PUBLIC KEY-----\n`;
88
- }
89
- /**
90
- * Imports a PEM-PKCS#1 formatted public key.
91
- * @param pem The PEM-PKCS#1 formatted public key.
92
- * @returns The imported public key.
93
- * @throws {TypeError} If the key is invalid or unsupported.
94
- * @since 1.5.0
95
- */
96
- function importPkcs1(pem) {
97
- const key = createPublicKey({
98
- key: pem,
99
- format: "pem",
100
- type: "pkcs1"
101
- });
102
- const spki = key.export({
103
- type: "spki",
104
- format: "pem"
105
- });
106
- return importSpki(spki);
107
- }
108
- const PKCS1_HEADER = /^\s*-----BEGIN\s+RSA\s+PUBLIC\s+KEY-----\s*\n/;
109
- /**
110
- * Imports a PEM formatted public key (SPKI or PKCS#1).
111
- * @param pem The PEM formatted public key to import (SPKI or PKCS#1).
112
- * @returns The imported public key.
113
- * @throws {TypeError} If the key is invalid or unsupported.
114
- * @since 1.5.0
115
- */
116
- function importPem(pem) {
117
- return PKCS1_HEADER.test(pem) ? importPkcs1(pem) : importSpki(pem);
118
- }
119
- /**
120
- * Imports a [Multibase]-encoded public key.
121
- *
122
- * [Multibase]: https://www.w3.org/TR/vc-data-integrity/#multibase-0
123
- * @param key The Multibase-encoded public key.
124
- * @returns The imported public key.
125
- * @throws {TypeError} If the key is invalid or unsupported.
126
- * @since 0.10.0
127
- */
128
- async function importMultibaseKey(key) {
129
- const decoded = decodeMultibase(key);
130
- const code = getCodeFromData(decoded);
131
- const content = rmPrefix(decoded);
132
- if (code === 4613) {
133
- const keyObject = createPublicKey({
134
- key: content,
135
- format: "der",
136
- type: "pkcs1"
137
- });
138
- const exported = keyObject.export({
139
- type: "spki",
140
- format: "der"
141
- });
142
- const spki = exported instanceof Uint8Array ? exported : new Uint8Array(exported);
143
- return await crypto.subtle.importKey("spki", new Uint8Array(spki), {
144
- name: "RSASSA-PKCS1-v1_5",
145
- hash: "SHA-256"
146
- }, true, ["verify"]);
147
- } else if (code === 237) return await crypto.subtle.importKey("raw", content.slice(), "Ed25519", true, ["verify"]);
148
- else throw new TypeError("Unsupported key type: 0x" + code.toString(16));
149
- }
150
- /**
151
- * Exports a public key in [Multibase] format.
152
- *
153
- * [Multibase]: https://www.w3.org/TR/vc-data-integrity/#multibase-0
154
- * @param key The public key to export.
155
- * @returns The exported public key in Multibase format.
156
- * @throws {TypeError} If the key is invalid or unsupported.
157
- * @since 0.10.0
158
- */
159
- async function exportMultibaseKey(key) {
160
- let content;
161
- let code;
162
- if (key.algorithm.name === "Ed25519") {
163
- content = await crypto.subtle.exportKey("raw", key);
164
- code = 237;
165
- } else if (key.algorithm.name === "RSASSA-PKCS1-v1_5" && key.algorithm.hash.name === "SHA-256") {
166
- const jwk = await crypto.subtle.exportKey("jwk", key);
167
- const decodedN = decodeBase64Url(jwk.n);
168
- const n = new Uint8Array(decodedN.length + 1);
169
- n.set(decodedN, 1);
170
- const sequence = new Sequence({ value: [new Integer({
171
- isHexOnly: true,
172
- valueHex: n
173
- }), new Integer({
174
- isHexOnly: true,
175
- valueHex: decodeBase64Url(jwk.e)
176
- })] });
177
- content = sequence.toBER(false);
178
- code = 4613;
179
- } else throw new TypeError("Unsupported key type: " + JSON.stringify(key.algorithm));
180
- const codeHex = code.toString(16);
181
- const codeBytes = decodeHex(codeHex.length % 2 < 1 ? codeHex : "0" + codeHex);
182
- const prefixed = addPrefix(codeBytes, new Uint8Array(content));
183
- const encoded = encodeMultibase("base58btc", prefixed);
184
- return new TextDecoder().decode(encoded);
185
- }
186
-
187
- //#endregion
188
7
  //#region src/key.test.ts
189
8
  const rsaSpki = "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxsRuvCkgJtflBTl4OVsm\nnt/J1mQfZasfJtN33dcZ3d1lJroxmgmMu69zjGEAwkNbMQaWNLqC4eogkJaeJ4RR\n5MHYXkL9nNilVoTkjX5BVit3puzs7XJ7WQnKQgQMI+ezn24GHsZ/v1JIo77lerX5\nk4HNwTNVt+yaZVQWaOMR3+6FwziQR6kd0VuG9/a9dgAnz2cEoORRC1i4W7IZaB1s\nZnh1WbHbevlGd72HSXll5rocPIHn8gq6xpBgpHwRphlRsgn4KHaJ6brXDIJjrnQh\nIe/YUBOGj/ImSEXhRwlFerKsoAVnZ0Hwbfa46qk44TAt8CyoPMWmpK6pt0ng4pQ2\nuwIDAQAB\n-----END PUBLIC KEY-----\n";
190
9
  const rsaPkcs1 = "-----BEGIN RSA PUBLIC KEY-----\nMIIBCgKCAQEAxsRuvCkgJtflBTl4OVsmnt/J1mQfZasfJtN33dcZ3d1lJroxmgmM\nu69zjGEAwkNbMQaWNLqC4eogkJaeJ4RR5MHYXkL9nNilVoTkjX5BVit3puzs7XJ7\nWQnKQgQMI+ezn24GHsZ/v1JIo77lerX5k4HNwTNVt+yaZVQWaOMR3+6FwziQR6kd\n0VuG9/a9dgAnz2cEoORRC1i4W7IZaB1sZnh1WbHbevlGd72HSXll5rocPIHn8gq6\nxpBgpHwRphlRsgn4KHaJ6brXDIJjrnQhIe/YUBOGj/ImSEXhRwlFerKsoAVnZ0Hw\nbfa46qk44TAt8CyoPMWmpK6pt0ng4pQ2uwIDAQAB\n-----END RSA PUBLIC KEY-----\n";
@@ -239,6 +58,11 @@ test("importMultibase()", async () => {
239
58
  const ed25519Key = await importMultibaseKey(ed25519Multibase);
240
59
  deepStrictEqual(await exportJwk(ed25519Key), ed25519Jwk);
241
60
  });
61
+ test("importMultibase() rejects malformed multicodec prefixes", async () => {
62
+ const decoder = new TextDecoder();
63
+ await rejects(() => importMultibaseKey(decoder.decode(encodeMultibase("base58btc", new Uint8Array([])))), /* @__PURE__ */ new TypeError("Invalid multicodec prefix."));
64
+ await rejects(() => importMultibaseKey(decoder.decode(encodeMultibase("base58btc", Uint8Array.from([128])))), /* @__PURE__ */ new TypeError("Invalid multicodec prefix."));
65
+ });
242
66
  test("exportMultibaseKey()", async () => {
243
67
  const rsaKey = await importJwk(rsaJwk, "public");
244
68
  const rsaMb = await exportMultibaseKey(rsaKey);
@@ -0,0 +1,30 @@
1
+ //#region src/langstr.ts
2
+ /**
3
+ * A language-tagged string which corresponds to the `rdf:langString` type.
4
+ */
5
+ var LanguageString = class extends String {
6
+ /**
7
+ * The locale of the string.
8
+ * @since 2.0.0
9
+ */
10
+ locale;
11
+ /**
12
+ * Constructs a new `LanguageString`.
13
+ * @param value A string value written in the given language.
14
+ * @param language The language of the string. If a string is given, it will
15
+ * be parsed as a `Intl.Locale` object.
16
+ */
17
+ constructor(value, language) {
18
+ super(value);
19
+ this.locale = typeof language === "string" ? new Intl.Locale(language) : language;
20
+ }
21
+ };
22
+ LanguageString.prototype[Symbol.for("Deno.customInspect")] = function(inspect, options) {
23
+ return `<${this.locale.baseName}> ${inspect(this.toString(), options)}`;
24
+ };
25
+ LanguageString.prototype[Symbol.for("nodejs.util.inspect.custom")] = function(_depth, options, inspect) {
26
+ return `<${this.locale.baseName}> ${inspect(this.toString(), options)}`;
27
+ };
28
+
29
+ //#endregion
30
+ export { LanguageString };
@@ -0,0 +1,36 @@
1
+
2
+ //#region src/langstr.ts
3
+ /**
4
+ * A language-tagged string which corresponds to the `rdf:langString` type.
5
+ */
6
+ var LanguageString = class extends String {
7
+ /**
8
+ * The locale of the string.
9
+ * @since 2.0.0
10
+ */
11
+ locale;
12
+ /**
13
+ * Constructs a new `LanguageString`.
14
+ * @param value A string value written in the given language.
15
+ * @param language The language of the string. If a string is given, it will
16
+ * be parsed as a `Intl.Locale` object.
17
+ */
18
+ constructor(value, language) {
19
+ super(value);
20
+ this.locale = typeof language === "string" ? new Intl.Locale(language) : language;
21
+ }
22
+ };
23
+ LanguageString.prototype[Symbol.for("Deno.customInspect")] = function(inspect, options) {
24
+ return `<${this.locale.baseName}> ${inspect(this.toString(), options)}`;
25
+ };
26
+ LanguageString.prototype[Symbol.for("nodejs.util.inspect.custom")] = function(_depth, options, inspect) {
27
+ return `<${this.locale.baseName}> ${inspect(this.toString(), options)}`;
28
+ };
29
+
30
+ //#endregion
31
+ Object.defineProperty(exports, 'LanguageString', {
32
+ enumerable: true,
33
+ get: function () {
34
+ return LanguageString;
35
+ }
36
+ });
@@ -1,50 +1,22 @@
1
1
  const require_chunk = require('./chunk-DWy1uDak.cjs');
2
+ const require_langstr = require('./langstr-EPh86hXK.cjs');
2
3
  const node_assert = require_chunk.__toESM(require("node:assert"));
3
4
  const node_test = require_chunk.__toESM(require("node:test"));
4
5
  const node_util = require_chunk.__toESM(require("node:util"));
5
6
 
6
- //#region src/langstr.ts
7
- /**
8
- * A language-tagged string which corresponds to the `rdf:langString` type.
9
- */
10
- var LanguageString = class extends String {
11
- /**
12
- * The locale of the string.
13
- * @since 2.0.0
14
- */
15
- locale;
16
- /**
17
- * Constructs a new `LanguageString`.
18
- * @param value A string value written in the given language.
19
- * @param language The language of the string. If a string is given, it will
20
- * be parsed as a `Intl.Locale` object.
21
- */
22
- constructor(value, language) {
23
- super(value);
24
- this.locale = typeof language === "string" ? new Intl.Locale(language) : language;
25
- }
26
- };
27
- LanguageString.prototype[Symbol.for("Deno.customInspect")] = function(inspect, options) {
28
- return `<${this.locale.baseName}> ${inspect(this.toString(), options)}`;
29
- };
30
- LanguageString.prototype[Symbol.for("nodejs.util.inspect.custom")] = function(_depth, options, inspect) {
31
- return `<${this.locale.baseName}> ${inspect(this.toString(), options)}`;
32
- };
33
-
34
- //#endregion
35
7
  //#region src/langstr.test.ts
36
8
  (0, node_test.test)("new LanguageString()", () => {
37
- const langStr = new LanguageString("Hello", "en");
9
+ const langStr = new require_langstr.LanguageString("Hello", "en");
38
10
  (0, node_assert.deepStrictEqual)(langStr.toString(), "Hello");
39
11
  (0, node_assert.deepStrictEqual)(langStr.locale, new Intl.Locale("en"));
40
- (0, node_assert.deepStrictEqual)(new LanguageString("Hello", new Intl.Locale("en")), langStr);
12
+ (0, node_assert.deepStrictEqual)(new require_langstr.LanguageString("Hello", new Intl.Locale("en")), langStr);
41
13
  });
42
14
  (0, node_test.test)("Deno.inspect(LanguageString)", () => {
43
- const langStr = new LanguageString("Hello, 'world'", "en");
15
+ const langStr = new require_langstr.LanguageString("Hello, 'world'", "en");
44
16
  (0, node_assert.deepStrictEqual)(node_util.default.inspect(langStr, { colors: false }), "<en> \"Hello, 'world'\"");
45
17
  });
46
18
  (0, node_test.test)("util.inspect(LanguageString)", () => {
47
- const langStr = new LanguageString("Hello, 'world'", "en");
19
+ const langStr = new require_langstr.LanguageString("Hello, 'world'", "en");
48
20
  (0, node_assert.deepStrictEqual)(node_util.default.inspect(langStr, { colors: false }), "<en> \"Hello, 'world'\"");
49
21
  });
50
22
 
@@ -1,36 +1,8 @@
1
+ import { LanguageString } from "./langstr-BsVE3s9u.js";
1
2
  import { deepStrictEqual } from "node:assert";
2
3
  import { test } from "node:test";
3
4
  import util from "node:util";
4
5
 
5
- //#region src/langstr.ts
6
- /**
7
- * A language-tagged string which corresponds to the `rdf:langString` type.
8
- */
9
- var LanguageString = class extends String {
10
- /**
11
- * The locale of the string.
12
- * @since 2.0.0
13
- */
14
- locale;
15
- /**
16
- * Constructs a new `LanguageString`.
17
- * @param value A string value written in the given language.
18
- * @param language The language of the string. If a string is given, it will
19
- * be parsed as a `Intl.Locale` object.
20
- */
21
- constructor(value, language) {
22
- super(value);
23
- this.locale = typeof language === "string" ? new Intl.Locale(language) : language;
24
- }
25
- };
26
- LanguageString.prototype[Symbol.for("Deno.customInspect")] = function(inspect, options) {
27
- return `<${this.locale.baseName}> ${inspect(this.toString(), options)}`;
28
- };
29
- LanguageString.prototype[Symbol.for("nodejs.util.inspect.custom")] = function(_depth, options, inspect) {
30
- return `<${this.locale.baseName}> ${inspect(this.toString(), options)}`;
31
- };
32
-
33
- //#endregion
34
6
  //#region src/langstr.test.ts
35
7
  test("new LanguageString()", () => {
36
8
  const langStr = new LanguageString("Hello", "en");
@@ -1,5 +1,5 @@
1
1
  const require_chunk = require('./chunk-DWy1uDak.cjs');
2
- const require_link = require('./link-CdFPEo9O.cjs');
2
+ const require_link = require('./link-DYNFAdNu.cjs');
3
3
  const node_assert = require_chunk.__toESM(require("node:assert"));
4
4
  const node_test = require_chunk.__toESM(require("node:test"));
5
5
 
@@ -1,4 +1,4 @@
1
- import { HttpHeaderLink } from "./link-Ck2yj4dH.js";
1
+ import { HttpHeaderLink } from "./link-C3q2TC2G.js";
2
2
  import { deepStrictEqual, throws } from "node:assert";
3
3
  import { test } from "node:test";
4
4