@fedify/vocab-runtime 2.4.0-dev.1634 → 2.4.0-dev.1659
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/deno.json +1 -1
- package/dist/mod.cjs +146 -3
- package/dist/mod.d.cts +82 -1
- package/dist/mod.d.ts +82 -1
- package/dist/mod.js +141 -4
- package/dist/tests/decimal.test.cjs +5 -4
- package/dist/tests/decimal.test.mjs +5 -4
- package/dist/tests/digest-BJlumPNJ.mjs +140 -0
- package/dist/tests/digest-DLwUyHCK.cjs +175 -0
- package/dist/tests/digest.test.cjs +103 -0
- package/dist/tests/digest.test.d.cts +1 -0
- package/dist/tests/digest.test.d.mts +1 -0
- package/dist/tests/digest.test.mjs +103 -0
- package/dist/tests/{docloader-CTd4XwqK.cjs → docloader-CDetn4RD.cjs} +1 -1
- package/dist/tests/{docloader-CNzoXrLM.mjs → docloader-C_0493V1.mjs} +1 -1
- package/dist/tests/docloader.test.cjs +2 -2
- package/dist/tests/docloader.test.mjs +2 -2
- package/dist/tests/{key-_wXwomh_.cjs → key-BcOWDLMm.cjs} +1 -1
- package/dist/tests/{key-CDGDH_vC.mjs → key-Drbw_2tw.mjs} +1 -1
- package/dist/tests/key.test.cjs +2 -2
- package/dist/tests/key.test.mjs +2 -2
- package/dist/tests/langstr.test.cjs +1 -1
- package/dist/tests/langstr.test.mjs +1 -1
- package/dist/tests/multibase/multibase.test.cjs +1 -1
- package/dist/tests/multibase/multibase.test.mjs +1 -1
- package/dist/tests/{multibase-B4bvakyA.mjs → multibase-Cluwl8OM.mjs} +12 -1
- package/dist/tests/{multibase-Bz_UUDtL.cjs → multibase-DcDQDNnI.cjs} +17 -0
- package/dist/tests/{request-BWDludWb.mjs → request-CMiFLtdL.mjs} +1 -1
- package/dist/tests/{request-Zpjq9m-W.cjs → request-DyhyDm6Z.cjs} +1 -1
- package/dist/tests/request.test.cjs +1 -1
- package/dist/tests/request.test.mjs +1 -1
- package/package.json +1 -1
- package/src/digest.test.ts +220 -0
- package/src/digest.ts +229 -0
- package/src/mod.ts +10 -0
- /package/dist/tests/{langstr-CbAxaeEZ.cjs → langstr-BOQHfJDr.cjs} +0 -0
- /package/dist/tests/{langstr-Di5AvKpB.mjs → langstr-DDLc4833.mjs} +0 -0
package/deno.json
CHANGED
package/dist/mod.cjs
CHANGED
|
@@ -4371,7 +4371,7 @@ const preloadedContexts = {
|
|
|
4371
4371
|
//#endregion
|
|
4372
4372
|
//#region deno.json
|
|
4373
4373
|
var name = "@fedify/vocab-runtime";
|
|
4374
|
-
var version = "2.4.0-dev.
|
|
4374
|
+
var version = "2.4.0-dev.1659+c20a23e9";
|
|
4375
4375
|
//#endregion
|
|
4376
4376
|
//#region src/link.ts
|
|
4377
4377
|
const parametersNeedLowerCase = ["rel", "type"];
|
|
@@ -4936,8 +4936,8 @@ function validateCryptoKey(key, type) {
|
|
|
4936
4936
|
}
|
|
4937
4937
|
//#endregion
|
|
4938
4938
|
//#region src/multibase/util.ts
|
|
4939
|
-
const textDecoder = new TextDecoder();
|
|
4940
|
-
const decodeText = (bytes) => textDecoder.decode(bytes);
|
|
4939
|
+
const textDecoder$1 = new TextDecoder();
|
|
4940
|
+
const decodeText = (bytes) => textDecoder$1.decode(bytes);
|
|
4941
4941
|
const textEncoder = new TextEncoder();
|
|
4942
4942
|
const encodeText = (text) => textEncoder.encode(text);
|
|
4943
4943
|
function concat(arrs, length) {
|
|
@@ -5526,6 +5526,143 @@ function parseDecimal(value) {
|
|
|
5526
5526
|
return normalized;
|
|
5527
5527
|
}
|
|
5528
5528
|
//#endregion
|
|
5529
|
+
//#region src/digest.ts
|
|
5530
|
+
const SHA2_256_MULTIHASH_CODE = 18;
|
|
5531
|
+
const SHA2_256_DIGEST_LENGTH = 32;
|
|
5532
|
+
const MAX_DIGEST_MULTIBASE_LENGTH = 1 + (SHA2_256_DIGEST_LENGTH + 2) * 8;
|
|
5533
|
+
const textDecoder = new TextDecoder();
|
|
5534
|
+
const getArrayBufferByteLength = Object.getOwnPropertyDescriptor(ArrayBuffer.prototype, "byteLength")?.get;
|
|
5535
|
+
function isCanonicalVarintPrefix(data, prefix) {
|
|
5536
|
+
const canonical = addMulticodecPrefix(prefix.code, new Uint8Array());
|
|
5537
|
+
if (canonical.length !== prefix.prefixLength) return false;
|
|
5538
|
+
for (let i = 0; i < canonical.length; i++) if (data[i] !== canonical[i]) return false;
|
|
5539
|
+
return true;
|
|
5540
|
+
}
|
|
5541
|
+
function toWebCryptoBytes(bytes) {
|
|
5542
|
+
if (getArrayBufferByteLength != null) try {
|
|
5543
|
+
getArrayBufferByteLength.call(bytes.buffer);
|
|
5544
|
+
return bytes;
|
|
5545
|
+
} catch {}
|
|
5546
|
+
return new Uint8Array(bytes);
|
|
5547
|
+
}
|
|
5548
|
+
/**
|
|
5549
|
+
* Computes the SHA-256 digest of a byte sequence and encodes it as a
|
|
5550
|
+
* base58-btc multibase multihash suitable for FEP-ef61's
|
|
5551
|
+
* `digestMultibase` property.
|
|
5552
|
+
*
|
|
5553
|
+
* @param bytes The bytes to digest.
|
|
5554
|
+
* @returns The base58-btc multibase-encoded SHA-256 multihash.
|
|
5555
|
+
* @since 2.4.0
|
|
5556
|
+
*/
|
|
5557
|
+
async function computeDigestMultibase(bytes) {
|
|
5558
|
+
const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", toWebCryptoBytes(bytes)));
|
|
5559
|
+
const multihash = addMulticodecPrefix(SHA2_256_MULTIHASH_CODE, addMulticodecPrefix(digest.length, digest));
|
|
5560
|
+
return textDecoder.decode(encodeMultibase("base58btc", multihash));
|
|
5561
|
+
}
|
|
5562
|
+
/**
|
|
5563
|
+
* Parses and validates a SHA-256 `digestMultibase` value.
|
|
5564
|
+
*
|
|
5565
|
+
* @param value The multibase-encoded multihash to parse.
|
|
5566
|
+
* @returns The digest algorithm and raw digest bytes.
|
|
5567
|
+
* @throws {TypeError} If the value is malformed or uses an unsupported hash
|
|
5568
|
+
* algorithm.
|
|
5569
|
+
* @since 2.4.0
|
|
5570
|
+
*/
|
|
5571
|
+
function parseDigestMultibase(value) {
|
|
5572
|
+
if (value.length > MAX_DIGEST_MULTIBASE_LENGTH) throw new TypeError("Invalid digestMultibase encoding.");
|
|
5573
|
+
let multihash;
|
|
5574
|
+
try {
|
|
5575
|
+
multihash = decodeMultibase(value);
|
|
5576
|
+
} catch (error) {
|
|
5577
|
+
throw new TypeError("Invalid digestMultibase encoding.", { cause: error });
|
|
5578
|
+
}
|
|
5579
|
+
const encoding = encodingFromBaseData(value);
|
|
5580
|
+
if (value !== textDecoder.decode(encodeMultibase(encoding.name, multihash))) throw new TypeError("Invalid digestMultibase encoding.");
|
|
5581
|
+
let algorithmPrefix;
|
|
5582
|
+
try {
|
|
5583
|
+
algorithmPrefix = getMulticodecPrefix(multihash);
|
|
5584
|
+
} catch (error) {
|
|
5585
|
+
throw new TypeError("Invalid digestMultibase multihash.", { cause: error });
|
|
5586
|
+
}
|
|
5587
|
+
if (!isCanonicalVarintPrefix(multihash, algorithmPrefix)) throw new TypeError("Invalid digestMultibase multihash.");
|
|
5588
|
+
if (algorithmPrefix.code !== SHA2_256_MULTIHASH_CODE) throw new TypeError(`Unsupported digest algorithm: 0x${algorithmPrefix.code.toString(16)}`);
|
|
5589
|
+
const lengthAndDigest = multihash.subarray(algorithmPrefix.prefixLength);
|
|
5590
|
+
let lengthPrefix;
|
|
5591
|
+
try {
|
|
5592
|
+
lengthPrefix = getMulticodecPrefix(lengthAndDigest);
|
|
5593
|
+
} catch (error) {
|
|
5594
|
+
throw new TypeError("Invalid digestMultibase multihash.", { cause: error });
|
|
5595
|
+
}
|
|
5596
|
+
if (!isCanonicalVarintPrefix(lengthAndDigest, lengthPrefix)) throw new TypeError("Invalid digestMultibase multihash.");
|
|
5597
|
+
const digest = lengthAndDigest.slice(lengthPrefix.prefixLength);
|
|
5598
|
+
if (lengthPrefix.code !== SHA2_256_DIGEST_LENGTH || digest.length !== SHA2_256_DIGEST_LENGTH) throw new TypeError("Invalid SHA-256 digest length.");
|
|
5599
|
+
return {
|
|
5600
|
+
algorithm: "sha2-256",
|
|
5601
|
+
digest
|
|
5602
|
+
};
|
|
5603
|
+
}
|
|
5604
|
+
function extractDigestMultibase(value) {
|
|
5605
|
+
const hashlink = typeof value === "string" ? value : value.href;
|
|
5606
|
+
const match = /^hl:([^:\r\n\u2028\u2029]+)$/i.exec(hashlink);
|
|
5607
|
+
if (match == null || match[0].length !== hashlink.length) throw new TypeError("Invalid simple hashlink.");
|
|
5608
|
+
return match[1];
|
|
5609
|
+
}
|
|
5610
|
+
/**
|
|
5611
|
+
* Parses a metadata-free `hl:` hashlink and validates its resource digest.
|
|
5612
|
+
*
|
|
5613
|
+
* @param value The simple hashlink to parse.
|
|
5614
|
+
* @returns The `digestMultibase` value carried by the hashlink.
|
|
5615
|
+
* @throws {TypeError} If the hashlink is malformed, contains metadata, or
|
|
5616
|
+
* carries an invalid or unsupported digest.
|
|
5617
|
+
* @since 2.4.0
|
|
5618
|
+
*/
|
|
5619
|
+
function parseHashlink(value) {
|
|
5620
|
+
const digestMultibase = extractDigestMultibase(value);
|
|
5621
|
+
parseDigestMultibase(digestMultibase);
|
|
5622
|
+
return { digestMultibase };
|
|
5623
|
+
}
|
|
5624
|
+
/**
|
|
5625
|
+
* Creates a metadata-free `hl:` hashlink from a `digestMultibase` value.
|
|
5626
|
+
*
|
|
5627
|
+
* @param digestMultibase The SHA-256 multibase multihash to embed.
|
|
5628
|
+
* @returns The simple hashlink.
|
|
5629
|
+
* @throws {TypeError} If the digest is malformed or unsupported.
|
|
5630
|
+
* @since 2.4.0
|
|
5631
|
+
*/
|
|
5632
|
+
function createHashlink(digestMultibase) {
|
|
5633
|
+
parseDigestMultibase(digestMultibase);
|
|
5634
|
+
return `hl:${digestMultibase}`;
|
|
5635
|
+
}
|
|
5636
|
+
/**
|
|
5637
|
+
* Verifies that bytes match a SHA-256 `digestMultibase` value.
|
|
5638
|
+
*
|
|
5639
|
+
* @param bytes The bytes to verify.
|
|
5640
|
+
* @param digestMultibase The expected digest.
|
|
5641
|
+
* @returns Whether the bytes match the digest.
|
|
5642
|
+
* @throws {TypeError} If the digest is malformed or unsupported.
|
|
5643
|
+
* @since 2.4.0
|
|
5644
|
+
*/
|
|
5645
|
+
async function verifyDigestMultibase(bytes, digestMultibase) {
|
|
5646
|
+
const expected = parseDigestMultibase(digestMultibase).digest;
|
|
5647
|
+
const actual = new Uint8Array(await crypto.subtle.digest("SHA-256", toWebCryptoBytes(bytes)));
|
|
5648
|
+
if (expected.length !== actual.length) return false;
|
|
5649
|
+
let difference = 0;
|
|
5650
|
+
for (let i = 0; i < expected.length; i++) difference |= expected[i] ^ actual[i];
|
|
5651
|
+
return difference === 0;
|
|
5652
|
+
}
|
|
5653
|
+
/**
|
|
5654
|
+
* Verifies that bytes match the resource digest in a simple hashlink.
|
|
5655
|
+
*
|
|
5656
|
+
* @param bytes The bytes to verify.
|
|
5657
|
+
* @param hashlink The simple hashlink containing the expected digest.
|
|
5658
|
+
* @returns Whether the bytes match the hashlink digest.
|
|
5659
|
+
* @throws {TypeError} If the hashlink or digest is malformed or unsupported.
|
|
5660
|
+
* @since 2.4.0
|
|
5661
|
+
*/
|
|
5662
|
+
async function verifyHashlink(bytes, hashlink) {
|
|
5663
|
+
return await verifyDigestMultibase(bytes, extractDigestMultibase(hashlink));
|
|
5664
|
+
}
|
|
5665
|
+
//#endregion
|
|
5529
5666
|
//#region src/langstr.ts
|
|
5530
5667
|
/**
|
|
5531
5668
|
* A language-tagged string which corresponds to the `rdf:langString` type.
|
|
@@ -5560,7 +5697,9 @@ exports.UrlError = require_url.UrlError;
|
|
|
5560
5697
|
exports.arePortableUrisEqual = require_url.arePortableUrisEqual;
|
|
5561
5698
|
exports.canParseDecimal = canParseDecimal;
|
|
5562
5699
|
exports.canonicalizePortableUri = require_url.canonicalizePortableUri;
|
|
5700
|
+
exports.computeDigestMultibase = computeDigestMultibase;
|
|
5563
5701
|
exports.createActivityPubRequest = createActivityPubRequest;
|
|
5702
|
+
exports.createHashlink = createHashlink;
|
|
5564
5703
|
exports.decodeMultibase = decodeMultibase;
|
|
5565
5704
|
exports.encodeMultibase = encodeMultibase;
|
|
5566
5705
|
exports.encodingFromBaseData = encodingFromBaseData;
|
|
@@ -5587,8 +5726,12 @@ exports.isValidPublicIPv6Address = require_url.isValidPublicIPv6Address;
|
|
|
5587
5726
|
exports.logRequest = logRequest;
|
|
5588
5727
|
exports.parseDecimal = parseDecimal;
|
|
5589
5728
|
exports.parseDidKeyVerificationMethod = parseDidKeyVerificationMethod;
|
|
5729
|
+
exports.parseDigestMultibase = parseDigestMultibase;
|
|
5590
5730
|
exports.parseGatewayUrl = require_url.parseGatewayUrl;
|
|
5731
|
+
exports.parseHashlink = parseHashlink;
|
|
5591
5732
|
exports.parseIri = require_url.parseIri;
|
|
5592
5733
|
exports.parseJsonLdId = require_url.parseJsonLdId;
|
|
5593
5734
|
exports.preloadedContexts = preloadedContexts;
|
|
5594
5735
|
exports.validatePublicUrl = require_url.validatePublicUrl;
|
|
5736
|
+
exports.verifyDigestMultibase = verifyDigestMultibase;
|
|
5737
|
+
exports.verifyHashlink = verifyHashlink;
|
package/dist/mod.d.cts
CHANGED
|
@@ -204,6 +204,87 @@ declare function canParseDecimal(value: string): boolean;
|
|
|
204
204
|
*/
|
|
205
205
|
declare function parseDecimal(value: string): Decimal;
|
|
206
206
|
//#endregion
|
|
207
|
+
//#region src/digest.d.ts
|
|
208
|
+
/**
|
|
209
|
+
* A parsed SHA-256 resource digest.
|
|
210
|
+
*
|
|
211
|
+
* @since 2.4.0
|
|
212
|
+
*/
|
|
213
|
+
interface ParsedDigestMultibase {
|
|
214
|
+
/** The multihash algorithm represented by the digest. */
|
|
215
|
+
readonly algorithm: "sha2-256";
|
|
216
|
+
/** The raw 32-byte SHA-256 digest. */
|
|
217
|
+
readonly digest: Uint8Array;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* A parsed simple hashlink.
|
|
221
|
+
*
|
|
222
|
+
* @since 2.4.0
|
|
223
|
+
*/
|
|
224
|
+
interface ParsedHashlink {
|
|
225
|
+
/** The multibase-encoded multihash carried by the hashlink. */
|
|
226
|
+
readonly digestMultibase: string;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Computes the SHA-256 digest of a byte sequence and encodes it as a
|
|
230
|
+
* base58-btc multibase multihash suitable for FEP-ef61's
|
|
231
|
+
* `digestMultibase` property.
|
|
232
|
+
*
|
|
233
|
+
* @param bytes The bytes to digest.
|
|
234
|
+
* @returns The base58-btc multibase-encoded SHA-256 multihash.
|
|
235
|
+
* @since 2.4.0
|
|
236
|
+
*/
|
|
237
|
+
declare function computeDigestMultibase(bytes: Uint8Array): Promise<string>;
|
|
238
|
+
/**
|
|
239
|
+
* Parses and validates a SHA-256 `digestMultibase` value.
|
|
240
|
+
*
|
|
241
|
+
* @param value The multibase-encoded multihash to parse.
|
|
242
|
+
* @returns The digest algorithm and raw digest bytes.
|
|
243
|
+
* @throws {TypeError} If the value is malformed or uses an unsupported hash
|
|
244
|
+
* algorithm.
|
|
245
|
+
* @since 2.4.0
|
|
246
|
+
*/
|
|
247
|
+
declare function parseDigestMultibase(value: string): ParsedDigestMultibase;
|
|
248
|
+
/**
|
|
249
|
+
* Parses a metadata-free `hl:` hashlink and validates its resource digest.
|
|
250
|
+
*
|
|
251
|
+
* @param value The simple hashlink to parse.
|
|
252
|
+
* @returns The `digestMultibase` value carried by the hashlink.
|
|
253
|
+
* @throws {TypeError} If the hashlink is malformed, contains metadata, or
|
|
254
|
+
* carries an invalid or unsupported digest.
|
|
255
|
+
* @since 2.4.0
|
|
256
|
+
*/
|
|
257
|
+
declare function parseHashlink(value: string | URL): ParsedHashlink;
|
|
258
|
+
/**
|
|
259
|
+
* Creates a metadata-free `hl:` hashlink from a `digestMultibase` value.
|
|
260
|
+
*
|
|
261
|
+
* @param digestMultibase The SHA-256 multibase multihash to embed.
|
|
262
|
+
* @returns The simple hashlink.
|
|
263
|
+
* @throws {TypeError} If the digest is malformed or unsupported.
|
|
264
|
+
* @since 2.4.0
|
|
265
|
+
*/
|
|
266
|
+
declare function createHashlink(digestMultibase: string): string;
|
|
267
|
+
/**
|
|
268
|
+
* Verifies that bytes match a SHA-256 `digestMultibase` value.
|
|
269
|
+
*
|
|
270
|
+
* @param bytes The bytes to verify.
|
|
271
|
+
* @param digestMultibase The expected digest.
|
|
272
|
+
* @returns Whether the bytes match the digest.
|
|
273
|
+
* @throws {TypeError} If the digest is malformed or unsupported.
|
|
274
|
+
* @since 2.4.0
|
|
275
|
+
*/
|
|
276
|
+
declare function verifyDigestMultibase(bytes: Uint8Array, digestMultibase: string): Promise<boolean>;
|
|
277
|
+
/**
|
|
278
|
+
* Verifies that bytes match the resource digest in a simple hashlink.
|
|
279
|
+
*
|
|
280
|
+
* @param bytes The bytes to verify.
|
|
281
|
+
* @param hashlink The simple hashlink containing the expected digest.
|
|
282
|
+
* @returns Whether the bytes match the hashlink digest.
|
|
283
|
+
* @throws {TypeError} If the hashlink or digest is malformed or unsupported.
|
|
284
|
+
* @since 2.4.0
|
|
285
|
+
*/
|
|
286
|
+
declare function verifyHashlink(bytes: Uint8Array, hashlink: string | URL): Promise<boolean>;
|
|
287
|
+
//#endregion
|
|
207
288
|
//#region src/langstr.d.ts
|
|
208
289
|
/**
|
|
209
290
|
* A language-tagged string which corresponds to the `rdf:langString` type.
|
|
@@ -390,4 +471,4 @@ declare function isValidPublicIPv4Address(address: string): boolean;
|
|
|
390
471
|
declare function isValidPublicIPv6Address(address: string): boolean;
|
|
391
472
|
declare function expandIPv6Address(address: string): string;
|
|
392
473
|
//#endregion
|
|
393
|
-
export { type AuthenticatedDocumentLoaderFactory, type CreateRequestOptions, type Decimal, type DidKeyVerificationMethod, type DocumentLoader, type DocumentLoaderFactory, type DocumentLoaderFactoryOptions, type DocumentLoaderOptions, FetchError, type GetDocumentLoaderOptions, type GetUserAgentOptions, type Json, LanguageString, type PropertyPreprocessor, type PropertyPreprocessorContext, type RemoteDocument, UrlError, arePortableUrisEqual, canParseDecimal, canonicalizePortableUri, createActivityPubRequest, decodeMultibase, encodeMultibase, encodingFromBaseData, expandIPv6Address, exportDidKey, exportMultibaseKey, exportSpki, formatIri, getDocumentLoader, getFe34Origin, getRemoteDocument, getUserAgent, haveSameFe34Origin, haveSameIriOrigin, importDidKey, importMultibaseKey, importPem, importPkcs1, importSpki, isDecimal, isGatewayUrl, isValidPublicIPv4Address, isValidPublicIPv6Address, logRequest, parseDecimal, parseDidKeyVerificationMethod, parseGatewayUrl, parseIri, parseJsonLdId, preloadedContexts, validatePublicUrl };
|
|
474
|
+
export { type AuthenticatedDocumentLoaderFactory, type CreateRequestOptions, type Decimal, type DidKeyVerificationMethod, type DocumentLoader, type DocumentLoaderFactory, type DocumentLoaderFactoryOptions, type DocumentLoaderOptions, FetchError, type GetDocumentLoaderOptions, type GetUserAgentOptions, type Json, LanguageString, type ParsedDigestMultibase, type ParsedHashlink, type PropertyPreprocessor, type PropertyPreprocessorContext, type RemoteDocument, UrlError, arePortableUrisEqual, canParseDecimal, canonicalizePortableUri, computeDigestMultibase, createActivityPubRequest, createHashlink, decodeMultibase, encodeMultibase, encodingFromBaseData, expandIPv6Address, exportDidKey, exportMultibaseKey, exportSpki, formatIri, getDocumentLoader, getFe34Origin, getRemoteDocument, getUserAgent, haveSameFe34Origin, haveSameIriOrigin, importDidKey, importMultibaseKey, importPem, importPkcs1, importSpki, isDecimal, isGatewayUrl, isValidPublicIPv4Address, isValidPublicIPv6Address, logRequest, parseDecimal, parseDidKeyVerificationMethod, parseDigestMultibase, parseGatewayUrl, parseHashlink, parseIri, parseJsonLdId, preloadedContexts, validatePublicUrl, verifyDigestMultibase, verifyHashlink };
|
package/dist/mod.d.ts
CHANGED
|
@@ -204,6 +204,87 @@ declare function canParseDecimal(value: string): boolean;
|
|
|
204
204
|
*/
|
|
205
205
|
declare function parseDecimal(value: string): Decimal;
|
|
206
206
|
//#endregion
|
|
207
|
+
//#region src/digest.d.ts
|
|
208
|
+
/**
|
|
209
|
+
* A parsed SHA-256 resource digest.
|
|
210
|
+
*
|
|
211
|
+
* @since 2.4.0
|
|
212
|
+
*/
|
|
213
|
+
interface ParsedDigestMultibase {
|
|
214
|
+
/** The multihash algorithm represented by the digest. */
|
|
215
|
+
readonly algorithm: "sha2-256";
|
|
216
|
+
/** The raw 32-byte SHA-256 digest. */
|
|
217
|
+
readonly digest: Uint8Array;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* A parsed simple hashlink.
|
|
221
|
+
*
|
|
222
|
+
* @since 2.4.0
|
|
223
|
+
*/
|
|
224
|
+
interface ParsedHashlink {
|
|
225
|
+
/** The multibase-encoded multihash carried by the hashlink. */
|
|
226
|
+
readonly digestMultibase: string;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Computes the SHA-256 digest of a byte sequence and encodes it as a
|
|
230
|
+
* base58-btc multibase multihash suitable for FEP-ef61's
|
|
231
|
+
* `digestMultibase` property.
|
|
232
|
+
*
|
|
233
|
+
* @param bytes The bytes to digest.
|
|
234
|
+
* @returns The base58-btc multibase-encoded SHA-256 multihash.
|
|
235
|
+
* @since 2.4.0
|
|
236
|
+
*/
|
|
237
|
+
declare function computeDigestMultibase(bytes: Uint8Array): Promise<string>;
|
|
238
|
+
/**
|
|
239
|
+
* Parses and validates a SHA-256 `digestMultibase` value.
|
|
240
|
+
*
|
|
241
|
+
* @param value The multibase-encoded multihash to parse.
|
|
242
|
+
* @returns The digest algorithm and raw digest bytes.
|
|
243
|
+
* @throws {TypeError} If the value is malformed or uses an unsupported hash
|
|
244
|
+
* algorithm.
|
|
245
|
+
* @since 2.4.0
|
|
246
|
+
*/
|
|
247
|
+
declare function parseDigestMultibase(value: string): ParsedDigestMultibase;
|
|
248
|
+
/**
|
|
249
|
+
* Parses a metadata-free `hl:` hashlink and validates its resource digest.
|
|
250
|
+
*
|
|
251
|
+
* @param value The simple hashlink to parse.
|
|
252
|
+
* @returns The `digestMultibase` value carried by the hashlink.
|
|
253
|
+
* @throws {TypeError} If the hashlink is malformed, contains metadata, or
|
|
254
|
+
* carries an invalid or unsupported digest.
|
|
255
|
+
* @since 2.4.0
|
|
256
|
+
*/
|
|
257
|
+
declare function parseHashlink(value: string | URL): ParsedHashlink;
|
|
258
|
+
/**
|
|
259
|
+
* Creates a metadata-free `hl:` hashlink from a `digestMultibase` value.
|
|
260
|
+
*
|
|
261
|
+
* @param digestMultibase The SHA-256 multibase multihash to embed.
|
|
262
|
+
* @returns The simple hashlink.
|
|
263
|
+
* @throws {TypeError} If the digest is malformed or unsupported.
|
|
264
|
+
* @since 2.4.0
|
|
265
|
+
*/
|
|
266
|
+
declare function createHashlink(digestMultibase: string): string;
|
|
267
|
+
/**
|
|
268
|
+
* Verifies that bytes match a SHA-256 `digestMultibase` value.
|
|
269
|
+
*
|
|
270
|
+
* @param bytes The bytes to verify.
|
|
271
|
+
* @param digestMultibase The expected digest.
|
|
272
|
+
* @returns Whether the bytes match the digest.
|
|
273
|
+
* @throws {TypeError} If the digest is malformed or unsupported.
|
|
274
|
+
* @since 2.4.0
|
|
275
|
+
*/
|
|
276
|
+
declare function verifyDigestMultibase(bytes: Uint8Array, digestMultibase: string): Promise<boolean>;
|
|
277
|
+
/**
|
|
278
|
+
* Verifies that bytes match the resource digest in a simple hashlink.
|
|
279
|
+
*
|
|
280
|
+
* @param bytes The bytes to verify.
|
|
281
|
+
* @param hashlink The simple hashlink containing the expected digest.
|
|
282
|
+
* @returns Whether the bytes match the hashlink digest.
|
|
283
|
+
* @throws {TypeError} If the hashlink or digest is malformed or unsupported.
|
|
284
|
+
* @since 2.4.0
|
|
285
|
+
*/
|
|
286
|
+
declare function verifyHashlink(bytes: Uint8Array, hashlink: string | URL): Promise<boolean>;
|
|
287
|
+
//#endregion
|
|
207
288
|
//#region src/langstr.d.ts
|
|
208
289
|
/**
|
|
209
290
|
* A language-tagged string which corresponds to the `rdf:langString` type.
|
|
@@ -390,4 +471,4 @@ declare function isValidPublicIPv4Address(address: string): boolean;
|
|
|
390
471
|
declare function isValidPublicIPv6Address(address: string): boolean;
|
|
391
472
|
declare function expandIPv6Address(address: string): string;
|
|
392
473
|
//#endregion
|
|
393
|
-
export { type AuthenticatedDocumentLoaderFactory, type CreateRequestOptions, type Decimal, type DidKeyVerificationMethod, type DocumentLoader, type DocumentLoaderFactory, type DocumentLoaderFactoryOptions, type DocumentLoaderOptions, FetchError, type GetDocumentLoaderOptions, type GetUserAgentOptions, type Json, LanguageString, type PropertyPreprocessor, type PropertyPreprocessorContext, type RemoteDocument, UrlError, arePortableUrisEqual, canParseDecimal, canonicalizePortableUri, createActivityPubRequest, decodeMultibase, encodeMultibase, encodingFromBaseData, expandIPv6Address, exportDidKey, exportMultibaseKey, exportSpki, formatIri, getDocumentLoader, getFe34Origin, getRemoteDocument, getUserAgent, haveSameFe34Origin, haveSameIriOrigin, importDidKey, importMultibaseKey, importPem, importPkcs1, importSpki, isDecimal, isGatewayUrl, isValidPublicIPv4Address, isValidPublicIPv6Address, logRequest, parseDecimal, parseDidKeyVerificationMethod, parseGatewayUrl, parseIri, parseJsonLdId, preloadedContexts, validatePublicUrl };
|
|
474
|
+
export { type AuthenticatedDocumentLoaderFactory, type CreateRequestOptions, type Decimal, type DidKeyVerificationMethod, type DocumentLoader, type DocumentLoaderFactory, type DocumentLoaderFactoryOptions, type DocumentLoaderOptions, FetchError, type GetDocumentLoaderOptions, type GetUserAgentOptions, type Json, LanguageString, type ParsedDigestMultibase, type ParsedHashlink, type PropertyPreprocessor, type PropertyPreprocessorContext, type RemoteDocument, UrlError, arePortableUrisEqual, canParseDecimal, canonicalizePortableUri, computeDigestMultibase, createActivityPubRequest, createHashlink, decodeMultibase, encodeMultibase, encodingFromBaseData, expandIPv6Address, exportDidKey, exportMultibaseKey, exportSpki, formatIri, getDocumentLoader, getFe34Origin, getRemoteDocument, getUserAgent, haveSameFe34Origin, haveSameIriOrigin, importDidKey, importMultibaseKey, importPem, importPkcs1, importSpki, isDecimal, isGatewayUrl, isValidPublicIPv4Address, isValidPublicIPv6Address, logRequest, parseDecimal, parseDidKeyVerificationMethod, parseDigestMultibase, parseGatewayUrl, parseHashlink, parseIri, parseJsonLdId, preloadedContexts, validatePublicUrl, verifyDigestMultibase, verifyHashlink };
|
package/dist/mod.js
CHANGED
|
@@ -4367,7 +4367,7 @@ const preloadedContexts = {
|
|
|
4367
4367
|
//#endregion
|
|
4368
4368
|
//#region deno.json
|
|
4369
4369
|
var name = "@fedify/vocab-runtime";
|
|
4370
|
-
var version = "2.4.0-dev.
|
|
4370
|
+
var version = "2.4.0-dev.1659+c20a23e9";
|
|
4371
4371
|
//#endregion
|
|
4372
4372
|
//#region src/link.ts
|
|
4373
4373
|
const parametersNeedLowerCase = ["rel", "type"];
|
|
@@ -4932,8 +4932,8 @@ function validateCryptoKey(key, type) {
|
|
|
4932
4932
|
}
|
|
4933
4933
|
//#endregion
|
|
4934
4934
|
//#region src/multibase/util.ts
|
|
4935
|
-
const textDecoder = new TextDecoder();
|
|
4936
|
-
const decodeText = (bytes) => textDecoder.decode(bytes);
|
|
4935
|
+
const textDecoder$1 = new TextDecoder();
|
|
4936
|
+
const decodeText = (bytes) => textDecoder$1.decode(bytes);
|
|
4937
4937
|
const textEncoder = new TextEncoder();
|
|
4938
4938
|
const encodeText = (text) => textEncoder.encode(text);
|
|
4939
4939
|
function concat(arrs, length) {
|
|
@@ -5522,6 +5522,143 @@ function parseDecimal(value) {
|
|
|
5522
5522
|
return normalized;
|
|
5523
5523
|
}
|
|
5524
5524
|
//#endregion
|
|
5525
|
+
//#region src/digest.ts
|
|
5526
|
+
const SHA2_256_MULTIHASH_CODE = 18;
|
|
5527
|
+
const SHA2_256_DIGEST_LENGTH = 32;
|
|
5528
|
+
const MAX_DIGEST_MULTIBASE_LENGTH = 1 + (SHA2_256_DIGEST_LENGTH + 2) * 8;
|
|
5529
|
+
const textDecoder = new TextDecoder();
|
|
5530
|
+
const getArrayBufferByteLength = Object.getOwnPropertyDescriptor(ArrayBuffer.prototype, "byteLength")?.get;
|
|
5531
|
+
function isCanonicalVarintPrefix(data, prefix) {
|
|
5532
|
+
const canonical = addMulticodecPrefix(prefix.code, new Uint8Array());
|
|
5533
|
+
if (canonical.length !== prefix.prefixLength) return false;
|
|
5534
|
+
for (let i = 0; i < canonical.length; i++) if (data[i] !== canonical[i]) return false;
|
|
5535
|
+
return true;
|
|
5536
|
+
}
|
|
5537
|
+
function toWebCryptoBytes(bytes) {
|
|
5538
|
+
if (getArrayBufferByteLength != null) try {
|
|
5539
|
+
getArrayBufferByteLength.call(bytes.buffer);
|
|
5540
|
+
return bytes;
|
|
5541
|
+
} catch {}
|
|
5542
|
+
return new Uint8Array(bytes);
|
|
5543
|
+
}
|
|
5544
|
+
/**
|
|
5545
|
+
* Computes the SHA-256 digest of a byte sequence and encodes it as a
|
|
5546
|
+
* base58-btc multibase multihash suitable for FEP-ef61's
|
|
5547
|
+
* `digestMultibase` property.
|
|
5548
|
+
*
|
|
5549
|
+
* @param bytes The bytes to digest.
|
|
5550
|
+
* @returns The base58-btc multibase-encoded SHA-256 multihash.
|
|
5551
|
+
* @since 2.4.0
|
|
5552
|
+
*/
|
|
5553
|
+
async function computeDigestMultibase(bytes) {
|
|
5554
|
+
const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", toWebCryptoBytes(bytes)));
|
|
5555
|
+
const multihash = addMulticodecPrefix(SHA2_256_MULTIHASH_CODE, addMulticodecPrefix(digest.length, digest));
|
|
5556
|
+
return textDecoder.decode(encodeMultibase("base58btc", multihash));
|
|
5557
|
+
}
|
|
5558
|
+
/**
|
|
5559
|
+
* Parses and validates a SHA-256 `digestMultibase` value.
|
|
5560
|
+
*
|
|
5561
|
+
* @param value The multibase-encoded multihash to parse.
|
|
5562
|
+
* @returns The digest algorithm and raw digest bytes.
|
|
5563
|
+
* @throws {TypeError} If the value is malformed or uses an unsupported hash
|
|
5564
|
+
* algorithm.
|
|
5565
|
+
* @since 2.4.0
|
|
5566
|
+
*/
|
|
5567
|
+
function parseDigestMultibase(value) {
|
|
5568
|
+
if (value.length > MAX_DIGEST_MULTIBASE_LENGTH) throw new TypeError("Invalid digestMultibase encoding.");
|
|
5569
|
+
let multihash;
|
|
5570
|
+
try {
|
|
5571
|
+
multihash = decodeMultibase(value);
|
|
5572
|
+
} catch (error) {
|
|
5573
|
+
throw new TypeError("Invalid digestMultibase encoding.", { cause: error });
|
|
5574
|
+
}
|
|
5575
|
+
const encoding = encodingFromBaseData(value);
|
|
5576
|
+
if (value !== textDecoder.decode(encodeMultibase(encoding.name, multihash))) throw new TypeError("Invalid digestMultibase encoding.");
|
|
5577
|
+
let algorithmPrefix;
|
|
5578
|
+
try {
|
|
5579
|
+
algorithmPrefix = getMulticodecPrefix(multihash);
|
|
5580
|
+
} catch (error) {
|
|
5581
|
+
throw new TypeError("Invalid digestMultibase multihash.", { cause: error });
|
|
5582
|
+
}
|
|
5583
|
+
if (!isCanonicalVarintPrefix(multihash, algorithmPrefix)) throw new TypeError("Invalid digestMultibase multihash.");
|
|
5584
|
+
if (algorithmPrefix.code !== SHA2_256_MULTIHASH_CODE) throw new TypeError(`Unsupported digest algorithm: 0x${algorithmPrefix.code.toString(16)}`);
|
|
5585
|
+
const lengthAndDigest = multihash.subarray(algorithmPrefix.prefixLength);
|
|
5586
|
+
let lengthPrefix;
|
|
5587
|
+
try {
|
|
5588
|
+
lengthPrefix = getMulticodecPrefix(lengthAndDigest);
|
|
5589
|
+
} catch (error) {
|
|
5590
|
+
throw new TypeError("Invalid digestMultibase multihash.", { cause: error });
|
|
5591
|
+
}
|
|
5592
|
+
if (!isCanonicalVarintPrefix(lengthAndDigest, lengthPrefix)) throw new TypeError("Invalid digestMultibase multihash.");
|
|
5593
|
+
const digest = lengthAndDigest.slice(lengthPrefix.prefixLength);
|
|
5594
|
+
if (lengthPrefix.code !== SHA2_256_DIGEST_LENGTH || digest.length !== SHA2_256_DIGEST_LENGTH) throw new TypeError("Invalid SHA-256 digest length.");
|
|
5595
|
+
return {
|
|
5596
|
+
algorithm: "sha2-256",
|
|
5597
|
+
digest
|
|
5598
|
+
};
|
|
5599
|
+
}
|
|
5600
|
+
function extractDigestMultibase(value) {
|
|
5601
|
+
const hashlink = typeof value === "string" ? value : value.href;
|
|
5602
|
+
const match = /^hl:([^:\r\n\u2028\u2029]+)$/i.exec(hashlink);
|
|
5603
|
+
if (match == null || match[0].length !== hashlink.length) throw new TypeError("Invalid simple hashlink.");
|
|
5604
|
+
return match[1];
|
|
5605
|
+
}
|
|
5606
|
+
/**
|
|
5607
|
+
* Parses a metadata-free `hl:` hashlink and validates its resource digest.
|
|
5608
|
+
*
|
|
5609
|
+
* @param value The simple hashlink to parse.
|
|
5610
|
+
* @returns The `digestMultibase` value carried by the hashlink.
|
|
5611
|
+
* @throws {TypeError} If the hashlink is malformed, contains metadata, or
|
|
5612
|
+
* carries an invalid or unsupported digest.
|
|
5613
|
+
* @since 2.4.0
|
|
5614
|
+
*/
|
|
5615
|
+
function parseHashlink(value) {
|
|
5616
|
+
const digestMultibase = extractDigestMultibase(value);
|
|
5617
|
+
parseDigestMultibase(digestMultibase);
|
|
5618
|
+
return { digestMultibase };
|
|
5619
|
+
}
|
|
5620
|
+
/**
|
|
5621
|
+
* Creates a metadata-free `hl:` hashlink from a `digestMultibase` value.
|
|
5622
|
+
*
|
|
5623
|
+
* @param digestMultibase The SHA-256 multibase multihash to embed.
|
|
5624
|
+
* @returns The simple hashlink.
|
|
5625
|
+
* @throws {TypeError} If the digest is malformed or unsupported.
|
|
5626
|
+
* @since 2.4.0
|
|
5627
|
+
*/
|
|
5628
|
+
function createHashlink(digestMultibase) {
|
|
5629
|
+
parseDigestMultibase(digestMultibase);
|
|
5630
|
+
return `hl:${digestMultibase}`;
|
|
5631
|
+
}
|
|
5632
|
+
/**
|
|
5633
|
+
* Verifies that bytes match a SHA-256 `digestMultibase` value.
|
|
5634
|
+
*
|
|
5635
|
+
* @param bytes The bytes to verify.
|
|
5636
|
+
* @param digestMultibase The expected digest.
|
|
5637
|
+
* @returns Whether the bytes match the digest.
|
|
5638
|
+
* @throws {TypeError} If the digest is malformed or unsupported.
|
|
5639
|
+
* @since 2.4.0
|
|
5640
|
+
*/
|
|
5641
|
+
async function verifyDigestMultibase(bytes, digestMultibase) {
|
|
5642
|
+
const expected = parseDigestMultibase(digestMultibase).digest;
|
|
5643
|
+
const actual = new Uint8Array(await crypto.subtle.digest("SHA-256", toWebCryptoBytes(bytes)));
|
|
5644
|
+
if (expected.length !== actual.length) return false;
|
|
5645
|
+
let difference = 0;
|
|
5646
|
+
for (let i = 0; i < expected.length; i++) difference |= expected[i] ^ actual[i];
|
|
5647
|
+
return difference === 0;
|
|
5648
|
+
}
|
|
5649
|
+
/**
|
|
5650
|
+
* Verifies that bytes match the resource digest in a simple hashlink.
|
|
5651
|
+
*
|
|
5652
|
+
* @param bytes The bytes to verify.
|
|
5653
|
+
* @param hashlink The simple hashlink containing the expected digest.
|
|
5654
|
+
* @returns Whether the bytes match the hashlink digest.
|
|
5655
|
+
* @throws {TypeError} If the hashlink or digest is malformed or unsupported.
|
|
5656
|
+
* @since 2.4.0
|
|
5657
|
+
*/
|
|
5658
|
+
async function verifyHashlink(bytes, hashlink) {
|
|
5659
|
+
return await verifyDigestMultibase(bytes, extractDigestMultibase(hashlink));
|
|
5660
|
+
}
|
|
5661
|
+
//#endregion
|
|
5525
5662
|
//#region src/langstr.ts
|
|
5526
5663
|
/**
|
|
5527
5664
|
* A language-tagged string which corresponds to the `rdf:langString` type.
|
|
@@ -5550,4 +5687,4 @@ LanguageString.prototype[Symbol.for("nodejs.util.inspect.custom")] = function(_d
|
|
|
5550
5687
|
return `<${this.locale.baseName}> ${inspect(this.toString(), options)}`;
|
|
5551
5688
|
};
|
|
5552
5689
|
//#endregion
|
|
5553
|
-
export { FetchError, LanguageString, UrlError, arePortableUrisEqual, canParseDecimal, canonicalizePortableUri, createActivityPubRequest, decodeMultibase, encodeMultibase, encodingFromBaseData, expandIPv6Address, exportDidKey, exportMultibaseKey, exportSpki, formatIri, getDocumentLoader, getFe34Origin, getRemoteDocument, getUserAgent, haveSameFe34Origin, haveSameIriOrigin, importDidKey, importMultibaseKey, importPem, importPkcs1, importSpki, isDecimal, isGatewayUrl, isValidPublicIPv4Address, isValidPublicIPv6Address, logRequest, parseDecimal, parseDidKeyVerificationMethod, parseGatewayUrl, parseIri, parseJsonLdId, preloadedContexts, validatePublicUrl };
|
|
5690
|
+
export { FetchError, LanguageString, UrlError, arePortableUrisEqual, canParseDecimal, canonicalizePortableUri, computeDigestMultibase, createActivityPubRequest, createHashlink, decodeMultibase, encodeMultibase, encodingFromBaseData, expandIPv6Address, exportDidKey, exportMultibaseKey, exportSpki, formatIri, getDocumentLoader, getFe34Origin, getRemoteDocument, getUserAgent, haveSameFe34Origin, haveSameIriOrigin, importDidKey, importMultibaseKey, importPem, importPkcs1, importSpki, isDecimal, isGatewayUrl, isValidPublicIPv4Address, isValidPublicIPv6Address, logRequest, parseDecimal, parseDidKeyVerificationMethod, parseDigestMultibase, parseGatewayUrl, parseHashlink, parseIri, parseJsonLdId, preloadedContexts, validatePublicUrl, verifyDigestMultibase, verifyHashlink };
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
require("./chunk-C2EiDwsr.cjs");
|
|
2
|
-
require("./docloader-
|
|
2
|
+
require("./docloader-CDetn4RD.cjs");
|
|
3
3
|
require("./url-CsOV_B_P.cjs");
|
|
4
|
-
require("./key-
|
|
5
|
-
require("./multibase-
|
|
6
|
-
require("./
|
|
4
|
+
require("./key-BcOWDLMm.cjs");
|
|
5
|
+
require("./multibase-DcDQDNnI.cjs");
|
|
6
|
+
require("./digest-DLwUyHCK.cjs");
|
|
7
|
+
require("./langstr-BOQHfJDr.cjs");
|
|
7
8
|
let node_assert = require("node:assert");
|
|
8
9
|
let node_test = require("node:test");
|
|
9
10
|
//#region src/decimal.ts
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import "./docloader-
|
|
1
|
+
import "./docloader-C_0493V1.mjs";
|
|
2
2
|
import "./url-Du7RQQgP.mjs";
|
|
3
|
-
import "./key-
|
|
4
|
-
import "./multibase-
|
|
5
|
-
import "./
|
|
3
|
+
import "./key-Drbw_2tw.mjs";
|
|
4
|
+
import "./multibase-Cluwl8OM.mjs";
|
|
5
|
+
import "./digest-BJlumPNJ.mjs";
|
|
6
|
+
import "./langstr-DDLc4833.mjs";
|
|
6
7
|
import { deepStrictEqual, throws } from "node:assert";
|
|
7
8
|
import { test } from "node:test";
|
|
8
9
|
//#region src/decimal.ts
|